This commit was generated by cvs2svn to track changes on a CVS vendor
[deliverable/binutils-gdb.git] / sim / ppc / device.h
index f5d513633f8bdddb58cdc3732a2c2dc315960704..56c8ce54d990d1c7f491802b199b20b1e5a03839 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-1997, 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
     */
 
 
-#ifndef _DEVICE_TREE_H_
-#define _DEVICE_TREE_H_
+#ifndef _DEVICE_H_
+#define _DEVICE_H_
 
 #ifndef INLINE_DEVICE
 #define INLINE_DEVICE
 #endif
 
-
-
 /* declared in basics.h, this object is used everywhere */
 /* typedef struct _device device; */
 
 
+/* Introduction:
 
-\f
-/* Device Tree:
+   As explained in earlier sections, the device, device instance,
+   property and interrupts lie at the heart of PSIM's device model.
 
-   All the devices in this model live in a tree. The following allow
-   the location/manipulation of this tree */
+   In the below a synopsis of the device object and the operations it
+   supports are given.  Details of this object can be found in the
+   files <<device.h>> and <<device.c>>.
 
-device INLINE_DEVICE *device_sibling
-(device *me);
+   */
 
-device INLINE_DEVICE *device_child
-(device *me);
 
-device INLINE_DEVICE *device_parent
+/* Device creation: */
+
+INLINE_DEVICE\
+(device *) device_create
+(device *parent,
+ const char *base,
+ const char *name,
+ const char *unit_address,
+ const char *args);
+
+INLINE_DEVICE\
+(void) device_usage
+(int verbose);
+
+
+/* Device initialization: */
+
+INLINE_DEVICE\
+(void) device_clean
+(device *root,
+ void *data);
+
+INLINE_DEVICE\
+(void) device_init_static_properties
+(device *me,
+ void *data);
+
+INLINE_DEVICE\
+(void) device_init_address
+(device *me,
+ void *data);
+
+INLINE_DEVICE\
+(void) device_init_runtime_properties
+(device *me,
+ void *data);
+
+INLINE_DEVICE\
+(void) device_init_data
+(device *me,
+ void *data);
+
+
+/* Relationships:
+
+   A device is able to determine its relationship to other devices
+   within the tree.  Operations include querying for a devices parent,
+   sibling, child, name, and path (from the root).
+
+   */
+
+INLINE_DEVICE\
+(device *) device_parent
 (device *me);
 
-const char INLINE_DEVICE *device_name
+INLINE_DEVICE\
+(device *) device_root
 (device *me);
 
-void INLINE_DEVICE *device_data
+INLINE_DEVICE\
+(device *) device_sibling
 (device *me);
 
+INLINE_DEVICE\
+(device *) device_child
+(device *me);
 
-/* Grow the device tree adding either a specific device or
-   alternativly a device found in the device table */
+INLINE_DEVICE\
+(const char *) device_name
+(device *me);
 
-device INLINE_DEVICE *device_tree_add_device
-(device *root,
- const char *prefix,
- device *new_sub_tree);
+INLINE_DEVICE\
+(const char *) device_base
+(device *me);
 
-device INLINE_DEVICE *device_tree_add_found
-(device *root,
- const char *prefix,
- const char *name);
+INLINE_DEVICE\
+(const char *) device_path
+(device *me);
 
-device INLINE_DEVICE *device_tree_add_found_c
-(device *root,
- const char *prefix,
- const char *name,
- const char *c1);
+INLINE_DEVICE\
+(void *) device_data
+(device *me);
 
-device INLINE_DEVICE *device_tree_add_found_c_uw
-(device *root,
- const char *prefix,
- const char *name,
- const char *c1,
- unsigned_word uw2);
+INLINE_DEVICE\
+(psim *) device_system
+(device *me);
 
-device INLINE_DEVICE *device_tree_add_found_uw_u
-(device *root,
- const char *prefix,
- const char *name,
- unsigned_word uw1,
- unsigned u2);
+typedef struct _device_unit {
+  int nr_cells;
+  unsigned_cell cells[4]; /* unused cells are zero */
+} device_unit;
 
-device INLINE_DEVICE *device_tree_add_found_uw_u_u
-(device *root,
- const char *prefix,
- const char *name,
- unsigned_word uw1,
- unsigned u2,
- unsigned u3);
+INLINE_DEVICE\
+(const device_unit *) device_unit_address
+(device *me);
 
-device INLINE_DEVICE *device_tree_add_found_uw_u_u_c
-(device *root,
- const char *prefix,
- const char *name,
- unsigned_word uw1,
- unsigned u2,
- unsigned u3,
- const char *c4);
+INLINE_DEVICE\
+(int) device_decode_unit
+(device *bus,
+ const char *unit,
+ device_unit *address);
 
-device INLINE_DEVICE *device_tree_add_found_uw_uw_u_u_c
-(device *root,
- const char *prefix,
- const char *name,
- unsigned_word uw1,
- unsigned_word uw2,
- unsigned u3,
- unsigned u4,
- const char *c5);
+INLINE_DEVICE\
+(int) device_encode_unit
+(device *bus,
+ const device_unit *unit_address,
+ char *buf,
+ int sizeof_buf);
 
-device INLINE_DEVICE *device_tree_add_found_uw_uw_u_u_u
-(device *root,
- const char *prefix,
- const char *name,
- unsigned_word uw1,
- unsigned_word uw2,
- unsigned u3,
- unsigned u4,
- unsigned u5);
 
+/* Convert an Open Firmware size into a form suitable for attach
+   address calls.
 
-/* Query the device tree, null is returned if the specified device is
-   not found */
+   Return a zero result if the address should be ignored when looking
+   for attach addresses */
 
-device INLINE_DEVICE *device_tree_find_device
-(device *root,
- const char *path);
+INLINE_DEVICE\
+(int) device_address_to_attach_address
+(device *me,
+ const device_unit *address,
+ int *attach_space,
+ unsigned_word *attach_address,
+ device *client);
 
 
-/* traverse the device tree visiting all notes (either pre or post
-   fix) */
+/* Convert an Open Firmware size into a form suitable for attach
+   address calls
 
-typedef void (device_tree_traverse_function)
-     (device *device,
-      void *data);
+   Return a zero result if the address should be ignored */
 
-void INLINE_DEVICE device_tree_traverse
-(device *root,
- device_tree_traverse_function *prefix,
- device_tree_traverse_function *postfix,
- void *data);
+INLINE_DEVICE\
+(int) device_size_to_attach_size
+(device *me,
+ const device_unit *size,
+ unsigned *nr_bytes,
+ device *client);
 
 
-/* dump a node, this can be passed to the device_tree_traverse()
-   function to dump out the entire device tree */
+INLINE_DEVICE\
+(unsigned) device_nr_address_cells
+(device *me);
 
-void INLINE_DEVICE device_tree_dump
-(device *device,
- void *ignore_data_argument);
+INLINE_DEVICE\
+(unsigned) device_nr_size_cells
+(device *me);
 
 
+/* Properties:
 
-\f
-/* Device Properties:
+   Attached to a device are a number of properties.  Each property has
+   a size and type (both of which can be queried).  A device is able
+   to iterate over or query and set a properties value.
 
-   Attached to a device (typically by open boot firmware) are
-   properties that profile the devices features.  The below allow the
-   manipulation of device properties */
+   */
 
-/* Each device can have associated properties.  Internal to
-   psim those properties are strictly typed.  Within the simulation,
-   no such control exists */
+/* The following are valid property types.  The property `array' is
+   for generic untyped data. */
 
 typedef enum {
-  integer_property,
+  array_property,
   boolean_property,
+  ihandle_property, /*runtime*/
+  integer_property,
+  range_array_property,
+  reg_array_property,
   string_property,
-  array_property,
-  null_property,
+  string_array_property,
 } device_property_type;
 
 typedef struct _device_property device_property;
 struct _device_property {
   device *owner;
+  const char *name;
   device_property_type type;
   unsigned sizeof_array;
   const void *array;
+  const device_property *original;
+  object_disposition disposition;
 };
 
 
-/* Basic operations used by software */
+/* iterate through the properties attached to a device */
 
-const char INLINE_DEVICE *device_find_next_property
+INLINE_DEVICE\
+(const device_property *) device_next_property
+(const device_property *previous);
+
+INLINE_DEVICE\
+(const device_property *) device_find_property
 (device *me,
- const char *previous);
+ const char *property); /* NULL for first property */
+
+
+/* Manipulate the properties belonging to a given device.
+
+   SET on the other hand will force the properties value.  The
+   simulation is aborted if the property was present but of a
+   conflicting type.
+
+   FIND returns the specified properties value, aborting the
+   simulation if the property is missing.  Code locating a property
+   should first check its type (using device_find_property above) and
+   then obtain its value using the below.
+
+   void device_add_<type>_property(device *, const char *, <type>)
+   void device_add_*_array_property(device *, const char *, const <type>*, int)
+   void device_set_*_property(device *, const char *, <type>)
+   void device_set_*_array_property(device *, const char *, const <type>*, int)
+   <type> device_find_*_property(device *, const char *)
+   int device_find_*_array_property(device *, const char *, int, <type>*)
+
+   */
+
 
-void INLINE_DEVICE device_set_property
+INLINE_DEVICE\
+(void) device_add_array_property
 (device *me,
  const char *property,
  const void *array,
  int sizeof_array);
 
-
-/* INLINE_DEVICE void device_add_property
-   No such external function, all properties, when added are explictly
-   typed */
-
-void INLINE_DEVICE device_add_array_property
+INLINE_DEVICE\
+(void) device_set_array_property
 (device *me,
  const char *property,
  const void *array,
  int sizeof_array);
 
-void INLINE_DEVICE device_add_integer_property
+INLINE_DEVICE\
+(const device_property *) device_find_array_property
 (device *me,
- const char *property,
- signed_word integer);
+ const char *property);
 
-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\
+(int) device_find_boolean_property
 (device *me,
  const char *property);
 
-void INLINE_DEVICE device_add_string_property
+
+
+typedef struct _ihandle_runtime_property_spec {
+  const char *full_path;
+} ihandle_runtime_property_spec;
+
+INLINE_DEVICE\
+(void) device_add_ihandle_runtime_property
 (device *me,
  const char *property,
- const char *string);
+ const ihandle_runtime_property_spec *ihandle);
 
+INLINE_DEVICE\
+(void) device_find_ihandle_runtime_property
+(device *me,
+ const char *property,
+ ihandle_runtime_property_spec *ihandle);
 
-/* Locate a property returning its description.  Return NULL if the
-   named property is not found */
+INLINE_DEVICE\
+(void) device_set_ihandle_property
+(device *me,
+ const char *property,
+ device_instance *ihandle);
 
-const device_property INLINE_DEVICE *device_find_property
+INLINE_DEVICE\
+(device_instance *) device_find_ihandle_property
 (device *me,
  const char *property);
 
 
-/* Process all properties attached to the named device */
 
-typedef void (device_traverse_property_function)
-     (device *me,
-      const char *name,
-      void *data);
+INLINE_DEVICE\
+(void) device_add_integer_property
+(device *me,
+ const char *property,
+ signed_cell integer);
 
-void INLINE_DEVICE device_traverse_properties
+INLINE_DEVICE\
+(signed_cell) device_find_integer_property
 (device *me,
- device_traverse_property_function *traverse,
- void *data);
+ const char *property);
+
+INLINE_DEVICE\
+(int) device_find_integer_array_property
+(device *me,
+ const char *property,
+ unsigned index,
+ signed_word *integer);
 
-/* 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
+
+typedef struct _range_property_spec {
+  device_unit child_address;
+  device_unit parent_address;
+  device_unit size;
+} range_property_spec;
+
+INLINE_DEVICE\
+(void) device_add_range_array_property
 (device *me,
- const char *property);
+ const char *property,
+ const range_property_spec *ranges,
+ unsigned nr_ranges);
 
-signed_word INLINE_DEVICE device_find_integer_property
+INLINE_DEVICE\
+(int) device_find_range_array_property
 (device *me,
- const char *property);
+ const char *property,
+ unsigned index,
+ range_property_spec *range);
+
+
+
+typedef struct _reg_property_spec {
+  device_unit address;
+  device_unit size;
+} reg_property_spec;
 
-const char INLINE_DEVICE *device_find_string_property
+INLINE_DEVICE\
+(void) device_add_reg_array_property
 (device *me,
- const char *property);
+ const char *property,
+ const reg_property_spec *reg,
+ unsigned nr_regs);
+
+INLINE_DEVICE\
+(int) device_find_reg_array_property
+(device *me,
+ const char *property,
+ unsigned index,
+ reg_property_spec *reg);
+
 
-int INLINE_DEVICE device_find_boolean_property
+
+INLINE_DEVICE\
+(void) device_add_string_property
+(device *me,
+ const char *property,
+ const char *string);
+
+INLINE_DEVICE\
+(const char *) device_find_string_property
 (device *me,
  const char *property);
 
 
-\f
-/* Device Hardware:
 
-   A device principaly is modeling real hardware that a processor can
-   directly interact with via load/stores dma's and interrupts.  The
-   interface below is used by the hardware side of the device
-   model. */
+typedef const char *string_property_spec;
 
-/* Address access attributes that can be attached to a devices address
-   range */
-typedef enum _access_type {
-  access_invalid = 0,
-  access_read = 1,
-  access_write = 2,
-  access_read_write = 3,
-  access_exec = 4,
-  access_read_exec = 5,
-  access_write_exec = 6,
-  access_read_write_exec = 7,
-} access_type;
+INLINE_DEVICE\
+(void) device_add_string_array_property
+(device *me,
+ const char *property,
+ const string_property_spec *strings,
+ unsigned nr_strings);
+
+INLINE_DEVICE\
+(int) device_find_string_array_property
+(device *me,
+ const char *property,
+ unsigned index,
+ string_property_spec *string);
 
 
-/* Address attachement types */
-typedef enum _attach_type {
-  attach_invalid,
-  attach_callback,
-  attach_default,
-  attach_raw_memory,
-} attach_type;
 
+INLINE_DEVICE\
+(void) device_add_duplicate_property
+(device *me,
+ const char *property,
+ const device_property *original);
 
-/* Initialization:
 
-   A device is made fully functional in two stages.
 
-   1. It is created. A device is created _before_ it is entered into
-   the device tree.  During creation any permenant structures needed
-   by the device should be created/initialized.
+/* Instances:
 
-   2. It is initialized.  Before a simulation run, each device in the
-   device tree is initialized in prefix order.  As part of this
-   initialization, a device should (re)attach its self to its parent
-   as needed.
+   As with IEEE1275, a device can be opened, creating an instance.
+   Instances provide more abstract interfaces to the underlying
+   hardware.  For example, the instance methods for a disk may include
+   code that is able to interpret file systems found on disks.  Such
+   methods would there for allow the manipulation of files on the
+   disks file system.  The operations would be implemented using the
+   basic block I/O model provided by the disk.
 
-   */
+   This model includes methods that faciliate the creation of device
+   instance and (should a given device support it) standard operations
+   on those instances.
 
-device INLINE_DEVICE *device_create
-(const char *name,
- device *parent);
+   */
 
-/* some external functions want to create things */
-typedef struct _device_callbacks device_callbacks;
+typedef struct _device_instance_callbacks device_instance_callbacks;
 
-device INLINE_DEVICE *device_create_from
-(const char *name,
+INLINE_DEVICE\
+(device_instance *) device_create_instance_from
+(device *me, /*OR*/ device_instance *parent,
  void *data,
- const device_callbacks *callbacks,
- device *parent);
+ const char *path,
+ const char *args,
+ const device_instance_callbacks *callbacks);
 
-void INLINE_DEVICE device_init
+INLINE_DEVICE\
+(device_instance *) device_create_instance
 (device *me,
- psim *system);
+ const char *full_path,
+ const char *args);
 
-/* initialize the entire tree */
+INLINE_DEVICE\
+(void) device_instance_delete
+(device_instance *instance);
 
-void INLINE_DEVICE device_tree_init
-(device *root,
- psim *system);
+INLINE_DEVICE\
+(int) device_instance_read
+(device_instance *instance,
+ void *addr,
+ unsigned_word len);
 
+INLINE_DEVICE\
+(int) device_instance_write
+(device_instance *instance,
+ const void *addr,
+ unsigned_word len);
 
-/* Data transfers:
+INLINE_DEVICE\
+(int) device_instance_seek
+(device_instance *instance,
+ unsigned_word pos_hi,
+ unsigned_word pos_lo);
 
-   A device may permit the reading/writing (IO) of its registers in
-   one or more address spaces.  For instance, a PCI device may have
-   config registers in its config space and control registers in both
-   the io and memory spaces of a PCI bus.
+INLINE_DEVICE\
+(int) device_instance_call_method
+(device_instance *instance,
+ const char *method,
+ int n_stack_args,
+ unsigned_cell stack_args[/*n_stack_args*/],
+ int n_stack_returns,
+ unsigned_cell stack_returns[/*n_stack_returns*/]);
+
+INLINE_DEVICE\
+(device *) device_instance_device
+(device_instance *instance);
 
-   Similarly, a device may initiate a data transfer (DMA) by passing
-   such a request up to its parent.
+INLINE_DEVICE\
+(const char *) device_instance_path
+(device_instance *instance);
 
-   Init:
+INLINE_DEVICE\
+(void *) device_instance_data
+(device_instance *instance);
 
-   As part of its initialization (not creation) and possibly also as a
-   consequence of IO a device may attach its self to one or more of
-   the address spaces of its parent device.
 
-   For instance, a PCI device, during initialization would attach its
-   config registers (space=0?, base=0, nr_bytes=64) to its parent PCI
-   bridge.  Later, due to a write to this config space, the same
-   device may in turn find it necessary to also attach its self to
-   it's parent's `memory' or `io' space.
+/* Interrupts:
 
-   To perform these operations, a device will call upon its parent
-   using either device_attach_address or device_detach_address.
+   */
 
-   * Any address specified is according to what the device expects to
-   see.
+/* Interrupt Source
 
-   * Any detach operation must exactly match a previous attach.
+   A device drives its interrupt line using the call
 
-   * included with the attach or detach is the devices name, the
-   parent may use this as part of determining how to map map between a
-   child's address + space and its own.
+   */
 
-   * at any time, at most one device can have a default mapping
-   registered.
+INLINE_DEVICE\
+(void) device_interrupt_event
+(device *me,
+ int my_port,
+ int value,
+ cpu *processor,
+ unsigned_word cia);
 
+/* This interrupt event will then be propogated to any attached
+   interrupt destinations.
 
-   IO:
+   Any interpretation of PORT and VALUE is model dependant.  However
+   as guidelines the following are recommended: PCI interrupts a-d
+   correspond to lines 0-3; level sensative interrupts be requested
+   with a value of one and withdrawn with a value of 0; edge sensative
+   interrupts always have a value of 1, the event its self is treated
+   as the interrupt.
 
-   A device receives requests to perform reads/writes to its registers
-   or memory either A. from a processor or B. from a parent device.
 
-   The device may then in turn either A. resolve the IO request
-   locally by processing the data or trigering an exception or
-   B. re-mapping the access onto one of its local address spaces and
-   then in turn passing that on to one of its children.
+   Interrupt Destinations
 
-   * Any address passed is relative to the local device.  Eg for PCI
-   config registers, the address would (normally) be in the range of 0
-   to 63.
+   Attached to each interrupt line of a device can be zero or more
+   desitinations.  These destinations consist of a device/port pair.
+   A destination is attached/detached to a device line using the
+   attach and detach calls. */
 
-   * Any exception situtation triggered by an IO operation (processor
-   != NULL) is handled in one of the following ways: 1. Machine check
-   (and similar): issued immediatly by restarting the cpu; 2. External
-   exception: issue delayed (using events.h) until the current
-   instruction execution cycle is completed; 3. Slave device (and
-   similar): the need for the interrupt is passed on to the devices
-   parent (which being an interrupt control unit will in turn take one
-   of the actions described here); 4. Forget it.
+INLINE_DEVICE\
+(void) device_interrupt_attach
+(device *me,
+ int my_port,
+ device *dest,
+ int dest_port,
+ object_disposition disposition);
 
-   * Any exception situtation trigered by a non IO operation
-   (processor == NULL) is handled buy returning 0.
+INLINE_DEVICE\
+(void) device_interrupt_detach
+(device *me,
+ int my_port,
+ device *dest,
+ int dest_port);
 
-   * Transfers of size <= 8 and of a power of 2 *must* be correctly
-   aligned and should be treated as a `single cycle' transfer.
+typedef void (device_interrupt_traverse_function)
+     (device *me,
+      int my_port,
+      device *dest,
+      int my_dest,
+      void *data);
 
-   DMA:
+INLINE_DEVICE\
+(void) device_interrupt_traverse
+(device *me,
+ device_interrupt_traverse_function *handler,
+ void *data);
 
-   A device initiates a DMA transfer by calling its parent with the
-   request.  At the top level (if not done earlier) this is reflected
-   back down the tree as io read/writes to the target device.
+/* DESTINATION is attached (detached) to LINE of the device ME
 
-   This function is subject to change ...
 
-   */
+   Interrupt conversion
+
+   Users refer to interrupt port numbers symbolically.  For instance a
+   device may refer to its `INT' signal which is internally
+   represented by port 3.
+
+   To convert to/from the symbolic and internal representation of a
+   port name/number.  The following functions are available. */
 
-void INLINE_DEVICE device_attach_address
+INLINE_DEVICE\
+(int) device_interrupt_decode
 (device *me,
- const char *name,
- attach_type attach,
- int space,
- unsigned_word addr,
- unsigned nr_bytes,
- access_type access,
- device *who); /*callback/default*/
+ const char *symbolic_name,
+ port_direction direction);
 
-void INLINE_DEVICE device_detach_address
+INLINE_DEVICE\
+(int) device_interrupt_encode
 (device *me,
- const char *name,
- attach_type attach,
- int space,
- unsigned_word addr,
- unsigned nr_bytes,
- access_type access,
- device *who); /*callback/default*/
+ int port_number,
+ char *buf,
+ int sizeof_buf,
+ port_direction direction);
+
+/* Hardware operations:
+
+   */
 
-unsigned INLINE_DEVICE device_io_read_buffer
+INLINE_DEVICE\
+(unsigned) device_io_read_buffer
 (device *me,
  void *dest,
  int space,
@@ -445,7 +603,8 @@ 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,
@@ -454,14 +613,23 @@ unsigned INLINE_DEVICE device_io_write_buffer
  cpu *processor,
  unsigned_word cia);
 
-unsigned INLINE_DEVICE device_dma_read_buffer
+
+/* Conversly, the device pci1000,1@1 my need to perform a dma transfer
+   into the cpu/memory core.  Just as I/O moves towards the leaves,
+   dma transfers move towards the core via the initiating devices
+   parent nodes.  The root device (special) converts the DMA transfer
+   into reads/writes to memory */
+
+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,
@@ -469,192 +637,161 @@ unsigned INLINE_DEVICE device_dma_write_buffer
  unsigned nr_bytes,
  int violate_read_only_section);
 
+/* To avoid the need for an intermediate (bridging) node to ask each
+   of its child devices in turn if an IO access is intended for them,
+   parent nodes maintain a table mapping addresses directly to
+   specific devices.  When a device is `connected' to its bus it
+   attaches its self to its parent. */
 
-/* Interrupts:
-
-   As mentioned above.  Instead of handling an interrupt directly, a
-   device may instead pass the need to interrupt on to its parent.
-
-   Init:
-
-   Before passing interrupts up to is parent, a device must first
-   attach its interrupt lines to the parent device.  To do this, the
-   device uses the parents attach/detach calls.
-  
-   Interrupts:
-
-   A child notifies a parent of a change in an interrupt lines status
-   using the interrupt call.  Similarly, a parent may notify a child
-   of any `interrupt ack' sequence using the interrupt_ack call.
+/* Address access attributes */
+typedef enum _access_type {
+  access_invalid = 0,
+  access_read = 1,
+  access_write = 2,
+  access_read_write = 3,
+  access_exec = 4,
+  access_read_exec = 5,
+  access_write_exec = 6,
+  access_read_write_exec = 7,
+} access_type;
 
-   */
+/* Address attachement types */
+typedef enum _attach_type {
+  attach_invalid,
+  attach_raw_memory,
+  attach_callback,
+  /* ... */
+} attach_type;
 
-void INLINE_DEVICE device_attach_interrupt
+INLINE_DEVICE\
+(void) device_attach_address
 (device *me,
- device *who,
- int interrupt_line,
- const char *name);
+ attach_type attach,
+ int space,
+ unsigned_word addr,
+ unsigned nr_bytes,
+ access_type access,
+ device *client); /*callback/default*/
 
-void INLINE_DEVICE device_detach_interrupt
+INLINE_DEVICE\
+(void) device_detach_address
 (device *me,
- device *who,
- int interrupt_line,
- const char *name);
+ attach_type attach,
+ int space,
+ unsigned_word addr,
+ unsigned nr_bytes,
+ access_type access,
+ device *client); /*callback/default*/
 
-void INLINE_DEVICE device_interrupt
-(device *me,
- device *who,
- int interrupt_line,
- int interrupt_status,
- cpu *processor,
- unsigned_word cia);
+/* Utilities:
 
-void INLINE_DEVICE device_interrupt_ack
-(device *me,
- int interrupt_line,
- int interrupt_status);
+   */
 
+/* IOCTL::
 
-/* IOCTL:
+   Often devices require `out of band' operations to be performed.
+   For instance a pal device may need to notify a PCI bridge device
+   that an interrupt ack cycle needs to be performed on the PCI bus.
+   Within PSIM such operations are performed by using the generic
+   ioctl call <<device_ioctl()>>.
 
-   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
+typedef enum {
+  device_ioctl_break, /* unsigned_word requested_break */
+  device_ioctl_set_trace, /* void */
+  device_ioctl_create_stack, /* unsigned_word *sp, char **argv, char **envp */
+  device_ioctl_change_media, /* const char *new_image (possibly NULL) */
+  nr_device_ioctl_requests,
+} device_ioctl_request;
+
+EXTERN_DEVICE\
+(int) device_ioctl
 (device *me,
- psim *system,
  cpu *processor,
  unsigned_word cia,
+ device_ioctl_request request,
  ...);
-      
 
-\f
-/* Device software - the instance
 
-   Under development
+/* Error reporting::
 
-   In addition to the processor directly manipulating a device via
-   read/write operations.  A program may manipulate a device
-   indirectly via OpenBoot calls.  The following provide a higher
-   level software interface to the devices */
+   So that errors originating from devices appear in a consistent
+   format, the <<device_error()>> function can be used.  Formats and
+   outputs the error message before aborting the simulation
 
-device_instance INLINE_DEVICE *device_instance_open
+   Devices should use this function to abort the simulation except
+   when the abort reason leaves the simulation in a hazardous
+   condition (for instance a failed malloc).
+
+   */
+
+EXTERN_DEVICE\
+(void volatile) device_error
 (device *me,
- const char *device_specifier);
+ const char *fmt,
+ ...) __attribute__ ((format (printf, 2, 3)));
 
-void INLINE_DEVICE device_instance_close
-(device_instance *instance);
+INLINE_DEVICE\
+(int) device_trace
+(device *me);
 
-int INLINE_DEVICE device_instance_read
-(device_instance *instance,
- void *addr,
- unsigned_word len);
 
-int INLINE_DEVICE device_instance_write
-(device_instance *instance,
- const void *addr,
- unsigned_word len);
 
-int INLINE_DEVICE device_instance_seek
-(device_instance *instance,
- unsigned_word pos_hi,
- unsigned_word pos_lo);
+/* External representation:
 
-device INLINE_DEVICE *device_instance_device
-(device_instance *instance);
+   Both device nodes and device instances, in OpenBoot firmware have
+   an external representation (phandles and ihandles) and these values
+   are both stored in the device tree in property nodes and passed
+   between the client program and the simulator during emulation
+   calls.
 
-const char INLINE_DEVICE *device_instance_name
-(device_instance *instance);
+   To limit the potential risk associated with trusing `data' from the
+   client program, the following mapping operators `safely' convert
+   between the two representations
 
+   */
 
+INLINE_DEVICE\
+(device *) external_to_device
+(device *tree_member,
+ unsigned_cell phandle);
 
+INLINE_DEVICE\
+(unsigned_cell) device_to_external
+(device *me);
 
-\f
-/* Device dregs... */
+INLINE_DEVICE\
+(device_instance *) external_to_device_instance
+(device *tree_member,
+ unsigned_cell ihandle);
 
-/* Parse a device name */
+INLINE_DEVICE\
+(unsigned_cell) device_instance_to_external
+(device_instance *me);
 
-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);
 
+/* Event queue:
 
-/* Parse a device name, various formats:
+   The device inherets certain event queue operations from the main
+   simulation. */
 
-   uw: unsigned_word
-   u: unsigned
-   c: string */
+typedef void device_event_handler(void *data);
 
-int INLINE_DEVICE scand_c
-(const char *name,
- char *c1,
- unsigned c1size);
+INLINE_DEVICE\
+(event_entry_tag) device_event_queue_schedule
+(device *me,
+ signed64 delta_time,
+ device_event_handler *handler,
+ void *data);
 
-int INLINE_DEVICE scand_c_uw_u
-(const char *name,
- char *c1,
- unsigned c1size,
- unsigned_word *uw2,
- unsigned *u3);
-int INLINE_DEVICE scand_uw
-(const char *name,
- unsigned_word *uw1);
-int INLINE_DEVICE scand_uw_c
-(const char *name,
- unsigned_word *uw1,
- char *c2,
- unsigned c2size);
-int INLINE_DEVICE scand_uw_u
-(const char *name,
- unsigned_word *uw1,
- unsigned *u2);
-int INLINE_DEVICE scand_uw_u_u
-(const char *name,
- unsigned_word *uw1,
- unsigned *u2,
- unsigned *u3);
-int INLINE_DEVICE scand_uw_u_u_c
-(const char *name,
- unsigned_word *uw1,
- unsigned *u2,
- unsigned *u3,
- char *c4,
- unsigned c4size);
-int INLINE_DEVICE scand_uw_uw
-(const char *name,
- unsigned_word *uw1,
- unsigned_word *uw2);
-
-int INLINE_DEVICE scand_uw_uw_u
-(const char *name,
- unsigned_word *uw1,
- unsigned_word *uw2,
- unsigned *u3);
-int INLINE_DEVICE scand_uw_uw_u_u_c
-(const char *name,
- unsigned_word *uw1,
- unsigned_word *uw2,
- unsigned *u3,
- unsigned *u4,
- char *c5,
- unsigned c5size);
-int INLINE_DEVICE scand_uw_uw_u_u_u
-(const char *name,
- unsigned_word *uw1,
- unsigned_word *uw2,
- unsigned *u3,
- unsigned *u4,
- unsigned *u5);
-#endif /* _DEVICE_TREE_H_ */
+INLINE_EVENTS\
+(void) device_event_queue_deschedule
+(device *me,
+ event_entry_tag event_to_remove);
+
+INLINE_EVENTS\
+(signed64) device_event_queue_time
+(device *me);
+
+#endif /* _DEVICE_H_ */
This page took 0.034142 seconds and 4 git commands to generate.