New simulator changes from Andrew
[deliverable/binutils-gdb.git] / sim / ppc / device.maybe
1 /* This file is part of the program psim.
2
3 Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
4
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 2 of the License, or
8 (at your option) any later version.
9
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.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20
21
22 #ifndef _DEVICE_H_
23 #define _DEVICE_H_
24
25 #ifndef INLINE_DEVICE
26 #define INLINE_DEVICE
27 #endif
28
29 /* declared in basics.h, this object is used everywhere */
30 /* typedef struct _device device; */
31
32
33 /* Device templates:
34
35 *** THIS SECTION DESCRIBES HOW A DEVICE HAS A STATIC AND DYNAMIC
36 COMPONENT ** on the device in the tree is dynamic. *****
37
38 A device node is created from its template. The only valid
39 operation on a template is to create a device node from it: */
40
41 INLINE_DEVICE\
42 (device *) device_template_create_device
43 (device *parent,
44 const char *name,
45 const char *unit_address,
46 const char *args);
47
48 /* The create is paramaterized by both the devices unit address (a
49 string that is converted into numeric form by the devices parent)
50 and optionally extra argument information.
51
52 The actual device node is constructed by a number of pieces provided
53 by the template function: */
54
55 typedef struct _device_callbacks device_callbacks;
56
57 INLINE_DEVICE\
58 (device *) device_create_from
59 (const char *name,
60 const device_unit *unit_address,
61 void *data,
62 const device_callbacks *callbacks,
63 device *parent);
64
65 /* OpenBoot discusses the creation of packages (devices). */
66
67
68 /* Devices:
69
70 As with OpenBoot, all nodes in the device tree are considered to be
71 devices. Each node then has associated with it a number of methods
72 and properties (duscussed later).
73
74 OpenBoot documentation refers to devices, device nodes, packages,
75 package instances, methods, static methods and properties. This
76 device implementation uses its own termonology. Where ever it
77 exists, the notes will indicate a correspondance between PSIM terms
78 and those found in OpenBoot.
79
80 device:
81
82 A device is the basic building block in this model. A device can
83 be further categorized into one of three classes - template, node
84 and instance.
85
86 device-node (aka device):
87
88 The device tree is constructed from device-nodes. Each node has
89 both local state (data), a relationship with the device nodes
90 around it and an address (unit-address) on the parents bus `bus' */
91
92 INLINE_DEVICE\
93 (device *) device_parent
94 (device *me);
95
96 INLINE_DEVICE\
97 (device *) device_sibling
98 (device *me);
99
100 INLINE_DEVICE\
101 (device *) device_child
102 (device *me);
103
104 INLINE_DEVICE\
105 (const char *) device_name
106 (device *me);
107
108 INLINE_DEVICE\
109 (const char *) device_path
110 (device *me);
111
112 INLINE_DEVICE\
113 (void *) device_data
114 (device *me);
115
116 INLINE_DEVICE\
117 (psim *) device_system
118 (device *me);
119
120 typedef struct _device_unit {
121 int nr_cells;
122 unsigned32 cells[4]; /* unused cells are zero */
123 } device_unit;
124
125 INLINE_DEVICE\
126 (const device_unit *) device_unit_address
127 (device *me);
128
129 /* Each device-node normally corresponds to a hardware component of
130 the system being modeled. Leaf nodes matching external devices and
131 intermediate nodes matching bridges and controllers.
132
133 Device nodes also support methods that are an abstraction of the
134 transactions that occure in real hardware. These operations
135 (io/dma read/writes and interrupts) are discussed separatly.
136
137 OpenBoot refers to device nodes by many names. The most common are
138 device, device node and package. */
139
140
141 /* Properties:
142
143 In IEEE1275 many of the the characteristics of a device are stored
144 in the device tree as properties. Each property consists of a name
145 and an associated (implicitly typed) value. A device will have a
146 list of properties attached to it. The user is able to manipulate
147 the list, adding and removing properties and set/modify the value
148 of each property.
149
150 PSIM's device tree follows this model but with the addition of
151 strongly typing each property's value. The simulator will detect
152 at run time, the incorrect use of a property.
153
154 In addition to the standard use of properties, Both PSIM and
155 individual devices will use properties to record simulation
156 configuration information. For instance, a disk device might store
157 in a string property called <<file>> the name of the file that
158 contains the disk image to use. */
159
160 /* The following are valid property types. The property `array' is a
161 for generic untyped data. */
162
163 typedef enum {
164 array_property,
165 boolean_property,
166 ihandle_property,
167 integer_property,
168 string_property,
169 } device_property_type;
170
171 typedef struct _device_property device_property;
172 struct _device_property {
173 device *owner;
174 const char *name;
175 device_property_type type;
176 unsigned sizeof_array;
177 const void *array;
178 const device_property *original;
179 object_disposition disposition;
180 };
181
182
183 /* iterate through the properties attached to a device */
184
185 INLINE_DEVICE\
186 (const device_property *) device_next_property
187 (const device_property *previous);
188
189 INLINE_DEVICE\
190 (const device_property *) device_find_property
191 (device *me,
192 const char *property); /* NULL for first property */
193
194
195 /* Manipulate the properties belonging to a given device.
196
197 SET on the other hand will force the properties value. The
198 simulation is aborted if the property was present but of a
199 conflicting type.
200
201 FIND returns the specified properties value, aborting the
202 simulation if the property is missing. Code locating a property
203 should first check its type (using device_find_property above) and
204 then obtain its value using the below. */
205
206
207 INLINE_DEVICE\
208 (void) device_set_array_property
209 (device *me,
210 const char *property,
211 const void *array,
212 int sizeof_array);
213
214 INLINE_DEVICE\
215 (const device_property *) device_find_array_property
216 (device *me,
217 const char *property);
218
219
220 #if 0
221 INLINE_DEVICE\
222 (void) device_set_boolean_property
223 (device *me,
224 const char *property,
225 int bool);
226 #endif
227
228 INLINE_DEVICE\
229 (int) device_find_boolean_property
230 (device *me,
231 const char *property);
232
233
234 #if 0
235 INLINE_DEVICE\
236 (void) device_set_ihandle_property
237 (device *me,
238 const char *property,
239 device_instance *ihandle);
240 #endif
241
242 INLINE_DEVICE\
243 (device_instance *) device_find_ihandle_property
244 (device *me,
245 const char *property);
246
247
248 #if 0
249 INLINE_DEVICE\
250 (void) device_set_integer_property
251 (device *me,
252 const char *property,
253 signed_word integer);
254 #endif
255
256 INLINE_DEVICE\
257 (signed_word) device_find_integer_property
258 (device *me,
259 const char *property);
260
261
262 #if 0
263 INLINE_DEVICE\
264 (void) device_set_string_property
265 (device *me,
266 const char *property,
267 const char *string);
268 #endif
269
270 INLINE_DEVICE\
271 (const char *) device_find_string_property
272 (device *me,
273 const char *property);
274
275
276 /* Instances:
277
278 As with IEEE1275, a device can be opened, creating an instance.
279 Instances provide more abstract interfaces to the underlying
280 hardware. For example, the instance methods for a disk may include
281 code that is able to interpret file systems found on disks. Such
282 methods would there for allow the manipulation of files on the
283 disks file system. The operations would be implemented using the
284 basic block I/O model provided by the disk.
285
286 This model includes methods that faciliate the creation of device
287 instance and (should a given device support it) standard operations
288 on those instances. */
289
290 *** device-instance ***
291
292 Devices support an abstract I/O model. A unique I/O instance can be
293 created from a device node and then this instance used to perform
294 I/O that is independant of other instances. */
295
296 typedef struct _device_instance_callbacks device_instance_callbacks;
297
298 INLINE_DEVICE\
299 (device_instance *) device_create_instance_from
300 (device *me, /*OR*/ device_instance *parent,
301 void *data,
302 const char *path,
303 const char *args,
304 const device_instance_callbacks *callbacks);
305
306 INLINE_DEVICE\
307 (device_instance *) device_create_instance
308 (device *me,
309 const char *device_specifier);
310
311 INLINE_DEVICE\
312 (void) device_instance_delete
313 (device_instance *instance);
314
315 INLINE_DEVICE\
316 (int) device_instance_read
317 (device_instance *instance,
318 void *addr,
319 unsigned_word len);
320
321 INLINE_DEVICE\
322 (int) device_instance_write
323 (device_instance *instance,
324 const void *addr,
325 unsigned_word len);
326
327 INLINE_DEVICE\
328 (int) device_instance_seek
329 (device_instance *instance,
330 unsigned_word pos_hi,
331 unsigned_word pos_lo);
332
333 INLINE_DEVICE\
334 (unsigned_word) device_instance_claim
335 (device_instance *instance,
336 unsigned_word address,
337 unsigned_word length,
338 unsigned_word alignment);
339
340 INLINE_DEVICE\
341 (void) device_instance_release
342 (device_instance *instance,
343 unsigned_word address,
344 unsigned_word length);
345
346 INLINE_DEVICE\
347 (device *) device_instance_device
348 (device_instance *instance);
349
350 INLINE_DEVICE\
351 (const char *) device_instance_path
352 (device_instance *instance);
353
354 INLINE_DEVICE\
355 (void *) device_instance_data
356 (device_instance *instance);
357
358 /* A device instance can be marked (when created) as being permenant.
359 Such instances are assigned a reserved address and are *not*
360 deleted between simulation runs.
361
362 OpenBoot refers to a device instace as a package instance */
363
364
365 /* PIO:
366
367 *** DESCRIBE HERE WHAT A PIO OPERATION IS and how, broadly it is
368 modeled ****
369
370
371 During initialization, each device attaches its self to is parent
372 registering the address spaces that it is interested in:
373
374 a. The <<com>> device attaches its self to its parent <<phb>>
375 device at address <<0x3f8>> through to address <<0x3f8 + 16>>.
376
377 b. The <<phb>> has in turn attached its self to addresses
378 <<0xf0000000 .. 0xf0100000>>.
379
380 During the execution of the simulation propper, the following then
381 occure:
382
383 1. After any virtual to physical translation, the processor
384 passes the address to be read (or written to the core device).
385 (eg address 0xf00003f8).
386
387 2. The core device then looks up the specified addresses in its
388 address to device map, determines that in this case the address
389 belongs to the phb and passes it down.
390
391 3. The <<phb>> in turn determines that the address belongs to the
392 serial port and passes to that device the request for an access
393 to location <<0x3f8>>.
394
395 @figure mio
396
397 */
398
399 /* Device Hardware
400
401 This model assumes that the data paths of the system being modeled
402 have a tree topology. That is, one or more processors sit at the
403 top of a tree. That tree containing leaf nodes (real devices) and
404 branch nodes (bridges).
405
406 For instance, consider the tree:
407
408 /pci # PCI-HOST bridge
409 /pci/pci1000,1@1 # A pci controller
410 /pci/isa8086 # PCI-ISA bridge
411 /pci/isa8086/fdc@300 # floppy disk controller on ISA bus
412
413 A processor needing to access the device fdc@300 on the ISA bus
414 would do so using a data path that goes through the pci-host bridge
415 (pci)and the isa-pci bridge (isa8086) to finally reach the device
416 fdc@300. As the data transfer passes through each intermediate
417 bridging node that bridge device is able to (just like with real
418 hardware) manipulate either the address or data involved in the
419 transfer. */
420
421 INLINE_DEVICE\
422 (unsigned) device_io_read_buffer
423 (device *me,
424 void *dest,
425 int space,
426 unsigned_word addr,
427 unsigned nr_bytes,
428 cpu *processor,
429 unsigned_word cia);
430
431 INLINE_DEVICE\
432 (unsigned) device_io_write_buffer
433 (device *me,
434 const void *source,
435 int space,
436 unsigned_word addr,
437 unsigned nr_bytes,
438 cpu *processor,
439 unsigned_word cia);
440
441 /* To avoid the need for an intermediate (bridging) node to ask each
442 of its child devices in turn if an IO access is intended for them,
443 parent nodes maintain a table mapping addresses directly to
444 specific devices. When a device is `connected' to its bus it
445 attaches its self to its parent. */
446
447 /* Address access attributes */
448 typedef enum _access_type {
449 access_invalid = 0,
450 access_read = 1,
451 access_write = 2,
452 access_read_write = 3,
453 access_exec = 4,
454 access_read_exec = 5,
455 access_write_exec = 6,
456 access_read_write_exec = 7,
457 } access_type;
458
459 /* Address attachement types */
460 typedef enum _attach_type {
461 attach_invalid,
462 attach_raw_memory,
463 attach_callback,
464 /* ... */
465 } attach_type;
466
467 INLINE_DEVICE\
468 (void) device_attach_address
469 (device *me,
470 const char *name,
471 attach_type attach,
472 int space,
473 unsigned_word addr,
474 unsigned nr_bytes,
475 access_type access,
476 device *who); /*callback/default*/
477
478 INLINE_DEVICE\
479 (void) device_detach_address
480 (device *me,
481 const char *name,
482 attach_type attach,
483 int space,
484 unsigned_word addr,
485 unsigned nr_bytes,
486 access_type access,
487 device *who); /*callback/default*/
488
489 /* where the attached address space can be any of
490
491 callback - all accesses to that range of addresses are past on to
492 the attached child device. The callback addresses are ordered
493 according to the callback level (attach_callback, .. + 1, .. + 2,
494 ...). Lower levels are searched first. This facilitates the
495 implementation of more unusual addressing schema such as
496 subtractive decoding (as seen on the PCI bus). Within a given
497 callback level addresses must not overlap.
498
499 memory - the specified address space contains RAM, the node that is
500 having the ram attached is responsible for allocating space for and
501 maintaining that space. The device initiating the attach will not
502 be notified of accesses to such an attachement.
503
504 The memory attachment is very important. By giving the parent node
505 the responsability (and freedom) of managing the RAM, that node is
506 able to implement memory spaces more efficiently. For instance it
507 could `cache' accesses or merge adjacent memory areas.
508
509
510 In addition to I/O and DMA, devices interact with the rest of the
511 system via interrupts. Interrupts are discussed separatly. */
512
513
514 /* DMA:
515
516 *** DESCRIBE HERE WHAT A DMA OPERATION IS AND HOW IT IS MODELED,
517 include an interation of an access being reflected back down ***
518
519 */
520
521 /* Conversly, the device pci1000,1@1 my need to perform a dma transfer
522 into the cpu/memory core. Just as I/O moves towards the leaves,
523 dma transfers move towards the core via the initiating devices
524 parent nodes. The root device (special) converts the DMA transfer
525 into reads/writes to memory */
526
527 INLINE_DEVICE\
528 (unsigned) device_dma_read_buffer
529 (device *me,
530 void *dest,
531 int space,
532 unsigned_word addr,
533 unsigned nr_bytes);
534
535 INLINE_DEVICE\
536 (unsigned) device_dma_write_buffer
537 (device *me,
538 const void *source,
539 int space,
540 unsigned_word addr,
541 unsigned nr_bytes,
542 int violate_read_only_section);
543
544
545 /* Interrupts:
546
547 *** DESCRIBE HERE THE INTERRUPT NETWORK ***
548
549 PSIM models interrupts and their wiring as a directed graph of
550 connections between interrupt sources and destinations. The source
551 and destination are both a tupple consisting of a port number and
552 device. Both multiple destinations attached to a single source and
553 multiple sources attached to a single destination are allowed.
554
555 When a device drives an interrupt port with multiple destinations a
556 broadcast of that interrupt event (message to all destinations)
557 occures. Each of those destination (device/port) are able to
558 further propogate the interrupt until it reaches its ultimate
559 destination.
560
561 Normally an interrupt source would be a model of a real device
562 (such as a keyboard) while an interrupt destination would be an
563 interrupt controller. The facility that allows an interrupt to be
564 delivered to multiple devices and to be propogated from device to
565 device was designed to support the requirements specified by
566 OpenPIC (ISA interrupts go to both OpenPIC and 8259), CHRP (8259
567 connected to OpenPIC) and hardware designs such as PCI-PCI
568 bridges. */
569
570
571 /* Interrupting a processor
572
573 The cpu object provides methods for delivering external interrupts
574 to a given processor.
575
576 The problem of synchronizing external interrupt delivery with the
577 execution of the cpu is handled internally by the processor object. */
578
579
580
581 /* Interrupt Source
582
583 A device drives its interrupt line using the call: */
584
585 INLINE_DEVICE\
586 (void) device_interrupt_event
587 (device *me,
588 int my_port,
589 int value,
590 cpu *processor,
591 unsigned_word cia);
592
593 /* This interrupt event will then be propogated to any attached
594 interrupt destinations.
595
596 Any interpretation of PORT and VALUE is model dependant. However
597 as guidelines the following are recommended: PCI interrupts a-d
598 correspond to lines 0-3; level sensative interrupts be requested
599 with a value of one and withdrawn with a value of 0; edge sensative
600 interrupts always have a value of 1, the event its self is treated
601 as the interrupt.
602
603
604 Interrupt Destinations
605
606 Attached to each interrupt line of a device can be zero or more
607 desitinations. These destinations consist of a device/port pair.
608 A destination is attached/detached to a device line using the
609 attach and detach calls. */
610
611 INLINE_DEVICE\
612 (void) device_interrupt_attach
613 (device *me,
614 int my_port,
615 device *dest,
616 int dest_port,
617 object_disposition disposition);
618
619 INLINE_DEVICE\
620 (void) device_interrupt_detach
621 (device *me,
622 int my_port,
623 device *dest,
624 int dest_port);
625
626 /* DESTINATION is attached (detached) to LINE of the device ME
627
628
629 Interrupt conversion
630
631 Users refer to interrupt port numbers symbolically. For instance a
632 device may refer to its `INT' signal which is internally
633 represented by port 3.
634
635 To convert to/from the symbolic and internal representation of a
636 port name/number. The following functions are available. */
637
638 INLINE_DEVICE\
639 (int) device_interrupt_decode
640 (device *me,
641 const char *symbolic_name);
642
643 INLINE_DEVICE\
644 (int) device_interrupt_encode
645 (device *me,
646 int port_number,
647 char *buf,
648 int sizeof_buf);
649
650
651
652 /* Initialization:
653
654 In PSIM, the device tree is created and then initialized in stages.
655 When using devices it is important to be clear what initialization
656 the simulator assumes is being performed during each of these
657 stages.
658
659 Firstly, each device is created in isolation (using the create from
660 template method). Only after it has been created will a device be
661 inserted into the tree ready for initialization.
662
663 Once the tree is created, it is initialized as follows:
664
665 1. All properties (apart from those containing instances)
666 are (re)initialized
667
668 2. Any interrupts addeded as part of the simulation run
669 are removed.
670
671 4. The initialize address method of each device (in top
672 down order) is called. At this stage the device
673 is expected to:
674
675 o Clear address maps and delete allocated memory
676 associated with the devices children.
677
678 o (Re)attach its own addresses to its parent device.
679
680 o Ensure that it is otherwize sufficiently
681 initialized such that it is ready for a
682 device instance create call.
683
684 5. All properties containing an instance of
685 a device are (re)initialized
686
687 6. The initialize data method for each device is called (in
688 top down) order. At this stage the device is expected to:
689
690 o Perform any needed data transfers. Such
691 transfers would include the initialization
692 of memory created during the address initialization
693 stage using DMA.
694
695 */
696
697 INLINE_DEVICE\
698 (void) device_tree_init
699 (device *root,
700 psim *system);
701
702
703
704 /* IOCTL:
705
706 Very simply, a catch all for any thing that turns up that until now
707 either hasn't been thought of or doesn't justify an extra function. */
708
709 EXTERN_DEVICE\
710 (int) device_ioctl
711 (device *me,
712 cpu *processor,
713 unsigned_word cia,
714 ...);
715
716
717 /* External communcation:
718
719 Devices interface to the external environment */
720
721 /* device_error() reports the problem to the console and aborts the
722 simulation. The error message is prefixed with the name of the
723 reporting device. */
724
725 EXTERN_DEVICE\
726 (void volatile) device_error
727 (device *me,
728 const char *fmt,
729 ...) __attribute__ ((format (printf, 2, 3)));
730
731
732 /* Tree utilities:
733
734 In addition to the standard method of creating a device from a
735 device template, the following sortcuts can be used.
736
737 Create a device or property from a textual representation */
738
739 EXTERN_DEVICE\
740 (device *) device_tree_add_parsed
741 (device *current,
742 const char *fmt,
743 ...) __attribute__ ((format (printf, 2, 3)));
744
745 /* where FMT,... once formatted (using vsprintf) is used to locate and
746 create either a device or property. Its syntax is almost identical
747 to that used in OpenBoot documentation - the only extension is in
748 allowing properties and their values to be specified vis:
749
750 "/pci/pci1000,1@1/disk@0,0"
751
752 Path:
753
754 The path to a device or property can either be absolute (leading
755 `/') or relative (leading `.' or `..'). Relative paths start from
756 the CURRENT node. The new current node is returned as the result.
757 In addition, a path may start with a leading alias (resolved by
758 looking in /aliases).
759
760 Device name:
761
762 <name> "@" <unit> [ ":" <args> ]
763
764 Where <name> is the name of the template device, <unit> is a
765 textual specification of the devices unit address (that is
766 converted into a numeric form by the devices parent) and <args> are
767 optional additional information to be passed to the device-template
768 when it creates the device.
769
770 Properties:
771
772 Properties are specified in a similar way to devices except that
773 the last element on the path (which would have been the device) is
774 the property name. This path is then followed by the property
775 value. Unlike OpenBoot, the property values in the device tree are
776 strongly typed.
777
778 String property:
779
780 <property-name> " " <text>
781 <property-name> " " "\"" <text>
782
783 Boolean property:
784
785 <property-name> " " [ "true" | "false" ]
786 Integer property or integer array property:
787
788 <property-name> " " <number> { <number> }
789
790 Phandle property:
791
792 <property-name> " " "&" <path-to-device>
793
794 Ihandle property:
795
796 <property-name> " " "*" <path-to-device-to-open>
797
798 Duplicate existing property:
799
800 <property-name> " " "!" <path-to-original-property>
801
802
803 In addition to properties, the wiring of interrupts can be
804 specified:
805
806 Attach interrupt <line> of <device> to <controller>:
807
808 <device> " " ">" <my-port> <dest-port> <dest-device>
809
810
811 Once created, a device tree can be traversed in various orders: */
812
813 typedef void (device_tree_traverse_function)
814 (device *device,
815 void *data);
816
817 INLINE_DEVICE\
818 (void) device_tree_traverse
819 (device *root,
820 device_tree_traverse_function *prefix,
821 device_tree_traverse_function *postfix,
822 void *data);
823
824 /* Or dumped out in a format that can be read back in using
825 device_add_parsed() */
826
827 INLINE_DEVICE\
828 (void) device_tree_print_device
829 (device *device,
830 void *ignore_data_argument);
831
832 /* Individual nodes can be located using */
833
834 INLINE_DEVICE\
835 (device *) device_tree_find_device
836 (device *root,
837 const char *path);
838
839 /* And the current list of devices can be listed */
840
841 INLINE_DEVICE\
842 (void) device_usage
843 (int verbose);
844
845 \f
846 /* ihandles and phandles:
847
848 Both device nodes and device instances, in OpenBoot firmware have
849 an external representation (phandles and ihandles) and these values
850 are both stored in the device tree in property nodes and passed
851 between the client program and the simulator during emulation
852 calls.
853
854 To limit the potential risk associated with trusing `data' from the
855 client program, the following mapping operators `safely' convert
856 between the two representations: */
857
858 INLINE_DEVICE\
859 (device *) external_to_device
860 (device *tree_member,
861 unsigned32 phandle);
862
863 INLINE_DEVICE\
864 (unsigned32) device_to_external
865 (device *me);
866
867 INLINE_DEVICE\
868 (device_instance *) external_to_device_instance
869 (device *tree_member,
870 unsigned32 ihandle);
871
872 INLINE_DEVICE\
873 (unsigned32) device_instance_to_external
874 (device_instance *me);
875
876 #endif /* _DEVICE_H_ */
This page took 0.053063 seconds and 4 git commands to generate.