Add --enable-sim-stdio to make console I/O use stdio, not printf_filtered and polling...
authorMichael Meissner <gnu@the-meissners.org>
Fri, 29 Mar 1996 17:33:56 +0000 (17:33 +0000)
committerMichael Meissner <gnu@the-meissners.org>
Fri, 29 Mar 1996 17:33:56 +0000 (17:33 +0000)
sim/ppc/ChangeLog
sim/ppc/Makefile.in
sim/ppc/configure.in
sim/ppc/device_table.c
sim/ppc/emul_bugapi.c

index 03297e7dc25ddb759f4e3ce3574b4366ec19003e..70398299dce037b7a14cc8739461c837b0efeb55 100644 (file)
@@ -1,3 +1,38 @@
+Fri Mar 29 12:17:58 1996  Michael Meissner  <meissner@tiktok.cygnus.com>
+
+       * Makefile.in (STDIO_CFLAGS): Pass on result of @sim_stdio@
+       configuration variable.
+       (CONFIG_CFLAGS): Include STDIO_CFLAGS.
+
+       * std-config.h (DO{,NT}_USE_STDIO): New flags for whether we
+       should use stdio for console input.
+       (WITH_STDIO): If not defined, define as DONT_USE_STDIO.
+
+       * configure.in (--enable-sim-stdio): Add new switch to control
+       whether stdio is used for console I/O.
+       * configure: Regenerate.
+
+       * device_table.c (console_use_stdio): New static variable set from
+       WITH_STDIO.
+       (scan_console): If console_use_stdio, use getchar to read byte
+       instead of doing polling I/O.
+       (write_console): If console_use_stdio, write byte with putchar.
+       (console_io_write_buffer_callback): If console_use_stdio, fflush
+       stdout.
+       (console_instance_write_callback): Ditto.
+       (console_instance_read_callback): If console_use_stdio, use fgets
+       to read line.
+
+Fri Mar 29 12:17:58 1996  Andrew Cagney  <cagney@kremvax.highland.com.au>
+
+       * emul_bugapi.c (_os_emul_data): Add fields for output, input.
+       (emul_bugapi_create): Create input, output from /chosen/stdin and
+       /chosen/stdout.
+       (emul_bugapi_do_{read,write}): Switch to use device_instance
+       interface.
+       (emul_bugapi_instruction_call): Change calls to
+       emul_bugapi_do_{read,write} to pass device instance argument.
+
 Tue Mar 26 14:57:58 1996  Michael Meissner  <meissner@tiktok.cygnus.com>
 
        * igen.c (idecode_switch_end): Fix 2/26 change so that an extra
index 9e11058ec09a8ba42ca7d38a27c7ba41956b63ba..26820d1825e157edb1ac14b2f4582a0da7d9c1a6 100644 (file)
@@ -1,7 +1,7 @@
 #
 #   This file is part of the program psim.
 #
-#   Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
+#   Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
 #
 #   This program is free software; you can redistribute it and/or modify
 #   it under the terms of the GNU General Public License as published by
@@ -84,6 +84,7 @@ ASSERT_CFLAGS = @sim_assert@
 RESERVED_CFLAGS = @sim_reserved@
 MONITOR_CFLAGS = @sim_monitor@
 MODEL_CFLAGS = @sim_model@ @sim_default_model@ @sim_model_issue@
+STDIO_CFLAGS = @sim_stdio@
 WARNING_CFLAGS = @sim_warnings@
 CONFIG_CFLAGS = $(BSWAP_CFLAGS) \
   $(ENDIAN_CFLAGS) \
@@ -100,7 +101,8 @@ CONFIG_CFLAGS = $(BSWAP_CFLAGS) \
   $(ASSERT_CFLAGS) \
   $(RESERVED_CFLAGS) \
   $(MONITOR_CFLAGS) \
-  $(MODEL_CFLAGS)
+  $(MODEL_CFLAGS) \
+  $(STDIO_CFLAGS)
 
 STD_CFLAGS     = $(CFLAGS) $(INLINE_CFLAGS) $(CONFIG_CFLAGS) $(WARNING_CFLAGS) $(SIM_CFLAGS) $(HDEFINES) $(TDEFINES) $(INCLUDES)
 NOWARN_CFLAGS  = $(CFLAGS) $(INLINE_CFLAGS) $(CONFIG_CFLAGS) $(SIM_CFLAGS) $(HDEFINES) $(TDEFINES) $(INCLUDES)
@@ -297,7 +299,7 @@ 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_chirp.o: emul_chirp.c emul_chirp.h $(EMUL_GENERIC_H)
 emul_bugapi.o: emul_bugapi.c emul_bugapi.h $(EMUL_GENERIC_H)
 
 registers.o: registers.c $(REGISTERS_H) $(BASICS_H) 
@@ -326,7 +328,7 @@ spreg.o: spreg.h spreg.c $(BASICS_H)
 
 main.o: main.c $(PSIM_H) itable.h options.h
 
-device.o: device.c $(DEVICE_TABLE_H)
+device.o: device.c $(DEVICE_TABLE_H) cap.h
 
 device_table.o: device_table.c $(DEVICE_TABLE_H) events.h
 
index 7df389f4b19e0bbf8d478e494c773ea228c5950e..0a51bdc345aa4619433278fc579aed6c8f5ccbd2 100644 (file)
@@ -364,6 +364,17 @@ if test x"$silent" != x"yes"; then
   echo "Setting model-issue flags = $sim_model_issue" 6>&1
 fi],[sim_model_issue=""])dnl
 
+AC_ARG_ENABLE(sim-stdio,
+[  --enable-sim-stdio                  Specify whether to use stdio for console input/output.],
+[case "${enableval}" in
+  yes) sim_stdio="-DWITH_STDIO=DO_USE_STDIO";;
+  no)  sim_stdio="-DWITH_STDIO=DONT_USE_STDIO";;
+  *)   AC_MSG_ERROR("Unknown value $enableval passed to --enable-sim-stdio"); sim_stdio="";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_stdio" != x""; then
+  echo "Setting stdio flags = $sim_stdio" 6>&1
+fi],[sim_stdio=""])dnl
+
 AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../..)
 AC_CANONICAL_SYSTEM
 AC_ARG_PROGRAM
@@ -405,6 +416,7 @@ AC_SUBST(sim_monitor)
 AC_SUBST(sim_model)
 AC_SUBST(sim_default_model)
 AC_SUBST(sim_model_issue)
+AC_SUBST(sim_stdio)
 
 AC_CHECK_FUNCS(getrusage)
 
index 15ef95a842ff23d51230dbc8e7c85b572f987004..08cfe1ca646a6e2fbc713abdf1390dd1eb267b20 100644 (file)
@@ -1,6 +1,6 @@
 /*  This file is part of the program psim.
 
-    Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
+    Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
    from <name>@<int>,<nr_bytes>) to its parent at address zero and
    with read/write access. */
 
-STATIC_INLINE_DEVICE_TABLE void
-generic_init_callback(device *me,
-                     psim *system)
+typedef struct _reg_spec {
+  unsigned32 base;
+  unsigned32 size;
+} reg_spec;
+
+void
+generic_device_init_address(device *me,
+                           psim *system)
 {
-  unsigned_word addr;
-  unsigned nr_bytes;
-  if (scand_uw_u(device_name(me), &addr, &nr_bytes) != 2)
-    error("generic_init_callback() invalid nr_bytes in %s\n", device_name(me));
-  device_attach_address(device_parent(me),
-                       device_name(me),
-                       attach_callback,
-                       0 /*space*/,
-                       addr,
-                       nr_bytes,
-                       access_read_write,
-                       me);
+  const device_property *reg = device_find_array_property(me, "reg");
+  const reg_spec *spec = reg->array;
+  int nr_entries = reg->sizeof_array / sizeof(reg_spec);
+
+  if ((reg->sizeof_array % sizeof(reg_spec)) != 0)
+    error("devices/%s reg property is of wrong size\n", device_name(me));
+  while (nr_entries > 0) {
+    device_attach_address(device_parent(me),
+                         device_name(me),
+                         attach_callback,
+                         0 /*space*/,
+                         BE2H_4(spec->base),
+                         BE2H_4(spec->size),
+                         access_read_write_exec,
+                         me);
+    spec++;
+    nr_entries--;
+  }
 }
 
+int
+generic_device_unit_decode(device *me,
+                          const char *unit,
+                          device_unit *phys)
+{
+  memset(phys, 0, sizeof(device_unit));
+  if (unit == NULL)
+    return 0;
+  else {
+    char *pos = (char*)unit; /* force for strtoul() */
+    while (1) {
+      char *old_pos = pos;
+      long int val = strtoul(pos, &pos, 0);
+      if (old_pos == pos && *pos == '\0')
+       return phys->nr_cells;
+      if (old_pos == pos && *pos != '\0')
+       return -1;
+      if (phys->nr_cells == 4)
+       return -1;
+      phys->cells[phys->nr_cells] = val;
+      phys->nr_cells++;
+    }
+  }
+}
+
+int
+generic_device_unit_encode(device *me,
+                          const device_unit *phys,
+                          char *buf,
+                          int sizeof_buf)
+{
+  int i;
+  int len;
+  char *pos = buf; /* force for strtoul() */
+  for (i = 0; i < phys->nr_cells; i++) {
+    if (pos != buf) {
+      strcat(pos, ",");
+      pos = strchr(pos, '\0');
+    }
+    sprintf(pos, "0x%lx", (unsigned long)phys->cells[i]);
+    pos = strchr(pos, '\0');
+  }
+  len = pos - buf;
+  if (len >= sizeof_buf)
+    error("generic_unit_encode - buffer overflow\n");
+  return len;
+}
 
 /* DMA a file into memory */
 STATIC_INLINE_DEVICE_TABLE int
@@ -208,42 +267,99 @@ unimp_device_dma_write_buffer(device *me,
 }
 
 void
-unimp_device_attach_interrupt(device *me,
-                             device *who,
-                             int interrupt_line,
-                             const char *name)
+unimp_device_interrupt_event(device *me,
+                            int my_port,
+                            device *source,
+                            int source_port,
+                            int level,
+                            cpu *processor,
+                            unsigned_word cia)
 {
-  error("device_attach_interrupt_callback for %s not implemented\n", device_name(me));
+  error("unimp_device_interrupt_event for %s unimplemented\n",
+       device_name(me));
 }
 
 void
-unimp_device_detach_interrupt(device *me,
-                             device *who,
-                             int interrupt_line,
-                             const char *name)
+unimp_device_child_interrupt_event(device *me,
+                                  device *parent,
+                                  device *source,
+                                  int source_port,
+                                  int level,
+                                  cpu *processor,
+                                  unsigned_word cia)
 {
-  error("device_detach_interrupt_callback for %s not implemented\n", device_name(me));
+  error("unimp_device_child_interrupt_event_callback for %s unimplemented\n",
+       device_name(me));
+}
+      
+int
+unimp_device_unit_decode(device *me,
+                        const char *unit,
+                        device_unit *address)
+{
+  error("unimp_device_unit_decode_callback for %s unimplemented\n",
+       device_name(me));
+  return 0;
 }
 
-void
-unimp_device_interrupt(device *me,
-                      device *who,
-                      int interrupt_line,
-                      int interrupt_status,
-                      cpu *processor,
-                      unsigned_word cia)
+int
+unimp_device_unit_encode(device *me,
+                        const device_unit *unit_address,
+                        char *buf,
+                        int sizeof_buf)
+{
+  error("unimp_device_unit_encode_callback for %s unimplemented\n",
+       device_name(me));
+  return 0;
+}
+
+void *
+unimp_device_instance_create(device *me,
+                            const char *args)
 {
-  error("device_interrupt_callback for %s not implemented\n", device_name(me));
+  error("unimp_device_instance_create_callback for %s unimplemented\n",
+       device_name(me));
+  return 0;
 }
 
 void
-unimp_device_interrupt_ack(device *me,
-                          int interrupt_line,
-                          int interrupt_status)
+unimp_device_instance_delete(device_instance *instance)
+{
+  error("unimp_device_instance_delete_callback for %s unimplemented\n",
+       device_instance_name(instance));
+}
+
+int
+unimp_device_instance_read(device_instance *instance,
+                          void *buf,
+                          unsigned_word len)
+{
+  error("unimp_device_instance_read_callback for %s unimplemented\n",
+       device_instance_name(instance));
+  return 0;
+}
+
+int
+unimp_device_instance_write(device_instance *instance,
+                           const void *buf,
+                           unsigned_word len)
 {
-  error("device_interrupt_ack_callback for %s not implemented\n", device_name(me));
+  error("unimp_device_instance_write_callback for %s unimplemented\n",
+       device_instance_name(instance));
+  return 0;
 }
 
+int
+unimp_device_instance_seek(device_instance *instance,
+                          unsigned_word pos_hi,
+                          unsigned_word pos_lo)
+{
+  error("unimp_device_instance_seek_callback for %s unimplemented\n",
+       device_instance_name(instance));
+  return 0;
+}
+
+
 void
 unimp_device_ioctl(device *me,
                   psim *system,
@@ -287,9 +403,9 @@ passthrough_device_detach_address(device *me,
                                  attach_type attach,
                                  int space,
                                  unsigned_word addr,
-                          unsigned nr_bytes,
-                          access_type access,
-                          device *who) /*callback/default*/
+                                 unsigned nr_bytes,
+                                 access_type access,
+                                 device *who) /*callback/default*/
 {
   device_detach_address(device_parent(me), name, attach,
                        space, addr, nr_bytes, access,
@@ -298,10 +414,10 @@ passthrough_device_detach_address(device *me,
 
 unsigned
 passthrough_device_dma_read_buffer(device *me,
-                           void *dest,
-                           int space,
-                           unsigned_word addr,
-                           unsigned nr_bytes)
+                                  void *dest,
+                                  int space,
+                                  unsigned_word addr,
+                                  unsigned nr_bytes)
 {
   return device_dma_read_buffer(device_parent(me), dest,
                                space, addr, nr_bytes);
@@ -321,42 +437,18 @@ passthrough_device_dma_write_buffer(device *me,
                                 violate_read_only_section);
 }
 
-void
-passthrough_device_attach_interrupt(device *me,
-                                   device *who,
-                                   int interrupt_line,
-                                   const char *name)
-{
-  device_attach_interrupt(device_parent(me), who,
-                         interrupt_line, name);
-}
-
-void
-passthrough_device_detach_interrupt(device *me,
-                            device *who,
-                            int interrupt_line,
-                            const char *name)
-{
-  device_detach_interrupt(device_parent(me), who,
-                         interrupt_line, name);
-}
-
-
-void
-passthrough_device_interrupt(device *me,
-                     device *who,
-                     int interrupt_line,
-                     int interrupt_status,
-                     cpu *processor,
-                     unsigned_word cia)
+int
+ignore_device_unit_decode(device *me,
+                         const char *unit,
+                         device_unit *phys)
 {
-  device_interrupt(device_parent(me), who,
-                                 interrupt_line, interrupt_status,
-                                 processor, cia);
+  memset(phys, 0, sizeof(device_unit));
+  return 0;
 }
 
 
 static const device_callbacks passthrough_callbacks = {
+  ignore_device_init,
   ignore_device_init,
   passthrough_device_attach_address,
   passthrough_device_detach_address,
@@ -364,10 +456,15 @@ static const device_callbacks passthrough_callbacks = {
   unimp_device_io_write_buffer,
   passthrough_device_dma_read_buffer,
   passthrough_device_dma_write_buffer,
-  passthrough_device_attach_interrupt,
-  passthrough_device_detach_interrupt,
-  passthrough_device_interrupt,
-  unimp_device_interrupt_ack,
+  unimp_device_interrupt_event,
+  unimp_device_child_interrupt_event,
+  generic_device_unit_decode,
+  generic_device_unit_encode,
+  unimp_device_instance_create,
+  unimp_device_instance_delete,
+  unimp_device_instance_read,
+  unimp_device_instance_write,
+  unimp_device_instance_seek,
   unimp_device_ioctl,
 };
 
@@ -408,6 +505,70 @@ typedef enum {
   console_size = 16,
 } console_offsets;
 
+static int console_use_stdio = WITH_STDIO;
+
+/* check the console for an available character */
+static void
+scan_console(console_device *console)
+{ /* check for input */
+  int flags;
+  int status;
+
+  /* Use stdio if desired.  */
+  if (console_use_stdio) {
+    int ch = getchar ();
+    if (ch == EOF) {
+      console->input.status = 0;
+      console->input.buffer = '\0';
+    } else {
+      console->input.status = 1;
+      console->input.buffer = ch;
+    }
+    return;
+  }
+
+  /* get the old status */
+  flags = fcntl(0, F_GETFL, 0);
+  if (flags == -1) {
+    perror("console");
+    return;
+  }
+
+  /* temp, disable blocking IO */
+  status = fcntl(0, F_SETFL, flags | O_NDELAY);
+  if (status == -1) {
+    perror("console");
+    return;
+  }
+  /* try for input */
+  status = read(0, &console->input.buffer, 1);
+  if (status == 1) {
+    console->input.status = 1;
+  }
+  else {
+    console->input.status = 0;
+  }
+  /* return to regular vewing */
+  flags = fcntl(0, F_SETFL, flags);
+  if (flags == -1) {
+    perror("console");
+    return;
+  }
+}
+
+/* write the character to the console */
+static void
+write_console(console_device *console,
+             char val)
+{
+  DTRACE(console, ("<%c:%d>", val, val));
+  if (console_use_stdio)
+    putchar (val);
+  else
+    printf_filtered("%c", val) ;
+  console->output.buffer = val;
+  console->output.status = 1;
+}
 
 static unsigned
 console_io_read_buffer_callback(device *me,
@@ -423,41 +584,14 @@ console_io_read_buffer_callback(device *me,
 
   /* determine what was read */
 
-  switch ((int)addr) {
+  switch ((int)addr & console_offset_mask) {
 
   case console_read_buffer:
     val = console->input.buffer;
     break;
 
   case console_read_status:
-    { /* check for input */
-      int flags;
-      int status;
-      /* get the old status */
-      flags = fcntl(0, F_GETFL, 0);
-      if (flags == -1) {
-       perror("console");
-       val = 0;
-       break;
-      }
-      /* temp, disable blocking IO */
-      status = fcntl(0, F_SETFL, flags | O_NDELAY);
-      if (status == -1) {
-       perror("console");
-       val = 0;
-       break;
-      }
-      /* try for input */
-      status = read(0, &console->input.buffer, 1);
-      if (status == 1) {
-       console->input.status = 1;
-      }
-      else {
-       console->input.status = 0;
-      }
-      /* return to regular vewing */
-      fcntl(0, F_SETFL, flags);
-    }
+    scan_console(console);
     val = console->input.status;
     break;
 
@@ -493,48 +627,117 @@ console_io_write_buffer_callback(device *me,
   console_device *console = (console_device*)device_data(me);
   unsigned_1 val = *(unsigned_1*)source;
 
-  switch ((int)addr) {
+  switch ((int)addr & console_offset_mask) {
+
   case console_read_buffer:
     console->input.buffer = val;
     break;
+
   case console_read_status:
     console->input.status = val;
     break;
+
   case console_write_buffer:
-    DTRACE(console, ("<%c:%d>", val, val));
-    printf_filtered("%c",val) ;
-    console->output.buffer = val;
-    console->output.status = 1;
+    write_console(console, val);
+    if (console_use_stdio)
+      fflush (stdout);
     break;
+
   case console_write_status:
     console->output.status = val;
     break;
+
   default:
     error("console_write_callback() internal error\n");
+
   }
         
   return nr_bytes;
 }
 
+/* instances of the console device */
+static void *
+console_instance_create_callback(device *me,
+                                const char *args)
+{
+  /* make life easier, attach the console data to the instance */
+  return device_data(me);
+}
+
+static void
+console_instance_delete_callback(device_instance *instance)
+{
+  /* nothing to delete, the console is attached to the device */
+  return;
+}
+
+static int
+console_instance_read_callback(device_instance *instance,
+                              void *buf,
+                              unsigned_word len)
+{
+  console_device *console = device_instance_data(instance);
+  if (console_use_stdio) {
+    char *p = fgets (buf, len, stdin);
+    if (!p)
+      return ferror (stdin) ? -1 : -2;
+
+    return strlen (p);
+  }
+
+  if (!console->input.status)
+    scan_console(console);
+  if (console->input.status) {
+    *(char*)buf = console->input.buffer;
+    console->input.status = 0;
+    return 1;
+  }
+  else {
+    return -2; /* not ready */
+  }
+}
+
+static int
+console_instance_write_callback(device_instance *instance,
+                               const void *buf,
+                               unsigned_word len)
+{
+  int i;
+  const char *chp = buf;
+  console_device *console = device_instance_data(instance);
+  for (i = 0; i < len; i++)
+    write_console(console, chp[i]);
+  if (console_use_stdio && len)
+    fflush (stdout);
+  return i;
+}
 
 static device_callbacks const console_callbacks = {
-  generic_init_callback,
+  generic_device_init_address,
+  ignore_device_init,
   unimp_device_attach_address,
   unimp_device_detach_address,
   console_io_read_buffer_callback,
   console_io_write_buffer_callback,
   unimp_device_dma_read_buffer,
   unimp_device_dma_write_buffer,
-  unimp_device_attach_interrupt,
-  unimp_device_detach_interrupt,
-  unimp_device_interrupt,
-  unimp_device_interrupt_ack,
+  unimp_device_interrupt_event,
+  unimp_device_child_interrupt_event,
+  unimp_device_unit_decode,
+  unimp_device_unit_encode,
+  console_instance_create_callback,
+  console_instance_delete_callback,
+  console_instance_read_callback,
+  console_instance_write_callback,
+  unimp_device_instance_seek,
   unimp_device_ioctl,
 };
 
 
 static void *
 console_create(const char *name,
+              const device_unit *unit_address,
+              const char *args,
               device *parent)
 {
   /* create the descriptor */
@@ -548,17 +751,17 @@ console_create(const char *name,
 
 
 \f
-/* ICU device: icu@0x<address>,4
+/* ICU device: icu@<address>
 
-   Single 4 byte register.  Read returns processor number.  Write
-   interrupts specified processor.
+   <address> : read - processor nr
+   <address> : write - interrupt processor nr
+   <address> + 4 : read - nr processors
+
+   Single byte registers that control a simple ICU.
 
    Illustrates passing of events to parent device. Passing of
-   interrupts to parent bus.
+   interrupts to an interrupt destination. */
 
-   NB: For the sake of illustrating the passing of interrupts.  This
-   device doesn't pass interrupt events to its parent.  Instead it
-   passes them back to its self. */
 
 static unsigned
 icu_io_read_buffer_callback(device *me,
@@ -569,10 +772,16 @@ icu_io_read_buffer_callback(device *me,
                            cpu *processor,
                            unsigned_word cia)
 {
-  unsigned_1 val;
-  val = cpu_nr(processor);
   memset(dest, 0, nr_bytes);
-  *(unsigned_1*)dest = val;
+  switch (addr & 4) {
+  case 0:
+    *(unsigned_1*)dest = cpu_nr(processor);
+    break;
+  case 4:
+    *(unsigned_1*)dest =
+      device_find_integer_property(me, "/openprom/options/smp");
+    break;
+  }
   return nr_bytes;
 }
 
@@ -590,25 +799,63 @@ icu_io_write_buffer_callback(device *me,
   /* tell the parent device that the interrupt lines have changed.
      For this fake ICU.  The interrupt lines just indicate the cpu to
      interrupt next */
-  device_interrupt(device_parent(me), me,
-                  val, val,
-                  processor, cia);
+  device_interrupt_event(me,
+                        val, /*my_port*/
+                        val, /*val*/
+                        processor, cia);
   return nr_bytes;
 }
 
+static void
+icu_do_interrupt(event_queue *queue,
+                void *data)
+{
+  cpu *target = (cpu*)data;
+  /* try to interrupt the processor.  If the attempt fails, try again
+     on the next tick */
+  if (!external_interrupt(target))
+    event_queue_schedule(queue, 1, icu_do_interrupt, target);
+}
+
+
+static void
+icu_interrupt_event_callback(device *me,
+                            int my_port,
+                            device *source,
+                            int source_port,
+                            int level,
+                            cpu *processor,
+                            unsigned_word cia)
+{
+  /* the interrupt controller can't interrupt a cpu at any time.
+     Rather it must synchronize with the system clock before
+     performing an interrupt on the given processor */
+  psim *system = cpu_system(processor);
+  cpu *target = psim_cpu(system, my_port);
+  if (target != NULL) {
+    event_queue *events = cpu_event_queue(target);
+    event_queue_schedule(events, 1, icu_do_interrupt, target);
+  }
+}
 
 static device_callbacks const icu_callbacks = {
-  generic_init_callback,
+  generic_device_init_address,
+  ignore_device_init,
   unimp_device_attach_address,
   unimp_device_detach_address,
   icu_io_read_buffer_callback,
   icu_io_write_buffer_callback,
   unimp_device_dma_read_buffer,
   unimp_device_dma_write_buffer,
-  unimp_device_attach_interrupt,
-  unimp_device_detach_interrupt,
-  unimp_device_interrupt,
-  unimp_device_interrupt_ack,
+  icu_interrupt_event_callback,
+  unimp_device_child_interrupt_event,
+  unimp_device_unit_decode,
+  unimp_device_unit_encode,
+  unimp_device_instance_create,
+  unimp_device_instance_delete,
+  unimp_device_instance_read,
+  unimp_device_instance_write,
+  unimp_device_instance_seek,
   unimp_device_ioctl,
 };
 
@@ -650,80 +897,153 @@ halt_io_write_buffer_callback(device *me,
 
 
 static device_callbacks const halt_callbacks = {
-  generic_init_callback,
+  generic_device_init_address,
+  ignore_device_init,
   unimp_device_attach_address,
   unimp_device_detach_address,
   halt_io_read_buffer_callback,
   halt_io_write_buffer_callback,
   unimp_device_dma_read_buffer,
   unimp_device_dma_write_buffer,
-  unimp_device_attach_interrupt,
-  unimp_device_detach_interrupt,
-  unimp_device_interrupt,
-  unimp_device_interrupt_ack,
+  unimp_device_interrupt_event,
+  unimp_device_child_interrupt_event,
+  unimp_device_unit_decode,
+  unimp_device_unit_encode,
+  unimp_device_instance_create,
+  unimp_device_instance_delete,
+  unimp_device_instance_read,
+  unimp_device_instance_write,
+  unimp_device_instance_seek,
   unimp_device_ioctl,
 };
 
 
 \f
-/* Register init device: register
+/* Register init device: register@<nothing>
 
    Properties attached to the register device specify the name/value
    initialization pair for cpu registers.
 
-   FIXME: A specific processor can be initialized by creating a
-   property with a name like `0.pc'. */
+   A specific processor can be initialized by creating a property with
+   a name like `0.pc'.
+
+   Properties are normally processed old-to-new and this function
+   needs to allow older (first in) properties to override new (last
+   in) ones.  The suport function do_register_init() manages this. */
 
 static void
-register_init(device *me,
-             const char *name,
-             void *data)
-{
-  psim *system = (psim*)data;
-  unsigned32 value = device_find_integer_property(me, name);
-  int processor;
-  if (isdigit(name[0]) && name[1] == '.') {
-    processor = atol(name);
-    name += 2;
-    DTRACE(register, ("%d.%s=0x%lx\n", processor, name, (unsigned long)value));
-  }    
-  else {
-    processor = -1;
-    DTRACE(register, ("%s=0x%lx\n", name, (unsigned long)value));
+do_register_init(device *me,
+                psim *system,
+                const device_property *prop)
+{
+  if (prop != NULL) {
+    const char *name = prop->name;
+    unsigned32 value = device_find_integer_property(me, name);
+    int processor;
+
+    do_register_init(me, system, device_next_property(prop));
+
+    if (strchr(name, '.') == NULL) {
+      processor = -1;
+      DTRACE(register, ("%s=0x%lx\n", name, (unsigned long)value));
+    }
+    else {
+      char *end;
+      processor = strtoul(name, &end, 0);
+      ASSERT(end[0] == '.');
+      name = end+1;
+      DTRACE(register, ("%d.%s=0x%lx\n", processor, name,
+                       (unsigned long)value));
+    }    
+    psim_write_register(system, processor, /* all processors */
+                       &value,
+                       name,
+                       cooked_transfer);
   }
-  psim_write_register(system, processor, /* all processors */
-                     &value,
-                     name,
-                     cooked_transfer);
 }
-
+                
 
 static void
-register_init_callback(device *me,
-                      psim *system)
+register_init_data_callback(device *me,
+                           psim *system)
 {
-  device_traverse_properties(me, register_init, system);
+  const device_property *prop = device_find_property(me, NULL);
+  do_register_init(me, system, prop);
 }
 
 
 static device_callbacks const register_callbacks = {
-  register_init_callback,
+  ignore_device_init,
+  register_init_data_callback,
   unimp_device_attach_address,
   unimp_device_detach_address,
   unimp_device_io_read_buffer,
   unimp_device_io_write_buffer,
   unimp_device_dma_read_buffer,
   unimp_device_dma_write_buffer,
-  unimp_device_attach_interrupt,
-  unimp_device_detach_interrupt,
-  unimp_device_interrupt,
-  unimp_device_interrupt_ack,
+  unimp_device_interrupt_event,
+  unimp_device_child_interrupt_event,
+  unimp_device_unit_decode,
+  unimp_device_unit_encode,
+  unimp_device_instance_create,
+  unimp_device_instance_delete,
+  unimp_device_instance_read,
+  unimp_device_instance_write,
+  unimp_device_instance_seek,
   unimp_device_ioctl,
 };
 
 
 \f
-/* VEA VM device: vm@0x<stack-base>,<nr_bytes>
+/* Trace device:
+
+   Properties attached to the trace device are names and values for
+   the various trace variables.  When initialized trace goes through
+   the propertie and sets the global trace variables so that they
+   match what was specified in the device tree. */
+
+static void
+trace_init_data_callback(device *me,
+                        psim *system)
+{
+  const device_property *prop = device_find_property(me, NULL);
+  while (prop != NULL) {
+    const char *name = prop->name;
+    unsigned32 value = device_find_integer_property(me, name);
+    trace_option(name, value);
+    prop = device_next_property(prop);
+  }
+}
+
+
+static device_callbacks const trace_callbacks = {
+  ignore_device_init,
+  trace_init_data_callback,
+  unimp_device_attach_address,
+  unimp_device_detach_address,
+  unimp_device_io_read_buffer,
+  unimp_device_io_write_buffer,
+  unimp_device_dma_read_buffer,
+  unimp_device_dma_write_buffer,
+  unimp_device_interrupt_event,
+  unimp_device_child_interrupt_event,
+  unimp_device_unit_decode,
+  unimp_device_unit_encode,
+  unimp_device_instance_create,
+  unimp_device_instance_delete,
+  unimp_device_instance_read,
+  unimp_device_instance_write,
+  unimp_device_instance_seek,
+  unimp_device_ioctl,
+};
+
+
+\f
+/* VEA VM:
+
+   vm@<stack-base>
+     stack-base =
+     nr-bytes =
 
    A VEA mode device. This sets its self up as the default memory
    device capturing all accesses (reads/writes) to currently unmapped
@@ -759,12 +1079,15 @@ typedef struct _vm_device {
 
 
 static void
-vm_init_callback(device *me,
-                psim *system)
+vm_init_address_callback(device *me,
+                        psim *system)
 {
   vm_device *vm = (vm_device*)device_data(me);
 
   /* revert the stack/heap variables to their defaults */
+  vm->stack_base = device_find_integer_property(me, "stack-base");
+  vm->stack_bound = (vm->stack_base
+                    + device_find_integer_property(me, "nr-bytes"));
   vm->stack_lower_limit = vm->stack_bound;
   vm->heap_base = 0;
   vm->heap_bound = 0;
@@ -917,87 +1240,98 @@ vm_ioctl_callback(device *me,
 
 
 static device_callbacks const vm_callbacks = {
-  vm_init_callback,
+  vm_init_address_callback,
+  ignore_device_init,
   vm_attach_address,
   passthrough_device_detach_address,
   vm_io_read_buffer_callback,
   vm_io_write_buffer_callback,
   unimp_device_dma_read_buffer,
   passthrough_device_dma_write_buffer,
-  unimp_device_attach_interrupt,
-  unimp_device_detach_interrupt,
-  unimp_device_interrupt,
-  unimp_device_interrupt_ack,
+  unimp_device_interrupt_event,
+  unimp_device_child_interrupt_event,
+  generic_device_unit_decode,
+  generic_device_unit_encode,
+  unimp_device_instance_create,
+  unimp_device_instance_delete,
+  unimp_device_instance_read,
+  unimp_device_instance_write,
+  unimp_device_instance_seek,
   vm_ioctl_callback,
 };
 
 
 static void *
 vea_vm_create(const char *name,
+             const device_unit *address,
+             const char *args,
              device *parent)
 {
   vm_device *vm = ZALLOC(vm_device);
-  unsigned_word addr;
-  unsigned nr_bytes;
-
-  /* extract out the stack parameters */
-  if (scand_uw_u(name, &addr, &nr_bytes) != 2)
-    error("vm_device_create() invalid vm device %s\n", name);
-  vm->stack_base = addr;
-  vm->stack_bound = addr + nr_bytes;
   return vm;
 }
 
 
 \f
-/* Memory init device: memory@0x<addr>,<size>,<access>
+/* Memory init device: memory@0x<addr>
 
    This strange device is used create sections of memory */
 
 static void
-memory_init_callback(device *me,
-                    psim *system)
-{
-  unsigned_word addr;
-  unsigned nr_bytes;
-  unsigned access;
-  int nr_args;
-
-  nr_args = scand_uw_u_u(device_name(me), &addr, &nr_bytes, &access);
-  switch (nr_args) {
-  case 2:
-    access = access_read_write_exec;
-    break;
-  case 3:
-    break;
-  default:
-    error("memory_init_callback() invalid memory device %s\n", device_name(me));
-    break;
+memory_init_address_callback(device *me,
+                            psim *system)
+{
+  const device_property *reg = device_find_array_property(me, "reg");
+  const reg_spec *spec = reg->array;
+  int nr_entries = reg->sizeof_array / sizeof(*spec);
+
+  if ((reg->sizeof_array % sizeof(*spec)) != 0)
+    error("devices/%s reg property of incorrect size\n", device_name(me));
+  while (nr_entries > 0) {
+    device_attach_address(device_parent(me),
+                         device_name(me),
+                         attach_raw_memory,
+                         0 /*address space*/,
+                         BE2H_4(spec->base),
+                         BE2H_4(spec->size),
+                         access_read_write_exec,
+                         me);
+    spec++;
+    nr_entries--;
   }
+}
 
-  device_attach_address(device_parent(me),
-                       device_name(me),
-                       attach_raw_memory,
-                       0 /*address space*/,
-                       addr,
-                       nr_bytes,
-                       (access_type)access,
-                       me);
+static void *
+memory_instance_create_callback(device *me,
+                               const char *args)
+{
+  return me; /* for want of any thing better */
 }
 
+static void
+memory_instance_delete_callback(device_instance *instance)
+{
+  return;
+}
 
 static device_callbacks const memory_callbacks = {
-  memory_init_callback,
+  memory_init_address_callback,
+  ignore_device_init,
   unimp_device_attach_address,
   unimp_device_detach_address,
   unimp_device_io_read_buffer,
   unimp_device_io_write_buffer,
   unimp_device_dma_read_buffer,
   unimp_device_dma_write_buffer,
-  unimp_device_attach_interrupt,
-  unimp_device_detach_interrupt,
-  unimp_device_interrupt,
-  unimp_device_interrupt_ack,
+  unimp_device_interrupt_event,
+  unimp_device_child_interrupt_event,
+  unimp_device_unit_decode,
+  unimp_device_unit_encode,
+  memory_instance_create_callback,
+  memory_instance_delete_callback,
+  unimp_device_instance_read,
+  unimp_device_instance_write,
+  unimp_device_instance_seek,
   unimp_device_ioctl,
 };
 
@@ -1026,9 +1360,10 @@ iobus_attach_address_callback(device *me,
     error("iobus_attach_address_callback() no space for %s/%s\n",
          device_name(me), name);
   /* get the bus address */
-  if (scand_uw(device_name(me), &iobus_addr) != 1)
+  if (device_unit_address(me)->nr_cells != 1)
     error("iobus_attach_address_callback() invalid address for %s\n",
          device_name(me));
+  iobus_addr = device_unit_address(me)->cells[0];
   device_attach_address(device_parent(me),
                        device_name(me),
                        type,
@@ -1040,39 +1375,8 @@ iobus_attach_address_callback(device *me,
 }
 
 
-STATIC_INLINE_DEVICE_TABLE void
-iobus_do_interrupt(event_queue *queue,
-                  void *data)
-{
-  cpu *target = (cpu*)data;
-  /* try to interrupt the processor.  If the attempt fails, try again
-     on the next tick */
-  if (!external_interrupt(target))
-    event_queue_schedule(queue, 1, iobus_do_interrupt, target);
-}
-
-
-static void
-iobus_interrupt_callback(device *me,
-                        device *who,
-                        int interrupt_line,
-                        int interrupt_status,
-                        cpu *processor,
-                        unsigned_word cia)
-{
-  /* the interrupt controler can't interrupt a cpu at any time.
-     Rather it must synchronize with the system clock before
-     performing an interrupt on the given processor */
-  psim *system = cpu_system(processor);
-  cpu *target = psim_cpu(system, interrupt_status);
-  if (target != NULL) {
-    event_queue *events = cpu_event_queue(target);
-    event_queue_schedule(events, 1, iobus_do_interrupt, target);
-  }
-}
-
-
 static device_callbacks const iobus_callbacks = {
+  ignore_device_init,
   ignore_device_init,
   iobus_attach_address_callback,
   unimp_device_detach_address,
@@ -1080,10 +1384,15 @@ static device_callbacks const iobus_callbacks = {
   unimp_device_io_write_buffer,
   unimp_device_dma_read_buffer,
   unimp_device_dma_write_buffer,
-  unimp_device_attach_interrupt,
-  unimp_device_detach_interrupt,
-  iobus_interrupt_callback,
-  unimp_device_interrupt_ack,
+  unimp_device_interrupt_event,
+  unimp_device_child_interrupt_event,
+  generic_device_unit_decode,
+  generic_device_unit_encode,
+  unimp_device_instance_create,
+  unimp_device_instance_delete,
+  unimp_device_instance_read,
+  unimp_device_instance_write,
+  unimp_device_instance_seek,
   unimp_device_ioctl,
 };
 
@@ -1096,109 +1405,122 @@ static device_callbacks const iobus_callbacks = {
 
 
 static void
-file_init_callback(device *me,
-                  psim *system)
+file_init_data_callback(device *me,
+                       psim *system)
 {
-  unsigned_word addr;
   int count;
-  char file_name[1024];
-
-  if (scand_uw_c(device_name(me), &addr, file_name, sizeof(file_name)) != 2)
-    error("devices/file - Usage: file@<address>,<file-name>\n");
+  const char *file_name = device_find_string_property(me, "file-name");
+  unsigned_word addr = device_find_integer_property(me, "real-address");
   /* load the file */
   count = dma_file(me, file_name, addr);
   if (count < 0)
-    error("device_table/%s - Problem loading file %s\n", device_name(me), file_name);
+    error("device_table/%s - Problem loading file %s\n",
+         device_name(me), file_name);
 }
 
 
 static device_callbacks const file_callbacks = {
-  file_init_callback,
+  ignore_device_init,
+  file_init_data_callback,
   unimp_device_attach_address,
   unimp_device_detach_address,
   unimp_device_io_read_buffer,
   unimp_device_io_write_buffer,
   unimp_device_dma_read_buffer,
   unimp_device_dma_write_buffer,
-  unimp_device_attach_interrupt,
-  unimp_device_detach_interrupt,
-  unimp_device_interrupt,
-  unimp_device_interrupt_ack,
+  unimp_device_interrupt_event,
+  unimp_device_child_interrupt_event,
+  unimp_device_unit_decode,
+  unimp_device_unit_encode,
+  unimp_device_instance_create,
+  unimp_device_instance_delete,
+  unimp_device_instance_read,
+  unimp_device_instance_write,
+  unimp_device_instance_seek,
   unimp_device_ioctl,
 };
 
 
 \f
-/* DATA device: data@<address>,<count>,<value>
+/* DATA device: data@<address>
+
+     <data> - property containing the value to store
+     <real-address> - address to store data at
 
-   Store <value> at <address> using <count> size transfer */
+   Store <data> at <address> using approperiate byte order */
 
 static void
-data_init_callback(device *me,
-                  psim *system)
+data_init_data_callback(device *me,
+                       psim *system)
 {
-  unsigned_word addr;
-  unsigned count;
-  unsigned value;
-  union {
-    unsigned_1 v1;
-    unsigned_2 v2;
-    unsigned_4 v4;
-    unsigned_8 v8;
-  } buf;
-
-  if (scand_uw_u_u(device_name(me), &addr, &count, &value) != 3)
-    error("devices/data - Usage: data@<address>,<count>,<value>\n");
-  /* store the data value */
-  switch (count) {
-  case 1:
-    buf.v1 = H2T_1(value);
-    break;
-  case 2:
-    buf.v2 = H2T_2(value);
-    break;
-  case 4:
-    buf.v4 = H2T_4(value);
+  unsigned_word addr = device_find_integer_property(me, "real-address");
+  const device_property *data = device_find_property(me, "data");
+  if (data == NULL)
+    error("devices/data - missing data property\n");
+  switch (data->type) {
+  case integer_property:
+    {
+      unsigned32 buf = device_find_integer_property(me, "data");
+      H2T(buf);
+      if (device_dma_write_buffer(device_parent(me),
+                                 &buf,
+                                 0 /*address-space*/,
+                                 addr,
+                                 sizeof(buf), /*nr-bytes*/
+                                 1 /*violate ro*/) != sizeof(buf))
+       error("devices/%s - Problem storing integer 0x%x at 0x%lx\n",
+             device_name(me), (long)buf, (unsigned long)addr);
+    }
     break;
-  case 8:
-    buf.v8 = H2T_8(value);
+  default:
+    error("devices/%s - write of this data is not yet implemented\n", device_name(me));
     break;
   }
-  if (device_dma_write_buffer(device_parent(me),
-                             &buf,
-                             0 /*address-space*/,
-                             addr,
-                             count, /*nr-bytes*/
-                             1 /*violate ro*/) != count) {
-    error("devices/%s - Problem storing 0x%x at 0x%lx\n",
-         device_name(me), value, (long)addr);
-  }
 }
 
 
 static device_callbacks const data_callbacks = {
-  data_init_callback,
+  ignore_device_init,
+  data_init_data_callback,
   unimp_device_attach_address,
   unimp_device_detach_address,
   unimp_device_io_read_buffer,
   unimp_device_io_write_buffer,
   unimp_device_dma_read_buffer,
   unimp_device_dma_write_buffer,
-  unimp_device_attach_interrupt,
-  unimp_device_detach_interrupt,
-  unimp_device_interrupt,
-  unimp_device_interrupt_ack,
+  unimp_device_interrupt_event,
+  unimp_device_child_interrupt_event,
+  unimp_device_unit_decode,
+  unimp_device_unit_encode,
+  unimp_device_instance_create,
+  unimp_device_instance_delete,
+  unimp_device_instance_read,
+  unimp_device_instance_write,
+  unimp_device_instance_seek,
   unimp_device_ioctl,
 };
 
 
 \f
-/* HTAB: htab@<address>,<nr_bytes>
-   PTE: pte@<real-address>,<virtual-address>,<nr_bytes>,<wimg>,<pp>
-   PTE: pte@<real-address>,<wimg>,<pp>,<binary>
-
+/* HTAB:
+
+   htab@<real-address>
+     real-address =
+     nr-bytes =
+
+   pte@<real-address>
+     real-address =
+     virtual-address =
+     nr-bytes =
+     wimg =
+     pp =
+
+   pte@<real-address>
+     real-address =
+     file-name =
+     wimg =
+     pp =
+     
    HTAB defines the location (in physical memory) of a HASH table.
    PTE (as a child of HTAB) defines a mapping that is to be entered
    into that table.
@@ -1207,7 +1529,6 @@ static device_callbacks const data_callbacks = {
    The pte, looks up its parent to determine the address of the HTAB
    and then uses DMA calls to establish the required mapping. */
 
-
 STATIC_INLINE_DEVICE_TABLE void
 htab_decode_hash_table(device *parent,
                       unsigned32 *htaborg,
@@ -1218,11 +1539,10 @@ htab_decode_hash_table(device *parent,
   unsigned n;
   /* determine the location/size of the hash table */
   if (parent == NULL
-      || strncmp(device_name(parent), "htab@", strlen("htab@")) != 0)
-    error("devices/htab - missing htab device\n");
-  if (scand_uw_u(device_name(parent), &htab_ra, &htab_nr_bytes) != 2)
-    error("devices/%s - Usage: htab@<real-addr>,<nr_bytes>\n",
-         device_name(parent));
+      || strcmp(device_name(parent), "htab") != 0)
+    error("devices/htab - missing htab parent device\n");
+  htab_ra = device_find_integer_property(parent, "real-address");
+  htab_nr_bytes = device_find_integer_property(parent, "nr-bytes");
   for (n = htab_nr_bytes; n > 1; n = n / 2) {
     if (n % 2 != 0)
       error("devices/%s - htab size 0x%x not a power of two\n",
@@ -1238,7 +1558,6 @@ htab_decode_hash_table(device *parent,
                (unsigned long)*htaborg, (unsigned long)*htabmask));
 }
 
-
 STATIC_INLINE void
 htab_map_page(device *me,
              unsigned_word ra,
@@ -1435,13 +1754,12 @@ htab_dma_binary(bfd *abfd,
   zfree(section_init); /* only free if load */
 }
 
-
 STATIC_INLINE_DEVICE_TABLE void
 htab_map_binary(device *me,
                unsigned_word ra,
                unsigned wimg,
                unsigned pp,
-               char *file_name,
+               const char *file_name,
                unsigned32 htaborg,
                unsigned32 htabmask)
 {
@@ -1499,40 +1817,26 @@ htab_map_binary(device *me,
 }
 
 static void
-htab_init_callback(device *me,
-                  psim *system)
+htab_init_data_callback(device *me,
+                       psim *system)
 {
   if (WITH_TARGET_WORD_BITSIZE != 32)
     error("devices/htab: only 32bit targets currently suported\n");
 
   /* only the pte does work */
-  if (strncmp(device_name(me), "pte@", strlen("pte@")) == 0) {
+  if (strcmp(device_name(me), "pte") == 0) {
     unsigned32 htaborg;
     unsigned32 htabmask;
-    signed32 pte_va; /* so that 0xff...0 is make 0xffffff00 */
-    unsigned32 pte_ra;
-    unsigned pte_nr_bytes;
-    unsigned pte_wimg;
-    unsigned pte_pp;
-    char file_name[1024];
 
     htab_decode_hash_table(device_parent(me), &htaborg, &htabmask);
 
-    /* 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%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%lx, wimg=%ld, pp=%ld, binary=%s\n",
+    if (device_find_property(me, "file-name") != NULL) {
+      /* map in a binary */
+      unsigned32 pte_ra = device_find_integer_property(me, "real-address");
+      unsigned pte_wimg = device_find_integer_property(me, "wimg");
+      unsigned pte_pp = device_find_integer_property(me, "pp");
+      const char *file_name = device_find_string_property(me, "file-name");
+      DTRACE(htab, ("pte - ra=0x%lx, wimg=%ld, pp=%ld, file-name=%s\n",
                    (unsigned long)pte_ra,
                    (unsigned long)pte_wimg,
                    (long)pte_pp,
@@ -1541,53 +1845,44 @@ htab_init_callback(device *me,
                      htaborg, htabmask);
     }
     else {
-      error("devices/%s - Usage: %s\nor\t%s\n",
-           device_name(me),
-           "pte@,<real-addr>,<virtual-addr>,<nr-bytes>,<wimg>,<pp>",
-           "pte@<real-addr>,<wimg>,<pp>,<binary>");
+      /* handle a normal mapping definition */
+      /* so that 0xff...0 is make 0xffffff00 */
+      signed32 pte_va = device_find_integer_property(me, "virtual-address");
+      unsigned32 pte_ra = device_find_integer_property(me, "real-address");
+      unsigned pte_nr_bytes = device_find_integer_property(me, "nr-bytes");
+      unsigned pte_wimg = device_find_integer_property(me, "wimg");
+      unsigned pte_pp = device_find_integer_property(me, "pp");
+      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);
     }
   }
 }
 
 
 static device_callbacks const htab_callbacks = {
-  htab_init_callback,
+  ignore_device_init,
+  htab_init_data_callback,
   unimp_device_attach_address,
   unimp_device_detach_address,
   unimp_device_io_read_buffer,
   unimp_device_io_write_buffer,
   passthrough_device_dma_read_buffer,
   passthrough_device_dma_write_buffer,
-  unimp_device_attach_interrupt,
-  unimp_device_detach_interrupt,
-  unimp_device_interrupt,
-  unimp_device_interrupt_ack,
-  unimp_device_ioctl,
-};
-
-
-\f
-/* Simulator device: sim@0x<address>,<nr_bytes>
-
-   Eventually gives access to the hardware configuration.  For
-   instance, it could allow the setting (on the fly) of variables such
-   as hardware floating-point or strict-alignment.
-
-   It's intended use is as part of testing the simulators
-   functionality */
-
-static device_callbacks const sim_callbacks = {
-  ignore_device_init,
-  unimp_device_attach_address,
-  unimp_device_detach_address,
-  unimp_device_io_read_buffer,
-  unimp_device_io_write_buffer,
-  unimp_device_dma_read_buffer,
-  unimp_device_dma_write_buffer,
-  unimp_device_attach_interrupt,
-  unimp_device_detach_interrupt,
-  unimp_device_interrupt,
-  unimp_device_interrupt_ack,
+  unimp_device_interrupt_event,
+  unimp_device_child_interrupt_event,
+  generic_device_unit_decode,
+  generic_device_unit_encode,
+  unimp_device_instance_create,
+  unimp_device_instance_delete,
+  unimp_device_instance_read,
+  unimp_device_instance_write,
+  unimp_device_instance_seek,
   unimp_device_ioctl,
 };
 
@@ -1676,16 +1971,13 @@ update_for_binary_section(bfd *abfd,
 
 
 static void
-binary_init_callback(device *me,
-                    psim *system)
+binary_init_data_callback(device *me,
+                         psim *system)
 {
-  const char *file_name;
+  /* get the file name */
+  const char *file_name = device_find_string_property(me, "file-name");
   bfd *image;
 
-
-  /* get the property specifying the file name */
-  file_name = device_find_next_property(me, NULL);
-
   /* open the file */
   image = bfd_openr(file_name, NULL);
   if (image == NULL) {
@@ -1710,17 +2002,23 @@ binary_init_callback(device *me,
 
 
 static device_callbacks const binary_callbacks = {
-  binary_init_callback,
+  ignore_device_init,
+  binary_init_data_callback,
   unimp_device_attach_address,
   unimp_device_detach_address,
   unimp_device_io_read_buffer,
   unimp_device_io_write_buffer,
   unimp_device_dma_read_buffer,
   unimp_device_dma_write_buffer,
-  unimp_device_attach_interrupt,
-  unimp_device_detach_interrupt,
-  unimp_device_interrupt,
-  unimp_device_interrupt_ack,
+  unimp_device_interrupt_event,
+  unimp_device_child_interrupt_event,
+  unimp_device_unit_decode,
+  unimp_device_unit_encode,
+  unimp_device_instance_create,
+  unimp_device_instance_delete,
+  unimp_device_instance_read,
+  unimp_device_instance_write,
+  unimp_device_instance_seek,
   unimp_device_ioctl,
 };
 
@@ -1914,21 +2212,17 @@ stack_ioctl_callback(device *me,
   DTRACE(stack,
         ("stack_ioctl_callback(me=0x%lx:%s, system=0x%lx, processor=0x%lx, cia=0x%lx, argv=0x%lx, envp=0x%lx)\n",
          (long)me, device_name(me), (long)system, (long)processor, (long)cia, (long)argv, (long)envp));
-  stack_type  = device_find_next_property(me, NULL);
-  if (stack_type != NULL) {
-    if (strcmp(stack_type, "elf") == 0)
-      create_elf_stack_frame(system, stack_pointer, argv, envp);
-    else if (strcmp(stack_type, "xcoff") == 0)
-      create_aix_stack_frame(system, stack_pointer, argv, envp);
-  }
+  stack_type = device_find_string_property(me, "stack-type");
+  if (strcmp(stack_type, "elf") == 0)
+    create_elf_stack_frame(system, stack_pointer, argv, envp);
+  else if (strcmp(stack_type, "xcoff") == 0)
+    create_aix_stack_frame(system, stack_pointer, argv, envp);
   DTRACE(stack, 
         ("stack_ioctl_callback() = void\n"));
 }
 
-\f
-
-
 static device_callbacks const stack_callbacks = {
+  ignore_device_init,
   ignore_device_init,
   unimp_device_attach_address,
   unimp_device_detach_address,
@@ -1936,10 +2230,15 @@ static device_callbacks const stack_callbacks = {
   unimp_device_io_write_buffer,
   unimp_device_dma_read_buffer,
   unimp_device_dma_write_buffer,
-  unimp_device_attach_interrupt,
-  unimp_device_detach_interrupt,
-  unimp_device_interrupt,
-  unimp_device_interrupt_ack,
+  unimp_device_interrupt_event,
+  unimp_device_child_interrupt_event,
+  unimp_device_unit_decode,
+  unimp_device_unit_encode,
+  unimp_device_instance_create,
+  unimp_device_instance_delete,
+  unimp_device_instance_read,
+  unimp_device_instance_write,
+  unimp_device_instance_seek,
   stack_ioctl_callback,
 };
 
@@ -1948,6 +2247,7 @@ static device_callbacks const stack_callbacks = {
 device_descriptor device_table[] = {
   { "console", console_create, &console_callbacks },
   { "memory", NULL, &memory_callbacks },
+  { "eeprom", NULL, &memory_callbacks },
   { "vm", vea_vm_create, &vm_callbacks },
   { "halt", NULL, &halt_callbacks },
   { "icu", NULL, &icu_callbacks },
@@ -1958,12 +2258,17 @@ device_descriptor device_table[] = {
   { "htab", NULL, &htab_callbacks },
   { "pte", NULL, &htab_callbacks }, /* yep - uses htab's table */
   { "stack", NULL, &stack_callbacks },
-  { "sim", NULL, &sim_callbacks },
   { "load-binary", NULL, &binary_callbacks },
   { "map-binary", NULL, &binary_callbacks },
+  /* standard OpenBoot devices */
+  { "aliases", NULL, &passthrough_callbacks },
   { "options", NULL, &passthrough_callbacks },
-  { "init", NULL, &passthrough_callbacks },
   { "chosen", NULL, &passthrough_callbacks },
+  { "packages", NULL, &passthrough_callbacks },
+  { "cpus", NULL, &passthrough_callbacks },
+  { "openprom", NULL, &passthrough_callbacks },
+  { "init", NULL, &passthrough_callbacks },
+  { "trace", NULL, &trace_callbacks },
   { NULL },
 };
 
index 35357dd35fcfe1d8bdc8be78f77a9a1ae43bf57e..9a33da1183616d18219e52a5de0dfe9334d9d9a0 100644 (file)
@@ -166,6 +166,9 @@ struct _os_emul_data {
   unsigned_word stall_cpu_loop_address;
   int little_endian;
   int floating_point_available;
+  /* I/O devices */
+  device_instance *output;
+  device_instance *input;
 };
 
 
@@ -214,6 +217,10 @@ emul_bugapi_create(device *root,
     = device_find_boolean_property(root, "/options/little-endian?");
   bugapi->floating_point_available
     = device_find_boolean_property(root, "/openprom/options/floating-point?");
+  bugapi->input
+    = device_find_ihandle_property(root, "/chosen/stdin");
+  bugapi->output
+    = device_find_ihandle_property(root, "/chosen/stdout");
 
   /* initialization */
   device_tree_add_parsed(root, "/openprom/init/register/0.pc 0x%lx",
@@ -239,15 +246,15 @@ emul_bugapi_create(device *root,
   /* patch the system call instruction to call this emulation and then
      do an rfi */
   node = device_tree_add_parsed(root, "/openprom/init/data@0x%lx",
-                               (long)bugapi->system_call_address);
+                               (unsigned long)bugapi->system_call_address);
   device_tree_add_parsed(node, "./real-address 0x%lx",
-                        (long)bugapi->system_call_address);
+                        (unsigned long)bugapi->system_call_address);
   device_tree_add_parsed(node, "./data 0x%x",
                         emul_call_instruction);
   node = device_tree_add_parsed(root, "/openprom/init/data@0x%lx",
-                               (long)(bugapi->system_call_address + 4));
+                               (unsigned long)bugapi->system_call_address + 4);
   device_tree_add_parsed(node, "./real-address 0x%lx",
-                        (long)(bugapi->system_call_address + 4));
+                        (unsigned long)bugapi->system_call_address + 4);
   device_tree_add_parsed(node, "./data 0x%x",
                         emul_rfi_instruction);
 
@@ -293,7 +300,8 @@ emul_bugapi_instruction_name(int call_id)
 }
 
 static int
-emul_bugapi_do_read(cpu *processor,
+emul_bugapi_do_read(os_emul_data *bugapi,
+                   cpu *processor,
                    unsigned_word cia,
                    unsigned_word buf,
                    int nbytes)
@@ -308,9 +316,11 @@ emul_bugapi_do_read(cpu *processor,
   emul_read_buffer((void *)scratch_buffer, buf, nbytes, processor, cia);
   
   /* read */
-  status = read (0, (void *)scratch_buffer, nbytes);
+  status = device_instance_read(bugapi->input,
+                               (void *)scratch_buffer, nbytes);
 
-  if (status == -1) {
+  /* -1 = error, -2 = nothing available - see "serial" [IEEE1275] */
+  if (status < 0) {
     status = 0;
   }
 
@@ -327,14 +337,14 @@ emul_bugapi_do_read(cpu *processor,
 }
 
 static void
-emul_bugapi_do_write(cpu *processor,
+emul_bugapi_do_write(os_emul_data *bugapi,
+                    cpu *processor,
                     unsigned_word cia,
                     unsigned_word buf,
                     int nbytes,
                     const char *suffix)
 {
   void *scratch_buffer = NULL;
-  char *p;
   int nr_moved;
 
   /* get a tempoary bufer */
@@ -354,14 +364,13 @@ emul_bugapi_do_write(cpu *processor,
       }
   
       /* write */
-      for (p = (char *)scratch_buffer; nbytes-- > 0; p++)
-       printf_filtered("%c", *p);
+      device_instance_write(bugapi->output, scratch_buffer, nbytes);
 
       zfree(scratch_buffer);
     }
 
   if (suffix)
-    printf_filtered("%s", suffix);
+    device_instance_write(bugapi->output, suffix, strlen(suffix));
 
   flush_stdoutput ();
 }
@@ -370,10 +379,10 @@ static int
 emul_bugapi_instruction_call(cpu *processor,
                             unsigned_word cia,
                             unsigned_word ra,
-                            os_emul_data *emul_data)
+                            os_emul_data *bugapi)
 {
   const int call_id = cpu_registers(processor)->gpr[10];
-  const char *my_prefix = "bugapi";
+  const char *my_prefix UNUSED = "bugapi";
   unsigned char uc;
 
   ITRACE (trace_os_emul,(" 0x%x %s, r3 = 0x%lx, r4 = 0x%lx\n",
@@ -382,7 +391,7 @@ emul_bugapi_instruction_call(cpu *processor,
                         (long)cpu_registers(processor)->gpr[4]));;
 
   /* check that this isn't an invalid instruction */
-  if (cia != emul_data->system_call_address)
+  if (cia != bugapi->system_call_address)
     return 0;
   switch (call_id) {
   default:
@@ -392,23 +401,28 @@ emul_bugapi_instruction_call(cpu *processor,
   /* read a single character, output r3 = byte */
   /* FIXME: Add support to unbuffer input */
   case _INCHR:
-    if (read (0, &uc, 1) < 0)
+    if (device_instance_read(bugapi->input, (void *)&uc, 1) <= 0)
       uc = 0;
     cpu_registers(processor)->gpr[3] = uc;
     break;
   /* read a line of at most 256 bytes, r3 = ptr to 1st byte, output r3 = ptr to last byte+1  */
   case _INLN:
-    cpu_registers(processor)->gpr[3] += emul_bugapi_do_read(processor, cia,
+    cpu_registers(processor)->gpr[3] += emul_bugapi_do_read(bugapi,
+                                                           processor, cia,
                                                            cpu_registers(processor)->gpr[3],
                                                            256);
     break;
   /* output a character, r3 = character */
   case _OUTCHR:
-    printf_filtered("%c", (char)cpu_registers(processor)->gpr[3]);
+    {
+      char out = (char)cpu_registers(processor)->gpr[3];
+      device_instance_write(bugapi->output, &out, 1);
+    }
     break;
   /* output a string, r3 = ptr to 1st byte, r4 = ptr to last byte+1 */
   case _OUTSTR:
-    emul_bugapi_do_write(processor, cia,
+    emul_bugapi_do_write(bugapi,
+                        processor, cia,
                         cpu_registers(processor)->gpr[3],
                         cpu_registers(processor)->gpr[4] - cpu_registers(processor)->gpr[3],
                         (const char *)0);
@@ -416,14 +430,15 @@ emul_bugapi_instruction_call(cpu *processor,
   /* output a string followed by \r\n, r3 = ptr to 1st byte, r4 = ptr to last byte+1 */
   case _OUTLN:
                                        
-    emul_bugapi_do_write(processor, cia,
+    emul_bugapi_do_write(bugapi,
+                        processor, cia,
                         cpu_registers(processor)->gpr[3],
                         cpu_registers(processor)->gpr[4] - cpu_registers(processor)->gpr[3],
                         "\n");
     break;
   /* output a \r\n */
   case _PCRLF:
-    printf_filtered("\n");
+    device_instance_write(bugapi->output, "\n", 1);
     break;
   /* return to ppcbug monitor */
   case _RETURN: