From 979c3c25fd3f51d8effb28593edf222841053de9 Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Mon, 8 Jan 1996 18:01:17 +0000 Subject: [PATCH] Latest cagney update --- sim/ppc/ChangeLog | 111 +++++++++++ sim/ppc/Makefile.in | 71 ++++--- sim/ppc/device.c | 199 +++++++++++++------- sim/ppc/device.h | 137 +++++++------- sim/ppc/device_table.c | 66 +++++-- sim/ppc/emul_bugapi.c | 98 +++++++++- sim/ppc/emul_chirp.c | 489 +++++++++++++++++++++++++++++++++++++++++++++---- 7 files changed, 941 insertions(+), 230 deletions(-) diff --git a/sim/ppc/ChangeLog b/sim/ppc/ChangeLog index 6b38aa8..2e62ae6 100644 --- a/sim/ppc/ChangeLog +++ b/sim/ppc/ChangeLog @@ -1,3 +1,114 @@ +Mon Jan 8 12:17:22 1996 Michael Meissner + + * device_table.c (register_init): Make format type correct. + +Wed Jan 3 19:21:46 1996 Andrew Cagney + + * emul_bugapi.c (emul_bugapi_create): Add nodes to init the + system-call trap to the emul instruction call instruction (Along + with an rfi and infinate loop). + + * emul_bugapi.c (emul_bugapi_instruction_call): Expand to include + a few real PPC bug calls. Test with simple hello world. + +Tue Jan 2 20:51:19 1996 Andrew Cagney - aka Noid + + * device.h, device.c (device_child, device_sibling): New + functions. Return corresponding device value. + + * emul_chirp.c (chirp_emul_child, chirp_emul_peer, + chirp_emul_parent): New functions - emulate corresponding OpenBoot + interfaces. + + * device_table.c (register_init): Extend properties attached to + register init node to allow a specific processor's register to be + specified. + + * emul_chirp.c (emul_chirp_create): Init SMP correctly - the + initial PC for all processors is an infinate loop but then, for + processor zero, is quickly changed to be the correct code starting + address. + + * emul_chirp.c (emul_chirp_create): Add fake bootpath + et.al. properties to tree. + + * emul_chirp.c (chirp_emul_getproplen): New function. Emulate the + getproplen OpenBoot call. + + * emul_chirp.c (emul_chirp_instruction_call): Document other + possible chirp emulation internal states. + + * emul_chirp.c (emul_chirp_instruction_call): Trace failed lookups + as well as successful ones. + + * emul_chirp.c (emul_chirp_open): New function - handle open + client call. + + * Makefile.in (maintainer-clean): Proper rule that eliminates more + junk. + +Tue Dec 19 13:00:11 1995 Andrew Cagney + + * emul_chirp.c (chirp_emul_exit): Full out call. + + * device_table.c (htab_map_page): Wasn't handling byte swap when + creating entries in the hash table. + + * device.c (device_tree_find_node): Allow primative wild-card match + of device names with the path. + + FIXME: As mentioned earlier, the device stuff needs work to bring + it into line with OpenBoot. Part of this work is rewriting the + find_node function so that it behaves as specified in p1275. + +Mon Dec 18 19:58:56 1995 Andrew Cagney + + * emul_chrp.c (chirp_emul_write, chirp_emul_finddevice): add + better tracing. + + * emul_chrp.c: Change return type of emul functions to int. Emul + functions either return -1 or zero so unsigned was a bit + dangerous. + + * inline.h (*), igen.c, dgen.c, *: Update INLINE macros so that + they are paramaterised with the type of the function. Gets around + the problem of `static' needing to come first with `attribute' + comming last. Format declarations and definitions so that emacs + doesn't get confused. + +Fri Dec 15 17:06:44 1995 Andrew Cagney + + * std-config.h (PSIM_INLINE): Add missing inline configuration + control for the main loop. + + * mon.c (mon_print_info): If monitoring disabled still print out + the number seconds used. + + * psim.c (run_until_stop): Don't monitor the cache misses when + monitoring is disabled. + + * configure.in (sim_mon, sim_monitor): Correct typo - sim_mon -> + sim_monitor for shell variable (or should that have been the other + way around?). + + * vm.c (vm_synchronize_context): Fix wrong test for unsuported + change in endian-mode. + + * std-config.h (WITH_REGPARM), inline.h (IDECODE_INLINE, + SEMANTICS_INLINE): Add -DWITH_REGPARM= option. Enables the + __attribute__((__regparm(WITH_REGPARM))) for some functions. + configure with --enable-sim-cflags="-DWITH_REGPARAM=3" (say). + Unfortunatly it tickles a bug (gcc?) and can't be used. + +Mon Dec 18 13:36:06 1995 Michael Meissner + + * device.c (device_tree_add_device): Make trace fprintf arguments + type correct. + * device_table.c (htab_decode_hash_table): Ditto. + (htab_map_binary): Ditto. + (htab_init_callback): Ditto. + * vm.c (om_virtual_to_real): Ditto. + Sat Dec 16 09:54:18 1995 Michael Meissner * emul_netbsd.c (emul_netbsd_create): Deal with new BFD that diff --git a/sim/ppc/Makefile.in b/sim/ppc/Makefile.in index d724371..e5684bb 100644 --- a/sim/ppc/Makefile.in +++ b/sim/ppc/Makefile.in @@ -83,8 +83,7 @@ TRACE_CFLAGS = @sim_trace@ ASSERT_CFLAGS = @sim_assert@ RESERVED_CFLAGS = @sim_reserved@ MONITOR_CFLAGS = @sim_monitor@ -FUNC_CFLAGS = @sim_func@ -MODEL_CFLAGS = @sim_model@ @sim_default_model@ +MODEL_CFLAGS = @sim_model@ @sim_default_model@ @sim_model_issue@ WARNING_CFLAGS = @sim_warnings@ CONFIG_CFLAGS = $(BSWAP_CFLAGS) \ $(ENDIAN_CFLAGS) \ @@ -101,7 +100,6 @@ CONFIG_CFLAGS = $(BSWAP_CFLAGS) \ $(ASSERT_CFLAGS) \ $(RESERVED_CFLAGS) \ $(MONITOR_CFLAGS) \ - $(FUNC_CFLAGS) \ $(MODEL_CFLAGS) STD_CFLAGS = $(CFLAGS) $(INLINE_CFLAGS) $(CONFIG_CFLAGS) $(WARNING_CFLAGS) $(SIM_CFLAGS) $(HDEFINES) $(TDEFINES) $(INCLUDES) @@ -139,14 +137,15 @@ all: run $(TARGETLIB) $(GDB_OBJ) BASICS_H = \ + basics.h \ config.h \ ppc-config.h \ + inline.h \ + sim_callbacks.h \ + debug.h filter_filename.h \ words.h \ - sim-endian.h \ - debug.h \ - filter_filename.h \ bits.h \ - sim_callbacks.h + sim-endian.h PSIM_H = \ psim.h \ @@ -167,7 +166,7 @@ CPU_H = \ cpu.h \ $(BASICS_H) \ $(REGISTERS_H) \ - device_tree.h \ + device.h \ corefile.h \ vm.h \ events.h \ @@ -176,9 +175,13 @@ CPU_H = \ icache.h \ itable.h \ mon.h \ - function_unit.h \ model.h +DEVICE_TABLE_H = \ + $(BASICS_H) \ + device_table.h \ + device.h + EMUL_GENERIC_H = \ $(CPU_H) \ $(IDECODE_H) \ @@ -213,16 +216,18 @@ LIB_SRC = \ vm.c \ vm_n.h \ corefile.c \ - function_unit.c \ events.c \ os_emul.c \ emul_generic.c \ emul_netbsd.c \ + emul_chirp.c \ + emul_bugapi.c \ registers.c \ cpu.c \ interrupts.c \ - devices.c \ - device_tree.c \ + device.c \ + device_table.c \ + cap.c \ mon.c \ options.c @@ -235,29 +240,31 @@ MAIN_SRC = \ # first LIB_OBJ = \ debug.o \ - options.o \ filter_filename.o \ bits.o \ sim-endian.o \ os_emul.o \ emul_generic.o \ emul_netbsd.o \ + emul_chirp.o \ + emul_bugapi.o \ registers.o \ vm.o \ corefile.o \ model.o \ - function_unit.o \ spreg.o \ cpu.o \ interrupts.o \ events.o \ - devices.o \ - device_tree.o \ + cap.o \ + device.o \ + device_table.o \ itable.o \ mon.o \ semantics.o \ idecode.o \ - psim.o + psim.o \ + options.o GDB_OBJ = sim_calls.o @@ -278,7 +285,6 @@ $(TARGETLIB): tmp-igen tmp-dgen $(LIB_OBJ) $(GDB_OBJ) # Given that inlines are turned on now, rebuild psim whenever # anything changes. psim.o: psim.c psim.h $(CPU_H) $(IDECODE_H) $(INLINE) $(LIB_SRC) $(BUILT_SRC) - $(CC) -c $(NOWARN_CFLAGS) $< bits.o: bits.c $(BASICS_H) @@ -287,9 +293,12 @@ filter_filename.o: filter_filename.c filter_filename.h config.h ppc-config.h sim-endian.o: sim-endian.c sim-endian-n.h $(BASICS_H) -os_emul.o: os_emul.c $(EMUL_GENERIC_H) +os_emul.o: os_emul.c emul_netbsd.h emul_chirp.h emul_bugapi.h $(EMUL_GENERIC_H) emul_generic.o: emul_generic.c $(EMUL_GENERIC_H) + emul_netbsd.o: emul_netbsd.c emul_netbsd.h $(EMUL_GENERIC_H) +emul_chirp.o: emul_chirp.c emul_chirp.h cap.h $(EMUL_GENERIC_H) +emul_bugapi.o: emul_bugapi.c emul_bugapi.h $(EMUL_GENERIC_H) registers.o: registers.c $(REGISTERS_H) $(BASICS_H) @@ -303,26 +312,25 @@ idecode.o: idecode.c $(CPU_H) $(IDECODE_H) semantics.h # double.o: double.c dp-bit.c vm.o: vm.c vm.h vm_n.h $(BASICS_H) $(REGISTERS_H) \ - device_tree.h corefile.h interrupts.h itable.h mon.h - -corefile.o: corefile.c corefile.h $(BASICS_H) device_tree.h + device.h corefile.h interrupts.h itable.h mon.h -function_unit.o: function_unit.c $(CPU_H) +corefile.o: corefile.c corefile.h corefile-n.h $(BASICS_H) device.h model.o: model.c $(CPU_H) events.o: events.c events.h $(BASICS_H) -sim_calls.o: sim_calls.c $(CPU_H) $(PSIM_H) ../../gdb/tm.h devices.h options.h +sim_calls.o: sim_calls.c $(PSIM_H) itable.h ../../gdb/tm.h options.h -spreg.o: spreg.h spreg.c words.h +spreg.o: spreg.h spreg.c $(BASICS_H) -main.o: main.c $(PSIM_H) function_unit.h itable.h options.h +main.o: main.c $(PSIM_H) itable.h options.h -devices.o: devices.c devices.h $(CPU_H) \ - device_tree.h events.h +device.o: device.c $(DEVICE_TABLE_H) -device_tree.o: device_tree.c device_tree.h devices.h $(BASICS_H) +device_table.o: device_table.c $(DEVICE_TABLE_H) events.h + +cap.o: cap.c cap.h $(BASICS_H) semantics.o: semantics.c semantics.h $(CPU_H) $(IDECODE_H) $(CC) -c $(NOWARN_CFLAGS) $< @@ -405,9 +413,12 @@ TAGS: $(BUILT_SRC) clean mostlyclean: rm -f tmp-* *.[oasi] core psim run igen dgen config.log $(BUILT_SRC_WO_CONFIG) -distclean maintainer-clean realclean: clean +distclean realclean: clean rm -f TAGS Makefile config.cache config.status config.h stamp-h +maintainer-clean: distclean + rm -f *~ ppc-config.h + Makefile: Makefile.in config.status CONFIG_FILES=Makefile CONFIG_HEADERS= $(SHELL) ./config.status diff --git a/sim/ppc/device.c b/sim/ppc/device.c index 5dc69cb..618c5a4 100644 --- a/sim/ppc/device.c +++ b/sim/ppc/device.c @@ -67,7 +67,8 @@ struct _device { }; -device INLINE_DEVICE * +INLINE_DEVICE\ +(device *) device_create(const char *name, device *parent) { @@ -90,7 +91,8 @@ device_create(const char *name, return NULL; } -device INLINE_DEVICE * +INLINE_DEVICE\ +(device *) device_create_from(const char *name, void *data, const device_callbacks *callbacks, @@ -105,25 +107,43 @@ device_create_from(const char *name, } -device INLINE_DEVICE * +INLINE_DEVICE\ +(device *) device_parent(device *me) { return me->parent; } -const char INLINE_DEVICE * +INLINE_DEVICE\ +(device *) +device_sibling(device *me) +{ + return me->sibling; +} + +INLINE_DEVICE\ +(device *) +device_child(device *me) +{ + return me->children; +} + +INLINE_DEVICE\ +(const char *) device_name(device *me) { return me->name; } -void INLINE_DEVICE * +INLINE_DEVICE\ +(void *) device_data(device *me) { return me->data; } -void INLINE_DEVICE +INLINE_DEVICE\ +(void) device_traverse_properties(device *me, device_traverse_property_function *traverse, void *data) @@ -135,14 +155,16 @@ device_traverse_properties(device *me, } } -void INLINE_DEVICE +INLINE_DEVICE\ +(void) device_init(device *me, psim *system) { me->callback->init(me, system); } -void INLINE_DEVICE +INLINE_DEVICE\ +(void) device_attach_address(device *me, const char *name, attach_type attach, @@ -156,7 +178,8 @@ device_attach_address(device *me, addr, nr_bytes, access, who); } -void INLINE_DEVICE +INLINE_DEVICE\ +(void) device_detach_address(device *me, const char *name, attach_type attach, @@ -170,7 +193,8 @@ device_detach_address(device *me, addr, nr_bytes, access, who); } -unsigned INLINE_DEVICE +INLINE_DEVICE\ +(unsigned) device_io_read_buffer(device *me, void *dest, int space, @@ -184,7 +208,8 @@ device_io_read_buffer(device *me, processor, cia); } -unsigned INLINE_DEVICE +INLINE_DEVICE\ +(unsigned) device_io_write_buffer(device *me, const void *source, int space, @@ -198,7 +223,8 @@ device_io_write_buffer(device *me, processor, cia); } -unsigned INLINE_DEVICE +INLINE_DEVICE\ +(unsigned) device_dma_read_buffer(device *me, void *dest, int space, @@ -209,7 +235,8 @@ device_dma_read_buffer(device *me, addr, nr_bytes); } -unsigned INLINE_DEVICE +INLINE_DEVICE\ +(unsigned) device_dma_write_buffer(device *me, const void *source, int space, @@ -222,7 +249,8 @@ device_dma_write_buffer(device *me, violate_read_only_section); } -void INLINE_DEVICE +INLINE_DEVICE\ +(void) device_attach_interrupt(device *me, device *who, int interrupt_line, @@ -231,7 +259,8 @@ device_attach_interrupt(device *me, me->callback->attach_interrupt(me, who, interrupt_line, name); } -void INLINE_DEVICE +INLINE_DEVICE\ +(void) device_detach_interrupt(device *me, device *who, int interrupt_line, @@ -240,7 +269,8 @@ device_detach_interrupt(device *me, me->callback->detach_interrupt(me, who, interrupt_line, name); } -void INLINE_DEVICE +INLINE_DEVICE\ +(void) device_interrupt(device *me, device *who, int interrupt_line, @@ -252,7 +282,8 @@ device_interrupt(device *me, processor, cia); } -void INLINE_DEVICE +INLINE_DEVICE\ +(void) device_interrupt_ack(device *me, int interrupt_line, int interrupt_status) @@ -260,7 +291,8 @@ device_interrupt_ack(device *me, me->callback->interrupt_ack(me, interrupt_line, interrupt_status); } -void EXTERN_DEVICE +EXTERN_DEVICE\ +(void) device_ioctl(device *me, psim *system, cpu *processor, @@ -276,7 +308,8 @@ device_ioctl(device *me, /* Manipulate properties attached to devices */ -device_property STATIC_INLINE_DEVICE * +STATIC_INLINE_DEVICE\ +(device_property *) device_add_property(device *me, const char *property, device_property_type type, @@ -311,7 +344,8 @@ device_add_property(device *me, return new_value; } -void INLINE_DEVICE +INLINE_DEVICE\ +(void) device_add_array_property(device *me, const char *property, const void *array, @@ -324,7 +358,8 @@ device_add_array_property(device *me, array_property, array, sizeof_array); } -void INLINE_DEVICE +INLINE_DEVICE\ +(void) device_add_integer_property(device *me, const char *property, signed32 integer) @@ -337,7 +372,8 @@ device_add_integer_property(device *me, &integer, sizeof(integer)); } -void INLINE_DEVICE +INLINE_DEVICE\ +(void) device_add_boolean_property(device *me, const char *property, int boolean) @@ -350,7 +386,8 @@ device_add_boolean_property(device *me, &new_boolean, sizeof(new_boolean)); } -void INLINE_DEVICE +INLINE_DEVICE\ +(void) device_add_null_property(device *me, const char *property) { @@ -361,7 +398,8 @@ device_add_null_property(device *me, NULL, 0); } -void INLINE_DEVICE +INLINE_DEVICE\ +(void) device_add_string_property(device *me, const char *property, const char *string) @@ -374,7 +412,8 @@ device_add_string_property(device *me, string, strlen(string) + 1); } -const device_property INLINE_DEVICE * +INLINE_DEVICE\ +(const device_property *) device_find_property(device *me, const char *property) { @@ -389,7 +428,8 @@ device_find_property(device *me, return (device_property*)0; } -const char INLINE_DEVICE * +INLINE_DEVICE\ +(const char *) device_find_next_property(device *me, const char *property) { @@ -413,7 +453,8 @@ device_find_next_property(device *me, return NULL; } -const device_property INLINE_DEVICE * +INLINE_DEVICE\ +(const device_property *) device_find_array_property(device *me, const char *property) { @@ -429,7 +470,8 @@ device_find_array_property(device *me, return node; } -signed_word INLINE_DEVICE +INLINE_DEVICE\ +(signed_word) device_find_integer_property(device *me, const char *property) { @@ -449,7 +491,8 @@ device_find_integer_property(device *me, return integer; } -int INLINE_DEVICE +INLINE_DEVICE\ +(int) device_find_boolean_property(device *me, const char *property) { @@ -468,7 +511,8 @@ device_find_boolean_property(device *me, return boolean; } -const char INLINE_DEVICE * +INLINE_DEVICE\ +(const char *) device_find_string_property(device *me, const char *property) { @@ -490,7 +534,8 @@ device_find_string_property(device *me, /* determine the full name of the device. If buf is specified it is stored in there. Failing that, a safe area of memory is allocated */ -const char STATIC_INLINE_DEVICE * +STATIC_INLINE_DEVICE\ +(const char *) device_tree_full_name(device *leaf, char *buf, unsigned sizeof_buf) @@ -530,7 +575,8 @@ typedef enum { device_tree_abort = 3, } device_tree_action; -device STATIC_INLINE_DEVICE * +STATIC_INLINE_DEVICE\ +(device *) device_tree_find_node(device *root, const char *path, const char *full_path, @@ -605,7 +651,9 @@ device_tree_find_node(device *root, child != NULL; child = child->sibling) { if (strncmp(name, child->name, strlen_name) == 0 - && strlen(child->name) == strlen_name) { + && strlen(child->name) >= strlen_name + && (child->name[strlen_name] == '\0' + || child->name[strlen_name] == '@')) { if (*path == '\0') return child; else @@ -634,7 +682,8 @@ device_tree_find_node(device *root, /* grow the device tree */ -device INLINE_DEVICE * +INLINE_DEVICE\ +(device *) device_tree_add_device(device *root, const char *prefix, device *new_sub_tree) @@ -662,7 +711,8 @@ device_tree_add_device(device *root, return new_sub_tree; } -device INLINE_DEVICE * +INLINE_DEVICE\ +(device *) device_tree_find_device(device *root, const char *path) { @@ -680,7 +730,8 @@ device_tree_find_device(device *root, /* init all the devices */ -void STATIC_INLINE_DEVICE +STATIC_INLINE_DEVICE\ +(void) device_tree_init_device(device *root, void *data) { @@ -693,7 +744,8 @@ device_tree_init_device(device *root, } -void INLINE_DEVICE +INLINE_DEVICE\ +(void) device_tree_init(device *root, psim *system) { @@ -707,7 +759,8 @@ device_tree_init(device *root, /* traverse a device tree applying prefix/postfix functions to it */ -void INLINE_DEVICE +INLINE_DEVICE\ +(void) device_tree_traverse(device *root, device_tree_traverse_function *prefix, device_tree_traverse_function *postfix, @@ -726,7 +779,8 @@ device_tree_traverse(device *root, /* dump out a device node and addresses */ -void INLINE_DEVICE +INLINE_DEVICE\ +(void) device_tree_dump(device *device, void *ignore_data_argument) { @@ -742,7 +796,8 @@ device_tree_dump(device *device, /* lookup/create a device various formats */ -void STATIC_INLINE_DEVICE +STATIC_INLINE_DEVICE\ +(void) u_strcat(char *buf, unsigned_word uw) { @@ -759,7 +814,8 @@ u_strcat(char *buf, } } -void STATIC_INLINE_DEVICE +STATIC_INLINE_DEVICE\ +(void) c_strcat(char *buf, const char *c) { @@ -772,7 +828,8 @@ c_strcat(char *buf, *end = '\0'; } -device INLINE_DEVICE * +INLINE_DEVICE\ +(device *) device_tree_add_found(device *root, const char *prefix, const char *name) @@ -781,8 +838,8 @@ device_tree_add_found(device *root, device *new_device; device *new_node; TRACE(trace_device_tree, - ("device_tree_add_found(root=0x%lx, prefix=%s, name=%x)\n", - (long)root, prefix, name)); + ("device_tree_add_found(root=0x%lx, prefix=%s, name=%lx)\n", + (unsigned long)root, prefix, (unsigned long)name)); parent = device_tree_find_node(root, prefix, prefix, device_tree_abort); new_device = device_tree_find_device(parent, name); @@ -796,7 +853,8 @@ device_tree_add_found(device *root, } } -device INLINE_DEVICE * +INLINE_DEVICE\ +(device *) device_tree_add_found_c(device *root, const char *prefix, const char *name, @@ -811,7 +869,8 @@ device_tree_add_found_c(device *root, return device_tree_add_found(root, prefix, buf); } -device INLINE_DEVICE * +INLINE_DEVICE\ +(device *) device_tree_add_found_c_uw(device *root, const char *prefix, const char *name, @@ -829,7 +888,8 @@ device_tree_add_found_c_uw(device *root, return device_tree_add_found(root, prefix, buf); } -device INLINE_DEVICE * +INLINE_DEVICE\ +(device *) device_tree_add_found_uw_u(device *root, const char *prefix, const char *name, @@ -847,7 +907,8 @@ device_tree_add_found_uw_u(device *root, return device_tree_add_found(root, prefix, buf); } -device INLINE_DEVICE * +INLINE_DEVICE\ +(device *) device_tree_add_found_uw_u_u(device *root, const char *prefix, const char *name, @@ -868,7 +929,8 @@ device_tree_add_found_uw_u_u(device *root, return device_tree_add_found(root, prefix, buf); } -device INLINE_DEVICE * +INLINE_DEVICE\ +(device *) device_tree_add_found_uw_u_u_c(device *root, const char *prefix, const char *name, @@ -892,7 +954,8 @@ device_tree_add_found_uw_u_u_c(device *root, return device_tree_add_found(root, prefix, buf); } -device INLINE_DEVICE * +INLINE_DEVICE\ +(device *) device_tree_add_found_uw_uw_u_u_c(device *root, const char *prefix, const char *name, @@ -919,7 +982,8 @@ device_tree_add_found_uw_uw_u_u_c(device *root, return device_tree_add_found(root, prefix, buf); } -device INLINE_DEVICE * +INLINE_DEVICE\ +(device *) device_tree_add_found_uw_uw_u_u_u(device *root, const char *prefix, const char *name, @@ -1007,7 +1071,8 @@ do { \ START = END + 1; \ } while (0) -int INLINE_DEVICE +INLINE_DEVICE\ +(int) scand_c(const char *name, char *c1, unsigned c1size) @@ -1017,7 +1082,8 @@ scand_c(const char *name, SCAN_END; } -int INLINE_DEVICE +INLINE_DEVICE\ +(int) scand_c_uw_u(const char *name, char *c1, unsigned c1size, @@ -1031,7 +1097,8 @@ scand_c_uw_u(const char *name, SCAN_END; } -int INLINE_DEVICE +INLINE_DEVICE\ +(int) scand_uw(const char *name, unsigned_word *uw1) { @@ -1040,7 +1107,8 @@ scand_uw(const char *name, SCAN_END; } -int INLINE_DEVICE +INLINE_DEVICE\ +(int) scand_uw_c(const char *name, unsigned_word *uw1, char *c2, @@ -1052,7 +1120,8 @@ scand_uw_c(const char *name, SCAN_END; } -int INLINE_DEVICE +INLINE_DEVICE\ +(int) scand_uw_u(const char *name, unsigned_word *uw1, unsigned *u2) @@ -1063,7 +1132,8 @@ scand_uw_u(const char *name, SCAN_END; } -int INLINE_DEVICE +INLINE_DEVICE\ +(int) scand_uw_u_u(const char *name, unsigned_word *uw1, unsigned *u2, @@ -1076,7 +1146,8 @@ scand_uw_u_u(const char *name, SCAN_END; } -int INLINE_DEVICE +INLINE_DEVICE\ +(int) scand_uw_u_u_c(const char *name, unsigned_word *uw1, unsigned *u2, @@ -1092,7 +1163,8 @@ scand_uw_u_u_c(const char *name, SCAN_END; } -int INLINE_DEVICE +INLINE_DEVICE\ +(int) scand_uw_uw(const char *name, unsigned_word *uw1, unsigned_word *uw2) @@ -1103,7 +1175,8 @@ scand_uw_uw(const char *name, SCAN_END; } -int INLINE_DEVICE +INLINE_DEVICE\ +(int) scand_uw_uw_u(const char *name, unsigned_word *uw1, unsigned_word *uw2, @@ -1116,7 +1189,8 @@ scand_uw_uw_u(const char *name, SCAN_END; } -int INLINE_DEVICE +INLINE_DEVICE\ +(int) scand_uw_uw_u_u_c(const char *name, unsigned_word *uw1, unsigned_word *uw2, @@ -1134,7 +1208,8 @@ scand_uw_uw_u_u_c(const char *name, SCAN_END; } -int INLINE_DEVICE +INLINE_DEVICE\ +(int) scand_uw_uw_u_u_u(const char *name, unsigned_word *uw1, unsigned_word *uw2, diff --git a/sim/ppc/device.h b/sim/ppc/device.h index 55009ee..cc6bd53 100644 --- a/sim/ppc/device.h +++ b/sim/ppc/device.h @@ -39,50 +39,56 @@ All the devices in this model live in a tree. The following allow the location/manipulation of this tree */ -device INLINE_DEVICE *device_parent +INLINE_DEVICE(device *) device_parent (device *me); -const char INLINE_DEVICE *device_name +INLINE_DEVICE(device *) device_sibling (device *me); -void INLINE_DEVICE *device_data +INLINE_DEVICE(device *) device_child +(device *me); + +INLINE_DEVICE(const char *) device_name +(device *me); + +INLINE_DEVICE(void *) device_data (device *me); /* Grow the device tree adding either a specific device or alternativly a device found in the device table */ -device INLINE_DEVICE *device_tree_add_device +INLINE_DEVICE(device *)device_tree_add_device (device *root, const char *prefix, device *new_sub_tree); -device INLINE_DEVICE *device_tree_add_found +INLINE_DEVICE(device *) device_tree_add_found (device *root, const char *prefix, const char *name); -device INLINE_DEVICE *device_tree_add_found_c +INLINE_DEVICE(device *) device_tree_add_found_c (device *root, const char *prefix, const char *name, const char *c1); -device INLINE_DEVICE *device_tree_add_found_c_uw +INLINE_DEVICE(device *) device_tree_add_found_c_uw (device *root, const char *prefix, const char *name, const char *c1, unsigned_word uw2); -device INLINE_DEVICE *device_tree_add_found_uw_u +INLINE_DEVICE(device *) device_tree_add_found_uw_u (device *root, const char *prefix, const char *name, unsigned_word uw1, unsigned u2); -device INLINE_DEVICE *device_tree_add_found_uw_u_u +INLINE_DEVICE(device *) device_tree_add_found_uw_u_u (device *root, const char *prefix, const char *name, @@ -90,7 +96,7 @@ device INLINE_DEVICE *device_tree_add_found_uw_u_u unsigned u2, unsigned u3); -device INLINE_DEVICE *device_tree_add_found_uw_u_u_c +INLINE_DEVICE(device *) device_tree_add_found_uw_u_u_c (device *root, const char *prefix, const char *name, @@ -99,7 +105,7 @@ device INLINE_DEVICE *device_tree_add_found_uw_u_u_c unsigned u3, const char *c4); -device INLINE_DEVICE *device_tree_add_found_uw_uw_u_u_c +INLINE_DEVICE(device *) device_tree_add_found_uw_uw_u_u_c (device *root, const char *prefix, const char *name, @@ -109,7 +115,7 @@ device INLINE_DEVICE *device_tree_add_found_uw_uw_u_u_c unsigned u4, const char *c5); -device INLINE_DEVICE *device_tree_add_found_uw_uw_u_u_u +INLINE_DEVICE(device *) device_tree_add_found_uw_uw_u_u_u (device *root, const char *prefix, const char *name, @@ -123,7 +129,7 @@ device INLINE_DEVICE *device_tree_add_found_uw_uw_u_u_u /* Query the device tree, null is returned if the specified device is not found */ -device INLINE_DEVICE *device_tree_find_device +INLINE_DEVICE(device *) device_tree_find_device (device *root, const char *path); @@ -135,7 +141,7 @@ typedef void (device_tree_traverse_function) (device *device, void *data); -void INLINE_DEVICE device_tree_traverse +INLINE_DEVICE(void) device_tree_traverse (device *root, device_tree_traverse_function *prefix, device_tree_traverse_function *postfix, @@ -145,7 +151,7 @@ void INLINE_DEVICE device_tree_traverse /* dump a node, this can be passed to the device_tree_traverse() function to dump out the entire device tree */ -void INLINE_DEVICE device_tree_dump +INLINE_DEVICE(void) device_tree_dump (device *device, void *ignore_data_argument); @@ -181,7 +187,7 @@ struct _device_property { /* Basic operations used by software */ -const char INLINE_DEVICE *device_find_next_property +INLINE_DEVICE(const char *) device_find_next_property (device *me, const char *previous); @@ -189,27 +195,27 @@ const char INLINE_DEVICE *device_find_next_property No such external function, all properties, when added are explictly typed */ -void INLINE_DEVICE device_add_array_property +INLINE_DEVICE(void) device_add_array_property (device *me, const char *property, const void *array, int sizeof_array); -void INLINE_DEVICE device_add_integer_property +INLINE_DEVICE(void) device_add_integer_property (device *me, const char *property, signed_word integer); -void INLINE_DEVICE device_add_boolean_property +INLINE_DEVICE(void) device_add_boolean_property (device *me, const char *property, int bool); -void INLINE_DEVICE device_add_null_property +INLINE_DEVICE(void) device_add_null_property (device *me, const char *property); -void INLINE_DEVICE device_add_string_property +INLINE_DEVICE(void) device_add_string_property (device *me, const char *property, const char *string); @@ -218,7 +224,7 @@ void INLINE_DEVICE device_add_string_property /* Locate a property returning its description. Return NULL if the named property is not found */ -const device_property INLINE_DEVICE *device_find_property +INLINE_DEVICE(const device_property *) device_find_property (device *me, const char *property); @@ -230,7 +236,7 @@ typedef void (device_traverse_property_function) const char *name, void *data); -void INLINE_DEVICE device_traverse_properties +INLINE_DEVICE(void) device_traverse_properties (device *me, device_traverse_property_function *traverse, void *data); @@ -239,19 +245,19 @@ void INLINE_DEVICE device_traverse_properties /* Similar to above except that the property *must* be in the device tree and *must* be of the specified type. */ -const device_property INLINE_DEVICE *device_find_array_property +INLINE_DEVICE(const device_property *) device_find_array_property (device *me, const char *property); -signed_word INLINE_DEVICE device_find_integer_property +INLINE_DEVICE(signed_word) device_find_integer_property (device *me, const char *property); -const char INLINE_DEVICE *device_find_string_property +INLINE_DEVICE(const char *) device_find_string_property (device *me, const char *property); -int INLINE_DEVICE device_find_boolean_property +INLINE_DEVICE(int) device_find_boolean_property (device *me, const char *property); @@ -302,26 +308,26 @@ typedef enum _attach_type { */ -device INLINE_DEVICE *device_create +INLINE_DEVICE(device *) device_create (const char *name, device *parent); /* some external functions want to create things */ typedef struct _device_callbacks device_callbacks; -device INLINE_DEVICE *device_create_from +INLINE_DEVICE(device *) device_create_from (const char *name, void *data, const device_callbacks *callbacks, device *parent); -void INLINE_DEVICE device_init +INLINE_DEVICE(void) device_init (device *me, psim *system); /* initialize the entire tree */ -void INLINE_DEVICE device_tree_init +INLINE_DEVICE(void) device_tree_init (device *root, psim *system); @@ -403,7 +409,7 @@ void INLINE_DEVICE device_tree_init */ -void INLINE_DEVICE device_attach_address +INLINE_DEVICE(void) device_attach_address (device *me, const char *name, attach_type attach, @@ -413,7 +419,7 @@ void INLINE_DEVICE device_attach_address access_type access, device *who); /*callback/default*/ -void INLINE_DEVICE device_detach_address +INLINE_DEVICE(void) device_detach_address (device *me, const char *name, attach_type attach, @@ -423,7 +429,7 @@ void INLINE_DEVICE device_detach_address access_type access, device *who); /*callback/default*/ -unsigned INLINE_DEVICE device_io_read_buffer +INLINE_DEVICE(unsigned) device_io_read_buffer (device *me, void *dest, int space, @@ -432,7 +438,7 @@ unsigned INLINE_DEVICE device_io_read_buffer cpu *processor, unsigned_word cia); -unsigned INLINE_DEVICE device_io_write_buffer +INLINE_DEVICE(unsigned) device_io_write_buffer (device *me, const void *source, int space, @@ -441,14 +447,14 @@ unsigned INLINE_DEVICE device_io_write_buffer cpu *processor, unsigned_word cia); -unsigned INLINE_DEVICE device_dma_read_buffer +INLINE_DEVICE(unsigned) device_dma_read_buffer (device *me, void *dest, int space, unsigned_word addr, unsigned nr_bytes); -unsigned INLINE_DEVICE device_dma_write_buffer +INLINE_DEVICE(unsigned) device_dma_write_buffer (device *me, const void *source, int space, @@ -476,19 +482,19 @@ unsigned INLINE_DEVICE device_dma_write_buffer */ -void INLINE_DEVICE device_attach_interrupt +INLINE_DEVICE(void) device_attach_interrupt (device *me, device *who, int interrupt_line, const char *name); -void INLINE_DEVICE device_detach_interrupt +INLINE_DEVICE(void) device_detach_interrupt (device *me, device *who, int interrupt_line, const char *name); -void INLINE_DEVICE device_interrupt +INLINE_DEVICE(void) device_interrupt (device *me, device *who, int interrupt_line, @@ -496,7 +502,7 @@ void INLINE_DEVICE device_interrupt cpu *processor, unsigned_word cia); -void INLINE_DEVICE device_interrupt_ack +INLINE_DEVICE(void) device_interrupt_ack (device *me, int interrupt_line, int interrupt_status); @@ -507,7 +513,8 @@ void INLINE_DEVICE device_interrupt_ack Very simply, a catch all for any thing that turns up that until now either hasn't been thought of or doesn't justify an extra function. */ -void EXTERN_DEVICE device_ioctl +EXTERN_DEVICE\ +(void) device_ioctl (device *me, psim *system, cpu *processor, @@ -526,32 +533,32 @@ void EXTERN_DEVICE device_ioctl level software interface to the devices */ #if 0 -device_instance INLINE_DEVICE *device_instance_open +INLINE_DEVICE(device_instance *)device_instance_open (device *me, const char *device_specifier); -void INLINE_DEVICE device_instance_close +INLINE_DEVICE(void) device_instance_close (device_instance *instance); -int INLINE_DEVICE device_instance_read +INLINE_DEVICE(int) device_instance_read (device_instance *instance, void *addr, unsigned_word len); -int INLINE_DEVICE device_instance_write +INLINE_DEVICE(int) device_instance_write (device_instance *instance, const void *addr, unsigned_word len); -int INLINE_DEVICE device_instance_seek +INLINE_DEVICE(int) device_instance_seek (device_instance *instance, unsigned_word pos_hi, unsigned_word pos_lo); -device INLINE_DEVICE *device_instance_device +INLINE_DEVICE(device *) device_instance_device (device_instance *instance); -const char INLINE_DEVICE *device_instance_name +INLINE_DEVICE(const char *) device_instance_name (device_instance *instance); #endif @@ -560,56 +567,46 @@ const char INLINE_DEVICE *device_instance_name /* Device dregs... */ -/* Parse a device name */ - -void INLINE_DEVICE device_tree_parse_name -(const char *name, - const char **driver_name, - const char **unit_address, - const char **device_arguments, - const char **end); - - /* Parse a device name, various formats: uw: unsigned_word u: unsigned c: string */ -int INLINE_DEVICE scand_c +INLINE_DEVICE(int) scand_c (const char *name, char *c1, unsigned c1size); -int INLINE_DEVICE scand_c_uw_u +INLINE_DEVICE(int) scand_c_uw_u (const char *name, char *c1, unsigned c1size, unsigned_word *uw2, unsigned *u3); -int INLINE_DEVICE scand_uw +INLINE_DEVICE(int) scand_uw (const char *name, unsigned_word *uw1); -int INLINE_DEVICE scand_uw_c +INLINE_DEVICE(int) scand_uw_c (const char *name, unsigned_word *uw1, char *c2, unsigned c2size); -int INLINE_DEVICE scand_uw_u +INLINE_DEVICE(int) scand_uw_u (const char *name, unsigned_word *uw1, unsigned *u2); -int INLINE_DEVICE scand_uw_u_u +INLINE_DEVICE(int) scand_uw_u_u (const char *name, unsigned_word *uw1, unsigned *u2, unsigned *u3); -int INLINE_DEVICE scand_uw_u_u_c +INLINE_DEVICE(int) scand_uw_u_u_c (const char *name, unsigned_word *uw1, unsigned *u2, @@ -617,18 +614,18 @@ int INLINE_DEVICE scand_uw_u_u_c char *c4, unsigned c4size); -int INLINE_DEVICE scand_uw_uw +INLINE_DEVICE(int) scand_uw_uw (const char *name, unsigned_word *uw1, unsigned_word *uw2); -int INLINE_DEVICE scand_uw_uw_u +INLINE_DEVICE(int) scand_uw_uw_u (const char *name, unsigned_word *uw1, unsigned_word *uw2, unsigned *u3); -int INLINE_DEVICE scand_uw_uw_u_u_c +INLINE_DEVICE(int) scand_uw_uw_u_u_c (const char *name, unsigned_word *uw1, unsigned_word *uw2, @@ -637,7 +634,7 @@ int INLINE_DEVICE scand_uw_uw_u_u_c char *c5, unsigned c5size); -int INLINE_DEVICE scand_uw_uw_u_u_u +INLINE_DEVICE(int) scand_uw_uw_u_u_u (const char *name, unsigned_word *uw1, unsigned_word *uw2, diff --git a/sim/ppc/device_table.c b/sim/ppc/device_table.c index 1155aeb..e723085 100644 --- a/sim/ppc/device_table.c +++ b/sim/ppc/device_table.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "device_table.h" @@ -668,7 +669,10 @@ static device_callbacks const halt_callbacks = { /* Register init device: register Properties attached to the register device specify the name/value - initialization pair for cpu registers. */ + initialization pair for cpu registers. + + FIXME: A specific processor can be initialized by creating a + property with a name like `0.pc'. */ static void register_init(device *me, @@ -677,8 +681,17 @@ register_init(device *me, { psim *system = (psim*)data; unsigned32 value = device_find_integer_property(me, name); - DTRACE(register, ("%s=0x%lx\n", name, (unsigned long)value)); - psim_write_register(system, -1, /* all processors */ + int processor; + if (isdigit(name[0]) && name[1] == '.') { + processor = atol(name); + name += 2; + DTRACE(register, ("%ld.%s=0x%lx\n", (long)name, processor, (unsigned long)value)); + } + else { + processor = -1; + DTRACE(register, ("%s=0x%lx\n", name, (unsigned long)value)); + } + psim_write_register(system, processor, /* all processors */ &value, name, cooked_transfer); @@ -1221,8 +1234,8 @@ htab_decode_hash_table(device *parent, error("devices/%s - htaborg 0x%x not aligned to htabmask 0x%x\n", device_name(parent), *htaborg, *htabmask); } - DTRACE(htab, ("htab - htaborg=0x%x htabmask=0x%x\n", - *htaborg, *htabmask)); + DTRACE(htab, ("htab - htaborg=0x%lx htabmask=0x%lx\n", + (unsigned long)*htaborg, (unsigned long)*htabmask)); } @@ -1246,34 +1259,38 @@ htab_map_page(device *me, unsigned32 pteg = (htaborg | (hash & htabmask)); int pti; for (pti = 0; pti < 8; pti++, pteg += 8) { - unsigned32 pte0; + unsigned32 current_target_pte0; + unsigned32 current_pte0; if (device_dma_read_buffer(device_parent(me), - &pte0, + ¤t_target_pte0, 0, /*space*/ pteg, - sizeof(pte0)) != 4) + sizeof(current_target_pte0)) != 4) error("htab_init_callback() failed to read a pte at 0x%x\n", pteg); - if (!MASKED32(pte0, 0, 0)) { + current_pte0 = T2H_4(current_target_pte0); + if (!MASKED32(current_pte0, 0, 0)) { /* empty pte fill it */ unsigned32 pte0 = (MASK32(0, 0) | INSERTED32(EXTRACTED32(vsid, 0, 23), 1, 24) | INSERTED32(h, 25, 25) | INSERTED32(EXTRACTED32(page, 0, 5), 26, 31)); + unsigned32 target_pte0 = H2T_4(pte0); unsigned32 pte1 = (INSERTED32(EXTRACTED32(ra, 0, 19), 0, 19) | INSERTED32(wimg, 25, 28) | INSERTED32(pp, 30, 31)); + unsigned32 target_pte1 = H2T_4(pte1); if (device_dma_write_buffer(device_parent(me), - &pte0, + &target_pte0, 0, /*space*/ pteg, - sizeof(pte0), + sizeof(target_pte0), 1/*ro?*/) != 4 || device_dma_write_buffer(device_parent(me), - &pte1, + &target_pte1, 0, /*space*/ pteg + 4, - sizeof(pte1), + sizeof(target_pte1), 1/*ro?*/) != 4) error("htab_init_callback() failed to write a pte a 0x%x\n", pteg); @@ -1459,9 +1476,13 @@ htab_map_binary(device *me, (sizes.text_bound - sizes.text_base)); DTRACE(htab, ("text map - base=0x%lx bound=0x%lx ra=0x%lx\n", - sizes.text_base, sizes.text_bound, sizes.text_ra)); + (unsigned long)sizes.text_base, + (unsigned long)sizes.text_bound, + (unsigned long)sizes.text_ra)); DTRACE(htab, ("data map - base=0x%lx bound=0x%lx ra=0x%lx\n", - sizes.data_base, sizes.data_bound, sizes.data_ra)); + (unsigned long)sizes.data_base, + (unsigned long)sizes.data_bound, + (unsigned long)sizes.data_ra)); /* set up virtual memory maps for each of the regions */ htab_map_region(me, sizes.text_ra, sizes.text_base, @@ -1500,15 +1521,22 @@ htab_init_callback(device *me, /* handle a normal mapping definition */ if (scand_uw_uw_u_u_u(device_name(me), &pte_ra, &pte_va, &pte_nr_bytes, &pte_wimg, &pte_pp) == 5) { - DTRACE(htab, ("pte - ra=0x%x, wimg=%d, pp=%d, va=0x%x, nr_bytes=%d\n", - pte_ra, pte_wimg, pte_pp, pte_va, pte_nr_bytes)); + DTRACE(htab, ("pte - ra=0x%lx, wimg=%ld, pp=%ld, va=0x%lx, nr_bytes=%ld\n", + (unsigned long)pte_ra, + (long)pte_wimg, + (long)pte_pp, + (unsigned long)pte_va, + (long)pte_nr_bytes)); htab_map_region(me, pte_ra, pte_va, pte_nr_bytes, pte_wimg, pte_pp, htaborg, htabmask); } else if (scand_uw_u_u_c(device_name(me), &pte_ra, &pte_wimg, &pte_pp, file_name, sizeof(file_name)) == 4) { - DTRACE(htab, ("pte - ra=0x%x, wimg=%d, pp=%d, binary=%s\n", - pte_ra, pte_wimg, pte_pp, file_name)); + DTRACE(htab, ("pte - ra=0x%lx, wimg=%ld, pp=%ld, binary=%s\n", + (unsigned long)pte_ra, + (unsigned long)pte_wimg, + (long)pte_pp, + file_name)); htab_map_binary(me, pte_ra, pte_wimg, pte_pp, file_name, htaborg, htabmask); } diff --git a/sim/ppc/emul_bugapi.c b/sim/ppc/emul_bugapi.c index 309869e..252c3ce 100644 --- a/sim/ppc/emul_bugapi.c +++ b/sim/ppc/emul_bugapi.c @@ -23,6 +23,27 @@ #define _EMUL_BUGAPI_C_ +/* from bug.S - Dale Rahn */ +#define _INCHR 0x00 +#define _INSTAT 0x01 +#define _INLN 0x02 +#define _READSTR 0x03 +#define _READLN 0x04 +#define _OUTCHR 0x20 +#define _OUTSTR 0x21 +#define _OUTLN 0x22 +#define _DSKRD 0x10 +#define _DSKWR 0x11 +#define _DSKCFIG 0x12 +#define _DSKFMT 0x14 +#define _DSKCTRL 0x15 +#define _WRITE 0x23 +#define _WRITELN 0x24 +#define _DELAY 0x43 +#define _RTC_RD 0x53 +#define _RETURN 0x63 +#define _BRD_ID 0x70 + /* Note: this module is called via a table. There is no benefit in making it inline */ @@ -32,13 +53,27 @@ /* Any starting address less than this is assumed to be an OEA program rather than VEA. */ #ifndef OEA_START_ADDRESS -#define OEA_START_ADDRESS 4096 +#define OEA_START_ADDRESS 0x4000 #endif #ifndef OEA_MEMORY_SIZE #define OEA_MEMORY_SIZE 0x100000 #endif +/* All but CPU 0 are put into an infinate loop, this loop instruction + is stored at the address below */ +#ifndef OEA_STALL_CPU_LOOP_ADDRESS +#define OEA_STALL_CPU_LOOP_ADDRESS 0x00c10 +#endif + +/* At initiallization, the system call exception branches to the BUG + emulation code */ + +#ifndef OEA_SYSTEM_CALL_ADDRESS +#define OEA_SYSTEM_CALL_ADDRESS 0x00c00 +#endif + + static os_emul_data * emul_bugapi_create(device *root, bfd *image, @@ -47,9 +82,11 @@ emul_bugapi_create(device *root, /* check it really is for us */ if (name != NULL - && strcmp(name, "bugapi") != 0) + && strcmp(name, "bugapi") != 0 + && strcmp(name, "bug") != 0) return NULL; if (image != NULL + && name == NULL && bfd_get_start_address(image) > OEA_START_ADDRESS) return NULL; @@ -58,8 +95,12 @@ emul_bugapi_create(device *root, const memory_size = OEA_MEMORY_SIZE; const elf_binary = (image != NULL && image->xvec->flavour == bfd_target_elf_flavour); - const little_endian = (image != NULL - && !image->xvec->byteorder_big_p); +#ifdef bfd_little_endian /* new bfd */ + const little_endian = (image != NULL && bfd_little_endian(image)); +#else + const little_endian = (image != NULL && + !image->xvec->byteorder_big_p); +#endif { /* options */ device *options = device_tree_add_found(root, "/", "options"); @@ -75,7 +116,7 @@ emul_bugapi_create(device *root, device_add_boolean_property(options, "strict-alignment?", (WITH_ALIGNMENT == STRICT_ALIGNMENT - || !image->xvec->byteorder_big_p)); + || little_endian)); device_add_boolean_property(options, "floating-point?", WITH_FLOATING_POINT); @@ -98,15 +139,32 @@ emul_bugapi_create(device *root, device *init_register = device_tree_add_found(init, "", "register"); device_add_integer_property(init_register, "pc", - 0); + OEA_STALL_CPU_LOOP_ADDRESS); + device_add_integer_property(init_register, + "0.pc", + bfd_get_start_address(image)); device_add_integer_property(init_register, "sp", memory_size-16); device_add_integer_property(init_register, "msr", - (little_endian - ? msr_little_endian_mode - : 0)); + (msr_recoverable_interrupt + | (little_endian + ? msr_little_endian_mode + : 0) + )); + device_tree_add_found_uw_u_u(init, "", + "data", + OEA_SYSTEM_CALL_ADDRESS, + 4, 0x1); /*emul-call*/ + device_tree_add_found_uw_u_u(init, "", + "data", + OEA_SYSTEM_CALL_ADDRESS + 4, + 4, 0x4c000064); /*rfi*/ + device_tree_add_found_uw_u_u(init, "", + "data", + OEA_STALL_CPU_LOOP_ADDRESS, + 4, 0x48000000); /*b .*/ } { device *init_stack = device_tree_add_found(init, "", "stack"); @@ -140,8 +198,28 @@ emul_bugapi_instruction_call(cpu *processor, unsigned_word ra, os_emul_data *emul_data) { - error("emul_bugapi_instruction_call() not implemented\n"); + const int call_id = cpu_registers(processor)->gpr[10]; + /* check that this isn't an invalid instruction */ + if (cia != OEA_SYSTEM_CALL_ADDRESS) + return 0; + switch (call_id) { + case _OUTCHR: + printf_filtered("%c", cpu_registers(processor)->gpr[3]); + break; + case _OUTLN: + printf_filtered("\n"); + break; + case _RETURN: + cpu_halt(processor, cia, was_exited, 0); /* always succeeds */ + break; + default: + error("emul-bugapi: unimplemented bugapi call 0x%x from address 0x%lx\n", + call_id, SRR0); + break; + } return 1; + /* the instruction following this one is a RFI. Thus by just + continuing the return from system call is performed */ } const os_emul emul_bugapi = { diff --git a/sim/ppc/emul_chirp.c b/sim/ppc/emul_chirp.c index dc1d8e6..9c20262 100644 --- a/sim/ppc/emul_chirp.c +++ b/sim/ppc/emul_chirp.c @@ -47,7 +47,7 @@ /* Descriptor of the open boot services being emulated */ -typedef unsigned_word (chirp_handler) +typedef int (chirp_handler) (os_emul_data *data, cpu *processor, unsigned_word cia); @@ -61,6 +61,7 @@ typedef struct _chirp_services { request or waiting on a client callback */ typedef enum { serving, + faulting, catching, } chirp_emul_state; @@ -78,7 +79,64 @@ struct _os_emul_data { /* OpenBoot emulation functions */ -static unsigned_word +static int +chirp_emul_child(os_emul_data *data, + cpu *processor, + unsigned_word cia) +{ + struct child_args { + unsigned32 service; + unsigned32 n_args; + unsigned32 n_returns; + /*in*/ + unsigned32 phandle; + /*out*/ + unsigned32 child_phandle; + } args; + device *dev; + device *child_dev; + emul_read_buffer(&args, data->arguments, + sizeof(args), + processor, cia); + if (T2H_4(args.n_args) != 1 || T2H_4(args.n_returns) != 1) { + TRACE(trace_os_emul, ("child - invalid nr - n_args=%ld, n_returns=%ld\n", + (long)T2H_4(args.n_args), + (long)T2H_4(args.n_returns))); + return -1; + } + /* read in the arguments */ + dev = cap_internal(data->phandles, args.phandle); + TRACE(trace_os_emul, ("child - in - phandle=0x%lx(0x%lx`%s')\n", + (unsigned long)T2H_4(args.phandle), + (unsigned long)dev, + (dev == NULL ? "" : device_name(dev)))); + if (dev == (device*)0) + return -1; + child_dev = device_child(dev); + if (child_dev == NULL) + args.child_phandle = 0; + else + args.child_phandle = cap_external(data->phandles, child_dev); + TRACE(trace_os_emul, ("child - out - child_phandle=0x%lx(0x%lx`%s')\n", + (unsigned long)T2H_4(args.child_phandle), + (unsigned long)child_dev, + (child_dev == NULL ? "" : device_name(child_dev)))); + emul_write_buffer(&args, data->arguments, + sizeof(args), + processor, cia); + return 0; +} + +static int +chirp_emul_exit(os_emul_data *data, + cpu *processor, + unsigned_word cia) +{ + cpu_halt(processor, cia, was_exited, 0); /* always succeeds */ + return 0; +} + +static int chirp_emul_finddevice(os_emul_data *data, cpu *processor, unsigned_word cia) @@ -97,25 +155,35 @@ chirp_emul_finddevice(os_emul_data *data, emul_read_buffer(&args, data->arguments, sizeof(args), processor, cia); - if (T2H_4(args.n_args) != 1 || T2H_4(args.n_returns) != 1) + if (T2H_4(args.n_args) != 1 || T2H_4(args.n_returns) != 1) { + TRACE(trace_os_emul, ("finddevice - invalid nr - n_args=%ld, n_returns=%ld\n", + (long)T2H_4(args.n_args), + (long)T2H_4(args.n_returns))); return -1; + } emul_read_string(device_specifier, T2H_4(args.device_specifier), sizeof(device_specifier), processor, cia); + TRACE(trace_os_emul, ("finddevice - in - device_specifier=`%s'\n", + device_specifier)); dev = device_tree_find_device(data->root, device_specifier); if (dev == (device*)0) args.phandle = -1; else args.phandle = cap_external(data->phandles, dev); + TRACE(trace_os_emul, ("finddevice - out - phandle=0x%lx(0x%lx`%s')\n", + (unsigned long)T2H_4(args.phandle), + (unsigned long)dev, + (dev == NULL ? "" : device_name(dev)))); emul_write_buffer(&args, data->arguments, sizeof(args), processor, cia); return 0; } -static unsigned_word +static int chirp_emul_getprop(os_emul_data *data, cpu *processor, unsigned_word cia) @@ -138,16 +206,27 @@ chirp_emul_getprop(os_emul_data *data, emul_read_buffer(&args, data->arguments, sizeof(args), processor, cia); - if (T2H_4(args.n_args) != 4 || T2H_4(args.n_returns) != 1) + if (T2H_4(args.n_args) != 4 || T2H_4(args.n_returns) != 1) { + TRACE(trace_os_emul, ("getprop - invalid nr - n_args=%ld, n_returns=%ld\n", + (long)T2H_4(args.n_args), + (long)T2H_4(args.n_returns))); return -1; + } /* read in the arguments */ dev = cap_internal(data->phandles, args.phandle); - if (dev == (device*)0) - return -1; emul_read_string(name, T2H_4(args.name), sizeof(name), processor, cia); + TRACE(trace_os_emul, ("getprop - in - phandle=0x%lx(0x%lx`%s') name=`%s' buf=0x%lx buflen=%ld\n", + (unsigned long)T2H_4(args.phandle), + (unsigned long)dev, + (dev == NULL ? "" : device_name(dev)), + name, + (unsigned long)T2H_4(args.buf), + (unsigned long)T2H_4(args.buflen))); + if (dev == (device*)0) + return -1; prop = device_find_property(dev, name); if (prop == (device_property*)0) { args.size = -1; @@ -161,18 +240,223 @@ chirp_emul_getprop(os_emul_data *data, processor, cia); args.size = H2T_4(size); } + switch (prop->type) { + case string_property: + TRACE(trace_os_emul, ("getprop - value=`%s' (string)\n", + (char*)prop->array)); + break; + default: + break; + } + TRACE(trace_os_emul, ("getprop - out - size=%ld\n", + (unsigned long)T2H_4(args.size))); emul_write_buffer(&args, data->arguments, sizeof(args), processor, cia); return 0; } -static unsigned_word -chirp_emul_write(os_emul_data *data, +static int +chirp_emul_getproplen(os_emul_data *data, + cpu *processor, + unsigned_word cia) +{ + struct getproplen_args { + unsigned32 service; + unsigned32 n_args; + unsigned32 n_returns; + /*in*/ + unsigned32 phandle; + unsigned32 name; + /*out*/ + unsigned32 proplen; + } args; + char name[32]; + device *dev; + const device_property *prop; + emul_read_buffer(&args, data->arguments, + sizeof(args), + processor, cia); + if (T2H_4(args.n_args) != 2 || T2H_4(args.n_returns) != 1) { + TRACE(trace_os_emul, ("getproplen - invalid nr - n_args=%ld, n_returns=%ld\n", + (long)T2H_4(args.n_args), + (long)T2H_4(args.n_returns))); + return -1; + } + /* read in the arguments */ + dev = cap_internal(data->phandles, args.phandle); + if (dev == (device*)0) + return -1; + emul_read_string(name, + T2H_4(args.name), + sizeof(name), + processor, cia); + TRACE(trace_os_emul, ("getproplen - in - phandle=0x%lx(0x%lx`%s') name=`%s'\n", + (unsigned long)T2H_4(args.phandle), + (unsigned long)dev, + (dev == NULL ? "" : device_name(dev)), + name)); + prop = device_find_property(dev, name); + if (prop == (device_property*)0) { + args.proplen = -1; + } + else { + args.proplen = H2T_4(prop->sizeof_array); + } + TRACE(trace_os_emul, ("getproplen - out - proplen=%ld\n", + (unsigned long)T2H_4(args.proplen))); + emul_write_buffer(&args, data->arguments, + sizeof(args), + processor, cia); + return 0; +} + +static int +chirp_emul_open(os_emul_data *data, cpu *processor, unsigned_word cia) { - struct write_args { + struct open_args { + unsigned32 service; + unsigned32 n_args; + unsigned32 n_returns; + /*in*/ + unsigned32 device_specifier; + /*out*/ + unsigned32 ihandle; + } args; + char name[1024]; + emul_read_buffer(&args, data->arguments, + sizeof(args), + processor, cia); + if (T2H_4(args.n_args) != 1 || T2H_4(args.n_returns) != 1) { + TRACE(trace_os_emul, ("open - invalid nr - n_args=%ld, n_returns=%ld\n", + (long)T2H_4(args.n_args), + (long)T2H_4(args.n_returns))); + return -1; + } + /* read in the arguments */ + emul_read_string(name, + T2H_4(args.device_specifier), + sizeof(name), + processor, cia); + TRACE(trace_os_emul, ("open - in - device_specifier=`%s'\n", + name)); + printf_filtered("OpenBoot - open unimplemented for %s\n", name); + args.ihandle = -1; + TRACE(trace_os_emul, ("open - out - ihandle=0x%lx\n", + (unsigned long)T2H_4(args.ihandle))); + emul_write_buffer(&args, data->arguments, + sizeof(args), + processor, cia); + return 0; +} + +static int +chirp_emul_parent(os_emul_data *data, + cpu *processor, + unsigned_word cia) +{ + struct parent_args { + unsigned32 service; + unsigned32 n_args; + unsigned32 n_returns; + /*in*/ + unsigned32 phandle; + /*out*/ + unsigned32 parent_phandle; + } args; + device *dev; + device *parent_dev; + emul_read_buffer(&args, data->arguments, + sizeof(args), + processor, cia); + if (T2H_4(args.n_args) != 1 || T2H_4(args.n_returns) != 1) { + TRACE(trace_os_emul, ("parent - invalid nr - n_args=%ld, n_returns=%ld\n", + (long)T2H_4(args.n_args), + (long)T2H_4(args.n_returns))); + return -1; + } + /* read in the arguments */ + dev = cap_internal(data->phandles, args.phandle); + TRACE(trace_os_emul, ("parent - in - phandle=0x%lx(0x%lx`%s')\n", + (unsigned long)T2H_4(args.phandle), + (unsigned long)dev, + (dev == NULL ? "" : device_name(dev)))); + if (dev == (device*)0) + return -1; + parent_dev = device_parent(dev); + if (parent_dev == NULL) + args.parent_phandle = 0; + else + args.parent_phandle = cap_external(data->phandles, parent_dev); + TRACE(trace_os_emul, ("parent - out - parent_phandle=0x%lx(0x%lx`%s')\n", + (unsigned long)T2H_4(args.parent_phandle), + (unsigned long)parent_dev, + (parent_dev == NULL ? "" : device_name(parent_dev)))); + emul_write_buffer(&args, data->arguments, + sizeof(args), + processor, cia); + return 0; +} + +static int +chirp_emul_peer(os_emul_data *data, + cpu *processor, + unsigned_word cia) +{ + struct peer_args { + unsigned32 service; + unsigned32 n_args; + unsigned32 n_returns; + /*in*/ + unsigned32 phandle; + /*out*/ + unsigned32 sibling_phandle; + } args; + device *dev; + device *sibling_dev = NULL; + emul_read_buffer(&args, data->arguments, + sizeof(args), + processor, cia); + if (T2H_4(args.n_args) != 1 || T2H_4(args.n_returns) != 1) { + TRACE(trace_os_emul, ("peer - invalid nr - n_args=%ld, n_returns=%ld\n", + (long)T2H_4(args.n_args), + (long)T2H_4(args.n_returns))); + return -1; + } + /* read in the arguments */ + dev = cap_internal(data->phandles, args.phandle); + TRACE(trace_os_emul, ("peer - in - phandle=0x%lx(0x%lx`%s')\n", + (unsigned long)T2H_4(args.phandle), + (unsigned long)dev, + (dev == NULL ? "" : device_name(dev)))); + if (dev == NULL && args.phandle != 0) + return -1; + if (args.phandle == 0) + sibling_dev = data->root; + else + sibling_dev = device_sibling(dev); + if (sibling_dev == NULL) + args.sibling_phandle = 0; + else + args.sibling_phandle = cap_external(data->phandles, sibling_dev); + TRACE(trace_os_emul, ("peer - out - sibling_phandle=0x%lx(0x%lx`%s')\n", + (unsigned long)T2H_4(args.sibling_phandle), + (unsigned long)sibling_dev, + (sibling_dev == NULL ? "" : device_name(sibling_dev)))); + emul_write_buffer(&args, data->arguments, + sizeof(args), + processor, cia); + return 0; +} + +static int +chirp_emul_read(os_emul_data *data, + cpu *processor, + unsigned_word cia) +{ + struct read_args { unsigned32 service; unsigned32 n_args; unsigned32 n_returns; @@ -188,40 +472,95 @@ chirp_emul_write(os_emul_data *data, emul_read_buffer(&args, data->arguments, sizeof(args), processor, cia); - if (T2H_4(args.n_args) != 3 || T2H_4(args.n_returns) != 1) + if (T2H_4(args.n_args) != 3 || T2H_4(args.n_returns) != 1) { + TRACE(trace_os_emul, ("read - invalid nr - n_args=%ld, n_returns=%ld\n", + (long)T2H_4(args.n_args), + (long)T2H_4(args.n_returns))); return -1; + } /* read in the arguments */ actual = T2H_4(args.len); - if (actual > sizeof(buf)) - actual = sizeof(buf); + if (actual >= sizeof(buf)) + actual = sizeof(buf) - 1; emul_read_buffer(buf, T2H_4(args.addr), actual, processor, cia); - /* write it out */ - write(BE2H_4(args.ihandle), buf, actual); + buf[actual] = '\0'; + /* read it in */ + TRACE(trace_os_emul, ("read - in - ihandle=0x%lx `%s' (%ld)\n", + (unsigned long)args.ihandle, buf, (long)actual)); + read(BE2H_4(args.ihandle), buf, actual); args.actual = H2T_4(actual); + TRACE(trace_os_emul, ("read - out - actual=%ld\n", + (long)T2H_4(args.actual))); emul_write_buffer(&args, data->arguments, sizeof(args), processor, cia); return 0; } -static unsigned_word -chirp_emul_exit(os_emul_data *data, - cpu *processor, - unsigned_word cia) +static int +chirp_emul_write(os_emul_data *data, + cpu *processor, + unsigned_word cia) { - error("chirp_emul_exit not implemnented\n"); + struct write_args { + unsigned32 service; + unsigned32 n_args; + unsigned32 n_returns; + /*in*/ + unsigned32 ihandle; + unsigned32 addr; + unsigned32 len; + /*out*/ + unsigned32 actual; + } args; + char buf[1024]; + int actual; + emul_read_buffer(&args, data->arguments, + sizeof(args), + processor, cia); + if (T2H_4(args.n_args) != 3 || T2H_4(args.n_returns) != 1) { + TRACE(trace_os_emul, ("write - invalid nr - n_args=%ld, n_returns=%ld\n", + (long)T2H_4(args.n_args), + (long)T2H_4(args.n_returns))); + return -1; + } + /* read in the arguments */ + actual = T2H_4(args.len); + if (actual >= sizeof(buf)) + actual = sizeof(buf) - 1; + emul_read_buffer(buf, + T2H_4(args.addr), + actual, + processor, cia); + buf[actual] = '\0'; + /* write it out */ + TRACE(trace_os_emul, ("write - in - ihandle=0x%lx `%s' (%ld)\n", + (unsigned long)args.ihandle, buf, (long)actual)); + write(BE2H_4(args.ihandle), buf, actual); + args.actual = H2T_4(actual); + TRACE(trace_os_emul, ("write - out - actual=%ld\n", + (long)T2H_4(args.actual))); + emul_write_buffer(&args, data->arguments, + sizeof(args), + processor, cia); return 0; } chirp_services services[] = { + { "child", chirp_emul_child }, + { "exit", chirp_emul_exit }, { "finddevice", chirp_emul_finddevice }, { "getprop", chirp_emul_getprop }, + { "getproplen", chirp_emul_getproplen }, + { "open", chirp_emul_open }, + { "parent", chirp_emul_parent }, + { "peer", chirp_emul_peer }, + { "read", chirp_emul_read }, { "write", chirp_emul_write }, - { "exit", chirp_emul_exit }, { 0, /* sentinal */ }, }; @@ -303,6 +642,7 @@ emul_chirp_create(device *root, { os_emul_data *data; chirp_note note; + int big_endian; /* Sanity check that this really is the chosen emulation */ if (name == NULL && image == NULL) @@ -322,6 +662,11 @@ emul_chirp_create(device *root, if (name == NULL && image != NULL && !note.found) return NULL; + /* the root node */ + device_add_string_property(root, + "name", + "gpl,clayton"); + { const unsigned_word memory_size = 0x200000; @@ -335,7 +680,7 @@ emul_chirp_create(device *root, /* a page for firmware calls */ const unsigned_word sizeof_code = 4096; const unsigned_word code_ra = htab_ra - sizeof_code; - + /* the stack */ const unsigned sizeof_stack = 32 * 1024; const unsigned_word stack_ra = code_ra - sizeof_stack; @@ -350,8 +695,17 @@ emul_chirp_create(device *root, /* the virtual addresses */ const unsigned_word stack_va = virt_base; const unsigned_word code_va = stack_va + sizeof_stack; + const unsigned_word code_client_va = code_va; + const unsigned_word code_callback_va = code_client_va + 16; + const unsigned_word code_loop_va = code_callback_va + 16; const unsigned_word htab_va = code_va + sizeof_code; - + +#ifdef bfd_big_endian /* new bfd */ + big_endian = bfd_big_endian(image); +#else + big_endian = image->xvec->byteorder_big_p; +#endif + /* options */ { device *options = device_tree_add_found(root, "/", "options"); @@ -360,14 +714,14 @@ emul_chirp_create(device *root, MAX_NR_PROCESSORS); device_add_boolean_property(options, "little-endian?", - !image->xvec->byteorder_big_p); + !big_endian); device_add_string_property(options, "env", "operating"); device_add_boolean_property(options, "strict-alignment?", (WITH_ALIGNMENT == STRICT_ALIGNMENT - || !image->xvec->byteorder_big_p)); + || !big_endian)); device_add_boolean_property(options, "floating-point?", WITH_FLOATING_POINT); @@ -387,17 +741,30 @@ emul_chirp_create(device *root, device *init_register = device_tree_add_found(init, "", "register"); device_add_integer_property(init_register, "pc", + code_loop_va); + device_add_integer_property(init_register, + "0.pc", bfd_get_start_address(image)); device_add_integer_property(init_register, "sp", stack_va + sizeof_stack - 16); - /* init the code callback */ + /* init the code callback along with a loop for the unused cpu's */ device_add_integer_property(init_register, "r5", - code_va); - device_tree_add_found_uw_u_u(init, "", "data", code_ra, 4, 0x1); - device_tree_add_found_uw_u_u(init, "", "data", code_ra+16, 4, 0x1); + code_client_va); + device_tree_add_found_uw_u_u(init, "", + "data", + code_ra + (code_client_va - code_va), + 4, 0x1); /*emul-call*/ + device_tree_add_found_uw_u_u(init, "", + "data", + code_ra + (code_callback_va - code_va), + 4, 0x1); /*emul-call*/ + device_tree_add_found_uw_u_u(init, "", + "data", + code_ra + (code_loop_va - code_va), + 4, 0x48000000); /*b .*/ device_add_integer_property(init_register, "msr", (msr_machine_check_enable @@ -405,7 +772,7 @@ emul_chirp_create(device *root, ? 0 : (msr_instruction_relocate | msr_data_relocate)) - | (image->xvec->byteorder_big_p + | (big_endian ? 0 : (msr_little_endian_mode | msr_interrupt_little_endian_mode @@ -445,15 +812,35 @@ emul_chirp_create(device *root, { /* chosen options */ device *chosen = device_tree_add_found(root, "/", "chosen"); + device_add_string_property(chosen, + "name", + "chosen"); + device_add_integer_property(chosen, + "stdin", + 0); /* FIXME: ihandle of stdin */ device_add_integer_property(chosen, "stdout", - 1); + 1); /* FIXME: ihandle of stdout */ + device_add_string_property(chosen, + "bootpath", + "/disk@0:\\boot"); + device_add_string_property(chosen, + "bootargs", + ""); +#if 0 + device_add_integer_property(chosen, + "memory", + 0); /* FIXME: ihandle of memory */ + device_add_integer_property(chosen, + "mmu", + 0); +#endif } /* FIXME - should come from the device tree */ data = ZALLOC(os_emul_data); - data->serving_instruction_ea = CHIRP_START_ADDRESS + sizeof_stack;; - data->catching_instruction_ea = CHIRP_START_ADDRESS + sizeof_stack + 16; + data->serving_instruction_ea = code_client_va; + data->catching_instruction_ea = code_callback_va; data->phandles = cap_create("chirp"); data->root = root; return data; @@ -470,9 +857,9 @@ emul_chirp_init(os_emul_data *emul_data, static int emul_chirp_instruction_call(cpu *processor, - unsigned_word cia, - unsigned_word ra, - os_emul_data *emul_data) + unsigned_word cia, + unsigned_word ra, + os_emul_data *emul_data) { unsigned_word service_name_addr; unsigned_word result; @@ -481,8 +868,10 @@ emul_chirp_instruction_call(cpu *processor, chirp_services *service; switch (emul_data->state) { + case serving: - /* verify then capture the current request */ + /* we are waiting on an OpenBoot request from the client program + via the client interface */ if (cia != emul_data->serving_instruction_ea) return 0; emul_data->return_address = LR; @@ -492,24 +881,46 @@ emul_chirp_instruction_call(cpu *processor, processor, cia); service_name = emul_read_string(service_buf, service_name_addr, sizeof(service_buf), processor, cia); + TRACE(trace_os_emul, ("%s called from 0x%lx with args 0x%lx\n", + service_name, + (unsigned long)emul_data->return_address, + (unsigned long)emul_data->arguments)); /* look it up */ service = services; while (service->name != NULL && strcmp(service->name, service_name) != 0) service++; if (service->name == NULL) { + error("OpenBoot service `%s' not found\n", service_name); + TRACE(trace_os_emul, ("%s not found\n", service_name)); cpu_registers(processor)->gpr[3] = 0; cpu_restart(processor, emul_data->return_address); } emul_data->service = service; - TRACE(trace_os_emul, ("%s called from 0x%lx\n", - service->name, emul_data->return_address)); /* call upon it */ result = service->handler(emul_data, processor, cia); break; + + case faulting: + /* We were handling a client request but encountered a page fault + (or other exception). The fault needs to be passed back to the + client using the the client suplied call back interface */ + error("emul_chirp_instruction_call() faulting unimplemented\n"); + result = -1; + break; + + case catching: + /* Have called the client (via the callback interface) because + some fault (hash table miss) occured. The client has finished + handling this and is now returning */ + error("emul_chirp_instruction_call() catching unimplemented\n"); + result = -1; + break; + default: error("emul_chirp_instruction_call() unknown internal state\n"); result = -1; break; + } /* return to caller */ -- 2.7.4