gas: avoid spurious failures in non-ELF targets in the SPARC testsuite.
[deliverable/binutils-gdb.git] / sim / ppc / hw_pal.c
index dd5a097127681c6d5ca91bc0e9e0ec354611e388..0789929cde067130165ea41d40d8ed6748663acd 100644 (file)
@@ -4,7 +4,7 @@
     
     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
-    the Free Software Foundation; either version 2 of the License, or
+    the Free Software Foundation; either version 3 of the License, or
     (at your option) any later version.
     
     This program is distributed in the hope that it will be useful,
@@ -13,8 +13,7 @@
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+    along with this program; if not, see <http://www.gnu.org/licenses/>.
     
     */
 
 #endif
 
 #include "device_table.h"
-#include "cpu.h"
-
 
-#include <stdio.h>
-#include <fcntl.h>
-
-#if 0
-#ifdef HAVE_TIME_H
-#include <time.h>
-#endif
-#endif
+#include "cpu.h"
 
 #ifdef HAVE_STRING_H
 #include <string.h>
 #endif
 
 
-/* Device:
-   
-   pal@<address>
+/* DEVICE
+
    
+   pal - glue logic device containing assorted junk
+
    
-   Description:
+   DESCRIPTION
+
    
    Typical hardware dependant hack.  This device allows the firmware
    to gain access to all the things the firmware needs (but the OS
-   doesn't).  All registers are little endian (byte 0 is the least
-   significant) and must be accessed correctly aligned.
-   
-   <address> + 0: write - halts simulation with exit code byte[0].
-   
-   <address> + 4: read - processor nr in byte[0].
-   
-   <address> + 8: write - send interrupt message to port byte[0] with
-   value byte[1].
+   doesn't).
+
+   The pal contains the following registers.  Except for the interrupt
+   level register, each of the below is 8 bytes in size and must be
+   accessed using correct alignment.  For 16 and 32 bit accesses the
+   bytes not directed to the register are ignored:
    
-   <address> + 12: read - nr processors in byte[0].
+   |0  reset register (write)
+   |4  processor id register (read)
+   |8  interrupt port (write)
+   |9  interrupt level (write)
+   |12 processor count register (read)
+   |16 tty input fifo register (read)
+   |20 tty input status register (read)
+   |24 tty output fifo register (write)
+   |28 tty output status register (read)
+
+   Reset register (write) halts the simulator exiting with the
+   value written.
    
+   Processor id register (read) returns the processor number (0
+   .. N-1) of the processor performing the read.
    
-   Properties:
+   The interrupt registers should be accessed as a pair (using a 16 or
+   32 bit store).  The low byte specifies the interrupt port while the
+   high byte specifies the level to drive that port at.  By
+   convention, the pal's interrupt ports (int0, int1, ...) are wired
+   up to the corresponding processor's level sensative external
+   interrupt pin.  Eg: A two byte write to address 8 of 0x0102
+   (big-endian) will result in processor 2's external interrupt pin to
+   be asserted.
+
+   Processor count register (read) returns the total number of
+   processors active in the current simulation.
+
+   TTY input fifo register (read), if the TTY input status register
+   indicates a character is available by being nonzero, returns the
+   next available character from the pal's tty input port.
+
+   Similarly, the TTY output fifo register (write), if the TTY output
+   status register indicates the output fifo is not full by being
+   nonzero, outputs the character written to the tty's output port.
+
+
+   PROPERTIES
    
-   NONE. */
+
+   reg = <address> <size> (required)
+
+   Specify the address (within the parent bus) that this device is to
+   live.
+
+
+   */
 
 
 enum {
@@ -103,6 +133,7 @@ typedef struct _hw_pal_console_buffer {
 typedef struct _hw_pal_device {
   hw_pal_console_buffer input;
   hw_pal_console_buffer output;
+  device *disk;
 } hw_pal_device;
 
 
@@ -110,46 +141,18 @@ typedef struct _hw_pal_device {
 static void
 scan_hw_pal(hw_pal_device *hw_pal)
 {
-  if (WITH_STDIO == DO_USE_STDIO) {
-    int c = getchar ();
-    if (c == EOF) {
-      hw_pal->input.buffer = 0;
-      hw_pal->input.status = 0;
-    } else {
-      hw_pal->input.buffer = c;
-      hw_pal->input.status = 1;
-    }
-
-  } else {
-    /* check for input */
-    int flags;
-    int status;
-    /* get the old status */
-    flags = fcntl(0, F_GETFL, 0);
-    if (flags == -1) {
-      perror("hw_pal");
-      return;
-    }
-    /* temp, disable blocking IO */
-    status = fcntl(0, F_SETFL, flags | O_NDELAY);
-    if (status == -1) {
-      perror("hw_pal");
-      return;
-    }
-    /* try for input */
-    status = read(0, &hw_pal->input.buffer, 1);
-    if (status == 1) {
-      hw_pal->input.status = 1;
-    }
-    else {
-      hw_pal->input.status = 0;
-    }
-    /* return to regular vewing */
-    flags = fcntl(0, F_SETFL, flags);
-    if (flags == -1) {
-      perror("hw_pal");
-      return;
-    }
+  char c;
+  int count;
+  count = sim_io_read_stdin(&c, sizeof(c));
+  switch (count) {
+  case sim_io_not_ready:
+  case sim_io_eof:
+    hw_pal->input.buffer = 0;
+    hw_pal->input.status = 0;
+    break;
+  default:
+    hw_pal->input.buffer = c;
+    hw_pal->input.status = 1;
   }
 }
 
@@ -158,13 +161,7 @@ static void
 write_hw_pal(hw_pal_device *hw_pal,
             char val)
 {
-  if (WITH_STDIO == DO_USE_STDIO) {
-    putchar (val);
-
-  } else {
-    printf_filtered("%c", val) ;
-  }
-
+  sim_io_write_stdout(&val, 1);
   hw_pal->output.buffer = val;
   hw_pal->output.status = 1;
 }
@@ -184,25 +181,32 @@ hw_pal_io_read_buffer_callback(device *me,
   switch (addr & hw_pal_address_mask) {
   case hw_pal_cpu_nr_register:
     val = cpu_nr(processor);
+    DTRACE(pal, ("read - cpu-nr %d\n", val));
     break;
   case hw_pal_nr_cpu_register:
-    val = device_find_integer_property(me, "/openprom/options/smp");
+    val = tree_find_integer_property(me, "/openprom/options/smp");
+    DTRACE(pal, ("read - nr-cpu %d\n", val));
     break;
   case hw_pal_read_fifo:
     val = hw_pal->input.buffer;
+    DTRACE(pal, ("read - input-fifo %d\n", val));
     break;
   case hw_pal_read_status:
     scan_hw_pal(hw_pal);
     val = hw_pal->input.status;
+    DTRACE(pal, ("read - input-status %d\n", val));
     break;
   case hw_pal_write_fifo:
     val = hw_pal->output.buffer;
+    DTRACE(pal, ("read - output-fifo %d\n", val));
     break;
   case hw_pal_write_status:
     val = hw_pal->output.status;
+    DTRACE(pal, ("read - output-status %d\n", val));
     break;
   default:
     val = 0;
+    DTRACE(pal, ("read - ???\n"));
   }
   memset(dest, 0, nr_bytes);
   *(unsigned_1*)dest = val;
@@ -234,15 +238,19 @@ hw_pal_io_write_buffer_callback(device *me,
     break;
   case hw_pal_read_fifo:
     hw_pal->input.buffer = byte[0];
+    DTRACE(pal, ("write - input-fifo %d\n", byte[0]));
     break;
   case hw_pal_read_status:
     hw_pal->input.status = byte[0];
+    DTRACE(pal, ("write - input-status %d\n", byte[0]));
     break;
   case hw_pal_write_fifo:
     write_hw_pal(hw_pal, byte[0]);
+    DTRACE(pal, ("write - output-fifo %d\n", byte[0]));
     break;
   case hw_pal_write_status:
     hw_pal->output.status = byte[0];
+    DTRACE(pal, ("write - output-status %d\n", byte[0]));
     break;
   }
   return nr_bytes;
@@ -250,13 +258,6 @@ hw_pal_io_write_buffer_callback(device *me,
 
 
 /* instances of the hw_pal device */
-static void *
-hw_pal_instance_create_callback(device *me,
-                               const char *args)
-{
-  /* make life easier, attach the hw_pal data to the instance */
-  return device_data(me);
-}
 
 static void
 hw_pal_instance_delete_callback(device_instance *instance)
@@ -270,15 +271,8 @@ hw_pal_instance_read_callback(device_instance *instance,
                              void *buf,
                              unsigned_word len)
 {
-  char *buf_char = (char *)buf;
-  hw_pal_device *hw_pal = device_instance_data(instance);
-  if (WITH_STDIO == DO_USE_STDIO) {
-    char *line = fgets (buf_char, len, stdin);
-    return ((!line) ? -1 : strlen (buf_char));
-
-  } else {
-    return read(0, buf_char, len);
-  }
+  DITRACE(pal, ("read - %s (%ld)", (const char*)buf, (long int)len));
+  return sim_io_read_stdin(buf, len);
 }
 
 static int
@@ -289,35 +283,69 @@ hw_pal_instance_write_callback(device_instance *instance,
   int i;
   const char *chp = buf;
   hw_pal_device *hw_pal = device_instance_data(instance);
+  DITRACE(pal, ("write - %s (%ld)", (const char*)buf, (long int)len));
   for (i = 0; i < len; i++)
     write_hw_pal(hw_pal, chp[i]);
-
-  if (WITH_STDIO == DO_USE_STDIO) {
-    fflush (stdout);
-  }
+  sim_io_flush_stdoutput();
   return i;
 }
 
+static const device_instance_callbacks hw_pal_instance_callbacks = {
+  hw_pal_instance_delete_callback,
+  hw_pal_instance_read_callback,
+  hw_pal_instance_write_callback,
+};
+
+static device_instance *
+hw_pal_create_instance(device *me,
+                      const char *path,
+                      const char *args)
+{
+  return device_create_instance_from(me, NULL,
+                                    device_data(me),
+                                    path, args,
+                                    &hw_pal_instance_callbacks);
+}
+
+static const device_interrupt_port_descriptor hw_pal_interrupt_ports[] = {
+  { "int", 0, MAX_NR_PROCESSORS },
+  { NULL }
+};
+
+
+static void
+hw_pal_attach_address(device *me,
+                     attach_type attach,
+                     int space,
+                     unsigned_word addr,
+                     unsigned nr_bytes,
+                     access_type access,
+                     device *client)
+{
+  hw_pal_device *pal = (hw_pal_device*)device_data(me);
+  pal->disk = client;
+}
+
+
 static device_callbacks const hw_pal_callbacks = {
   { generic_device_init_address, },
-  { NULL, }, /* address */
+  { hw_pal_attach_address, }, /* address */
   { hw_pal_io_read_buffer_callback,
       hw_pal_io_write_buffer_callback, },
   { NULL, }, /* DMA */
-  { NULL, }, /* interrupt */
-  { NULL, }, /* unit */
-  { hw_pal_instance_create_callback,
-      hw_pal_instance_delete_callback,
-      hw_pal_instance_read_callback,
-      hw_pal_instance_write_callback, },
+  { NULL, NULL, hw_pal_interrupt_ports }, /* interrupt */
+  { generic_device_unit_decode,
+    generic_device_unit_encode,
+    generic_device_address_to_attach_address,
+    generic_device_size_to_attach_size },
+  hw_pal_create_instance,
 };
 
 
 static void *
 hw_pal_create(const char *name,
              const device_unit *unit_address,
-             const char *args,
-             device *parent)
+             const char *args)
 {
   /* create the descriptor */
   hw_pal_device *hw_pal = ZALLOC(hw_pal_device);
This page took 0.027127 seconds and 4 git commands to generate.