More changes for GO32 canadian cross builds
[deliverable/binutils-gdb.git] / sim / ppc / device_table.c
1 /* This file is part of the program psim.
2
3 Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20
21
22 #ifndef _DEVICE_TABLE_C_
23 #define _DEVICE_TABLE_C_
24
25 #ifndef STATIC_INLINE_DEVICE_TABLE
26 #define STATIC_INLINE_DEVICE_TABLE STATIC_INLINE
27 #endif
28
29 #include <stdio.h>
30 #include <fcntl.h>
31 #include <signal.h>
32 #include <stdarg.h>
33 #include <ctype.h>
34
35 #include "device_table.h"
36
37 #include "events.h"
38
39 #ifdef HAVE_UNISTD_H
40 #include <unistd.h>
41 #endif
42
43 #ifdef HAVE_STDLIB_H
44 #include <stdlib.h>
45 #endif
46
47 #ifdef HAVE_STRING_H
48 #include <string.h>
49 #else
50 #ifdef HAVE_STRINGS_H
51 #include <strings.h>
52 #endif
53 #endif
54
55 #include "cpu.h"
56
57 #include "bfd.h"
58
59 /* Helper functions */
60
61 /* Generic device init: Attaches the device of size <nr_bytes> (taken
62 from <name>@<int>,<nr_bytes>) to its parent at address zero and
63 with read/write access. */
64
65 typedef struct _reg_spec {
66 unsigned32 base;
67 unsigned32 size;
68 } reg_spec;
69
70 void
71 generic_device_init_address(device *me,
72 psim *system)
73 {
74 const device_property *reg = device_find_array_property(me, "reg");
75 const reg_spec *spec = reg->array;
76 int nr_entries = reg->sizeof_array / sizeof(reg_spec);
77
78 if ((reg->sizeof_array % sizeof(reg_spec)) != 0)
79 error("devices/%s reg property is of wrong size\n", device_name(me));
80
81 while (nr_entries > 0) {
82 device_attach_address(device_parent(me),
83 device_name(me),
84 attach_callback,
85 0 /*space*/,
86 BE2H_4(spec->base),
87 BE2H_4(spec->size),
88 access_read_write_exec,
89 me);
90 spec++;
91 nr_entries--;
92 }
93 }
94
95 int
96 generic_device_unit_decode(device *me,
97 const char *unit,
98 device_unit *phys)
99 {
100 memset(phys, 0, sizeof(device_unit));
101 if (unit == NULL)
102 return 0;
103 else {
104 char *pos = (char*)unit; /* force for strtoul() */
105 while (1) {
106 char *old_pos = pos;
107 long int val = strtoul(pos, &pos, 0);
108 if (old_pos == pos && *pos == '\0')
109 return phys->nr_cells;
110 if (old_pos == pos && *pos != '\0')
111 return -1;
112 if (phys->nr_cells == 4)
113 return -1;
114 phys->cells[phys->nr_cells] = val;
115 phys->nr_cells++;
116 }
117 }
118 }
119
120 int
121 generic_device_unit_encode(device *me,
122 const device_unit *phys,
123 char *buf,
124 int sizeof_buf)
125 {
126 int i;
127 int len;
128 char *pos = buf; /* force for strtoul() */
129 for (i = 0; i < phys->nr_cells; i++) {
130 if (pos != buf) {
131 strcat(pos, ",");
132 pos = strchr(pos, '\0');
133 }
134 sprintf(pos, "0x%lx", (unsigned long)phys->cells[i]);
135 pos = strchr(pos, '\0');
136 }
137 len = pos - buf;
138 if (len >= sizeof_buf)
139 error("generic_unit_encode - buffer overflow\n");
140 return len;
141 }
142
143 /* DMA a file into memory */
144 STATIC_INLINE_DEVICE_TABLE int
145 dma_file(device *me,
146 const char *file_name,
147 unsigned_word addr)
148 {
149 int count;
150 int inc;
151 FILE *image;
152 char buf[1024];
153
154 /* get it open */
155 image = fopen(file_name, "r");
156 if (image == NULL)
157 return -1;
158
159 /* read it in slowly */
160 count = 0;
161 while (1) {
162 inc = fread(buf, 1, sizeof(buf), image);
163 if (feof(image) || ferror(image))
164 break;
165 if (device_dma_write_buffer(device_parent(me),
166 buf,
167 0 /*address-space*/,
168 addr+count,
169 inc /*nr-bytes*/,
170 1 /*violate ro*/) != inc) {
171 fclose(image);
172 return -1;
173 }
174 count += inc;
175 }
176
177 /* close down again */
178 fclose(image);
179
180 return count;
181 }
182
183
184 \f
185 /* inimplemented versions of each function */
186
187 void
188 unimp_device_init(device *me,
189 psim *system)
190 {
191 error("device_init_callback for %s not implemented\n", device_name(me));
192 }
193
194 void
195 unimp_device_attach_address(device *me,
196 const char *name,
197 attach_type type,
198 int space,
199 unsigned_word addr,
200 unsigned nr_bytes,
201 access_type access,
202 device *who) /*callback/default*/
203 {
204 error("device_attach_address_callback for %s not implemented\n", device_name(me));
205 }
206
207 void
208 unimp_device_detach_address(device *me,
209 const char *name,
210 attach_type type,
211 int space,
212 unsigned_word addr,
213 unsigned nr_bytes,
214 access_type access,
215 device *who) /*callback/default*/
216 {
217 error("device_detach_address_callback for %s not implemented\n", device_name(me));
218 }
219
220 unsigned
221 unimp_device_io_read_buffer(device *me,
222 void *dest,
223 int space,
224 unsigned_word addr,
225 unsigned nr_bytes,
226 cpu *processor,
227 unsigned_word cia)
228 {
229 error("device_io_read_buffer_callback for %s not implemented\n", device_name(me));
230 return 0;
231 }
232
233 unsigned
234 unimp_device_io_write_buffer(device *me,
235 const void *source,
236 int space,
237 unsigned_word addr,
238 unsigned nr_bytes,
239 cpu *processor,
240 unsigned_word cia)
241 {
242 error("device_io_write_buffer_callback for %s not implemented\n", device_name(me));
243 return 0;
244 }
245
246 unsigned
247 unimp_device_dma_read_buffer(device *me,
248 void *target,
249 int space,
250 unsigned_word addr,
251 unsigned nr_bytes)
252 {
253 error("device_dma_read_buffer_callback for %s not implemented\n", device_name(me));
254 return 0;
255 }
256
257 unsigned
258 unimp_device_dma_write_buffer(device *me,
259 const void *source,
260 int space,
261 unsigned_word addr,
262 unsigned nr_bytes,
263 int violate_read_only_section)
264 {
265 error("device_dma_write_buffer_callback for %s not implemented\n", device_name(me));
266 return 0;
267 }
268
269 void
270 unimp_device_interrupt_event(device *me,
271 int my_port,
272 device *source,
273 int source_port,
274 int level,
275 cpu *processor,
276 unsigned_word cia)
277 {
278 error("unimp_device_interrupt_event for %s unimplemented\n",
279 device_name(me));
280 }
281
282 void
283 unimp_device_child_interrupt_event(device *me,
284 device *parent,
285 device *source,
286 int source_port,
287 int level,
288 cpu *processor,
289 unsigned_word cia)
290 {
291 error("unimp_device_child_interrupt_event_callback for %s unimplemented\n",
292 device_name(me));
293 }
294
295 int
296 unimp_device_unit_decode(device *me,
297 const char *unit,
298 device_unit *address)
299 {
300 error("unimp_device_unit_decode_callback for %s unimplemented\n",
301 device_name(me));
302 return 0;
303 }
304
305 int
306 unimp_device_unit_encode(device *me,
307 const device_unit *unit_address,
308 char *buf,
309 int sizeof_buf)
310 {
311 error("unimp_device_unit_encode_callback for %s unimplemented\n",
312 device_name(me));
313 return 0;
314 }
315
316 void *
317 unimp_device_instance_create(device *me,
318 const char *args)
319 {
320 error("unimp_device_instance_create_callback for %s unimplemented\n",
321 device_name(me));
322 return 0;
323 }
324
325 void
326 unimp_device_instance_delete(device_instance *instance)
327 {
328 error("unimp_device_instance_delete_callback for %s unimplemented\n",
329 device_instance_name(instance));
330 }
331
332 int
333 unimp_device_instance_read(device_instance *instance,
334 void *buf,
335 unsigned_word len)
336 {
337 error("unimp_device_instance_read_callback for %s unimplemented\n",
338 device_instance_name(instance));
339 return 0;
340 }
341
342 int
343 unimp_device_instance_write(device_instance *instance,
344 const void *buf,
345 unsigned_word len)
346 {
347 error("unimp_device_instance_write_callback for %s unimplemented\n",
348 device_instance_name(instance));
349 return 0;
350 }
351
352 int
353 unimp_device_instance_seek(device_instance *instance,
354 unsigned_word pos_hi,
355 unsigned_word pos_lo)
356 {
357 error("unimp_device_instance_seek_callback for %s unimplemented\n",
358 device_instance_name(instance));
359 return 0;
360 }
361
362
363 void
364 unimp_device_ioctl(device *me,
365 psim *system,
366 cpu *processor,
367 unsigned_word cia,
368 va_list ap)
369 {
370 error("device_ioctl_callback for %s not implemented\n", device_name(me));
371 }
372
373
374 \f
375 /* ignore/passthrough versions of each function */
376
377 void
378 ignore_device_init(device *me,
379 psim *system)
380 {
381 /*null*/
382 }
383
384 void
385 passthrough_device_attach_address(device *me,
386 const char *name,
387 attach_type attach,
388 int space,
389 unsigned_word addr,
390 unsigned nr_bytes,
391 access_type access,
392 device *who) /*callback/default*/
393 {
394 device_attach_address(device_parent(me), name, attach,
395 space, addr, nr_bytes,
396 access,
397 who);
398 }
399
400 void
401 passthrough_device_detach_address(device *me,
402 const char *name,
403 attach_type attach,
404 int space,
405 unsigned_word addr,
406 unsigned nr_bytes,
407 access_type access,
408 device *who) /*callback/default*/
409 {
410 device_detach_address(device_parent(me), name, attach,
411 space, addr, nr_bytes, access,
412 who);
413 }
414
415 unsigned
416 passthrough_device_dma_read_buffer(device *me,
417 void *dest,
418 int space,
419 unsigned_word addr,
420 unsigned nr_bytes)
421 {
422 return device_dma_read_buffer(device_parent(me), dest,
423 space, addr, nr_bytes);
424 }
425
426 unsigned
427 passthrough_device_dma_write_buffer(device *me,
428 const void *source,
429 int space,
430 unsigned_word addr,
431 unsigned nr_bytes,
432 int violate_read_only_section)
433 {
434 return device_dma_write_buffer(device_parent(me), source,
435 space, addr,
436 nr_bytes,
437 violate_read_only_section);
438 }
439
440 int
441 ignore_device_unit_decode(device *me,
442 const char *unit,
443 device_unit *phys)
444 {
445 memset(phys, 0, sizeof(device_unit));
446 return 0;
447 }
448
449
450 static const device_callbacks passthrough_callbacks = {
451 ignore_device_init,
452 ignore_device_init,
453 passthrough_device_attach_address,
454 passthrough_device_detach_address,
455 unimp_device_io_read_buffer,
456 unimp_device_io_write_buffer,
457 passthrough_device_dma_read_buffer,
458 passthrough_device_dma_write_buffer,
459 unimp_device_interrupt_event,
460 unimp_device_child_interrupt_event,
461 generic_device_unit_decode,
462 generic_device_unit_encode,
463 unimp_device_instance_create,
464 unimp_device_instance_delete,
465 unimp_device_instance_read,
466 unimp_device_instance_write,
467 unimp_device_instance_seek,
468 unimp_device_ioctl,
469 };
470
471
472 \f
473 /* Simple console device: console@<address>,16
474
475 Input characters are taken from the keyboard, output characters
476 sent to the terminal. Echoing of characters is not disabled.
477
478 The device has four registers:
479
480 0x0: read
481 0x4: read-status
482 0x8: write
483 0xC: write-status
484
485 Where a nonzero status register indicates that the device is ready
486 (input fifo contains a character or output fifo has space). */
487
488 typedef struct _console_buffer {
489 char buffer;
490 int status;
491 event_entry_tag event_tag;
492 } console_buffer;
493
494 typedef struct _console_device {
495 console_buffer input;
496 console_buffer output;
497 } console_device;
498
499 typedef enum {
500 console_read_buffer = 0,
501 console_read_status = 4,
502 console_write_buffer = 8,
503 console_write_status = 12,
504 console_offset_mask = 0xc,
505 console_size = 16,
506 } console_offsets;
507
508 static int console_use_stdio = WITH_STDIO;
509
510 /* check the console for an available character */
511 static void
512 scan_console(console_device *console)
513 { /* check for input */
514 int flags;
515 int status;
516
517 /* Use stdio if desired. */
518 if (console_use_stdio) {
519 int ch = getchar ();
520 if (ch == EOF) {
521 console->input.status = 0;
522 console->input.buffer = '\0';
523 } else {
524 console->input.status = 1;
525 console->input.buffer = ch;
526 }
527 return;
528 }
529
530 /* get the old status */
531 flags = fcntl(0, F_GETFL, 0);
532 if (flags == -1) {
533 perror("console");
534 return;
535 }
536
537 /* temp, disable blocking IO */
538 status = fcntl(0, F_SETFL, flags | O_NDELAY);
539 if (status == -1) {
540 perror("console");
541 return;
542 }
543 /* try for input */
544 status = read(0, &console->input.buffer, 1);
545 if (status == 1) {
546 console->input.status = 1;
547 }
548 else {
549 console->input.status = 0;
550 }
551 /* return to regular vewing */
552 flags = fcntl(0, F_SETFL, flags);
553 if (flags == -1) {
554 perror("console");
555 return;
556 }
557 }
558
559 /* write the character to the console */
560 static void
561 write_console(console_device *console,
562 char val)
563 {
564 DTRACE(console, ("<%c:%d>", val, val));
565 if (console_use_stdio)
566 putchar (val);
567 else
568 printf_filtered("%c", val) ;
569 console->output.buffer = val;
570 console->output.status = 1;
571 }
572
573 static unsigned
574 console_io_read_buffer_callback(device *me,
575 void *dest,
576 int space,
577 unsigned_word addr,
578 unsigned nr_bytes,
579 cpu *processor,
580 unsigned_word cia)
581 {
582 console_device *console = (console_device*)device_data(me);
583 unsigned_1 val;
584
585 /* determine what was read */
586
587 switch ((int)addr & console_offset_mask) {
588
589 case console_read_buffer:
590 val = console->input.buffer;
591 break;
592
593 case console_read_status:
594 scan_console(console);
595 val = console->input.status;
596 break;
597
598 case console_write_buffer:
599 val = console->output.buffer;
600 break;
601
602 case console_write_status:
603 val = console->output.status;
604 break;
605
606 default:
607 error("console_read_callback() internal error\n");
608 val = 0;
609 break;
610
611 }
612
613 memset(dest, 0, nr_bytes);
614 *(unsigned_1*)dest = val;
615 return nr_bytes;
616 }
617
618 static unsigned
619 console_io_write_buffer_callback(device *me,
620 const void *source,
621 int space,
622 unsigned_word addr,
623 unsigned nr_bytes,
624 cpu *processor,
625 unsigned_word cia)
626 {
627 console_device *console = (console_device*)device_data(me);
628 unsigned_1 val = *(unsigned_1*)source;
629
630 switch ((int)addr & console_offset_mask) {
631
632 case console_read_buffer:
633 console->input.buffer = val;
634 break;
635
636 case console_read_status:
637 console->input.status = val;
638 break;
639
640 case console_write_buffer:
641 write_console(console, val);
642 if (console_use_stdio)
643 fflush (stdout);
644 break;
645
646 case console_write_status:
647 console->output.status = val;
648 break;
649
650 default:
651 error("console_write_callback() internal error\n");
652
653 }
654
655 return nr_bytes;
656 }
657
658 /* instances of the console device */
659 static void *
660 console_instance_create_callback(device *me,
661 const char *args)
662 {
663 /* make life easier, attach the console data to the instance */
664 return device_data(me);
665 }
666
667 static void
668 console_instance_delete_callback(device_instance *instance)
669 {
670 /* nothing to delete, the console is attached to the device */
671 return;
672 }
673
674 static int
675 console_instance_read_callback(device_instance *instance,
676 void *buf,
677 unsigned_word len)
678 {
679 console_device *console = device_instance_data(instance);
680 if (console_use_stdio) {
681 char *p = fgets (buf, len, stdin);
682 if (!p)
683 return ferror (stdin) ? -1 : -2;
684
685 return strlen (p);
686 }
687
688 if (!console->input.status)
689 scan_console(console);
690 if (console->input.status) {
691 *(char*)buf = console->input.buffer;
692 console->input.status = 0;
693 return 1;
694 }
695 else {
696 return -2; /* not ready */
697 }
698 }
699
700 static int
701 console_instance_write_callback(device_instance *instance,
702 const void *buf,
703 unsigned_word len)
704 {
705 int i;
706 const char *chp = buf;
707 console_device *console = device_instance_data(instance);
708 for (i = 0; i < len; i++)
709 write_console(console, chp[i]);
710 if (console_use_stdio && len)
711 fflush (stdout);
712 return i;
713 }
714
715 static device_callbacks const console_callbacks = {
716 generic_device_init_address,
717 ignore_device_init,
718 unimp_device_attach_address,
719 unimp_device_detach_address,
720 console_io_read_buffer_callback,
721 console_io_write_buffer_callback,
722 unimp_device_dma_read_buffer,
723 unimp_device_dma_write_buffer,
724 unimp_device_interrupt_event,
725 unimp_device_child_interrupt_event,
726 unimp_device_unit_decode,
727 unimp_device_unit_encode,
728 console_instance_create_callback,
729 console_instance_delete_callback,
730 console_instance_read_callback,
731 console_instance_write_callback,
732 unimp_device_instance_seek,
733 unimp_device_ioctl,
734 };
735
736
737 static void *
738 console_create(const char *name,
739 const device_unit *unit_address,
740 const char *args,
741 device *parent)
742 {
743 /* create the descriptor */
744 console_device *console = ZALLOC(console_device);
745 console->output.status = 1;
746 console->output.buffer = '\0';
747 console->input.status = 0;
748 console->input.buffer = '\0';
749 return console;
750 }
751
752
753 \f
754 /* ICU device: icu@<address>
755
756 <address> : read - processor nr
757 <address> : write - interrupt processor nr
758 <address> + 4 : read - nr processors
759
760 Single byte registers that control a simple ICU.
761
762 Illustrates passing of events to parent device. Passing of
763 interrupts to an interrupt destination. */
764
765
766 static unsigned
767 icu_io_read_buffer_callback(device *me,
768 void *dest,
769 int space,
770 unsigned_word addr,
771 unsigned nr_bytes,
772 cpu *processor,
773 unsigned_word cia)
774 {
775 memset(dest, 0, nr_bytes);
776 switch (addr & 4) {
777 case 0:
778 *(unsigned_1*)dest = cpu_nr(processor);
779 break;
780 case 4:
781 *(unsigned_1*)dest =
782 device_find_integer_property(me, "/openprom/options/smp");
783 break;
784 }
785 return nr_bytes;
786 }
787
788
789 static unsigned
790 icu_io_write_buffer_callback(device *me,
791 const void *source,
792 int space,
793 unsigned_word addr,
794 unsigned nr_bytes,
795 cpu *processor,
796 unsigned_word cia)
797 {
798 unsigned_1 val = H2T_1(*(unsigned_1*)source);
799 /* tell the parent device that the interrupt lines have changed.
800 For this fake ICU. The interrupt lines just indicate the cpu to
801 interrupt next */
802 device_interrupt_event(me,
803 val, /*my_port*/
804 val, /*val*/
805 processor, cia);
806 return nr_bytes;
807 }
808
809 static void
810 icu_do_interrupt(event_queue *queue,
811 void *data)
812 {
813 cpu *target = (cpu*)data;
814 /* try to interrupt the processor. If the attempt fails, try again
815 on the next tick */
816 if (!external_interrupt(target))
817 event_queue_schedule(queue, 1, icu_do_interrupt, target);
818 }
819
820
821 static void
822 icu_interrupt_event_callback(device *me,
823 int my_port,
824 device *source,
825 int source_port,
826 int level,
827 cpu *processor,
828 unsigned_word cia)
829 {
830 /* the interrupt controller can't interrupt a cpu at any time.
831 Rather it must synchronize with the system clock before
832 performing an interrupt on the given processor */
833 psim *system = cpu_system(processor);
834 cpu *target = psim_cpu(system, my_port);
835 if (target != NULL) {
836 event_queue *events = cpu_event_queue(target);
837 event_queue_schedule(events, 1, icu_do_interrupt, target);
838 }
839 }
840
841 static device_callbacks const icu_callbacks = {
842 generic_device_init_address,
843 ignore_device_init,
844 unimp_device_attach_address,
845 unimp_device_detach_address,
846 icu_io_read_buffer_callback,
847 icu_io_write_buffer_callback,
848 unimp_device_dma_read_buffer,
849 unimp_device_dma_write_buffer,
850 icu_interrupt_event_callback,
851 unimp_device_child_interrupt_event,
852 unimp_device_unit_decode,
853 unimp_device_unit_encode,
854 unimp_device_instance_create,
855 unimp_device_instance_delete,
856 unimp_device_instance_read,
857 unimp_device_instance_write,
858 unimp_device_instance_seek,
859 unimp_device_ioctl,
860 };
861
862
863 \f
864 /* HALT device: halt@0x<address>,4
865
866 With real hardware, the processor operation is normally terminated
867 through a reset. This device illustrates how a reset device could
868 be attached to an address */
869
870
871 static unsigned
872 halt_io_read_buffer_callback(device *me,
873 void *dest,
874 int space,
875 unsigned_word addr,
876 unsigned nr_bytes,
877 cpu *processor,
878 unsigned_word cia)
879 {
880 cpu_halt(processor, cia, was_exited, 0);
881 return 0;
882 }
883
884
885 static unsigned
886 halt_io_write_buffer_callback(device *me,
887 const void *source,
888 int space,
889 unsigned_word addr,
890 unsigned nr_bytes,
891 cpu *processor,
892 unsigned_word cia)
893 {
894 cpu_halt(processor, cia, was_exited, *(unsigned_1*)source);
895 return 0;
896 }
897
898
899 static device_callbacks const halt_callbacks = {
900 generic_device_init_address,
901 ignore_device_init,
902 unimp_device_attach_address,
903 unimp_device_detach_address,
904 halt_io_read_buffer_callback,
905 halt_io_write_buffer_callback,
906 unimp_device_dma_read_buffer,
907 unimp_device_dma_write_buffer,
908 unimp_device_interrupt_event,
909 unimp_device_child_interrupt_event,
910 unimp_device_unit_decode,
911 unimp_device_unit_encode,
912 unimp_device_instance_create,
913 unimp_device_instance_delete,
914 unimp_device_instance_read,
915 unimp_device_instance_write,
916 unimp_device_instance_seek,
917 unimp_device_ioctl,
918 };
919
920
921 \f
922 /* Register init device: register@<nothing>
923
924 Properties attached to the register device specify the name/value
925 initialization pair for cpu registers.
926
927 A specific processor can be initialized by creating a property with
928 a name like `0.pc'.
929
930 Properties are normally processed old-to-new and this function
931 needs to allow older (first in) properties to override new (last
932 in) ones. The suport function do_register_init() manages this. */
933
934 static void
935 do_register_init(device *me,
936 psim *system,
937 const device_property *prop)
938 {
939 if (prop != NULL) {
940 const char *name = prop->name;
941 unsigned32 value = device_find_integer_property(me, name);
942 int processor;
943
944 do_register_init(me, system, device_next_property(prop));
945
946 if (strchr(name, '.') == NULL) {
947 processor = -1;
948 DTRACE(register, ("%s=0x%lx\n", name, (unsigned long)value));
949 }
950 else {
951 char *end;
952 processor = strtoul(name, &end, 0);
953 ASSERT(end[0] == '.');
954 name = end+1;
955 DTRACE(register, ("%d.%s=0x%lx\n", processor, name,
956 (unsigned long)value));
957 }
958 psim_write_register(system, processor, /* all processors */
959 &value,
960 name,
961 cooked_transfer);
962 }
963 }
964
965
966 static void
967 register_init_data_callback(device *me,
968 psim *system)
969 {
970 const device_property *prop = device_find_property(me, NULL);
971 do_register_init(me, system, prop);
972 }
973
974
975 static device_callbacks const register_callbacks = {
976 ignore_device_init,
977 register_init_data_callback,
978 unimp_device_attach_address,
979 unimp_device_detach_address,
980 unimp_device_io_read_buffer,
981 unimp_device_io_write_buffer,
982 unimp_device_dma_read_buffer,
983 unimp_device_dma_write_buffer,
984 unimp_device_interrupt_event,
985 unimp_device_child_interrupt_event,
986 unimp_device_unit_decode,
987 unimp_device_unit_encode,
988 unimp_device_instance_create,
989 unimp_device_instance_delete,
990 unimp_device_instance_read,
991 unimp_device_instance_write,
992 unimp_device_instance_seek,
993 unimp_device_ioctl,
994 };
995
996
997 \f
998 /* Trace device:
999
1000 Properties attached to the trace device are names and values for
1001 the various trace variables. When initialized trace goes through
1002 the propertie and sets the global trace variables so that they
1003 match what was specified in the device tree. */
1004
1005 static void
1006 trace_init_data_callback(device *me,
1007 psim *system)
1008 {
1009 const device_property *prop = device_find_property(me, NULL);
1010 while (prop != NULL) {
1011 const char *name = prop->name;
1012 unsigned32 value = device_find_integer_property(me, name);
1013 trace_option(name, value);
1014 prop = device_next_property(prop);
1015 }
1016 }
1017
1018
1019 static device_callbacks const trace_callbacks = {
1020 ignore_device_init,
1021 trace_init_data_callback,
1022 unimp_device_attach_address,
1023 unimp_device_detach_address,
1024 unimp_device_io_read_buffer,
1025 unimp_device_io_write_buffer,
1026 unimp_device_dma_read_buffer,
1027 unimp_device_dma_write_buffer,
1028 unimp_device_interrupt_event,
1029 unimp_device_child_interrupt_event,
1030 unimp_device_unit_decode,
1031 unimp_device_unit_encode,
1032 unimp_device_instance_create,
1033 unimp_device_instance_delete,
1034 unimp_device_instance_read,
1035 unimp_device_instance_write,
1036 unimp_device_instance_seek,
1037 unimp_device_ioctl,
1038 };
1039
1040
1041 \f
1042 /* VEA VM:
1043
1044 vm@<stack-base>
1045 stack-base =
1046 nr-bytes =
1047
1048 A VEA mode device. This sets its self up as the default memory
1049 device capturing all accesses (reads/writes) to currently unmapped
1050 addresses. If the unmaped access falls within unallocated stack or
1051 heap address ranges then memory is allocated and the access is
1052 allowed to continue.
1053
1054 During init phase, this device expects to receive `attach' requests
1055 from its children for the text/data/bss memory areas. Typically,
1056 this would be done by the binary device.
1057
1058 STACK: The location of the stack in memory is specified as part of
1059 the devices name. Unmaped accesses that fall within the stack
1060 space result in the allocated stack being grown downwards so that
1061 it includes the page of the culprit access.
1062
1063 HEAP: During initialization, the vm device monitors all `attach'
1064 operations from its children using this to determine the initial
1065 location of the heap. The heap is then extended by system calls
1066 that frob the heap upper bound variable (see system.c). */
1067
1068
1069 typedef struct _vm_device {
1070 /* area of memory valid for stack addresses */
1071 unsigned_word stack_base; /* min possible stack value */
1072 unsigned_word stack_bound;
1073 unsigned_word stack_lower_limit;
1074 /* area of memory valid for heap addresses */
1075 unsigned_word heap_base;
1076 unsigned_word heap_bound;
1077 unsigned_word heap_upper_limit;
1078 } vm_device;
1079
1080
1081 static void
1082 vm_init_address_callback(device *me,
1083 psim *system)
1084 {
1085 vm_device *vm = (vm_device*)device_data(me);
1086
1087 /* revert the stack/heap variables to their defaults */
1088 vm->stack_base = device_find_integer_property(me, "stack-base");
1089 vm->stack_bound = (vm->stack_base
1090 + device_find_integer_property(me, "nr-bytes"));
1091 vm->stack_lower_limit = vm->stack_bound;
1092 vm->heap_base = 0;
1093 vm->heap_bound = 0;
1094 vm->heap_upper_limit = 0;
1095
1096 /* establish this device as the default memory handler */
1097 device_attach_address(device_parent(me),
1098 device_name(me),
1099 attach_default,
1100 0 /*address space - ignore*/,
1101 0 /*addr - ignore*/,
1102 0 /*nr_bytes - ignore*/,
1103 access_read_write /*access*/,
1104 me);
1105 }
1106
1107
1108 static void
1109 vm_attach_address(device *me,
1110 const char *name,
1111 attach_type attach,
1112 int space,
1113 unsigned_word addr,
1114 unsigned nr_bytes,
1115 access_type access,
1116 device *who) /*callback/default*/
1117 {
1118 vm_device *vm = (vm_device*)device_data(me);
1119 /* update end of bss if necessary */
1120 if (vm->heap_base < addr + nr_bytes) {
1121 vm->heap_base = addr + nr_bytes;
1122 vm->heap_bound = addr + nr_bytes;
1123 vm->heap_upper_limit = addr + nr_bytes;
1124 }
1125 device_attach_address(device_parent(me),
1126 "vm@0x0,0", /* stop remap */
1127 attach_raw_memory,
1128 0 /*address space*/,
1129 addr,
1130 nr_bytes,
1131 access,
1132 me);
1133 }
1134
1135
1136 STATIC_INLINE_DEVICE_TABLE unsigned
1137 add_vm_space(device *me,
1138 unsigned_word addr,
1139 unsigned nr_bytes,
1140 cpu *processor,
1141 unsigned_word cia)
1142 {
1143 vm_device *vm = (vm_device*)device_data(me);
1144 unsigned_word block_addr;
1145 unsigned block_nr_bytes;
1146
1147 /* an address in the stack area, allocate just down to the addressed
1148 page */
1149 if (addr >= vm->stack_base && addr < vm->stack_lower_limit) {
1150 block_addr = FLOOR_PAGE(addr);
1151 block_nr_bytes = vm->stack_lower_limit - block_addr;
1152 vm->stack_lower_limit = block_addr;
1153 }
1154 /* an address in the heap area, allocate all of the required heap */
1155 else if (addr >= vm->heap_upper_limit && addr < vm->heap_bound) {
1156 block_addr = vm->heap_upper_limit;
1157 block_nr_bytes = vm->heap_bound - vm->heap_upper_limit;
1158 vm->heap_upper_limit = vm->heap_bound;
1159 }
1160 /* oops - an invalid address - abort the cpu */
1161 else if (processor != NULL) {
1162 cpu_halt(processor, cia, was_signalled, SIGSEGV);
1163 return 0;
1164 }
1165 /* 2*oops - an invalid address and no processor */
1166 else {
1167 return 0;
1168 }
1169
1170 /* got the parameters, allocate the space */
1171 device_attach_address(device_parent(me),
1172 "vm@0x0,0", /* stop remap */
1173 attach_raw_memory,
1174 0 /*address space*/,
1175 block_addr,
1176 block_nr_bytes,
1177 access_read_write,
1178 me);
1179 return block_nr_bytes;
1180 }
1181
1182
1183 static unsigned
1184 vm_io_read_buffer_callback(device *me,
1185 void *dest,
1186 int space,
1187 unsigned_word addr,
1188 unsigned nr_bytes,
1189 cpu *processor,
1190 unsigned_word cia)
1191 {
1192 if (add_vm_space(me, addr, nr_bytes, processor, cia) >= nr_bytes) {
1193 memset(dest, 0, nr_bytes); /* always initialized to zero */
1194 return nr_bytes;
1195 }
1196 else
1197 return 0;
1198 }
1199
1200
1201 static unsigned
1202 vm_io_write_buffer_callback(device *me,
1203 const void *source,
1204 int space,
1205 unsigned_word addr,
1206 unsigned nr_bytes,
1207 cpu *processor,
1208 unsigned_word cia)
1209 {
1210 if (add_vm_space(me, addr, nr_bytes, processor, cia) >= nr_bytes) {
1211 return device_dma_write_buffer(device_parent(me), source,
1212 space, addr,
1213 nr_bytes,
1214 0/*violate_read_only*/);
1215 }
1216 else
1217 return 0;
1218 }
1219
1220
1221 static void
1222 vm_ioctl_callback(device *me,
1223 psim *system,
1224 cpu *processor,
1225 unsigned_word cia,
1226 va_list ap)
1227 {
1228 /* While the caller is notified that the heap has grown by the
1229 requested amount, the heap is infact extended out to a page
1230 boundary. */
1231 vm_device *vm = (vm_device*)device_data(me);
1232 unsigned_word new_break = ALIGN_8(cpu_registers(processor)->gpr[3]);
1233 unsigned_word old_break = vm->heap_bound;
1234 signed_word delta = new_break - old_break;
1235 if (delta > 0)
1236 vm->heap_bound = ALIGN_PAGE(new_break);
1237 cpu_registers(processor)->gpr[0] = 0;
1238 cpu_registers(processor)->gpr[3] = new_break;
1239 }
1240
1241
1242 static device_callbacks const vm_callbacks = {
1243 vm_init_address_callback,
1244 ignore_device_init,
1245 vm_attach_address,
1246 passthrough_device_detach_address,
1247 vm_io_read_buffer_callback,
1248 vm_io_write_buffer_callback,
1249 unimp_device_dma_read_buffer,
1250 passthrough_device_dma_write_buffer,
1251 unimp_device_interrupt_event,
1252 unimp_device_child_interrupt_event,
1253 generic_device_unit_decode,
1254 generic_device_unit_encode,
1255 unimp_device_instance_create,
1256 unimp_device_instance_delete,
1257 unimp_device_instance_read,
1258 unimp_device_instance_write,
1259 unimp_device_instance_seek,
1260 vm_ioctl_callback,
1261 };
1262
1263
1264 static void *
1265 vea_vm_create(const char *name,
1266 const device_unit *address,
1267 const char *args,
1268 device *parent)
1269 {
1270 vm_device *vm = ZALLOC(vm_device);
1271 return vm;
1272 }
1273
1274
1275 \f
1276 /* Memory init device: memory@0x<addr>
1277
1278 This strange device is used create sections of memory */
1279
1280 static void
1281 memory_init_address_callback(device *me,
1282 psim *system)
1283 {
1284 const device_property *reg = device_find_array_property(me, "reg");
1285 const reg_spec *spec = reg->array;
1286 int nr_entries = reg->sizeof_array / sizeof(*spec);
1287
1288 if ((reg->sizeof_array % sizeof(*spec)) != 0)
1289 error("devices/%s reg property of incorrect size\n", device_name(me));
1290 while (nr_entries > 0) {
1291 device_attach_address(device_parent(me),
1292 device_name(me),
1293 attach_raw_memory,
1294 0 /*address space*/,
1295 BE2H_4(spec->base),
1296 BE2H_4(spec->size),
1297 access_read_write_exec,
1298 me);
1299 spec++;
1300 nr_entries--;
1301 }
1302 }
1303
1304 static void *
1305 memory_instance_create_callback(device *me,
1306 const char *args)
1307 {
1308 return me; /* for want of any thing better */
1309 }
1310
1311 static void
1312 memory_instance_delete_callback(device_instance *instance)
1313 {
1314 return;
1315 }
1316
1317 static device_callbacks const memory_callbacks = {
1318 memory_init_address_callback,
1319 ignore_device_init,
1320 unimp_device_attach_address,
1321 unimp_device_detach_address,
1322 unimp_device_io_read_buffer,
1323 unimp_device_io_write_buffer,
1324 unimp_device_dma_read_buffer,
1325 unimp_device_dma_write_buffer,
1326 unimp_device_interrupt_event,
1327 unimp_device_child_interrupt_event,
1328 unimp_device_unit_decode,
1329 unimp_device_unit_encode,
1330 memory_instance_create_callback,
1331 memory_instance_delete_callback,
1332 unimp_device_instance_read,
1333 unimp_device_instance_write,
1334 unimp_device_instance_seek,
1335 unimp_device_ioctl,
1336 };
1337
1338
1339 \f
1340 /* IOBUS device: iobus@<address>
1341
1342 Simple bus on which some IO devices live */
1343
1344 static void
1345 iobus_attach_address_callback(device *me,
1346 const char *name,
1347 attach_type type,
1348 int space,
1349 unsigned_word addr,
1350 unsigned nr_bytes,
1351 access_type access,
1352 device *who) /*callback/default*/
1353 {
1354 unsigned_word iobus_addr;
1355 /* sanity check */
1356 if (type == attach_default)
1357 error("iobus_attach_address_callback() no default for %s/%s\n",
1358 device_name(me), name);
1359 if (space != 0)
1360 error("iobus_attach_address_callback() no space for %s/%s\n",
1361 device_name(me), name);
1362 /* get the bus address */
1363 if (device_unit_address(me)->nr_cells != 1)
1364 error("iobus_attach_address_callback() invalid address for %s\n",
1365 device_name(me));
1366 iobus_addr = device_unit_address(me)->cells[0];
1367 device_attach_address(device_parent(me),
1368 device_name(me),
1369 type,
1370 0 /*space*/,
1371 iobus_addr + addr,
1372 nr_bytes,
1373 access,
1374 who);
1375 }
1376
1377
1378 static device_callbacks const iobus_callbacks = {
1379 ignore_device_init,
1380 ignore_device_init,
1381 iobus_attach_address_callback,
1382 unimp_device_detach_address,
1383 unimp_device_io_read_buffer,
1384 unimp_device_io_write_buffer,
1385 unimp_device_dma_read_buffer,
1386 unimp_device_dma_write_buffer,
1387 unimp_device_interrupt_event,
1388 unimp_device_child_interrupt_event,
1389 generic_device_unit_decode,
1390 generic_device_unit_encode,
1391 unimp_device_instance_create,
1392 unimp_device_instance_delete,
1393 unimp_device_instance_read,
1394 unimp_device_instance_write,
1395 unimp_device_instance_seek,
1396 unimp_device_ioctl,
1397 };
1398
1399
1400 \f
1401 /* FILE device: file@0x<address>,<file-name>
1402 (later - file@0x<address>,<size>,<file-offset>,<file-name>)
1403
1404 Specifies a file to read directly into memory starting at <address> */
1405
1406
1407 static void
1408 file_init_data_callback(device *me,
1409 psim *system)
1410 {
1411 int count;
1412 const char *file_name = device_find_string_property(me, "file-name");
1413 unsigned_word addr = device_find_integer_property(me, "real-address");
1414 /* load the file */
1415 count = dma_file(me, file_name, addr);
1416 if (count < 0)
1417 error("device_table/%s - Problem loading file %s\n",
1418 device_name(me), file_name);
1419 }
1420
1421
1422 static device_callbacks const file_callbacks = {
1423 ignore_device_init,
1424 file_init_data_callback,
1425 unimp_device_attach_address,
1426 unimp_device_detach_address,
1427 unimp_device_io_read_buffer,
1428 unimp_device_io_write_buffer,
1429 unimp_device_dma_read_buffer,
1430 unimp_device_dma_write_buffer,
1431 unimp_device_interrupt_event,
1432 unimp_device_child_interrupt_event,
1433 unimp_device_unit_decode,
1434 unimp_device_unit_encode,
1435 unimp_device_instance_create,
1436 unimp_device_instance_delete,
1437 unimp_device_instance_read,
1438 unimp_device_instance_write,
1439 unimp_device_instance_seek,
1440 unimp_device_ioctl,
1441 };
1442
1443
1444 \f
1445 /* DATA device: data@<address>
1446
1447 <data> - property containing the value to store
1448 <real-address> - address to store data at
1449
1450 Store <data> at <address> using approperiate byte order */
1451
1452 static void
1453 data_init_data_callback(device *me,
1454 psim *system)
1455 {
1456 unsigned_word addr = device_find_integer_property(me, "real-address");
1457 const device_property *data = device_find_property(me, "data");
1458 if (data == NULL)
1459 error("devices/data - missing data property\n");
1460 switch (data->type) {
1461 case integer_property:
1462 {
1463 unsigned32 buf = device_find_integer_property(me, "data");
1464 H2T(buf);
1465 if (device_dma_write_buffer(device_parent(me),
1466 &buf,
1467 0 /*address-space*/,
1468 addr,
1469 sizeof(buf), /*nr-bytes*/
1470 1 /*violate ro*/) != sizeof(buf))
1471 error("devices/%s - Problem storing integer 0x%x at 0x%lx\n",
1472 device_name(me), (long)buf, (unsigned long)addr);
1473 }
1474 break;
1475 default:
1476 error("devices/%s - write of this data is not yet implemented\n", device_name(me));
1477 break;
1478 }
1479 }
1480
1481
1482 static device_callbacks const data_callbacks = {
1483 ignore_device_init,
1484 data_init_data_callback,
1485 unimp_device_attach_address,
1486 unimp_device_detach_address,
1487 unimp_device_io_read_buffer,
1488 unimp_device_io_write_buffer,
1489 unimp_device_dma_read_buffer,
1490 unimp_device_dma_write_buffer,
1491 unimp_device_interrupt_event,
1492 unimp_device_child_interrupt_event,
1493 unimp_device_unit_decode,
1494 unimp_device_unit_encode,
1495 unimp_device_instance_create,
1496 unimp_device_instance_delete,
1497 unimp_device_instance_read,
1498 unimp_device_instance_write,
1499 unimp_device_instance_seek,
1500 unimp_device_ioctl,
1501 };
1502
1503
1504 \f
1505 /* HTAB:
1506
1507 htab@<real-address>
1508 real-address =
1509 nr-bytes =
1510
1511 pte@<real-address>
1512 real-address =
1513 virtual-address =
1514 nr-bytes =
1515 wimg =
1516 pp =
1517
1518 pte@<real-address>
1519 real-address =
1520 file-name =
1521 wimg =
1522 pp =
1523
1524 HTAB defines the location (in physical memory) of a HASH table.
1525 PTE (as a child of HTAB) defines a mapping that is to be entered
1526 into that table.
1527
1528 NB: All the work in this device is done during init by the PTE.
1529 The pte, looks up its parent to determine the address of the HTAB
1530 and then uses DMA calls to establish the required mapping. */
1531
1532 STATIC_INLINE_DEVICE_TABLE void
1533 htab_decode_hash_table(device *parent,
1534 unsigned32 *htaborg,
1535 unsigned32 *htabmask)
1536 {
1537 unsigned_word htab_ra;
1538 unsigned htab_nr_bytes;
1539 unsigned n;
1540 /* determine the location/size of the hash table */
1541 if (parent == NULL
1542 || strcmp(device_name(parent), "htab") != 0)
1543 error("devices/htab - missing htab parent device\n");
1544 htab_ra = device_find_integer_property(parent, "real-address");
1545 htab_nr_bytes = device_find_integer_property(parent, "nr-bytes");
1546 for (n = htab_nr_bytes; n > 1; n = n / 2) {
1547 if (n % 2 != 0)
1548 error("devices/%s - htab size 0x%x not a power of two\n",
1549 device_name(parent), htab_nr_bytes);
1550 }
1551 *htaborg = htab_ra;
1552 *htabmask = MASKED32(htab_nr_bytes - 1, 7, 31-6);
1553 if ((htab_ra & INSERTED32(*htabmask, 7, 15)) != 0) {
1554 error("devices/%s - htaborg 0x%x not aligned to htabmask 0x%x\n",
1555 device_name(parent), *htaborg, *htabmask);
1556 }
1557 DTRACE(htab, ("htab - htaborg=0x%lx htabmask=0x%lx\n",
1558 (unsigned long)*htaborg, (unsigned long)*htabmask));
1559 }
1560
1561 STATIC_INLINE void
1562 htab_map_page(device *me,
1563 unsigned_word ra,
1564 unsigned64 va,
1565 unsigned wimg,
1566 unsigned pp,
1567 unsigned32 htaborg,
1568 unsigned32 htabmask)
1569 {
1570 unsigned64 vpn = va << 12;
1571 unsigned32 vsid = INSERTED32(EXTRACTED64(vpn, 0, 23), 0, 23);
1572 unsigned32 page = INSERTED32(EXTRACTED64(vpn, 24, 39), 0, 15);
1573 unsigned32 hash = INSERTED32(EXTRACTED32(vsid, 5, 23)
1574 ^ EXTRACTED32(page, 0, 15),
1575 7, 31-6);
1576 int h;
1577 for (h = 0; h < 2; h++) {
1578 unsigned32 pteg = (htaborg | (hash & htabmask));
1579 int pti;
1580 for (pti = 0; pti < 8; pti++, pteg += 8) {
1581 unsigned32 current_target_pte0;
1582 unsigned32 current_pte0;
1583 if (device_dma_read_buffer(device_parent(me),
1584 &current_target_pte0,
1585 0, /*space*/
1586 pteg,
1587 sizeof(current_target_pte0)) != 4)
1588 error("htab_init_callback() failed to read a pte at 0x%x\n",
1589 pteg);
1590 current_pte0 = T2H_4(current_target_pte0);
1591 if (!MASKED32(current_pte0, 0, 0)) {
1592 /* empty pte fill it */
1593 unsigned32 pte0 = (MASK32(0, 0)
1594 | INSERTED32(EXTRACTED32(vsid, 0, 23), 1, 24)
1595 | INSERTED32(h, 25, 25)
1596 | INSERTED32(EXTRACTED32(page, 0, 5), 26, 31));
1597 unsigned32 target_pte0 = H2T_4(pte0);
1598 unsigned32 pte1 = (INSERTED32(EXTRACTED32(ra, 0, 19), 0, 19)
1599 | INSERTED32(wimg, 25, 28)
1600 | INSERTED32(pp, 30, 31));
1601 unsigned32 target_pte1 = H2T_4(pte1);
1602 if (device_dma_write_buffer(device_parent(me),
1603 &target_pte0,
1604 0, /*space*/
1605 pteg,
1606 sizeof(target_pte0),
1607 1/*ro?*/) != 4
1608 || device_dma_write_buffer(device_parent(me),
1609 &target_pte1,
1610 0, /*space*/
1611 pteg + 4,
1612 sizeof(target_pte1),
1613 1/*ro?*/) != 4)
1614 error("htab_init_callback() failed to write a pte a 0x%x\n",
1615 pteg);
1616 DTRACE(htab, ("map - va=0x%lx ra=0x%lx &pte0=0x%lx pte0=0x%lx pte1=0x%lx\n",
1617 (unsigned long)va, (unsigned long)ra,
1618 (unsigned long)pteg,
1619 (unsigned long)pte0, (unsigned long)pte1));
1620 return;
1621 }
1622 }
1623 /* re-hash */
1624 hash = MASKED32(~hash, 0, 18);
1625 }
1626 }
1627
1628 STATIC_INLINE_DEVICE_TABLE void
1629 htab_map_region(device *me,
1630 unsigned_word pte_ra,
1631 unsigned_word pte_va,
1632 unsigned nr_bytes,
1633 unsigned wimg,
1634 unsigned pp,
1635 unsigned32 htaborg,
1636 unsigned32 htabmask)
1637 {
1638 unsigned_word ra;
1639 unsigned64 va;
1640 /* go through all pages and create a pte for each */
1641 for (ra = pte_ra, va = (signed_word)pte_va;
1642 ra < pte_ra + nr_bytes;
1643 ra += 0x1000, va += 0x1000) {
1644 htab_map_page(me, ra, va, wimg, pp, htaborg, htabmask);
1645 }
1646 }
1647
1648 typedef struct _htab_binary_sizes {
1649 unsigned_word text_ra;
1650 unsigned_word text_base;
1651 unsigned_word text_bound;
1652 unsigned_word data_ra;
1653 unsigned_word data_base;
1654 unsigned data_bound;
1655 device *me;
1656 } htab_binary_sizes;
1657
1658 STATIC_INLINE_DEVICE_TABLE void
1659 htab_sum_binary(bfd *abfd,
1660 sec_ptr sec,
1661 PTR data)
1662 {
1663 htab_binary_sizes *sizes = (htab_binary_sizes*)data;
1664 unsigned_word size = bfd_get_section_size_before_reloc (sec);
1665 unsigned_word vma = bfd_get_section_vma (abfd, sec);
1666
1667 /* skip the section if no memory to allocate */
1668 if (! (bfd_get_section_flags(abfd, sec) & SEC_ALLOC))
1669 return;
1670
1671 if ((bfd_get_section_flags (abfd, sec) & SEC_CODE)
1672 || (bfd_get_section_flags (abfd, sec) & SEC_READONLY)) {
1673 if (sizes->text_bound < vma + size)
1674 sizes->text_bound = ALIGN_PAGE(vma + size);
1675 if (sizes->text_base > vma)
1676 sizes->text_base = FLOOR_PAGE(vma);
1677 }
1678 else if ((bfd_get_section_flags (abfd, sec) & SEC_DATA)
1679 || (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)) {
1680 if (sizes->data_bound < vma + size)
1681 sizes->data_bound = ALIGN_PAGE(vma + size);
1682 if (sizes->data_base > vma)
1683 sizes->data_base = FLOOR_PAGE(vma);
1684 }
1685 }
1686
1687 STATIC_INLINE_DEVICE_TABLE void
1688 htab_dma_binary(bfd *abfd,
1689 sec_ptr sec,
1690 PTR data)
1691 {
1692 htab_binary_sizes *sizes = (htab_binary_sizes*)data;
1693 void *section_init;
1694 unsigned_word section_vma;
1695 unsigned_word section_size;
1696 unsigned_word section_ra;
1697 device *me = sizes->me;
1698
1699 /* skip the section if no memory to allocate */
1700 if (! (bfd_get_section_flags(abfd, sec) & SEC_ALLOC))
1701 return;
1702
1703 /* check/ignore any sections of size zero */
1704 section_size = bfd_get_section_size_before_reloc(sec);
1705 if (section_size == 0)
1706 return;
1707
1708 /* if nothing to load, ignore this one */
1709 if (! (bfd_get_section_flags(abfd, sec) & SEC_LOAD))
1710 return;
1711
1712 /* find where it is to go */
1713 section_vma = bfd_get_section_vma(abfd, sec);
1714 section_ra = 0;
1715 if ((bfd_get_section_flags (abfd, sec) & SEC_CODE)
1716 || (bfd_get_section_flags (abfd, sec) & SEC_READONLY))
1717 section_ra = (section_vma - sizes->text_base + sizes->text_ra);
1718 else if ((bfd_get_section_flags (abfd, sec) & SEC_DATA))
1719 section_ra = (section_vma - sizes->data_base + sizes->data_ra);
1720 else
1721 return; /* just ignore it */
1722
1723 DTRACE(htab,
1724 ("load - name=%-7s vma=0x%.8lx size=%6ld ra=0x%.8lx flags=%3lx(%s%s%s%s%s )\n",
1725 bfd_get_section_name(abfd, sec),
1726 (long)section_vma,
1727 (long)section_size,
1728 (long)section_ra,
1729 (long)bfd_get_section_flags(abfd, sec),
1730 bfd_get_section_flags(abfd, sec) & SEC_LOAD ? " LOAD" : "",
1731 bfd_get_section_flags(abfd, sec) & SEC_CODE ? " CODE" : "",
1732 bfd_get_section_flags(abfd, sec) & SEC_DATA ? " DATA" : "",
1733 bfd_get_section_flags(abfd, sec) & SEC_ALLOC ? " ALLOC" : "",
1734 bfd_get_section_flags(abfd, sec) & SEC_READONLY ? " READONLY" : ""
1735 ));
1736
1737 /* dma in the sections data */
1738 section_init = zalloc(section_size);
1739 if (!bfd_get_section_contents(abfd,
1740 sec,
1741 section_init, 0,
1742 section_size)) {
1743 bfd_perror("devices/pte");
1744 error("devices/%s - no data loaded\n", device_name(me));
1745 }
1746 if (device_dma_write_buffer(device_parent(me),
1747 section_init,
1748 0 /*space*/,
1749 section_ra,
1750 section_size,
1751 1 /*violate_read_only*/)
1752 != section_size)
1753 error("devices/%s - broken dma transfer\n", device_name(me));
1754 zfree(section_init); /* only free if load */
1755 }
1756
1757 STATIC_INLINE_DEVICE_TABLE void
1758 htab_map_binary(device *me,
1759 unsigned_word ra,
1760 unsigned wimg,
1761 unsigned pp,
1762 const char *file_name,
1763 unsigned32 htaborg,
1764 unsigned32 htabmask)
1765 {
1766 htab_binary_sizes sizes;
1767 bfd *image;
1768 sizes.text_base = -1;
1769 sizes.data_base = -1;
1770 sizes.text_bound = 0;
1771 sizes.data_bound = 0;
1772 sizes.me = me;
1773
1774 /* open the file */
1775 image = bfd_openr(file_name, NULL);
1776 if (image == NULL) {
1777 bfd_perror("devices/pte");
1778 error("devices/%s - the file %s not loaded\n", device_name(me), file_name);
1779 }
1780
1781 /* check it is valid */
1782 if (!bfd_check_format(image, bfd_object)) {
1783 bfd_close(image);
1784 error("devices/%s - the file %s has an invalid binary format\n",
1785 device_name(me), file_name);
1786 }
1787
1788 /* determine the size of each of the files regions */
1789 bfd_map_over_sections (image, htab_sum_binary, (PTR) &sizes);
1790
1791 /* determine the real addresses of the sections */
1792 sizes.text_ra = ra;
1793 sizes.data_ra = ALIGN_PAGE(sizes.text_ra +
1794 (sizes.text_bound - sizes.text_base));
1795
1796 DTRACE(htab, ("text map - base=0x%lx bound=0x%lx ra=0x%lx\n",
1797 (unsigned long)sizes.text_base,
1798 (unsigned long)sizes.text_bound,
1799 (unsigned long)sizes.text_ra));
1800 DTRACE(htab, ("data map - base=0x%lx bound=0x%lx ra=0x%lx\n",
1801 (unsigned long)sizes.data_base,
1802 (unsigned long)sizes.data_bound,
1803 (unsigned long)sizes.data_ra));
1804
1805 /* set up virtual memory maps for each of the regions */
1806 htab_map_region(me, sizes.text_ra, sizes.text_base,
1807 sizes.text_bound - sizes.text_base,
1808 wimg, pp,
1809 htaborg, htabmask);
1810 htab_map_region(me, sizes.data_ra, sizes.data_base,
1811 sizes.data_bound - sizes.data_base,
1812 wimg, pp,
1813 htaborg, htabmask);
1814
1815 /* dma the sections into physical memory */
1816 bfd_map_over_sections (image, htab_dma_binary, (PTR) &sizes);
1817 }
1818
1819 static void
1820 htab_init_data_callback(device *me,
1821 psim *system)
1822 {
1823 if (WITH_TARGET_WORD_BITSIZE != 32)
1824 error("devices/htab: only 32bit targets currently suported\n");
1825
1826 /* only the pte does work */
1827 if (strcmp(device_name(me), "pte") == 0) {
1828 unsigned32 htaborg;
1829 unsigned32 htabmask;
1830
1831 htab_decode_hash_table(device_parent(me), &htaborg, &htabmask);
1832
1833 if (device_find_property(me, "file-name") != NULL) {
1834 /* map in a binary */
1835 unsigned32 pte_ra = device_find_integer_property(me, "real-address");
1836 unsigned pte_wimg = device_find_integer_property(me, "wimg");
1837 unsigned pte_pp = device_find_integer_property(me, "pp");
1838 const char *file_name = device_find_string_property(me, "file-name");
1839 DTRACE(htab, ("pte - ra=0x%lx, wimg=%ld, pp=%ld, file-name=%s\n",
1840 (unsigned long)pte_ra,
1841 (unsigned long)pte_wimg,
1842 (long)pte_pp,
1843 file_name));
1844 htab_map_binary(me, pte_ra, pte_wimg, pte_pp, file_name,
1845 htaborg, htabmask);
1846 }
1847 else {
1848 /* handle a normal mapping definition */
1849 /* so that 0xff...0 is make 0xffffff00 */
1850 signed32 pte_va = device_find_integer_property(me, "virtual-address");
1851 unsigned32 pte_ra = device_find_integer_property(me, "real-address");
1852 unsigned pte_nr_bytes = device_find_integer_property(me, "nr-bytes");
1853 unsigned pte_wimg = device_find_integer_property(me, "wimg");
1854 unsigned pte_pp = device_find_integer_property(me, "pp");
1855 DTRACE(htab, ("pte - ra=0x%lx, wimg=%ld, pp=%ld, va=0x%lx, nr_bytes=%ld\n",
1856 (unsigned long)pte_ra,
1857 (long)pte_wimg,
1858 (long)pte_pp,
1859 (unsigned long)pte_va,
1860 (long)pte_nr_bytes));
1861 htab_map_region(me, pte_ra, pte_va, pte_nr_bytes, pte_wimg, pte_pp,
1862 htaborg, htabmask);
1863 }
1864 }
1865 }
1866
1867
1868 static device_callbacks const htab_callbacks = {
1869 ignore_device_init,
1870 htab_init_data_callback,
1871 unimp_device_attach_address,
1872 unimp_device_detach_address,
1873 unimp_device_io_read_buffer,
1874 unimp_device_io_write_buffer,
1875 passthrough_device_dma_read_buffer,
1876 passthrough_device_dma_write_buffer,
1877 unimp_device_interrupt_event,
1878 unimp_device_child_interrupt_event,
1879 generic_device_unit_decode,
1880 generic_device_unit_encode,
1881 unimp_device_instance_create,
1882 unimp_device_instance_delete,
1883 unimp_device_instance_read,
1884 unimp_device_instance_write,
1885 unimp_device_instance_seek,
1886 unimp_device_ioctl,
1887 };
1888
1889
1890 \f
1891 /* Load device: binary
1892
1893 Single property the name of which specifies the file (understood by
1894 BFD) that is to be DMAed into memory as part of init */
1895
1896 STATIC_INLINE_DEVICE_TABLE void
1897 update_for_binary_section(bfd *abfd,
1898 asection *the_section,
1899 PTR obj)
1900 {
1901 unsigned_word section_vma;
1902 unsigned_word section_size;
1903 access_type access;
1904 device *me = (device*)obj;
1905
1906 /* skip the section if no memory to allocate */
1907 if (! (bfd_get_section_flags(abfd, the_section) & SEC_ALLOC))
1908 return;
1909
1910 /* check/ignore any sections of size zero */
1911 section_size = bfd_get_section_size_before_reloc(the_section);
1912 if (section_size == 0)
1913 return;
1914
1915 /* find where it is to go */
1916 section_vma = bfd_get_section_vma(abfd, the_section);
1917
1918 DTRACE(binary,
1919 ("name=%-7s, vma=0x%.8lx, size=%6ld, flags=%3lx(%s%s%s%s%s )\n",
1920 bfd_get_section_name(abfd, the_section),
1921 (long)section_vma,
1922 (long)section_size,
1923 (long)bfd_get_section_flags(abfd, the_section),
1924 bfd_get_section_flags(abfd, the_section) & SEC_LOAD ? " LOAD" : "",
1925 bfd_get_section_flags(abfd, the_section) & SEC_CODE ? " CODE" : "",
1926 bfd_get_section_flags(abfd, the_section) & SEC_DATA ? " DATA" : "",
1927 bfd_get_section_flags(abfd, the_section) & SEC_ALLOC ? " ALLOC" : "",
1928 bfd_get_section_flags(abfd, the_section) & SEC_READONLY ? " READONLY" : ""
1929 ));
1930
1931 /* determine the devices access */
1932 access = access_read;
1933 if (bfd_get_section_flags(abfd, the_section) & SEC_CODE)
1934 access |= access_exec;
1935 if (!(bfd_get_section_flags(abfd, the_section) & SEC_READONLY))
1936 access |= access_write;
1937
1938 /* if a map, pass up a request to create the memory in core */
1939 if (strncmp(device_name(me), "map-binary", strlen("map-binary")) == 0)
1940 device_attach_address(device_parent(me),
1941 device_name(me),
1942 attach_raw_memory,
1943 0 /*address space*/,
1944 section_vma,
1945 section_size,
1946 access,
1947 me);
1948
1949 /* if a load dma in the required data */
1950 if (bfd_get_section_flags(abfd, the_section) & SEC_LOAD) {
1951 void *section_init = zalloc(section_size);
1952 if (!bfd_get_section_contents(abfd,
1953 the_section,
1954 section_init, 0,
1955 section_size)) {
1956 bfd_perror("core:load_section()");
1957 error("load of data failed");
1958 return;
1959 }
1960 if (device_dma_write_buffer(device_parent(me),
1961 section_init,
1962 0 /*space*/,
1963 section_vma,
1964 section_size,
1965 1 /*violate_read_only*/)
1966 != section_size)
1967 error("data_init_callback() broken transfer for %s\n", device_name(me));
1968 zfree(section_init); /* only free if load */
1969 }
1970 }
1971
1972
1973 static void
1974 binary_init_data_callback(device *me,
1975 psim *system)
1976 {
1977 /* get the file name */
1978 const char *file_name = device_find_string_property(me, "file-name");
1979 bfd *image;
1980
1981 /* open the file */
1982 image = bfd_openr(file_name, NULL);
1983 if (image == NULL) {
1984 bfd_perror("devices/binary");
1985 error("devices/%s - the file %s not loaded\n", device_name(me), file_name);
1986 }
1987
1988 /* check it is valid */
1989 if (!bfd_check_format(image, bfd_object)) {
1990 bfd_close(image);
1991 error("devices/%s - the file %s has an invalid binary format\n",
1992 device_name(me), file_name);
1993 }
1994
1995 /* and the data sections */
1996 bfd_map_over_sections(image,
1997 update_for_binary_section,
1998 (PTR)me);
1999
2000 bfd_close(image);
2001 }
2002
2003
2004 static device_callbacks const binary_callbacks = {
2005 ignore_device_init,
2006 binary_init_data_callback,
2007 unimp_device_attach_address,
2008 unimp_device_detach_address,
2009 unimp_device_io_read_buffer,
2010 unimp_device_io_write_buffer,
2011 unimp_device_dma_read_buffer,
2012 unimp_device_dma_write_buffer,
2013 unimp_device_interrupt_event,
2014 unimp_device_child_interrupt_event,
2015 unimp_device_unit_decode,
2016 unimp_device_unit_encode,
2017 unimp_device_instance_create,
2018 unimp_device_instance_delete,
2019 unimp_device_instance_read,
2020 unimp_device_instance_write,
2021 unimp_device_instance_seek,
2022 unimp_device_ioctl,
2023 };
2024
2025
2026 \f
2027 /* Stack device: stack@<type>
2028
2029 Has a single IOCTL to create a stack frame of the specified type.
2030 If <type> is elf or xcoff then a corresponding stack is created.
2031 Any other value of type is ignored.
2032
2033 The IOCTL takes the additional arguments:
2034
2035 unsigned_word stack_end -- where the stack should come down from
2036 char **argv -- ...
2037 char **envp -- ...
2038
2039 */
2040
2041 STATIC_INLINE_DEVICE_TABLE int
2042 sizeof_argument_strings(char **arg)
2043 {
2044 int sizeof_strings = 0;
2045
2046 /* robust */
2047 if (arg == NULL)
2048 return 0;
2049
2050 /* add up all the string sizes (padding as we go) */
2051 for (; *arg != NULL; arg++) {
2052 int len = strlen(*arg) + 1;
2053 sizeof_strings += ALIGN_8(len);
2054 }
2055
2056 return sizeof_strings;
2057 }
2058
2059 STATIC_INLINE_DEVICE_TABLE int
2060 number_of_arguments(char **arg)
2061 {
2062 int nr;
2063 if (arg == NULL)
2064 return 0;
2065 for (nr = 0; *arg != NULL; arg++, nr++);
2066 return nr;
2067 }
2068
2069 STATIC_INLINE_DEVICE_TABLE int
2070 sizeof_arguments(char **arg)
2071 {
2072 return ALIGN_8((number_of_arguments(arg) + 1) * sizeof(unsigned_word));
2073 }
2074
2075 STATIC_INLINE_DEVICE_TABLE void
2076 write_stack_arguments(psim *system,
2077 char **arg,
2078 unsigned_word start_block,
2079 unsigned_word end_block,
2080 unsigned_word start_arg,
2081 unsigned_word end_arg)
2082 {
2083 DTRACE(stack,
2084 ("write_stack_arguments(system=0x%lx, arg=0x%lx, start_block=0x%lx, end_block=0x%lx, start_arg=0x%lx, end_arg=0x%lx)\n",
2085 (long)system, (long)arg, (long)start_block, (long)end_block, (long)start_arg, (long)end_arg));
2086 if (arg == NULL)
2087 error("write_arguments: character array NULL\n");
2088 /* only copy in arguments, memory is already zero */
2089 for (; *arg != NULL; arg++) {
2090 int len = strlen(*arg)+1;
2091 unsigned_word target_start_block;
2092 DTRACE(stack,
2093 ("write_stack_arguments() write %s=%s at %s=0x%lx %s=0x%lx %s=0x%lx\n",
2094 "**arg", *arg, "start_block", (long)start_block,
2095 "len", (long)len, "start_arg", (long)start_arg));
2096 if (psim_write_memory(system, 0, *arg,
2097 start_block, len,
2098 0/*violate_readonly*/) != len)
2099 error("write_stack_arguments() - write of **arg (%s) at 0x%x failed\n",
2100 *arg, start_block);
2101 target_start_block = H2T_word(start_block);
2102 if (psim_write_memory(system, 0, &target_start_block,
2103 start_arg, sizeof(target_start_block),
2104 0) != sizeof(target_start_block))
2105 error("write_stack_arguments() - write of *arg failed\n");
2106 start_block += ALIGN_8(len);
2107 start_arg += sizeof(start_block);
2108 }
2109 start_arg += sizeof(start_block); /*the null at the end*/
2110 if (start_block != end_block
2111 || ALIGN_8(start_arg) != end_arg)
2112 error("write_stack_arguments - possible corruption\n");
2113 DTRACE(stack,
2114 ("write_stack_arguments() = void\n"));
2115 }
2116
2117 STATIC_INLINE_DEVICE_TABLE void
2118 create_elf_stack_frame(psim *system,
2119 unsigned_word bottom_of_stack,
2120 char **argv,
2121 char **envp)
2122 {
2123 /* fixme - this is over aligned */
2124
2125 /* information block */
2126 const unsigned sizeof_envp_block = sizeof_argument_strings(envp);
2127 const unsigned_word start_envp_block = bottom_of_stack - sizeof_envp_block;
2128 const unsigned sizeof_argv_block = sizeof_argument_strings(argv);
2129 const unsigned_word start_argv_block = start_envp_block - sizeof_argv_block;
2130
2131 /* auxiliary vector - contains only one entry */
2132 const unsigned sizeof_aux_entry = 2*sizeof(unsigned_word); /* magic */
2133 const unsigned_word start_aux = start_argv_block - ALIGN_8(sizeof_aux_entry);
2134
2135 /* environment points (including null sentinal) */
2136 const unsigned sizeof_envp = sizeof_arguments(envp);
2137 const unsigned_word start_envp = start_aux - sizeof_envp;
2138
2139 /* argument pointers (including null sentinal) */
2140 const int argc = number_of_arguments(argv);
2141 const unsigned sizeof_argv = sizeof_arguments(argv);
2142 const unsigned_word start_argv = start_envp - sizeof_argv;
2143
2144 /* link register save address - alligned to a 16byte boundary */
2145 const unsigned_word top_of_stack = ((start_argv
2146 - 2 * sizeof(unsigned_word))
2147 & ~0xf);
2148
2149 /* install arguments on stack */
2150 write_stack_arguments(system, envp,
2151 start_envp_block, bottom_of_stack,
2152 start_envp, start_aux);
2153 write_stack_arguments(system, argv,
2154 start_argv_block, start_envp_block,
2155 start_argv, start_envp);
2156
2157 /* set up the registers */
2158 psim_write_register(system, -1,
2159 &top_of_stack, "sp", cooked_transfer);
2160 psim_write_register(system, -1,
2161 &argc, "r3", cooked_transfer);
2162 psim_write_register(system, -1,
2163 &start_argv, "r4", cooked_transfer);
2164 psim_write_register(system, -1,
2165 &start_envp, "r5", cooked_transfer);
2166 psim_write_register(system, -1,
2167 &start_aux, "r6", cooked_transfer);
2168 }
2169
2170 STATIC_INLINE_DEVICE_TABLE void
2171 create_aix_stack_frame(psim *system,
2172 unsigned_word bottom_of_stack,
2173 char **argv,
2174 char **envp)
2175 {
2176 unsigned_word core_envp;
2177 unsigned_word core_argv;
2178 unsigned_word core_argc;
2179 unsigned_word core_aux;
2180 unsigned_word top_of_stack;
2181
2182 /* cheat - create an elf stack frame */
2183 create_elf_stack_frame(system, bottom_of_stack, argv, envp);
2184
2185 /* extract argument addresses from registers */
2186 psim_read_register(system, 0, &top_of_stack, "r1", cooked_transfer);
2187 psim_read_register(system, 0, &core_argc, "r3", cooked_transfer);
2188 psim_read_register(system, 0, &core_argv, "r4", cooked_transfer);
2189 psim_read_register(system, 0, &core_envp, "r5", cooked_transfer);
2190 psim_read_register(system, 0, &core_aux, "r6", cooked_transfer);
2191
2192 /* extract arguments from registers */
2193 error("create_aix_stack_frame() - what happens next?\n");
2194 }
2195
2196
2197
2198 static void
2199 stack_ioctl_callback(device *me,
2200 psim *system,
2201 cpu *processor,
2202 unsigned_word cia,
2203 va_list ap)
2204 {
2205 unsigned_word stack_pointer;
2206 const char *stack_type;
2207 char **argv;
2208 char **envp;
2209 stack_pointer = va_arg(ap, unsigned_word);
2210 argv = va_arg(ap, char **);
2211 envp = va_arg(ap, char **);
2212 DTRACE(stack,
2213 ("stack_ioctl_callback(me=0x%lx:%s, system=0x%lx, processor=0x%lx, cia=0x%lx, argv=0x%lx, envp=0x%lx)\n",
2214 (long)me, device_name(me), (long)system, (long)processor, (long)cia, (long)argv, (long)envp));
2215 stack_type = device_find_string_property(me, "stack-type");
2216 if (strcmp(stack_type, "elf") == 0)
2217 create_elf_stack_frame(system, stack_pointer, argv, envp);
2218 else if (strcmp(stack_type, "xcoff") == 0)
2219 create_aix_stack_frame(system, stack_pointer, argv, envp);
2220 DTRACE(stack,
2221 ("stack_ioctl_callback() = void\n"));
2222 }
2223
2224 static device_callbacks const stack_callbacks = {
2225 ignore_device_init,
2226 ignore_device_init,
2227 unimp_device_attach_address,
2228 unimp_device_detach_address,
2229 unimp_device_io_read_buffer,
2230 unimp_device_io_write_buffer,
2231 unimp_device_dma_read_buffer,
2232 unimp_device_dma_write_buffer,
2233 unimp_device_interrupt_event,
2234 unimp_device_child_interrupt_event,
2235 unimp_device_unit_decode,
2236 unimp_device_unit_encode,
2237 unimp_device_instance_create,
2238 unimp_device_instance_delete,
2239 unimp_device_instance_read,
2240 unimp_device_instance_write,
2241 unimp_device_instance_seek,
2242 stack_ioctl_callback,
2243 };
2244
2245
2246 \f
2247 device_descriptor device_table[] = {
2248 { "console", console_create, &console_callbacks },
2249 { "memory", NULL, &memory_callbacks },
2250 { "eeprom", NULL, &memory_callbacks },
2251 { "vm", vea_vm_create, &vm_callbacks },
2252 { "halt", NULL, &halt_callbacks },
2253 { "icu", NULL, &icu_callbacks },
2254 { "register", NULL, &register_callbacks },
2255 { "iobus", NULL, &iobus_callbacks },
2256 { "file", NULL, &file_callbacks },
2257 { "data", NULL, &data_callbacks },
2258 { "htab", NULL, &htab_callbacks },
2259 { "pte", NULL, &htab_callbacks }, /* yep - uses htab's table */
2260 { "stack", NULL, &stack_callbacks },
2261 { "load-binary", NULL, &binary_callbacks },
2262 { "map-binary", NULL, &binary_callbacks },
2263 /* standard OpenBoot devices */
2264 { "aliases", NULL, &passthrough_callbacks },
2265 { "options", NULL, &passthrough_callbacks },
2266 { "chosen", NULL, &passthrough_callbacks },
2267 { "packages", NULL, &passthrough_callbacks },
2268 { "cpus", NULL, &passthrough_callbacks },
2269 { "openprom", NULL, &passthrough_callbacks },
2270 { "init", NULL, &passthrough_callbacks },
2271 { "trace", NULL, &trace_callbacks },
2272 { NULL },
2273 };
2274
2275 #endif /* _DEVICE_TABLE_C_ */
This page took 0.085389 seconds and 4 git commands to generate.