1 /* This file is part of the program psim.
3 Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
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.
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.
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.
22 #ifndef _DEVICE_TABLE_C_
23 #define _DEVICE_TABLE_C_
25 #ifndef STATIC_INLINE_DEVICE_TABLE
26 #define STATIC_INLINE_DEVICE_TABLE STATIC_INLINE
35 #include "device_table.h"
59 /* Helper functions */
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. */
65 STATIC_INLINE_DEVICE_TABLE
void
66 generic_init_callback(device
*me
,
71 if (scand_uw_u(device_name(me
), &addr
, &nr_bytes
) != 2)
72 error("generic_init_callback() invalid nr_bytes in %s\n", device_name(me
));
73 device_attach_address(device_parent(me
),
84 /* DMA a file into memory */
85 STATIC_INLINE_DEVICE_TABLE
int
87 const char *file_name
,
96 image
= fopen(file_name
, "r");
100 /* read it in slowly */
103 inc
= fread(buf
, 1, sizeof(buf
), image
);
104 if (feof(image
) || ferror(image
))
106 if (device_dma_write_buffer(device_parent(me
),
111 1 /*violate ro*/) != inc
) {
118 /* close down again */
126 /* inimplemented versions of each function */
129 unimp_device_init(device
*me
,
132 error("device_init_callback for %s not implemented\n", device_name(me
));
136 unimp_device_attach_address(device
*me
,
143 device
*who
) /*callback/default*/
145 error("device_attach_address_callback for %s not implemented\n", device_name(me
));
149 unimp_device_detach_address(device
*me
,
156 device
*who
) /*callback/default*/
158 error("device_detach_address_callback for %s not implemented\n", device_name(me
));
162 unimp_device_io_read_buffer(device
*me
,
170 error("device_io_read_buffer_callback for %s not implemented\n", device_name(me
));
175 unimp_device_io_write_buffer(device
*me
,
183 error("device_io_write_buffer_callback for %s not implemented\n", device_name(me
));
188 unimp_device_dma_read_buffer(device
*me
,
194 error("device_dma_read_buffer_callback for %s not implemented\n", device_name(me
));
199 unimp_device_dma_write_buffer(device
*me
,
204 int violate_read_only_section
)
206 error("device_dma_write_buffer_callback for %s not implemented\n", device_name(me
));
211 unimp_device_attach_interrupt(device
*me
,
216 error("device_attach_interrupt_callback for %s not implemented\n", device_name(me
));
220 unimp_device_detach_interrupt(device
*me
,
225 error("device_detach_interrupt_callback for %s not implemented\n", device_name(me
));
229 unimp_device_interrupt(device
*me
,
232 int interrupt_status
,
236 error("device_interrupt_callback for %s not implemented\n", device_name(me
));
240 unimp_device_interrupt_ack(device
*me
,
242 int interrupt_status
)
244 error("device_interrupt_ack_callback for %s not implemented\n", device_name(me
));
248 unimp_device_ioctl(device
*me
,
254 error("device_ioctl_callback for %s not implemented\n", device_name(me
));
259 /* ignore/passthrough versions of each function */
262 ignore_device_init(device
*me
,
269 passthrough_device_attach_address(device
*me
,
276 device
*who
) /*callback/default*/
278 device_attach_address(device_parent(me
), name
, attach
,
279 space
, addr
, nr_bytes
,
285 passthrough_device_detach_address(device
*me
,
292 device
*who
) /*callback/default*/
294 device_detach_address(device_parent(me
), name
, attach
,
295 space
, addr
, nr_bytes
, access
,
300 passthrough_device_dma_read_buffer(device
*me
,
306 return device_dma_read_buffer(device_parent(me
), dest
,
307 space
, addr
, nr_bytes
);
311 passthrough_device_dma_write_buffer(device
*me
,
316 int violate_read_only_section
)
318 return device_dma_write_buffer(device_parent(me
), source
,
321 violate_read_only_section
);
325 passthrough_device_attach_interrupt(device
*me
,
330 device_attach_interrupt(device_parent(me
), who
,
331 interrupt_line
, name
);
335 passthrough_device_detach_interrupt(device
*me
,
340 device_detach_interrupt(device_parent(me
), who
,
341 interrupt_line
, name
);
346 passthrough_device_interrupt(device
*me
,
349 int interrupt_status
,
353 device_interrupt(device_parent(me
), who
,
354 interrupt_line
, interrupt_status
,
359 static const device_callbacks passthrough_callbacks
= {
361 passthrough_device_attach_address
,
362 passthrough_device_detach_address
,
363 unimp_device_io_read_buffer
,
364 unimp_device_io_write_buffer
,
365 passthrough_device_dma_read_buffer
,
366 passthrough_device_dma_write_buffer
,
367 passthrough_device_attach_interrupt
,
368 passthrough_device_detach_interrupt
,
369 passthrough_device_interrupt
,
370 unimp_device_interrupt_ack
,
376 /* Simple console device: console@<address>,16
378 Input characters are taken from the keyboard, output characters
379 sent to the terminal. Echoing of characters is not disabled.
381 The device has four registers:
388 Where a nonzero status register indicates that the device is ready
389 (input fifo contains a character or output fifo has space). */
391 typedef struct _console_buffer
{
394 event_entry_tag event_tag
;
397 typedef struct _console_device
{
398 console_buffer input
;
399 console_buffer output
;
403 console_read_buffer
= 0,
404 console_read_status
= 4,
405 console_write_buffer
= 8,
406 console_write_status
= 12,
407 console_offset_mask
= 0xc,
413 console_io_read_buffer_callback(device
*me
,
421 console_device
*console
= (console_device
*)device_data(me
);
424 /* determine what was read */
428 case console_read_buffer
:
429 val
= console
->input
.buffer
;
432 case console_read_status
:
433 { /* check for input */
436 /* get the old status */
437 flags
= fcntl(0, F_GETFL
, 0);
443 /* temp, disable blocking IO */
444 status
= fcntl(0, F_SETFL
, flags
| O_NDELAY
);
451 status
= read(0, &console
->input
.buffer
, 1);
453 console
->input
.status
= 1;
456 console
->input
.status
= 0;
458 /* return to regular vewing */
459 fcntl(0, F_SETFL
, flags
);
461 val
= console
->input
.status
;
464 case console_write_buffer
:
465 val
= console
->output
.buffer
;
468 case console_write_status
:
469 val
= console
->output
.status
;
473 error("console_read_callback() internal error\n");
479 memset(dest
, 0, nr_bytes
);
480 *(unsigned_1
*)dest
= val
;
485 console_io_write_buffer_callback(device
*me
,
493 console_device
*console
= (console_device
*)device_data(me
);
494 unsigned_1 val
= *(unsigned_1
*)source
;
497 case console_read_buffer
:
498 console
->input
.buffer
= val
;
500 case console_read_status
:
501 console
->input
.status
= val
;
503 case console_write_buffer
:
504 DTRACE(console
, ("<%c:%d>", val
, val
));
505 printf_filtered("%c",val
) ;
506 console
->output
.buffer
= val
;
507 console
->output
.status
= 1;
509 case console_write_status
:
510 console
->output
.status
= val
;
513 error("console_write_callback() internal error\n");
520 static device_callbacks
const console_callbacks
= {
521 generic_init_callback
,
522 unimp_device_attach_address
,
523 unimp_device_detach_address
,
524 console_io_read_buffer_callback
,
525 console_io_write_buffer_callback
,
526 unimp_device_dma_read_buffer
,
527 unimp_device_dma_write_buffer
,
528 unimp_device_attach_interrupt
,
529 unimp_device_detach_interrupt
,
530 unimp_device_interrupt
,
531 unimp_device_interrupt_ack
,
537 console_create(const char *name
,
540 /* create the descriptor */
541 console_device
*console
= ZALLOC(console_device
);
542 console
->output
.status
= 1;
543 console
->output
.buffer
= '\0';
544 console
->input
.status
= 0;
545 console
->input
.buffer
= '\0';
551 /* ICU device: icu@0x<address>,4
553 Single 4 byte register. Read returns processor number. Write
554 interrupts specified processor.
556 Illustrates passing of events to parent device. Passing of
557 interrupts to parent bus.
559 NB: For the sake of illustrating the passing of interrupts. This
560 device doesn't pass interrupt events to its parent. Instead it
561 passes them back to its self. */
564 icu_io_read_buffer_callback(device
*me
,
573 val
= cpu_nr(processor
);
574 memset(dest
, 0, nr_bytes
);
575 *(unsigned_1
*)dest
= val
;
581 icu_io_write_buffer_callback(device
*me
,
589 unsigned_1 val
= H2T_1(*(unsigned_1
*)source
);
590 /* tell the parent device that the interrupt lines have changed.
591 For this fake ICU. The interrupt lines just indicate the cpu to
593 device_interrupt(device_parent(me
), me
,
600 static device_callbacks
const icu_callbacks
= {
601 generic_init_callback
,
602 unimp_device_attach_address
,
603 unimp_device_detach_address
,
604 icu_io_read_buffer_callback
,
605 icu_io_write_buffer_callback
,
606 unimp_device_dma_read_buffer
,
607 unimp_device_dma_write_buffer
,
608 unimp_device_attach_interrupt
,
609 unimp_device_detach_interrupt
,
610 unimp_device_interrupt
,
611 unimp_device_interrupt_ack
,
617 /* HALT device: halt@0x<address>,4
619 With real hardware, the processor operation is normally terminated
620 through a reset. This device illustrates how a reset device could
621 be attached to an address */
625 halt_io_read_buffer_callback(device
*me
,
633 cpu_halt(processor
, cia
, was_exited
, 0);
639 halt_io_write_buffer_callback(device
*me
,
647 cpu_halt(processor
, cia
, was_exited
, *(unsigned_1
*)source
);
652 static device_callbacks
const halt_callbacks
= {
653 generic_init_callback
,
654 unimp_device_attach_address
,
655 unimp_device_detach_address
,
656 halt_io_read_buffer_callback
,
657 halt_io_write_buffer_callback
,
658 unimp_device_dma_read_buffer
,
659 unimp_device_dma_write_buffer
,
660 unimp_device_attach_interrupt
,
661 unimp_device_detach_interrupt
,
662 unimp_device_interrupt
,
663 unimp_device_interrupt_ack
,
669 /* Register init device: register
671 Properties attached to the register device specify the name/value
672 initialization pair for cpu registers.
674 FIXME: A specific processor can be initialized by creating a
675 property with a name like `0.pc'. */
678 register_init(device
*me
,
682 psim
*system
= (psim
*)data
;
683 unsigned32 value
= device_find_integer_property(me
, name
);
685 if (isdigit(name
[0]) && name
[1] == '.') {
686 processor
= atol(name
);
688 DTRACE(register, ("%ld.%s=0x%lx\n", (long)name
, processor
, (unsigned long)value
));
692 DTRACE(register, ("%s=0x%lx\n", name
, (unsigned long)value
));
694 psim_write_register(system
, processor
, /* all processors */
702 register_init_callback(device
*me
,
705 device_traverse_properties(me
, register_init
, system
);
709 static device_callbacks
const register_callbacks
= {
710 register_init_callback
,
711 unimp_device_attach_address
,
712 unimp_device_detach_address
,
713 unimp_device_io_read_buffer
,
714 unimp_device_io_write_buffer
,
715 unimp_device_dma_read_buffer
,
716 unimp_device_dma_write_buffer
,
717 unimp_device_attach_interrupt
,
718 unimp_device_detach_interrupt
,
719 unimp_device_interrupt
,
720 unimp_device_interrupt_ack
,
726 /* VEA VM device: vm@0x<stack-base>,<nr_bytes>
728 A VEA mode device. This sets its self up as the default memory
729 device capturing all accesses (reads/writes) to currently unmapped
730 addresses. If the unmaped access falls within unallocated stack or
731 heap address ranges then memory is allocated and the access is
734 During init phase, this device expects to receive `attach' requests
735 from its children for the text/data/bss memory areas. Typically,
736 this would be done by the binary device.
738 STACK: The location of the stack in memory is specified as part of
739 the devices name. Unmaped accesses that fall within the stack
740 space result in the allocated stack being grown downwards so that
741 it includes the page of the culprit access.
743 HEAP: During initialization, the vm device monitors all `attach'
744 operations from its children using this to determine the initial
745 location of the heap. The heap is then extended by system calls
746 that frob the heap upper bound variable (see system.c). */
749 typedef struct _vm_device
{
750 /* area of memory valid for stack addresses */
751 unsigned_word stack_base
; /* min possible stack value */
752 unsigned_word stack_bound
;
753 unsigned_word stack_lower_limit
;
754 /* area of memory valid for heap addresses */
755 unsigned_word heap_base
;
756 unsigned_word heap_bound
;
757 unsigned_word heap_upper_limit
;
762 vm_init_callback(device
*me
,
765 vm_device
*vm
= (vm_device
*)device_data(me
);
767 /* revert the stack/heap variables to their defaults */
768 vm
->stack_lower_limit
= vm
->stack_bound
;
771 vm
->heap_upper_limit
= 0;
773 /* establish this device as the default memory handler */
774 device_attach_address(device_parent(me
),
777 0 /*address space - ignore*/,
779 0 /*nr_bytes - ignore*/,
780 access_read_write
/*access*/,
786 vm_attach_address(device
*me
,
793 device
*who
) /*callback/default*/
795 vm_device
*vm
= (vm_device
*)device_data(me
);
796 /* update end of bss if necessary */
797 if (vm
->heap_base
< addr
+ nr_bytes
) {
798 vm
->heap_base
= addr
+ nr_bytes
;
799 vm
->heap_bound
= addr
+ nr_bytes
;
800 vm
->heap_upper_limit
= addr
+ nr_bytes
;
802 device_attach_address(device_parent(me
),
803 "vm@0x0,0", /* stop remap */
813 STATIC_INLINE_DEVICE_TABLE
unsigned
814 add_vm_space(device
*me
,
820 vm_device
*vm
= (vm_device
*)device_data(me
);
821 unsigned_word block_addr
;
822 unsigned block_nr_bytes
;
824 /* an address in the stack area, allocate just down to the addressed
826 if (addr
>= vm
->stack_base
&& addr
< vm
->stack_lower_limit
) {
827 block_addr
= FLOOR_PAGE(addr
);
828 block_nr_bytes
= vm
->stack_lower_limit
- block_addr
;
829 vm
->stack_lower_limit
= block_addr
;
831 /* an address in the heap area, allocate all of the required heap */
832 else if (addr
>= vm
->heap_upper_limit
&& addr
< vm
->heap_bound
) {
833 block_addr
= vm
->heap_upper_limit
;
834 block_nr_bytes
= vm
->heap_bound
- vm
->heap_upper_limit
;
835 vm
->heap_upper_limit
= vm
->heap_bound
;
837 /* oops - an invalid address - abort the cpu */
838 else if (processor
!= NULL
) {
839 cpu_halt(processor
, cia
, was_signalled
, SIGSEGV
);
842 /* 2*oops - an invalid address and no processor */
847 /* got the parameters, allocate the space */
848 device_attach_address(device_parent(me
),
849 "vm@0x0,0", /* stop remap */
856 return block_nr_bytes
;
861 vm_io_read_buffer_callback(device
*me
,
869 if (add_vm_space(me
, addr
, nr_bytes
, processor
, cia
) >= nr_bytes
) {
870 memset(dest
, 0, nr_bytes
); /* always initialized to zero */
879 vm_io_write_buffer_callback(device
*me
,
887 if (add_vm_space(me
, addr
, nr_bytes
, processor
, cia
) >= nr_bytes
) {
888 return device_dma_write_buffer(device_parent(me
), source
,
891 0/*violate_read_only*/);
899 vm_ioctl_callback(device
*me
,
905 /* While the caller is notified that the heap has grown by the
906 requested amount, the heap is infact extended out to a page
908 vm_device
*vm
= (vm_device
*)device_data(me
);
909 unsigned_word new_break
= ALIGN_8(cpu_registers(processor
)->gpr
[3]);
910 unsigned_word old_break
= vm
->heap_bound
;
911 signed_word delta
= new_break
- old_break
;
913 vm
->heap_bound
= ALIGN_PAGE(new_break
);
914 cpu_registers(processor
)->gpr
[0] = 0;
915 cpu_registers(processor
)->gpr
[3] = new_break
;
919 static device_callbacks
const vm_callbacks
= {
922 passthrough_device_detach_address
,
923 vm_io_read_buffer_callback
,
924 vm_io_write_buffer_callback
,
925 unimp_device_dma_read_buffer
,
926 passthrough_device_dma_write_buffer
,
927 unimp_device_attach_interrupt
,
928 unimp_device_detach_interrupt
,
929 unimp_device_interrupt
,
930 unimp_device_interrupt_ack
,
936 vea_vm_create(const char *name
,
939 vm_device
*vm
= ZALLOC(vm_device
);
943 /* extract out the stack parameters */
944 if (scand_uw_u(name
, &addr
, &nr_bytes
) != 2)
945 error("vm_device_create() invalid vm device %s\n", name
);
946 vm
->stack_base
= addr
;
947 vm
->stack_bound
= addr
+ nr_bytes
;
953 /* Memory init device: memory@0x<addr>,<size>,<access>
955 This strange device is used create sections of memory */
958 memory_init_callback(device
*me
,
966 nr_args
= scand_uw_u_u(device_name(me
), &addr
, &nr_bytes
, &access
);
969 access
= access_read_write_exec
;
974 error("memory_init_callback() invalid memory device %s\n", device_name(me
));
978 device_attach_address(device_parent(me
),
989 static device_callbacks
const memory_callbacks
= {
990 memory_init_callback
,
991 unimp_device_attach_address
,
992 unimp_device_detach_address
,
993 unimp_device_io_read_buffer
,
994 unimp_device_io_write_buffer
,
995 unimp_device_dma_read_buffer
,
996 unimp_device_dma_write_buffer
,
997 unimp_device_attach_interrupt
,
998 unimp_device_detach_interrupt
,
999 unimp_device_interrupt
,
1000 unimp_device_interrupt_ack
,
1006 /* IOBUS device: iobus@<address>
1008 Simple bus on which some IO devices live */
1011 iobus_attach_address_callback(device
*me
,
1018 device
*who
) /*callback/default*/
1020 unsigned_word iobus_addr
;
1022 if (type
== attach_default
)
1023 error("iobus_attach_address_callback() no default for %s/%s\n",
1024 device_name(me
), name
);
1026 error("iobus_attach_address_callback() no space for %s/%s\n",
1027 device_name(me
), name
);
1028 /* get the bus address */
1029 if (scand_uw(device_name(me
), &iobus_addr
) != 1)
1030 error("iobus_attach_address_callback() invalid address for %s\n",
1032 device_attach_address(device_parent(me
),
1043 STATIC_INLINE_DEVICE_TABLE
void
1044 iobus_do_interrupt(event_queue
*queue
,
1047 cpu
*target
= (cpu
*)data
;
1048 /* try to interrupt the processor. If the attempt fails, try again
1050 if (!external_interrupt(target
))
1051 event_queue_schedule(queue
, 1, iobus_do_interrupt
, target
);
1056 iobus_interrupt_callback(device
*me
,
1059 int interrupt_status
,
1063 /* the interrupt controler can't interrupt a cpu at any time.
1064 Rather it must synchronize with the system clock before
1065 performing an interrupt on the given processor */
1066 psim
*system
= cpu_system(processor
);
1067 cpu
*target
= psim_cpu(system
, interrupt_status
);
1068 if (target
!= NULL
) {
1069 event_queue
*events
= cpu_event_queue(target
);
1070 event_queue_schedule(events
, 1, iobus_do_interrupt
, target
);
1075 static device_callbacks
const iobus_callbacks
= {
1077 iobus_attach_address_callback
,
1078 unimp_device_detach_address
,
1079 unimp_device_io_read_buffer
,
1080 unimp_device_io_write_buffer
,
1081 unimp_device_dma_read_buffer
,
1082 unimp_device_dma_write_buffer
,
1083 unimp_device_attach_interrupt
,
1084 unimp_device_detach_interrupt
,
1085 iobus_interrupt_callback
,
1086 unimp_device_interrupt_ack
,
1092 /* FILE device: file@0x<address>,<file-name>
1093 (later - file@0x<address>,<size>,<file-offset>,<file-name>)
1095 Specifies a file to read directly into memory starting at <address> */
1099 file_init_callback(device
*me
,
1104 char file_name
[1024];
1106 if (scand_uw_c(device_name(me
), &addr
, file_name
, sizeof(file_name
)) != 2)
1107 error("devices/file - Usage: file@<address>,<file-name>\n");
1110 count
= dma_file(me
, file_name
, addr
);
1112 error("device_table/%s - Problem loading file %s\n", device_name(me
), file_name
);
1116 static device_callbacks
const file_callbacks
= {
1118 unimp_device_attach_address
,
1119 unimp_device_detach_address
,
1120 unimp_device_io_read_buffer
,
1121 unimp_device_io_write_buffer
,
1122 unimp_device_dma_read_buffer
,
1123 unimp_device_dma_write_buffer
,
1124 unimp_device_attach_interrupt
,
1125 unimp_device_detach_interrupt
,
1126 unimp_device_interrupt
,
1127 unimp_device_interrupt_ack
,
1133 /* DATA device: data@<address>,<count>,<value>
1135 Store <value> at <address> using <count> size transfer */
1138 data_init_callback(device
*me
,
1151 if (scand_uw_u_u(device_name(me
), &addr
, &count
, &value
) != 3)
1152 error("devices/data - Usage: data@<address>,<count>,<value>\n");
1154 /* store the data value */
1157 buf
.v1
= H2T_1(value
);
1160 buf
.v2
= H2T_2(value
);
1163 buf
.v4
= H2T_4(value
);
1166 buf
.v8
= H2T_8(value
);
1169 if (device_dma_write_buffer(device_parent(me
),
1171 0 /*address-space*/,
1174 1 /*violate ro*/) != count
) {
1175 error("devices/%s - Problem storing 0x%x at 0x%lx\n",
1176 device_name(me
), value
, (long)addr
);
1181 static device_callbacks
const data_callbacks
= {
1183 unimp_device_attach_address
,
1184 unimp_device_detach_address
,
1185 unimp_device_io_read_buffer
,
1186 unimp_device_io_write_buffer
,
1187 unimp_device_dma_read_buffer
,
1188 unimp_device_dma_write_buffer
,
1189 unimp_device_attach_interrupt
,
1190 unimp_device_detach_interrupt
,
1191 unimp_device_interrupt
,
1192 unimp_device_interrupt_ack
,
1198 /* HTAB: htab@<address>,<nr_bytes>
1199 PTE: pte@<real-address>,<virtual-address>,<nr_bytes>,<wimg>,<pp>
1200 PTE: pte@<real-address>,<wimg>,<pp>,<binary>
1202 HTAB defines the location (in physical memory) of a HASH table.
1203 PTE (as a child of HTAB) defines a mapping that is to be entered
1206 NB: All the work in this device is done during init by the PTE.
1207 The pte, looks up its parent to determine the address of the HTAB
1208 and then uses DMA calls to establish the required mapping. */
1211 STATIC_INLINE_DEVICE_TABLE
void
1212 htab_decode_hash_table(device
*parent
,
1213 unsigned32
*htaborg
,
1214 unsigned32
*htabmask
)
1216 unsigned_word htab_ra
;
1217 unsigned htab_nr_bytes
;
1219 /* determine the location/size of the hash table */
1221 || strncmp(device_name(parent
), "htab@", strlen("htab@")) != 0)
1222 error("devices/htab - missing htab device\n");
1223 if (scand_uw_u(device_name(parent
), &htab_ra
, &htab_nr_bytes
) != 2)
1224 error("devices/%s - Usage: htab@<real-addr>,<nr_bytes>\n",
1225 device_name(parent
));
1226 for (n
= htab_nr_bytes
; n
> 1; n
= n
/ 2) {
1228 error("devices/%s - htab size 0x%x not a power of two\n",
1229 device_name(parent
), htab_nr_bytes
);
1232 *htabmask
= MASKED32(htab_nr_bytes
- 1, 7, 31-6);
1233 if ((htab_ra
& INSERTED32(*htabmask
, 7, 15)) != 0) {
1234 error("devices/%s - htaborg 0x%x not aligned to htabmask 0x%x\n",
1235 device_name(parent
), *htaborg
, *htabmask
);
1237 DTRACE(htab
, ("htab - htaborg=0x%lx htabmask=0x%lx\n",
1238 (unsigned long)*htaborg
, (unsigned long)*htabmask
));
1243 htab_map_page(device
*me
,
1249 unsigned32 htabmask
)
1251 unsigned64 vpn
= va
<< 12;
1252 unsigned32 vsid
= INSERTED32(EXTRACTED64(vpn
, 0, 23), 0, 23);
1253 unsigned32 page
= INSERTED32(EXTRACTED64(vpn
, 24, 39), 0, 15);
1254 unsigned32 hash
= INSERTED32(EXTRACTED32(vsid
, 5, 23)
1255 ^ EXTRACTED32(page
, 0, 15),
1258 for (h
= 0; h
< 2; h
++) {
1259 unsigned32 pteg
= (htaborg
| (hash
& htabmask
));
1261 for (pti
= 0; pti
< 8; pti
++, pteg
+= 8) {
1262 unsigned32 current_target_pte0
;
1263 unsigned32 current_pte0
;
1264 if (device_dma_read_buffer(device_parent(me
),
1265 ¤t_target_pte0
,
1268 sizeof(current_target_pte0
)) != 4)
1269 error("htab_init_callback() failed to read a pte at 0x%x\n",
1271 current_pte0
= T2H_4(current_target_pte0
);
1272 if (!MASKED32(current_pte0
, 0, 0)) {
1273 /* empty pte fill it */
1274 unsigned32 pte0
= (MASK32(0, 0)
1275 | INSERTED32(EXTRACTED32(vsid
, 0, 23), 1, 24)
1276 | INSERTED32(h
, 25, 25)
1277 | INSERTED32(EXTRACTED32(page
, 0, 5), 26, 31));
1278 unsigned32 target_pte0
= H2T_4(pte0
);
1279 unsigned32 pte1
= (INSERTED32(EXTRACTED32(ra
, 0, 19), 0, 19)
1280 | INSERTED32(wimg
, 25, 28)
1281 | INSERTED32(pp
, 30, 31));
1282 unsigned32 target_pte1
= H2T_4(pte1
);
1283 if (device_dma_write_buffer(device_parent(me
),
1287 sizeof(target_pte0
),
1289 || device_dma_write_buffer(device_parent(me
),
1293 sizeof(target_pte1
),
1295 error("htab_init_callback() failed to write a pte a 0x%x\n",
1297 DTRACE(htab
, ("map - va=0x%lx ra=0x%lx &pte0=0x%lx pte0=0x%lx pte1=0x%lx\n",
1298 (unsigned long)va
, (unsigned long)ra
,
1299 (unsigned long)pteg
,
1300 (unsigned long)pte0
, (unsigned long)pte1
));
1305 hash
= MASKED32(~hash
, 0, 18);
1309 STATIC_INLINE_DEVICE_TABLE
void
1310 htab_map_region(device
*me
,
1311 unsigned_word pte_ra
,
1312 unsigned_word pte_va
,
1317 unsigned32 htabmask
)
1321 /* go through all pages and create a pte for each */
1322 for (ra
= pte_ra
, va
= (signed_word
)pte_va
;
1323 ra
< pte_ra
+ nr_bytes
;
1324 ra
+= 0x1000, va
+= 0x1000) {
1325 htab_map_page(me
, ra
, va
, wimg
, pp
, htaborg
, htabmask
);
1329 typedef struct _htab_binary_sizes
{
1330 unsigned_word text_ra
;
1331 unsigned_word text_base
;
1332 unsigned_word text_bound
;
1333 unsigned_word data_ra
;
1334 unsigned_word data_base
;
1335 unsigned data_bound
;
1337 } htab_binary_sizes
;
1339 STATIC_INLINE_DEVICE_TABLE
void
1340 htab_sum_binary(bfd
*abfd
,
1344 htab_binary_sizes
*sizes
= (htab_binary_sizes
*)data
;
1345 unsigned_word size
= bfd_get_section_size_before_reloc (sec
);
1346 unsigned_word vma
= bfd_get_section_vma (abfd
, sec
);
1348 /* skip the section if no memory to allocate */
1349 if (! (bfd_get_section_flags(abfd
, sec
) & SEC_ALLOC
))
1352 if ((bfd_get_section_flags (abfd
, sec
) & SEC_CODE
)
1353 || (bfd_get_section_flags (abfd
, sec
) & SEC_READONLY
)) {
1354 if (sizes
->text_bound
< vma
+ size
)
1355 sizes
->text_bound
= ALIGN_PAGE(vma
+ size
);
1356 if (sizes
->text_base
> vma
)
1357 sizes
->text_base
= FLOOR_PAGE(vma
);
1359 else if ((bfd_get_section_flags (abfd
, sec
) & SEC_DATA
)
1360 || (bfd_get_section_flags (abfd
, sec
) & SEC_ALLOC
)) {
1361 if (sizes
->data_bound
< vma
+ size
)
1362 sizes
->data_bound
= ALIGN_PAGE(vma
+ size
);
1363 if (sizes
->data_base
> vma
)
1364 sizes
->data_base
= FLOOR_PAGE(vma
);
1368 STATIC_INLINE_DEVICE_TABLE
void
1369 htab_dma_binary(bfd
*abfd
,
1373 htab_binary_sizes
*sizes
= (htab_binary_sizes
*)data
;
1375 unsigned_word section_vma
;
1376 unsigned_word section_size
;
1377 unsigned_word section_ra
;
1378 device
*me
= sizes
->me
;
1380 /* skip the section if no memory to allocate */
1381 if (! (bfd_get_section_flags(abfd
, sec
) & SEC_ALLOC
))
1384 /* check/ignore any sections of size zero */
1385 section_size
= bfd_get_section_size_before_reloc(sec
);
1386 if (section_size
== 0)
1389 /* if nothing to load, ignore this one */
1390 if (! (bfd_get_section_flags(abfd
, sec
) & SEC_LOAD
))
1393 /* find where it is to go */
1394 section_vma
= bfd_get_section_vma(abfd
, sec
);
1396 if ((bfd_get_section_flags (abfd
, sec
) & SEC_CODE
)
1397 || (bfd_get_section_flags (abfd
, sec
) & SEC_READONLY
))
1398 section_ra
= (section_vma
- sizes
->text_base
+ sizes
->text_ra
);
1399 else if ((bfd_get_section_flags (abfd
, sec
) & SEC_DATA
))
1400 section_ra
= (section_vma
- sizes
->data_base
+ sizes
->data_ra
);
1402 return; /* just ignore it */
1405 ("load - name=%-7s vma=0x%.8lx size=%6ld ra=0x%.8lx flags=%3lx(%s%s%s%s%s )\n",
1406 bfd_get_section_name(abfd
, sec
),
1410 (long)bfd_get_section_flags(abfd
, sec
),
1411 bfd_get_section_flags(abfd
, sec
) & SEC_LOAD
? " LOAD" : "",
1412 bfd_get_section_flags(abfd
, sec
) & SEC_CODE
? " CODE" : "",
1413 bfd_get_section_flags(abfd
, sec
) & SEC_DATA
? " DATA" : "",
1414 bfd_get_section_flags(abfd
, sec
) & SEC_ALLOC
? " ALLOC" : "",
1415 bfd_get_section_flags(abfd
, sec
) & SEC_READONLY
? " READONLY" : ""
1418 /* dma in the sections data */
1419 section_init
= zalloc(section_size
);
1420 if (!bfd_get_section_contents(abfd
,
1424 bfd_perror("devices/pte");
1425 error("devices/%s - no data loaded\n", device_name(me
));
1427 if (device_dma_write_buffer(device_parent(me
),
1432 1 /*violate_read_only*/)
1434 error("devices/%s - broken dma transfer\n", device_name(me
));
1435 zfree(section_init
); /* only free if load */
1439 STATIC_INLINE_DEVICE_TABLE
void
1440 htab_map_binary(device
*me
,
1446 unsigned32 htabmask
)
1448 htab_binary_sizes sizes
;
1450 sizes
.text_base
= -1;
1451 sizes
.data_base
= -1;
1452 sizes
.text_bound
= 0;
1453 sizes
.data_bound
= 0;
1457 image
= bfd_openr(file_name
, NULL
);
1458 if (image
== NULL
) {
1459 bfd_perror("devices/pte");
1460 error("devices/%s - the file %s not loaded\n", device_name(me
), file_name
);
1463 /* check it is valid */
1464 if (!bfd_check_format(image
, bfd_object
)) {
1466 error("devices/%s - the file %s has an invalid binary format\n",
1467 device_name(me
), file_name
);
1470 /* determine the size of each of the files regions */
1471 bfd_map_over_sections (image
, htab_sum_binary
, (PTR
) &sizes
);
1473 /* determine the real addresses of the sections */
1475 sizes
.data_ra
= ALIGN_PAGE(sizes
.text_ra
+
1476 (sizes
.text_bound
- sizes
.text_base
));
1478 DTRACE(htab
, ("text map - base=0x%lx bound=0x%lx ra=0x%lx\n",
1479 (unsigned long)sizes
.text_base
,
1480 (unsigned long)sizes
.text_bound
,
1481 (unsigned long)sizes
.text_ra
));
1482 DTRACE(htab
, ("data map - base=0x%lx bound=0x%lx ra=0x%lx\n",
1483 (unsigned long)sizes
.data_base
,
1484 (unsigned long)sizes
.data_bound
,
1485 (unsigned long)sizes
.data_ra
));
1487 /* set up virtual memory maps for each of the regions */
1488 htab_map_region(me
, sizes
.text_ra
, sizes
.text_base
,
1489 sizes
.text_bound
- sizes
.text_base
,
1492 htab_map_region(me
, sizes
.data_ra
, sizes
.data_base
,
1493 sizes
.data_bound
- sizes
.data_base
,
1497 /* dma the sections into physical memory */
1498 bfd_map_over_sections (image
, htab_dma_binary
, (PTR
) &sizes
);
1502 htab_init_callback(device
*me
,
1505 if (WITH_TARGET_WORD_BITSIZE
!= 32)
1506 error("devices/htab: only 32bit targets currently suported\n");
1508 /* only the pte does work */
1509 if (strncmp(device_name(me
), "pte@", strlen("pte@")) == 0) {
1511 unsigned32 htabmask
;
1512 signed32 pte_va
; /* so that 0xff...0 is make 0xffffff00 */
1514 unsigned pte_nr_bytes
;
1517 char file_name
[1024];
1519 htab_decode_hash_table(device_parent(me
), &htaborg
, &htabmask
);
1521 /* handle a normal mapping definition */
1522 if (scand_uw_uw_u_u_u(device_name(me
), &pte_ra
, &pte_va
, &pte_nr_bytes
,
1523 &pte_wimg
, &pte_pp
) == 5) {
1524 DTRACE(htab
, ("pte - ra=0x%lx, wimg=%ld, pp=%ld, va=0x%lx, nr_bytes=%ld\n",
1525 (unsigned long)pte_ra
,
1528 (unsigned long)pte_va
,
1529 (long)pte_nr_bytes
));
1530 htab_map_region(me
, pte_ra
, pte_va
, pte_nr_bytes
, pte_wimg
, pte_pp
,
1533 else if (scand_uw_u_u_c(device_name(me
), &pte_ra
, &pte_wimg
, &pte_pp
,
1534 file_name
, sizeof(file_name
)) == 4) {
1535 DTRACE(htab
, ("pte - ra=0x%lx, wimg=%ld, pp=%ld, binary=%s\n",
1536 (unsigned long)pte_ra
,
1537 (unsigned long)pte_wimg
,
1540 htab_map_binary(me
, pte_ra
, pte_wimg
, pte_pp
, file_name
,
1544 error("devices/%s - Usage: %s\nor\t%s\n",
1546 "pte@,<real-addr>,<virtual-addr>,<nr-bytes>,<wimg>,<pp>",
1547 "pte@<real-addr>,<wimg>,<pp>,<binary>");
1553 static device_callbacks
const htab_callbacks
= {
1555 unimp_device_attach_address
,
1556 unimp_device_detach_address
,
1557 unimp_device_io_read_buffer
,
1558 unimp_device_io_write_buffer
,
1559 passthrough_device_dma_read_buffer
,
1560 passthrough_device_dma_write_buffer
,
1561 unimp_device_attach_interrupt
,
1562 unimp_device_detach_interrupt
,
1563 unimp_device_interrupt
,
1564 unimp_device_interrupt_ack
,
1570 /* Simulator device: sim@0x<address>,<nr_bytes>
1572 Eventually gives access to the hardware configuration. For
1573 instance, it could allow the setting (on the fly) of variables such
1574 as hardware floating-point or strict-alignment.
1576 It's intended use is as part of testing the simulators
1579 static device_callbacks
const sim_callbacks
= {
1581 unimp_device_attach_address
,
1582 unimp_device_detach_address
,
1583 unimp_device_io_read_buffer
,
1584 unimp_device_io_write_buffer
,
1585 unimp_device_dma_read_buffer
,
1586 unimp_device_dma_write_buffer
,
1587 unimp_device_attach_interrupt
,
1588 unimp_device_detach_interrupt
,
1589 unimp_device_interrupt
,
1590 unimp_device_interrupt_ack
,
1596 /* Load device: binary
1598 Single property the name of which specifies the file (understood by
1599 BFD) that is to be DMAed into memory as part of init */
1601 STATIC_INLINE_DEVICE_TABLE
void
1602 update_for_binary_section(bfd
*abfd
,
1603 asection
*the_section
,
1606 unsigned_word section_vma
;
1607 unsigned_word section_size
;
1609 device
*me
= (device
*)obj
;
1611 /* skip the section if no memory to allocate */
1612 if (! (bfd_get_section_flags(abfd
, the_section
) & SEC_ALLOC
))
1615 /* check/ignore any sections of size zero */
1616 section_size
= bfd_get_section_size_before_reloc(the_section
);
1617 if (section_size
== 0)
1620 /* find where it is to go */
1621 section_vma
= bfd_get_section_vma(abfd
, the_section
);
1624 ("name=%-7s, vma=0x%.8lx, size=%6ld, flags=%3lx(%s%s%s%s%s )\n",
1625 bfd_get_section_name(abfd
, the_section
),
1628 (long)bfd_get_section_flags(abfd
, the_section
),
1629 bfd_get_section_flags(abfd
, the_section
) & SEC_LOAD
? " LOAD" : "",
1630 bfd_get_section_flags(abfd
, the_section
) & SEC_CODE
? " CODE" : "",
1631 bfd_get_section_flags(abfd
, the_section
) & SEC_DATA
? " DATA" : "",
1632 bfd_get_section_flags(abfd
, the_section
) & SEC_ALLOC
? " ALLOC" : "",
1633 bfd_get_section_flags(abfd
, the_section
) & SEC_READONLY
? " READONLY" : ""
1636 /* determine the devices access */
1637 access
= access_read
;
1638 if (bfd_get_section_flags(abfd
, the_section
) & SEC_CODE
)
1639 access
|= access_exec
;
1640 if (!(bfd_get_section_flags(abfd
, the_section
) & SEC_READONLY
))
1641 access
|= access_write
;
1643 /* if a map, pass up a request to create the memory in core */
1644 if (strncmp(device_name(me
), "map-binary", strlen("map-binary")) == 0)
1645 device_attach_address(device_parent(me
),
1648 0 /*address space*/,
1654 /* if a load dma in the required data */
1655 if (bfd_get_section_flags(abfd
, the_section
) & SEC_LOAD
) {
1656 void *section_init
= zalloc(section_size
);
1657 if (!bfd_get_section_contents(abfd
,
1661 bfd_perror("core:load_section()");
1662 error("load of data failed");
1665 if (device_dma_write_buffer(device_parent(me
),
1670 1 /*violate_read_only*/)
1672 error("data_init_callback() broken transfer for %s\n", device_name(me
));
1673 zfree(section_init
); /* only free if load */
1679 binary_init_callback(device
*me
,
1682 const char *file_name
;
1686 /* get the property specifying the file name */
1687 file_name
= device_find_next_property(me
, NULL
);
1690 image
= bfd_openr(file_name
, NULL
);
1691 if (image
== NULL
) {
1692 bfd_perror("devices/binary");
1693 error("devices/%s - the file %s not loaded\n", device_name(me
), file_name
);
1696 /* check it is valid */
1697 if (!bfd_check_format(image
, bfd_object
)) {
1699 error("devices/%s - the file %s has an invalid binary format\n",
1700 device_name(me
), file_name
);
1703 /* and the data sections */
1704 bfd_map_over_sections(image
,
1705 update_for_binary_section
,
1712 static device_callbacks
const binary_callbacks
= {
1713 binary_init_callback
,
1714 unimp_device_attach_address
,
1715 unimp_device_detach_address
,
1716 unimp_device_io_read_buffer
,
1717 unimp_device_io_write_buffer
,
1718 unimp_device_dma_read_buffer
,
1719 unimp_device_dma_write_buffer
,
1720 unimp_device_attach_interrupt
,
1721 unimp_device_detach_interrupt
,
1722 unimp_device_interrupt
,
1723 unimp_device_interrupt_ack
,
1729 /* Stack device: stack@<type>
1731 Has a single IOCTL to create a stack frame of the specified type.
1732 If <type> is elf or xcoff then a corresponding stack is created.
1733 Any other value of type is ignored.
1735 The IOCTL takes the additional arguments:
1737 unsigned_word stack_end -- where the stack should come down from
1743 STATIC_INLINE_DEVICE_TABLE
int
1744 sizeof_argument_strings(char **arg
)
1746 int sizeof_strings
= 0;
1752 /* add up all the string sizes (padding as we go) */
1753 for (; *arg
!= NULL
; arg
++) {
1754 int len
= strlen(*arg
) + 1;
1755 sizeof_strings
+= ALIGN_8(len
);
1758 return sizeof_strings
;
1761 STATIC_INLINE_DEVICE_TABLE
int
1762 number_of_arguments(char **arg
)
1767 for (nr
= 0; *arg
!= NULL
; arg
++, nr
++);
1771 STATIC_INLINE_DEVICE_TABLE
int
1772 sizeof_arguments(char **arg
)
1774 return ALIGN_8((number_of_arguments(arg
) + 1) * sizeof(unsigned_word
));
1777 STATIC_INLINE_DEVICE_TABLE
void
1778 write_stack_arguments(psim
*system
,
1780 unsigned_word start_block
,
1781 unsigned_word end_block
,
1782 unsigned_word start_arg
,
1783 unsigned_word end_arg
)
1786 ("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",
1787 (long)system
, (long)arg
, (long)start_block
, (long)end_block
, (long)start_arg
, (long)end_arg
));
1789 error("write_arguments: character array NULL\n");
1790 /* only copy in arguments, memory is already zero */
1791 for (; *arg
!= NULL
; arg
++) {
1792 int len
= strlen(*arg
)+1;
1793 unsigned_word target_start_block
;
1795 ("write_stack_arguments() write %s=%s at %s=0x%lx %s=0x%lx %s=0x%lx\n",
1796 "**arg", *arg
, "start_block", (long)start_block
,
1797 "len", (long)len
, "start_arg", (long)start_arg
));
1798 if (psim_write_memory(system
, 0, *arg
,
1800 0/*violate_readonly*/) != len
)
1801 error("write_stack_arguments() - write of **arg (%s) at 0x%x failed\n",
1803 target_start_block
= H2T_word(start_block
);
1804 if (psim_write_memory(system
, 0, &target_start_block
,
1805 start_arg
, sizeof(target_start_block
),
1806 0) != sizeof(target_start_block
))
1807 error("write_stack_arguments() - write of *arg failed\n");
1808 start_block
+= ALIGN_8(len
);
1809 start_arg
+= sizeof(start_block
);
1811 start_arg
+= sizeof(start_block
); /*the null at the end*/
1812 if (start_block
!= end_block
1813 || ALIGN_8(start_arg
) != end_arg
)
1814 error("write_stack_arguments - possible corruption\n");
1816 ("write_stack_arguments() = void\n"));
1819 STATIC_INLINE_DEVICE_TABLE
void
1820 create_elf_stack_frame(psim
*system
,
1821 unsigned_word bottom_of_stack
,
1825 /* fixme - this is over aligned */
1827 /* information block */
1828 const unsigned sizeof_envp_block
= sizeof_argument_strings(envp
);
1829 const unsigned_word start_envp_block
= bottom_of_stack
- sizeof_envp_block
;
1830 const unsigned sizeof_argv_block
= sizeof_argument_strings(argv
);
1831 const unsigned_word start_argv_block
= start_envp_block
- sizeof_argv_block
;
1833 /* auxiliary vector - contains only one entry */
1834 const unsigned sizeof_aux_entry
= 2*sizeof(unsigned_word
); /* magic */
1835 const unsigned_word start_aux
= start_argv_block
- ALIGN_8(sizeof_aux_entry
);
1837 /* environment points (including null sentinal) */
1838 const unsigned sizeof_envp
= sizeof_arguments(envp
);
1839 const unsigned_word start_envp
= start_aux
- sizeof_envp
;
1841 /* argument pointers (including null sentinal) */
1842 const int argc
= number_of_arguments(argv
);
1843 const unsigned sizeof_argv
= sizeof_arguments(argv
);
1844 const unsigned_word start_argv
= start_envp
- sizeof_argv
;
1846 /* link register save address - alligned to a 16byte boundary */
1847 const unsigned_word top_of_stack
= ((start_argv
1848 - 2 * sizeof(unsigned_word
))
1851 /* install arguments on stack */
1852 write_stack_arguments(system
, envp
,
1853 start_envp_block
, bottom_of_stack
,
1854 start_envp
, start_aux
);
1855 write_stack_arguments(system
, argv
,
1856 start_argv_block
, start_envp_block
,
1857 start_argv
, start_envp
);
1859 /* set up the registers */
1860 psim_write_register(system
, -1,
1861 &top_of_stack
, "sp", cooked_transfer
);
1862 psim_write_register(system
, -1,
1863 &argc
, "r3", cooked_transfer
);
1864 psim_write_register(system
, -1,
1865 &start_argv
, "r4", cooked_transfer
);
1866 psim_write_register(system
, -1,
1867 &start_envp
, "r5", cooked_transfer
);
1868 psim_write_register(system
, -1,
1869 &start_aux
, "r6", cooked_transfer
);
1872 STATIC_INLINE_DEVICE_TABLE
void
1873 create_aix_stack_frame(psim
*system
,
1874 unsigned_word bottom_of_stack
,
1878 unsigned_word core_envp
;
1879 unsigned_word core_argv
;
1880 unsigned_word core_argc
;
1881 unsigned_word core_aux
;
1882 unsigned_word top_of_stack
;
1884 /* cheat - create an elf stack frame */
1885 create_elf_stack_frame(system
, bottom_of_stack
, argv
, envp
);
1887 /* extract argument addresses from registers */
1888 psim_read_register(system
, 0, &top_of_stack
, "r1", cooked_transfer
);
1889 psim_read_register(system
, 0, &core_argc
, "r3", cooked_transfer
);
1890 psim_read_register(system
, 0, &core_argv
, "r4", cooked_transfer
);
1891 psim_read_register(system
, 0, &core_envp
, "r5", cooked_transfer
);
1892 psim_read_register(system
, 0, &core_aux
, "r6", cooked_transfer
);
1894 /* extract arguments from registers */
1895 error("create_aix_stack_frame() - what happens next?\n");
1901 stack_ioctl_callback(device
*me
,
1907 unsigned_word stack_pointer
;
1908 const char *stack_type
;
1911 stack_pointer
= va_arg(ap
, unsigned_word
);
1912 argv
= va_arg(ap
, char **);
1913 envp
= va_arg(ap
, char **);
1915 ("stack_ioctl_callback(me=0x%lx:%s, system=0x%lx, processor=0x%lx, cia=0x%lx, argv=0x%lx, envp=0x%lx)\n",
1916 (long)me
, device_name(me
), (long)system
, (long)processor
, (long)cia
, (long)argv
, (long)envp
));
1917 stack_type
= device_find_next_property(me
, NULL
);
1918 if (stack_type
!= NULL
) {
1919 if (strcmp(stack_type
, "elf") == 0)
1920 create_elf_stack_frame(system
, stack_pointer
, argv
, envp
);
1921 else if (strcmp(stack_type
, "xcoff") == 0)
1922 create_aix_stack_frame(system
, stack_pointer
, argv
, envp
);
1925 ("stack_ioctl_callback() = void\n"));
1931 static device_callbacks
const stack_callbacks
= {
1933 unimp_device_attach_address
,
1934 unimp_device_detach_address
,
1935 unimp_device_io_read_buffer
,
1936 unimp_device_io_write_buffer
,
1937 unimp_device_dma_read_buffer
,
1938 unimp_device_dma_write_buffer
,
1939 unimp_device_attach_interrupt
,
1940 unimp_device_detach_interrupt
,
1941 unimp_device_interrupt
,
1942 unimp_device_interrupt_ack
,
1943 stack_ioctl_callback
,
1948 device_descriptor device_table
[] = {
1949 { "console", console_create
, &console_callbacks
},
1950 { "memory", NULL
, &memory_callbacks
},
1951 { "vm", vea_vm_create
, &vm_callbacks
},
1952 { "halt", NULL
, &halt_callbacks
},
1953 { "icu", NULL
, &icu_callbacks
},
1954 { "register", NULL
, ®ister_callbacks
},
1955 { "iobus", NULL
, &iobus_callbacks
},
1956 { "file", NULL
, &file_callbacks
},
1957 { "data", NULL
, &data_callbacks
},
1958 { "htab", NULL
, &htab_callbacks
},
1959 { "pte", NULL
, &htab_callbacks
}, /* yep - uses htab's table */
1960 { "stack", NULL
, &stack_callbacks
},
1961 { "sim", NULL
, &sim_callbacks
},
1962 { "load-binary", NULL
, &binary_callbacks
},
1963 { "map-binary", NULL
, &binary_callbacks
},
1964 { "options", NULL
, &passthrough_callbacks
},
1965 { "init", NULL
, &passthrough_callbacks
},
1966 { "chosen", NULL
, &passthrough_callbacks
},
1970 #endif /* _DEVICE_TABLE_C_ */