aboutsummaryrefslogtreecommitdiff
path: root/sim/ppc/device.h
diff options
context:
space:
mode:
Diffstat (limited to 'sim/ppc/device.h')
-rw-r--r--sim/ppc/device.h837
1 files changed, 411 insertions, 426 deletions
diff --git a/sim/ppc/device.h b/sim/ppc/device.h
index cc6bd53..4fa5a9d 100644
--- a/sim/ppc/device.h
+++ b/sim/ppc/device.h
@@ -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
@@ -19,417 +19,396 @@
*/
-#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:
-
-/* 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>>.
-INLINE_DEVICE(device *) device_parent
-(device *me);
-
-INLINE_DEVICE(device *) device_sibling
-(device *me);
+ */
-INLINE_DEVICE(device *) device_child
-(device *me);
-INLINE_DEVICE(const char *) device_name
-(device *me);
+/* Constructing the device tree:
-INLINE_DEVICE(void *) device_data
-(device *me);
+ The initial device tree populated with devices and basic properties
+ is created using the function <<device_tree_add_parsed()>>. This
+ function parses a PSIM device specification and uses it to populate
+ the tree accordingly.
+ This function accepts a printf style formatted string as the
+ argument that describes the entry. Any properties or interrupt
+ connections added to a device tree using this function are marked
+ as having a permenant disposition. When the tree is (re)
+ initialized they will be restored to their initial value.
-/* Grow the device tree adding either a specific device or
- alternativly a device found in the device table */
+ */
-INLINE_DEVICE(device *)device_tree_add_device
-(device *root,
- const char *prefix,
- device *new_sub_tree);
+EXTERN_DEVICE\
+(device *) device_tree_add_parsed
+(device *current,
+ const char *fmt,
+ ...) __attribute__ ((format (printf, 2, 3)));
-INLINE_DEVICE(device *) device_tree_add_found
-(device *root,
- const char *prefix,
- const char *name);
-INLINE_DEVICE(device *) device_tree_add_found_c
-(device *root,
- const char *prefix,
- const char *name,
- const char *c1);
+/* Initializing the created tree:
-INLINE_DEVICE(device *) device_tree_add_found_c_uw
-(device *root,
- const char *prefix,
- const char *name,
- const char *c1,
- unsigned_word uw2);
+ Once a device tree has been created the <<device_tree_init()>>
+ function is used to initialize it. The exact sequence of events
+ that occure during initialization are described separatly.
-INLINE_DEVICE(device *) device_tree_add_found_uw_u
-(device *root,
- const char *prefix,
- const char *name,
- unsigned_word uw1,
- unsigned u2);
+ */
-INLINE_DEVICE(device *) device_tree_add_found_uw_u_u
+INLINE_DEVICE\
+(void) device_tree_init
(device *root,
- const char *prefix,
- const char *name,
- unsigned_word uw1,
- unsigned u2,
- unsigned u3);
+ psim *system);
-INLINE_DEVICE(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(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);
+/* Relationships:
-INLINE_DEVICE(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);
+ 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).
+ */
-/* Query the device tree, null is returned if the specified device is
- not found */
+INLINE_DEVICE\
+(device *) device_parent
+(device *me);
-INLINE_DEVICE(device *) device_tree_find_device
-(device *root,
- const char *path);
+INLINE_DEVICE\
+(device *) device_sibling
+(device *me);
+INLINE_DEVICE\
+(device *) device_child
+(device *me);
-/* traverse the device tree visiting all notes (either pre or post
- fix) */
+INLINE_DEVICE\
+(const char *) device_name
+(device *me);
-typedef void (device_tree_traverse_function)
- (device *device,
- void *data);
+INLINE_DEVICE\
+(const char *) device_path
+(device *me);
-INLINE_DEVICE(void) device_tree_traverse
-(device *root,
- device_tree_traverse_function *prefix,
- device_tree_traverse_function *postfix,
- void *data);
+INLINE_DEVICE\
+(void *) device_data
+(device *me);
+INLINE_DEVICE\
+(psim *) device_system
+(device *me);
-/* dump a node, this can be passed to the device_tree_traverse()
- function to dump out the entire device tree */
+typedef struct _device_unit {
+ int nr_cells;
+ unsigned32 cells[4]; /* unused cells are zero */
+} device_unit;
-INLINE_DEVICE(void) device_tree_dump
-(device *device,
- void *ignore_data_argument);
+INLINE_DEVICE\
+(const device_unit *) device_unit_address
+(device *me);
+/* Properties:
-
-/* 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 a
+ for generic untyped data. */
typedef enum {
- integer_property,
+ array_property,
boolean_property,
+ ihandle_property,
+ integer_property,
string_property,
- array_property,
- null_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 */
+
+INLINE_DEVICE\
+(const device_property *) device_next_property
+(const device_property *previous);
-INLINE_DEVICE(const char *) device_find_next_property
+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. */
-/* INLINE_DEVICE void device_add_property
- No such external function, all properties, when added are explictly
- typed */
-INLINE_DEVICE(void) device_add_array_property
+INLINE_DEVICE\
+(void) device_set_array_property
(device *me,
const char *property,
const void *array,
int sizeof_array);
-INLINE_DEVICE(void) device_add_integer_property
+INLINE_DEVICE\
+(const device_property *) device_find_array_property
(device *me,
- const char *property,
- signed_word integer);
+ const char *property);
+
-INLINE_DEVICE(void) device_add_boolean_property
+#if 0
+INLINE_DEVICE\
+(void) device_set_boolean_property
(device *me,
const char *property,
int bool);
+#endif
-INLINE_DEVICE(void) device_add_null_property
+INLINE_DEVICE\
+(int) device_find_boolean_property
(device *me,
const char *property);
-INLINE_DEVICE(void) device_add_string_property
+
+#if 0
+INLINE_DEVICE\
+(void) device_set_ihandle_property
(device *me,
const char *property,
- const char *string);
-
-
-/* Locate a property returning its description. Return NULL if the
- named property is not found */
+ device_instance *ihandle);
+#endif
-INLINE_DEVICE(const device_property *) 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_traverse_properties
+#if 0
+INLINE_DEVICE\
+(void) device_set_integer_property
(device *me,
- device_traverse_property_function *traverse,
- void *data);
-
-
-/* Similar to above except that the property *must* be in the device
- tree and *must* be of the specified type. */
+ const char *property,
+ signed_word integer);
+#endif
-INLINE_DEVICE(const device_property *) device_find_array_property
+INLINE_DEVICE\
+(signed_word) device_find_integer_property
(device *me,
const char *property);
-INLINE_DEVICE(signed_word) device_find_integer_property
-(device *me,
- const char *property);
-INLINE_DEVICE(const char *) device_find_string_property
+#if 0
+INLINE_DEVICE\
+(void) device_set_string_property
(device *me,
- const char *property);
+ const char *property,
+ const char *string);
+#endif
-INLINE_DEVICE(int) device_find_boolean_property
+INLINE_DEVICE\
+(const char *) device_find_string_property
(device *me,
const char *property);
-
-/* Device Hardware:
+/* Instances:
- 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. */
-
-/* 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;
+ 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.
-
-/* Address attachement types */
-typedef enum _attach_type {
- attach_invalid,
- attach_callback,
- attach_default,
- attach_raw_memory,
-} attach_type;
-
-
-/* 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.
-
- 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.
+ This model includes methods that faciliate the creation of device
+ instance and (should a given device support it) standard operations
+ on those instances.
*/
-INLINE_DEVICE(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;
-INLINE_DEVICE(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);
-INLINE_DEVICE(void) device_init
+INLINE_DEVICE\
+(device_instance *) device_create_instance
(device *me,
- psim *system);
+ const char *device_specifier);
-/* initialize the entire tree */
+INLINE_DEVICE\
+(void) device_instance_delete
+(device_instance *instance);
-INLINE_DEVICE(void) 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\
+(unsigned_word) device_instance_claim
+(device_instance *instance,
+ unsigned_word address,
+ unsigned_word length,
+ unsigned_word alignment);
- Similarly, a device may initiate a data transfer (DMA) by passing
- such a request up to its parent.
+INLINE_DEVICE\
+(void) device_instance_release
+(device_instance *instance,
+ unsigned_word address,
+ unsigned_word length);
- Init:
+INLINE_DEVICE\
+(device *) device_instance_device
+(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.
+INLINE_DEVICE\
+(const char *) device_instance_path
+(device_instance *instance);
- 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.
+INLINE_DEVICE\
+(void *) device_instance_data
+(device_instance *instance);
- 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.
+/* Interrupts:
- * Any detach operation must exactly match a previous attach.
+ */
- * 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.
+/* Interrupt Source
- * at any time, at most one device can have a default mapping
- registered.
+ A device drives its interrupt line using the call
+ */
- IO:
+INLINE_DEVICE\
+(void) device_interrupt_event
+(device *me,
+ int my_port,
+ int value,
+ cpu *processor,
+ unsigned_word cia);
- A device receives requests to perform reads/writes to its registers
- or memory either A. from a processor or B. from a parent device.
+/* This interrupt event will then be propogated to any attached
+ interrupt destinations.
- 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.
+ 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.
- * 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.
- * 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.
+ Interrupt Destinations
- * Any exception situtation trigered by a non IO operation
- (processor == NULL) is handled buy returning 0.
+ 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. */
- * Transfers of size <= 8 and of a power of 2 *must* be correctly
- aligned and should be treated as a `single cycle' transfer.
+INLINE_DEVICE\
+(void) device_interrupt_attach
+(device *me,
+ int my_port,
+ device *dest,
+ int dest_port,
+ object_disposition disposition);
+
+INLINE_DEVICE\
+(void) device_interrupt_detach
+(device *me,
+ int my_port,
+ device *dest,
+ int dest_port);
- DMA:
+/* DESTINATION is attached (detached) to LINE of the device ME
- 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.
- 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.
-INLINE_DEVICE(void) device_attach_address
+ To convert to/from the symbolic and internal representation of a
+ port name/number. The following functions are available. */
+
+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);
-INLINE_DEVICE(void) 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);
+
-INLINE_DEVICE(unsigned) device_io_read_buffer
+/* Hardware operations:
+
+ */
+
+INLINE_DEVICE\
+(unsigned) device_io_read_buffer
(device *me,
void *dest,
int space,
@@ -438,7 +417,8 @@ INLINE_DEVICE(unsigned) device_io_read_buffer
cpu *processor,
unsigned_word cia);
-INLINE_DEVICE(unsigned) device_io_write_buffer
+INLINE_DEVICE\
+(unsigned) device_io_write_buffer
(device *me,
const void *source,
int space,
@@ -447,14 +427,23 @@ INLINE_DEVICE(unsigned) device_io_write_buffer
cpu *processor,
unsigned_word cia);
-INLINE_DEVICE(unsigned) 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);
-INLINE_DEVICE(unsigned) device_dma_write_buffer
+INLINE_DEVICE\
+(unsigned) device_dma_write_buffer
(device *me,
const void *source,
int space,
@@ -462,184 +451,180 @@ INLINE_DEVICE(unsigned) 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:
+/* 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;
- As mentioned above. Instead of handling an interrupt directly, a
- device may instead pass the need to interrupt on to its parent.
+/* Address attachement types */
+typedef enum _attach_type {
+ attach_invalid,
+ attach_raw_memory,
+ attach_callback,
+ /* ... */
+} attach_type;
- Init:
+INLINE_DEVICE\
+(void) device_attach_address
+(device *me,
+ const char *name,
+ attach_type attach,
+ int space,
+ unsigned_word addr,
+ unsigned nr_bytes,
+ access_type access,
+ device *who); /*callback/default*/
- 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:
+INLINE_DEVICE\
+(void) device_detach_address
+(device *me,
+ const char *name,
+ attach_type attach,
+ int space,
+ unsigned_word addr,
+ unsigned nr_bytes,
+ access_type access,
+ device *who); /*callback/default*/
- 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.
+/* Utilities:
*/
-INLINE_DEVICE(void) device_attach_interrupt
-(device *me,
- device *who,
- int interrupt_line,
- const char *name);
+/* IOCTL::
-INLINE_DEVICE(void) device_detach_interrupt
-(device *me,
- device *who,
- int interrupt_line,
- const char *name);
+ 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()>>.
-INLINE_DEVICE(void) device_interrupt
+ */
+
+EXTERN_DEVICE\
+(int) device_ioctl
(device *me,
- device *who,
- int interrupt_line,
- int interrupt_status,
cpu *processor,
- unsigned_word cia);
+ unsigned_word cia,
+ ...);
-INLINE_DEVICE(void) device_interrupt_ack
-(device *me,
- int interrupt_line,
- int interrupt_status);
+/* Error reporting::
-/* IOCTL:
+ 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
- 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. */
+ 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) device_ioctl
+(void volatile) device_error
(device *me,
- psim *system,
- cpu *processor,
- unsigned_word cia,
- ...);
-
+ const char *fmt,
+ ...) __attribute__ ((format (printf, 2, 3)));
-
-/* Device software - the instance
+/* Tree traversal::
- Under development
+ The entire device tree can be traversed using the
+ <<device_tree_traverse()>> function. The traversal can be in
+ either pre- or postfix order.
- 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 */
+ */
-#if 0
-INLINE_DEVICE(device_instance *)device_instance_open
-(device *me,
- const char *device_specifier);
+typedef void (device_tree_traverse_function)
+ (device *device,
+ void *data);
-INLINE_DEVICE(void) device_instance_close
-(device_instance *instance);
+INLINE_DEVICE\
+(void) device_tree_traverse
+(device *root,
+ device_tree_traverse_function *prefix,
+ device_tree_traverse_function *postfix,
+ void *data);
-INLINE_DEVICE(int) device_instance_read
-(device_instance *instance,
- void *addr,
- unsigned_word len);
+/* Device description::
-INLINE_DEVICE(int) device_instance_write
-(device_instance *instance,
- const void *addr,
- unsigned_word len);
+ */
-INLINE_DEVICE(int) device_instance_seek
-(device_instance *instance,
- unsigned_word pos_hi,
- unsigned_word pos_lo);
+INLINE_DEVICE\
+(void) device_tree_print_device
+(device *device,
+ void *ignore_data_argument);
-INLINE_DEVICE(device *) device_instance_device
-(device_instance *instance);
-INLINE_DEVICE(const char *) device_instance_name
-(device_instance *instance);
-#endif
+/* Tree lookup::
+ The function <<device_tree_find_device()>> will attempt to locate
+ the specified device within the tree. If the device is not found a
+ NULL device is returned.
+ */
-
-/* Device dregs... */
+INLINE_DEVICE\
+(device *) device_tree_find_device
+(device *root,
+ const char *path);
-/* Parse a device name, various formats:
- uw: unsigned_word
- u: unsigned
- c: string */
+/* Device list or usage::
-INLINE_DEVICE(int) scand_c
-(const char *name,
- char *c1,
- unsigned c1size);
+ The <<device_usage()>> function outputs a list of all the devices
+ compiled into PSIM. The verbose option will result in additional
+ information being printed (for instance, the interrupt ports).
-INLINE_DEVICE(int) scand_c_uw_u
-(const char *name,
- char *c1,
- unsigned c1size,
- unsigned_word *uw2,
- unsigned *u3);
-
-INLINE_DEVICE(int) scand_uw
-(const char *name,
- unsigned_word *uw1);
-
-INLINE_DEVICE(int) scand_uw_c
-(const char *name,
- unsigned_word *uw1,
- char *c2,
- unsigned c2size);
-
-INLINE_DEVICE(int) scand_uw_u
-(const char *name,
- unsigned_word *uw1,
- unsigned *u2);
-
-INLINE_DEVICE(int) scand_uw_u_u
-(const char *name,
- unsigned_word *uw1,
- unsigned *u2,
- unsigned *u3);
-
-INLINE_DEVICE(int) scand_uw_u_u_c
-(const char *name,
- unsigned_word *uw1,
- unsigned *u2,
- unsigned *u3,
- char *c4,
- unsigned c4size);
-
-INLINE_DEVICE(int) scand_uw_uw
-(const char *name,
- unsigned_word *uw1,
- unsigned_word *uw2);
-
-INLINE_DEVICE(int) scand_uw_uw_u
-(const char *name,
- unsigned_word *uw1,
- unsigned_word *uw2,
- unsigned *u3);
-
-INLINE_DEVICE(int) scand_uw_uw_u_u_c
-(const char *name,
- unsigned_word *uw1,
- unsigned_word *uw2,
- unsigned *u3,
- unsigned *u4,
- char *c5,
- unsigned c5size);
-
-INLINE_DEVICE(int) 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_DEVICE\
+(void) device_usage
+(int verbose);
+
+
+/* External representation:
+
+ 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.
+
+ 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,
+ unsigned32 phandle);
+
+INLINE_DEVICE\
+(unsigned32) device_to_external
+(device *me);
+
+INLINE_DEVICE\
+(device_instance *) external_to_device_instance
+(device *tree_member,
+ unsigned32 ihandle);
+
+INLINE_DEVICE\
+(unsigned32) device_instance_to_external
+(device_instance *me);
+
+#endif /* _DEVICE_H_ */