1 /* This file is part of the program psim.
3 Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, see <http://www.gnu.org/licenses/>.
28 /* declared in basics.h, this object is used everywhere */
29 /* typedef struct _device device; */
34 As explained in earlier sections, the device, device instance,
35 property and interrupts lie at the heart of PSIM's device model.
37 In the below a synopsis of the device object and the operations it
38 supports are given. Details of this object can be found in the
39 files <<device.h>> and <<device.c>>.
44 /* Device creation: */
47 (device
*) device_create
51 const char *unit_address
,
59 /* Device initialization: */
67 (void) device_init_static_properties
72 (void) device_init_address
77 (void) device_init_runtime_properties
82 (void) device_init_data
89 A device is able to determine its relationship to other devices
90 within the tree. Operations include querying for a devices parent,
91 sibling, child, name, and path (from the root).
96 (device
*) device_parent
100 (device
*) device_root
104 (device
*) device_sibling
108 (device
*) device_child
112 (const char *) device_name
116 (const char *) device_base
120 (const char *) device_path
128 (psim
*) device_system
131 typedef struct _device_unit
{
133 unsigned_cell cells
[4]; /* unused cells are zero */
137 (const device_unit
*) device_unit_address
141 (int) device_decode_unit
144 device_unit
*address
);
147 (int) device_encode_unit
149 const device_unit
*unit_address
,
154 /* Convert an Open Firmware size into a form suitable for attach
157 Return a zero result if the address should be ignored when looking
158 for attach addresses */
161 (int) device_address_to_attach_address
163 const device_unit
*address
,
165 unsigned_word
*attach_address
,
169 /* Convert an Open Firmware size into a form suitable for attach
172 Return a zero result if the address should be ignored */
175 (int) device_size_to_attach_size
177 const device_unit
*size
,
183 (unsigned) device_nr_address_cells
187 (unsigned) device_nr_size_cells
193 Attached to a device are a number of properties. Each property has
194 a size and type (both of which can be queried). A device is able
195 to iterate over or query and set a properties value.
199 /* The following are valid property types. The property `array' is
200 for generic untyped data. */
205 ihandle_property
, /*runtime*/
207 range_array_property
,
210 string_array_property
,
211 } device_property_type
;
213 typedef struct _device_property device_property
;
214 struct _device_property
{
217 device_property_type type
;
218 unsigned sizeof_array
;
220 const device_property
*original
;
221 object_disposition disposition
;
225 /* iterate through the properties attached to a device */
228 (const device_property
*) device_next_property
229 (const device_property
*previous
);
232 (const device_property
*) device_find_property
234 const char *property
); /* NULL for first property */
237 /* Manipulate the properties belonging to a given device.
239 SET on the other hand will force the properties value. The
240 simulation is aborted if the property was present but of a
243 FIND returns the specified properties value, aborting the
244 simulation if the property is missing. Code locating a property
245 should first check its type (using device_find_property above) and
246 then obtain its value using the below.
248 void device_add_<type>_property(device *, const char *, <type>)
249 void device_add_*_array_property(device *, const char *, const <type>*, int)
250 void device_set_*_property(device *, const char *, <type>)
251 void device_set_*_array_property(device *, const char *, const <type>*, int)
252 <type> device_find_*_property(device *, const char *)
253 int device_find_*_array_property(device *, const char *, int, <type>*)
259 (void) device_add_array_property
261 const char *property
,
266 (void) device_set_array_property
268 const char *property
,
273 (const device_property
*) device_find_array_property
275 const char *property
);
280 (void) device_add_boolean_property
282 const char *property
,
286 (int) device_find_boolean_property
288 const char *property
);
292 typedef struct _ihandle_runtime_property_spec
{
293 const char *full_path
;
294 } ihandle_runtime_property_spec
;
297 (void) device_add_ihandle_runtime_property
299 const char *property
,
300 const ihandle_runtime_property_spec
*ihandle
);
303 (void) device_find_ihandle_runtime_property
305 const char *property
,
306 ihandle_runtime_property_spec
*ihandle
);
309 (void) device_set_ihandle_property
311 const char *property
,
312 device_instance
*ihandle
);
315 (device_instance
*) device_find_ihandle_property
317 const char *property
);
322 (void) device_add_integer_property
324 const char *property
,
325 signed_cell integer
);
328 (signed_cell
) device_find_integer_property
330 const char *property
);
333 (int) device_find_integer_array_property
335 const char *property
,
337 signed_cell
*integer
);
341 typedef struct _range_property_spec
{
342 device_unit child_address
;
343 device_unit parent_address
;
345 } range_property_spec
;
348 (void) device_add_range_array_property
350 const char *property
,
351 const range_property_spec
*ranges
,
355 (int) device_find_range_array_property
357 const char *property
,
359 range_property_spec
*range
);
363 typedef struct _reg_property_spec
{
369 (void) device_add_reg_array_property
371 const char *property
,
372 const reg_property_spec
*reg
,
376 (int) device_find_reg_array_property
378 const char *property
,
380 reg_property_spec
*reg
);
385 (void) device_add_string_property
387 const char *property
,
391 (const char *) device_find_string_property
393 const char *property
);
397 typedef const char *string_property_spec
;
400 (void) device_add_string_array_property
402 const char *property
,
403 const string_property_spec
*strings
,
404 unsigned nr_strings
);
407 (int) device_find_string_array_property
409 const char *property
,
411 string_property_spec
*string
);
416 (void) device_add_duplicate_property
418 const char *property
,
419 const device_property
*original
);
425 As with IEEE1275, a device can be opened, creating an instance.
426 Instances provide more abstract interfaces to the underlying
427 hardware. For example, the instance methods for a disk may include
428 code that is able to interpret file systems found on disks. Such
429 methods would there for allow the manipulation of files on the
430 disks file system. The operations would be implemented using the
431 basic block I/O model provided by the disk.
433 This model includes methods that faciliate the creation of device
434 instance and (should a given device support it) standard operations
439 typedef struct _device_instance_callbacks device_instance_callbacks
;
442 (device_instance
*) device_create_instance_from
443 (device
*me
, /*OR*/ device_instance
*parent
,
447 const device_instance_callbacks
*callbacks
);
450 (device_instance
*) device_create_instance
452 const char *full_path
,
456 (void) device_instance_delete
457 (device_instance
*instance
);
460 (int) device_instance_read
461 (device_instance
*instance
,
466 (int) device_instance_write
467 (device_instance
*instance
,
472 (int) device_instance_seek
473 (device_instance
*instance
,
474 unsigned_word pos_hi
,
475 unsigned_word pos_lo
);
478 (int) device_instance_call_method
479 (device_instance
*instance
,
482 unsigned_cell stack_args
[/*n_stack_args*/],
484 unsigned_cell stack_returns
[/*n_stack_returns*/]);
487 (device
*) device_instance_device
488 (device_instance
*instance
);
491 (const char *) device_instance_path
492 (device_instance
*instance
);
495 (void *) device_instance_data
496 (device_instance
*instance
);
505 A device drives its interrupt line using the call
510 (void) device_interrupt_event
517 /* This interrupt event will then be propogated to any attached
518 interrupt destinations.
520 Any interpretation of PORT and VALUE is model dependant. However
521 as guidelines the following are recommended: PCI interrupts a-d
522 correspond to lines 0-3; level sensative interrupts be requested
523 with a value of one and withdrawn with a value of 0; edge sensative
524 interrupts always have a value of 1, the event its self is treated
528 Interrupt Destinations
530 Attached to each interrupt line of a device can be zero or more
531 desitinations. These destinations consist of a device/port pair.
532 A destination is attached/detached to a device line using the
533 attach and detach calls. */
536 (void) device_interrupt_attach
541 object_disposition disposition
);
544 (void) device_interrupt_detach
550 typedef void (device_interrupt_traverse_function
)
558 (void) device_interrupt_traverse
560 device_interrupt_traverse_function
*handler
,
564 /* DESTINATION is attached (detached) to LINE of the device ME
569 Users refer to interrupt port numbers symbolically. For instance a
570 device may refer to its `INT' signal which is internally
571 represented by port 3.
573 To convert to/from the symbolic and internal representation of a
574 port name/number. The following functions are available. */
577 (int) device_interrupt_decode
579 const char *symbolic_name
,
580 port_direction direction
);
583 (int) device_interrupt_encode
588 port_direction direction
);
591 /* Hardware operations:
596 (unsigned) device_io_read_buffer
606 (unsigned) device_io_write_buffer
616 /* Conversly, the device pci1000,1@1 my need to perform a dma transfer
617 into the cpu/memory core. Just as I/O moves towards the leaves,
618 dma transfers move towards the core via the initiating devices
619 parent nodes. The root device (special) converts the DMA transfer
620 into reads/writes to memory */
623 (unsigned) device_dma_read_buffer
631 (unsigned) device_dma_write_buffer
637 int violate_read_only_section
);
639 /* To avoid the need for an intermediate (bridging) node to ask each
640 of its child devices in turn if an IO access is intended for them,
641 parent nodes maintain a table mapping addresses directly to
642 specific devices. When a device is `connected' to its bus it
643 attaches its self to its parent. */
645 /* Address access attributes */
646 typedef enum _access_type
{
650 access_read_write
= 3,
652 access_read_exec
= 5,
653 access_write_exec
= 6,
654 access_read_write_exec
= 7,
657 /* Address attachement types */
658 typedef enum _attach_type
{
666 (void) device_attach_address
673 device
*client
); /*callback/default*/
676 (void) device_detach_address
683 device
*client
); /*callback/default*/
691 Often devices require `out of band' operations to be performed.
692 For instance a pal device may need to notify a PCI bridge device
693 that an interrupt ack cycle needs to be performed on the PCI bus.
694 Within PSIM such operations are performed by using the generic
695 ioctl call <<device_ioctl()>>.
700 device_ioctl_break
, /* unsigned_word requested_break */
701 device_ioctl_set_trace
, /* void */
702 device_ioctl_create_stack
, /* unsigned_word *sp, char **argv, char **envp */
703 device_ioctl_change_media
, /* const char *new_image (possibly NULL) */
704 nr_device_ioctl_requests
,
705 } device_ioctl_request
;
712 device_ioctl_request request
,
718 So that errors originating from devices appear in a consistent
719 format, the <<device_error()>> function can be used. Formats and
720 outputs the error message before aborting the simulation
722 Devices should use this function to abort the simulation except
723 when the abort reason leaves the simulation in a hazardous
724 condition (for instance a failed malloc).
732 ...) __attribute__ ((format (printf
, 2, 3)));
740 /* External representation:
742 Both device nodes and device instances, in OpenBoot firmware have
743 an external representation (phandles and ihandles) and these values
744 are both stored in the device tree in property nodes and passed
745 between the client program and the simulator during emulation
748 To limit the potential risk associated with trusing `data' from the
749 client program, the following mapping operators `safely' convert
750 between the two representations
755 (device
*) external_to_device
756 (device
*tree_member
,
757 unsigned_cell phandle
);
760 (unsigned_cell
) device_to_external
764 (device_instance
*) external_to_device_instance
765 (device
*tree_member
,
766 unsigned_cell ihandle
);
769 (unsigned_cell
) device_instance_to_external
770 (device_instance
*me
);
775 The device inherets certain event queue operations from the main
778 typedef void device_event_handler(void *data
);
781 (event_entry_tag
) device_event_queue_schedule
784 device_event_handler
*handler
,
788 (void) device_event_queue_deschedule
790 event_entry_tag event_to_remove
);
793 (signed64
) device_event_queue_time
796 #endif /* _DEVICE_H_ */