Tue Jun 16 13:06:21 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
[binutils-gdb.git] / sim / ppc / device.h
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 /* Introduction:
34
35 As explained in earlier sections, the device, device instance,
36 property and interrupts lie at the heart of PSIM's device model.
37
38 In the below a synopsis of the device object and the operations it
39 supports are given. Details of this object can be found in the
40 files <<device.h>> and <<device.c>>.
41
42 */
43
44
45 /* Device creation: */
46
47 INLINE_DEVICE\
48 (device *) device_create
49 (device *parent,
50 const char *base,
51 const char *name,
52 const char *unit_address,
53 const char *args);
54
55 INLINE_DEVICE\
56 (void) device_usage
57 (int verbose);
58
59
60 /* Device initialization: */
61
62 INLINE_DEVICE\
63 (void) device_clean
64 (device *root,
65 void *data);
66
67 INLINE_DEVICE\
68 (void) device_init_static_properties
69 (device *me,
70 void *data);
71
72 INLINE_DEVICE\
73 (void) device_init_address
74 (device *me,
75 void *data);
76
77 INLINE_DEVICE\
78 (void) device_init_runtime_properties
79 (device *me,
80 void *data);
81
82 INLINE_DEVICE\
83 (void) device_init_data
84 (device *me,
85 void *data);
86
87
88 /* Relationships:
89
90 A device is able to determine its relationship to other devices
91 within the tree. Operations include querying for a devices parent,
92 sibling, child, name, and path (from the root).
93
94 */
95
96 INLINE_DEVICE\
97 (device *) device_parent
98 (device *me);
99
100 INLINE_DEVICE\
101 (device *) device_root
102 (device *me);
103
104 INLINE_DEVICE\
105 (device *) device_sibling
106 (device *me);
107
108 INLINE_DEVICE\
109 (device *) device_child
110 (device *me);
111
112 INLINE_DEVICE\
113 (const char *) device_name
114 (device *me);
115
116 INLINE_DEVICE\
117 (const char *) device_base
118 (device *me);
119
120 INLINE_DEVICE\
121 (const char *) device_path
122 (device *me);
123
124 INLINE_DEVICE\
125 (void *) device_data
126 (device *me);
127
128 INLINE_DEVICE\
129 (psim *) device_system
130 (device *me);
131
132 typedef struct _device_unit {
133 int nr_cells;
134 unsigned_cell cells[4]; /* unused cells are zero */
135 } device_unit;
136
137 INLINE_DEVICE\
138 (const device_unit *) device_unit_address
139 (device *me);
140
141 INLINE_DEVICE\
142 (int) device_decode_unit
143 (device *bus,
144 const char *unit,
145 device_unit *address);
146
147 INLINE_DEVICE\
148 (int) device_encode_unit
149 (device *bus,
150 const device_unit *unit_address,
151 char *buf,
152 int sizeof_buf);
153
154
155 /* Convert an Open Firmware size into a form suitable for attach
156 address calls.
157
158 Return a zero result if the address should be ignored when looking
159 for attach addresses */
160
161 INLINE_DEVICE\
162 (int) device_address_to_attach_address
163 (device *me,
164 const device_unit *address,
165 int *attach_space,
166 unsigned_word *attach_address,
167 device *client);
168
169
170 /* Convert an Open Firmware size into a form suitable for attach
171 address calls
172
173 Return a zero result if the address should be ignored */
174
175 INLINE_DEVICE\
176 (int) device_size_to_attach_size
177 (device *me,
178 const device_unit *size,
179 unsigned *nr_bytes,
180 device *client);
181
182
183 INLINE_DEVICE\
184 (unsigned) device_nr_address_cells
185 (device *me);
186
187 INLINE_DEVICE\
188 (unsigned) device_nr_size_cells
189 (device *me);
190
191
192 /* Properties:
193
194 Attached to a device are a number of properties. Each property has
195 a size and type (both of which can be queried). A device is able
196 to iterate over or query and set a properties value.
197
198 */
199
200 /* The following are valid property types. The property `array' is
201 for generic untyped data. */
202
203 typedef enum {
204 array_property,
205 boolean_property,
206 ihandle_property, /*runtime*/
207 integer_property,
208 range_array_property,
209 reg_array_property,
210 string_property,
211 string_array_property,
212 } device_property_type;
213
214 typedef struct _device_property device_property;
215 struct _device_property {
216 device *owner;
217 const char *name;
218 device_property_type type;
219 unsigned sizeof_array;
220 const void *array;
221 const device_property *original;
222 object_disposition disposition;
223 };
224
225
226 /* iterate through the properties attached to a device */
227
228 INLINE_DEVICE\
229 (const device_property *) device_next_property
230 (const device_property *previous);
231
232 INLINE_DEVICE\
233 (const device_property *) device_find_property
234 (device *me,
235 const char *property); /* NULL for first property */
236
237
238 /* Manipulate the properties belonging to a given device.
239
240 SET on the other hand will force the properties value. The
241 simulation is aborted if the property was present but of a
242 conflicting type.
243
244 FIND returns the specified properties value, aborting the
245 simulation if the property is missing. Code locating a property
246 should first check its type (using device_find_property above) and
247 then obtain its value using the below.
248
249 void device_add_<type>_property(device *, const char *, <type>)
250 void device_add_*_array_property(device *, const char *, const <type>*, int)
251 void device_set_*_property(device *, const char *, <type>)
252 void device_set_*_array_property(device *, const char *, const <type>*, int)
253 <type> device_find_*_property(device *, const char *)
254 int device_find_*_array_property(device *, const char *, int, <type>*)
255
256 */
257
258
259 INLINE_DEVICE\
260 (void) device_add_array_property
261 (device *me,
262 const char *property,
263 const void *array,
264 int sizeof_array);
265
266 INLINE_DEVICE\
267 (void) device_set_array_property
268 (device *me,
269 const char *property,
270 const void *array,
271 int sizeof_array);
272
273 INLINE_DEVICE\
274 (const device_property *) device_find_array_property
275 (device *me,
276 const char *property);
277
278
279
280 INLINE_DEVICE\
281 (void) device_add_boolean_property
282 (device *me,
283 const char *property,
284 int bool);
285
286 INLINE_DEVICE\
287 (int) device_find_boolean_property
288 (device *me,
289 const char *property);
290
291
292
293 typedef struct _ihandle_runtime_property_spec {
294 device *phandle;
295 const char *full_path;
296 const char *args;
297 } ihandle_runtime_property_spec;
298
299 INLINE_DEVICE\
300 (void) device_add_ihandle_runtime_property
301 (device *me,
302 const char *property,
303 const ihandle_runtime_property_spec *ihandle);
304
305 INLINE_DEVICE\
306 (void) device_find_ihandle_runtime_property
307 (device *me,
308 const char *property,
309 ihandle_runtime_property_spec *ihandle);
310
311 INLINE_DEVICE\
312 (void) device_set_ihandle_property
313 (device *me,
314 const char *property,
315 device_instance *ihandle);
316
317 INLINE_DEVICE\
318 (device_instance *) device_find_ihandle_property
319 (device *me,
320 const char *property);
321
322
323
324 INLINE_DEVICE\
325 (void) device_add_integer_property
326 (device *me,
327 const char *property,
328 signed_cell integer);
329
330 INLINE_DEVICE\
331 (signed_cell) device_find_integer_property
332 (device *me,
333 const char *property);
334
335 INLINE_DEVICE\
336 (int) device_find_integer_array_property
337 (device *me,
338 const char *property,
339 unsigned index,
340 signed_word *integer);
341
342
343
344 typedef struct _range_property_spec {
345 device_unit child_address;
346 device_unit parent_address;
347 device_unit size;
348 } range_property_spec;
349
350 INLINE_DEVICE\
351 (void) device_add_range_array_property
352 (device *me,
353 const char *property,
354 const range_property_spec *ranges,
355 unsigned nr_ranges);
356
357 INLINE_DEVICE\
358 (int) device_find_range_array_property
359 (device *me,
360 const char *property,
361 unsigned index,
362 range_property_spec *range);
363
364
365
366 typedef struct _reg_property_spec {
367 device_unit address;
368 device_unit size;
369 } reg_property_spec;
370
371 INLINE_DEVICE\
372 (void) device_add_reg_array_property
373 (device *me,
374 const char *property,
375 const reg_property_spec *reg,
376 unsigned nr_regs);
377
378 INLINE_DEVICE\
379 (int) device_find_reg_array_property
380 (device *me,
381 const char *property,
382 unsigned index,
383 reg_property_spec *reg);
384
385
386
387 INLINE_DEVICE\
388 (void) device_add_string_property
389 (device *me,
390 const char *property,
391 const char *string);
392
393 INLINE_DEVICE\
394 (const char *) device_find_string_property
395 (device *me,
396 const char *property);
397
398
399
400 typedef const char *string_property_spec;
401
402 INLINE_DEVICE\
403 (void) device_add_string_array_property
404 (device *me,
405 const char *property,
406 const string_property_spec *strings,
407 unsigned nr_strings);
408
409 INLINE_DEVICE\
410 (int) device_find_string_array_property
411 (device *me,
412 const char *property,
413 unsigned index,
414 string_property_spec *string);
415
416
417
418 INLINE_DEVICE\
419 (void) device_add_duplicate_property
420 (device *me,
421 const char *property,
422 const device_property *original);
423
424
425
426 /* Instances:
427
428 As with IEEE1275, a device can be opened, creating an instance.
429 Instances provide more abstract interfaces to the underlying
430 hardware. For example, the instance methods for a disk may include
431 code that is able to interpret file systems found on disks. Such
432 methods would there for allow the manipulation of files on the
433 disks file system. The operations would be implemented using the
434 basic block I/O model provided by the disk.
435
436 This model includes methods that faciliate the creation of device
437 instance and (should a given device support it) standard operations
438 on those instances.
439
440 */
441
442 typedef struct _device_instance_callbacks device_instance_callbacks;
443
444 INLINE_DEVICE\
445 (device_instance *) device_create_instance_from
446 (device *me, /*OR*/ device_instance *parent,
447 void *data,
448 const char *path,
449 const char *args,
450 const device_instance_callbacks *callbacks);
451
452 INLINE_DEVICE\
453 (device_instance *) device_create_instance
454 (device *me,
455 const char *full_path,
456 const char *args);
457
458 INLINE_DEVICE\
459 (void) device_instance_delete
460 (device_instance *instance);
461
462 INLINE_DEVICE\
463 (int) device_instance_read
464 (device_instance *instance,
465 void *addr,
466 unsigned_word len);
467
468 INLINE_DEVICE\
469 (int) device_instance_write
470 (device_instance *instance,
471 const void *addr,
472 unsigned_word len);
473
474 INLINE_DEVICE\
475 (int) device_instance_seek
476 (device_instance *instance,
477 unsigned_word pos_hi,
478 unsigned_word pos_lo);
479
480 INLINE_DEVICE\
481 (int) device_instance_call_method
482 (device_instance *instance,
483 const char *method,
484 int n_stack_args,
485 unsigned_cell stack_args[/*n_stack_args*/],
486 int n_stack_returns,
487 unsigned_cell stack_returns[/*n_stack_returns*/]);
488
489 INLINE_DEVICE\
490 (device *) device_instance_device
491 (device_instance *instance);
492
493 INLINE_DEVICE\
494 (const char *) device_instance_path
495 (device_instance *instance);
496
497 INLINE_DEVICE\
498 (void *) device_instance_data
499 (device_instance *instance);
500
501
502 /* Interrupts:
503
504 */
505
506 /* Interrupt Source
507
508 A device drives its interrupt line using the call
509
510 */
511
512 INLINE_DEVICE\
513 (void) device_interrupt_event
514 (device *me,
515 int my_port,
516 int value,
517 cpu *processor,
518 unsigned_word cia);
519
520 /* This interrupt event will then be propogated to any attached
521 interrupt destinations.
522
523 Any interpretation of PORT and VALUE is model dependant. However
524 as guidelines the following are recommended: PCI interrupts a-d
525 correspond to lines 0-3; level sensative interrupts be requested
526 with a value of one and withdrawn with a value of 0; edge sensative
527 interrupts always have a value of 1, the event its self is treated
528 as the interrupt.
529
530
531 Interrupt Destinations
532
533 Attached to each interrupt line of a device can be zero or more
534 desitinations. These destinations consist of a device/port pair.
535 A destination is attached/detached to a device line using the
536 attach and detach calls. */
537
538 INLINE_DEVICE\
539 (void) device_interrupt_attach
540 (device *me,
541 int my_port,
542 device *dest,
543 int dest_port,
544 object_disposition disposition);
545
546 INLINE_DEVICE\
547 (void) device_interrupt_detach
548 (device *me,
549 int my_port,
550 device *dest,
551 int dest_port);
552
553 typedef void (device_interrupt_traverse_function)
554 (device *me,
555 int my_port,
556 device *dest,
557 int my_dest,
558 void *data);
559
560 INLINE_DEVICE\
561 (void) device_interrupt_traverse
562 (device *me,
563 device_interrupt_traverse_function *handler,
564 void *data);
565
566
567 /* DESTINATION is attached (detached) to LINE of the device ME
568
569
570 Interrupt conversion
571
572 Users refer to interrupt port numbers symbolically. For instance a
573 device may refer to its `INT' signal which is internally
574 represented by port 3.
575
576 To convert to/from the symbolic and internal representation of a
577 port name/number. The following functions are available. */
578
579 INLINE_DEVICE\
580 (int) device_interrupt_decode
581 (device *me,
582 const char *symbolic_name,
583 port_direction direction);
584
585 INLINE_DEVICE\
586 (int) device_interrupt_encode
587 (device *me,
588 int port_number,
589 char *buf,
590 int sizeof_buf,
591 port_direction direction);
592
593
594 /* Hardware operations:
595
596 */
597
598 INLINE_DEVICE\
599 (unsigned) device_io_read_buffer
600 (device *me,
601 void *dest,
602 int space,
603 unsigned_word addr,
604 unsigned nr_bytes,
605 cpu *processor,
606 unsigned_word cia);
607
608 INLINE_DEVICE\
609 (unsigned) device_io_write_buffer
610 (device *me,
611 const void *source,
612 int space,
613 unsigned_word addr,
614 unsigned nr_bytes,
615 cpu *processor,
616 unsigned_word cia);
617
618
619 /* Conversly, the device pci1000,1@1 my need to perform a dma transfer
620 into the cpu/memory core. Just as I/O moves towards the leaves,
621 dma transfers move towards the core via the initiating devices
622 parent nodes. The root device (special) converts the DMA transfer
623 into reads/writes to memory */
624
625 INLINE_DEVICE\
626 (unsigned) device_dma_read_buffer
627 (device *me,
628 void *dest,
629 int space,
630 unsigned_word addr,
631 unsigned nr_bytes);
632
633 INLINE_DEVICE\
634 (unsigned) device_dma_write_buffer
635 (device *me,
636 const void *source,
637 int space,
638 unsigned_word addr,
639 unsigned nr_bytes,
640 int violate_read_only_section);
641
642 /* To avoid the need for an intermediate (bridging) node to ask each
643 of its child devices in turn if an IO access is intended for them,
644 parent nodes maintain a table mapping addresses directly to
645 specific devices. When a device is `connected' to its bus it
646 attaches its self to its parent. */
647
648 /* Address access attributes */
649 typedef enum _access_type {
650 access_invalid = 0,
651 access_read = 1,
652 access_write = 2,
653 access_read_write = 3,
654 access_exec = 4,
655 access_read_exec = 5,
656 access_write_exec = 6,
657 access_read_write_exec = 7,
658 } access_type;
659
660 /* Address attachement types */
661 typedef enum _attach_type {
662 attach_invalid,
663 attach_raw_memory,
664 attach_callback,
665 /* ... */
666 } attach_type;
667
668 INLINE_DEVICE\
669 (void) device_attach_address
670 (device *me,
671 attach_type attach,
672 int space,
673 unsigned_word addr,
674 unsigned nr_bytes,
675 access_type access,
676 device *client); /*callback/default*/
677
678 INLINE_DEVICE\
679 (void) device_detach_address
680 (device *me,
681 attach_type attach,
682 int space,
683 unsigned_word addr,
684 unsigned nr_bytes,
685 access_type access,
686 device *client); /*callback/default*/
687
688 /* Utilities:
689
690 */
691
692 /* IOCTL::
693
694 Often devices require `out of band' operations to be performed.
695 For instance a pal device may need to notify a PCI bridge device
696 that an interrupt ack cycle needs to be performed on the PCI bus.
697 Within PSIM such operations are performed by using the generic
698 ioctl call <<device_ioctl()>>.
699
700 */
701
702 typedef enum {
703 device_ioctl_break, /* unsigned_word requested_break */
704 device_ioctl_set_trace, /* void */
705 device_ioctl_create_stack, /* unsigned_word *sp, char **argv, char **envp */
706 device_ioctl_change_media, /* const char *new_image (possibly NULL) */
707 nr_device_ioctl_requests,
708 } device_ioctl_request;
709
710 EXTERN_DEVICE\
711 (int) device_ioctl
712 (device *me,
713 cpu *processor,
714 unsigned_word cia,
715 device_ioctl_request request,
716 ...);
717
718
719 /* Error reporting::
720
721 So that errors originating from devices appear in a consistent
722 format, the <<device_error()>> function can be used. Formats and
723 outputs the error message before aborting the simulation
724
725 Devices should use this function to abort the simulation except
726 when the abort reason leaves the simulation in a hazardous
727 condition (for instance a failed malloc).
728
729 */
730
731 EXTERN_DEVICE\
732 (void volatile) device_error
733 (device *me,
734 const char *fmt,
735 ...) __attribute__ ((format (printf, 2, 3)));
736
737 INLINE_DEVICE\
738 (int) device_trace
739 (device *me);
740
741
742
743 /* External representation:
744
745 Both device nodes and device instances, in OpenBoot firmware have
746 an external representation (phandles and ihandles) and these values
747 are both stored in the device tree in property nodes and passed
748 between the client program and the simulator during emulation
749 calls.
750
751 To limit the potential risk associated with trusing `data' from the
752 client program, the following mapping operators `safely' convert
753 between the two representations
754
755 */
756
757 INLINE_DEVICE\
758 (device *) external_to_device
759 (device *tree_member,
760 unsigned_cell phandle);
761
762 INLINE_DEVICE\
763 (unsigned_cell) device_to_external
764 (device *me);
765
766 INLINE_DEVICE\
767 (device_instance *) external_to_device_instance
768 (device *tree_member,
769 unsigned_cell ihandle);
770
771 INLINE_DEVICE\
772 (unsigned_cell) device_instance_to_external
773 (device_instance *me);
774
775
776 /* Event queue:
777
778 The device inherets certain event queue operations from the main
779 simulation. */
780
781 typedef void device_event_handler(void *data);
782
783 INLINE_DEVICE\
784 (event_entry_tag) device_event_queue_schedule
785 (device *me,
786 signed64 delta_time,
787 device_event_handler *handler,
788 void *data);
789
790 INLINE_EVENTS\
791 (void) device_event_queue_deschedule
792 (device *me,
793 event_entry_tag event_to_remove);
794
795 INLINE_EVENTS\
796 (signed64) device_event_queue_time
797 (device *me);
798
799 #endif /* _DEVICE_H_ */