X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sim%2Fppc%2Fdevice.h;h=56c8ce54d990d1c7f491802b199b20b1e5a03839;hb=30727aa6d12fb866494020c0b62ab265a2bdcdfe;hp=f5d513633f8bdddb58cdc3732a2c2dc315960704;hpb=93fac32455bb5f7277b85fec5ead13f7abb9fde8;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/ppc/device.h b/sim/ppc/device.h index f5d513633f..56c8ce54d9 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 + Copyright (C) 1994-1997, Andrew Cagney 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,424 +19,582 @@ */ -#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 <> and <>. -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: - -/* 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__property(device *, const char *, ) + void device_add_*_array_property(device *, const char *, const *, int) + void device_set_*_property(device *, const char *, ) + void device_set_*_array_property(device *, const char *, const *, int) + device_find_*_property(device *, const char *) + int device_find_*_array_property(device *, const char *, int, *) + + */ + -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); - -/* 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 <>. - 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, ...); - - -/* 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 <> 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); - -/* 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_ */