Latest cagney update
authorMichael Meissner <gnu@the-meissners.org>
Mon, 8 Jan 1996 18:01:17 +0000 (18:01 +0000)
committerMichael Meissner <gnu@the-meissners.org>
Mon, 8 Jan 1996 18:01:17 +0000 (18:01 +0000)
sim/ppc/ChangeLog
sim/ppc/Makefile.in
sim/ppc/device.c
sim/ppc/device.h
sim/ppc/device_table.c
sim/ppc/emul_bugapi.c
sim/ppc/emul_chirp.c

index 6b38aa812b9b5db3e623ed5d307f3130140d38cf..2e62ae6d73c581f180e51c32a9e69e93d33ae7a8 100644 (file)
@@ -1,3 +1,114 @@
+Mon Jan  8 12:17:22 1996  Michael Meissner  <meissner@tiktok.cygnus.com>
+
+       * device_table.c (register_init): Make format type correct.
+
+Wed Jan  3 19:21:46 1996  Andrew Cagney  <cagney@highland.com.au>
+
+       * 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  <cagney@highland.com.au>
+
+       * 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  <cagney@highland.com.au>
+
+       * 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  <cagney@highland.com.au>
+
+       * 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  <cagney@highland.com.au>
+
+       * 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=<n> 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  <meissner@tiktok.cygnus.com>
+
+       * 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  <meissner@wogglebug.tiac.net>
 
        * emul_netbsd.c (emul_netbsd_create): Deal with new BFD that
index d7243713cf960eb0803562ff1cc4f70885a134b9..e5684bbdda21e6b7e3fd946219add34935cbd873 100644 (file)
@@ -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
 
index 5dc69cb2498745a02a32f87a1991fa976d65b914..618c5a48954a33807f1551765b1e7ae05fcebc51 100644 (file)
@@ -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,
index 55009eebe739d3fa7edb7cf29b4cfceb535841c3..cc6bd5373edb28e76e038025e65cdf984a98fd67 100644 (file)
    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
 \f
 /* 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,
index 1155aebcb73b86d6637d8eb49fdc9720a8677874..e723085e6e58f6bcd9e3d3f9a03041da69023dad 100644 (file)
@@ -30,6 +30,7 @@
 #include <fcntl.h>
 #include <signal.h>
 #include <stdarg.h>
+#include <ctype.h>
 
 #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,
+                                &current_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);
     }
index 309869e312ea5227c868d21ab2f6ac82e1497d80..252c3ce1ea652019b16038f91257f009442d266f 100644 (file)
 #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 */
 
 /* 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 = {
index dc1d8e685dc5db042713c3da720a4418a3d5877d..9c2026218b96901fd9ac6939a7fb9d0d2744b480 100644 (file)
@@ -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 */