* Makefile.in (INSTALL): Set to @INSTALL@.
[deliverable/binutils-gdb.git] / sim / ppc / device.h
CommitLineData
93fac324
MM
1/* This file is part of the program psim.
2
30c87b55 3 Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
93fac324
MM
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
30c87b55
MM
22#ifndef _DEVICE_H_
23#define _DEVICE_H_
93fac324
MM
24
25#ifndef INLINE_DEVICE
26#define INLINE_DEVICE
27#endif
28
93fac324
MM
29/* declared in basics.h, this object is used everywhere */
30/* typedef struct _device device; */
31
32
30c87b55 33/* Introduction:
93fac324 34
30c87b55
MM
35 As explained in earlier sections, the device, device instance,
36 property and interrupts lie at the heart of PSIM's device model.
93fac324 37
30c87b55
MM
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>>.
93fac324 41
30c87b55 42 */
93fac324 43
979c3c25 44
5c04f4f7 45/* Device creation: */
979c3c25 46
5c04f4f7
MM
47INLINE_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);
93fac324 54
5c04f4f7
MM
55INLINE_DEVICE\
56(void) device_usage
57(int verbose);
93fac324 58
93fac324 59
5c04f4f7 60/* Device initialization: */
93fac324 61
5c04f4f7
MM
62INLINE_DEVICE\
63(void) device_clean
64(device *root,
65 void *data);
93fac324 66
5c04f4f7
MM
67INLINE_DEVICE\
68(void) device_init_static_properties
69(device *me,
70 void *data);
93fac324 71
5c04f4f7
MM
72INLINE_DEVICE\
73(void) device_init_address
74(device *me,
75 void *data);
93fac324 76
5c04f4f7
MM
77INLINE_DEVICE\
78(void) device_init_runtime_properties
79(device *me,
80 void *data);
93fac324 81
30c87b55 82INLINE_DEVICE\
5c04f4f7
MM
83(void) device_init_data
84(device *me,
85 void *data);
93fac324 86
93fac324 87
30c87b55 88/* Relationships:
93fac324 89
30c87b55
MM
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).
93fac324 93
30c87b55 94 */
93fac324 95
30c87b55
MM
96INLINE_DEVICE\
97(device *) device_parent
98(device *me);
93fac324 99
5c04f4f7
MM
100INLINE_DEVICE\
101(device *) device_root
102(device *me);
103
30c87b55
MM
104INLINE_DEVICE\
105(device *) device_sibling
106(device *me);
93fac324 107
30c87b55
MM
108INLINE_DEVICE\
109(device *) device_child
110(device *me);
93fac324 111
30c87b55
MM
112INLINE_DEVICE\
113(const char *) device_name
114(device *me);
93fac324 115
5c04f4f7
MM
116INLINE_DEVICE\
117(const char *) device_base
118(device *me);
119
30c87b55
MM
120INLINE_DEVICE\
121(const char *) device_path
122(device *me);
93fac324 123
30c87b55
MM
124INLINE_DEVICE\
125(void *) device_data
126(device *me);
93fac324 127
30c87b55
MM
128INLINE_DEVICE\
129(psim *) device_system
130(device *me);
93fac324 131
30c87b55
MM
132typedef struct _device_unit {
133 int nr_cells;
5c04f4f7 134 unsigned_cell cells[4]; /* unused cells are zero */
30c87b55 135} device_unit;
93fac324 136
30c87b55
MM
137INLINE_DEVICE\
138(const device_unit *) device_unit_address
139(device *me);
93fac324 140
5c04f4f7
MM
141INLINE_DEVICE\
142(int) device_decode_unit
143(device *bus,
144 const char *unit,
145 device_unit *address);
146
147INLINE_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
161INLINE_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
175INLINE_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
183INLINE_DEVICE\
184(unsigned) device_nr_address_cells
185(device *me);
186
187INLINE_DEVICE\
188(unsigned) device_nr_size_cells
189(device *me);
190
93fac324 191
30c87b55 192/* Properties:
93fac324 193
30c87b55
MM
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.
93fac324 197
30c87b55 198 */
93fac324 199
5c04f4f7 200/* The following are valid property types. The property `array' is
30c87b55 201 for generic untyped data. */
93fac324
MM
202
203typedef enum {
30c87b55 204 array_property,
93fac324 205 boolean_property,
5c04f4f7 206 ihandle_property, /*runtime*/
30c87b55 207 integer_property,
5c04f4f7
MM
208 range_array_property,
209 reg_array_property,
93fac324 210 string_property,
5c04f4f7 211 string_array_property,
93fac324
MM
212} device_property_type;
213
214typedef struct _device_property device_property;
215struct _device_property {
216 device *owner;
30c87b55 217 const char *name;
93fac324
MM
218 device_property_type type;
219 unsigned sizeof_array;
220 const void *array;
30c87b55
MM
221 const device_property *original;
222 object_disposition disposition;
93fac324
MM
223};
224
225
30c87b55
MM
226/* iterate through the properties attached to a device */
227
228INLINE_DEVICE\
229(const device_property *) device_next_property
230(const device_property *previous);
93fac324 231
30c87b55
MM
232INLINE_DEVICE\
233(const device_property *) device_find_property
93fac324 234(device *me,
30c87b55
MM
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
5c04f4f7
MM
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 */
93fac324 257
93fac324 258
5c04f4f7
MM
259INLINE_DEVICE\
260(void) device_add_array_property
261(device *me,
262 const char *property,
263 const void *array,
264 int sizeof_array);
265
30c87b55
MM
266INLINE_DEVICE\
267(void) device_set_array_property
93fac324
MM
268(device *me,
269 const char *property,
270 const void *array,
271 int sizeof_array);
272
30c87b55
MM
273INLINE_DEVICE\
274(const device_property *) device_find_array_property
93fac324 275(device *me,
30c87b55
MM
276 const char *property);
277
93fac324 278
5c04f4f7 279
30c87b55 280INLINE_DEVICE\
5c04f4f7 281(void) device_add_boolean_property
93fac324
MM
282(device *me,
283 const char *property,
284 int bool);
285
30c87b55
MM
286INLINE_DEVICE\
287(int) device_find_boolean_property
93fac324
MM
288(device *me,
289 const char *property);
290
30c87b55 291
5c04f4f7
MM
292
293typedef struct _ihandle_runtime_property_spec {
294 device *phandle;
295 const char *full_path;
296 const char *args;
297} ihandle_runtime_property_spec;
298
299INLINE_DEVICE\
300(void) device_add_ihandle_runtime_property
301(device *me,
302 const char *property,
303 const ihandle_runtime_property_spec *ihandle);
304
305INLINE_DEVICE\
306(void) device_find_ihandle_runtime_property
307(device *me,
308 const char *property,
309 ihandle_runtime_property_spec *ihandle);
310
30c87b55
MM
311INLINE_DEVICE\
312(void) device_set_ihandle_property
93fac324
MM
313(device *me,
314 const char *property,
30c87b55 315 device_instance *ihandle);
93fac324 316
30c87b55
MM
317INLINE_DEVICE\
318(device_instance *) device_find_ihandle_property
93fac324
MM
319(device *me,
320 const char *property);
321
322
5c04f4f7 323
30c87b55 324INLINE_DEVICE\
5c04f4f7 325(void) device_add_integer_property
93fac324 326(device *me,
30c87b55 327 const char *property,
5c04f4f7 328 signed_cell integer);
93fac324 329
30c87b55 330INLINE_DEVICE\
5c04f4f7 331(signed_cell) device_find_integer_property
93fac324
MM
332(device *me,
333 const char *property);
334
5c04f4f7
MM
335INLINE_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
344typedef struct _range_property_spec {
345 device_unit child_address;
346 device_unit parent_address;
347 device_unit size;
348} range_property_spec;
93fac324 349
30c87b55 350INLINE_DEVICE\
5c04f4f7
MM
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
357INLINE_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
366typedef struct _reg_property_spec {
367 device_unit address;
368 device_unit size;
369} reg_property_spec;
370
371INLINE_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
378INLINE_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
387INLINE_DEVICE\
388(void) device_add_string_property
93fac324 389(device *me,
30c87b55
MM
390 const char *property,
391 const char *string);
93fac324 392
30c87b55
MM
393INLINE_DEVICE\
394(const char *) device_find_string_property
93fac324
MM
395(device *me,
396 const char *property);
397
398
5c04f4f7
MM
399
400typedef const char *string_property_spec;
401
402INLINE_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
409INLINE_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
418INLINE_DEVICE\
419(void) device_add_duplicate_property
420(device *me,
421 const char *property,
422 const device_property *original);
423
424
425
30c87b55 426/* Instances:
93fac324 427
30c87b55
MM
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.
93fac324 435
30c87b55
MM
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.
93fac324
MM
439
440 */
441
30c87b55 442typedef struct _device_instance_callbacks device_instance_callbacks;
93fac324 443
30c87b55
MM
444INLINE_DEVICE\
445(device_instance *) device_create_instance_from
446(device *me, /*OR*/ device_instance *parent,
93fac324 447 void *data,
30c87b55
MM
448 const char *path,
449 const char *args,
450 const device_instance_callbacks *callbacks);
93fac324 451
30c87b55
MM
452INLINE_DEVICE\
453(device_instance *) device_create_instance
93fac324 454(device *me,
5c04f4f7
MM
455 const char *full_path,
456 const char *args);
93fac324 457
30c87b55
MM
458INLINE_DEVICE\
459(void) device_instance_delete
460(device_instance *instance);
93fac324 461
30c87b55
MM
462INLINE_DEVICE\
463(int) device_instance_read
464(device_instance *instance,
465 void *addr,
466 unsigned_word len);
93fac324 467
30c87b55
MM
468INLINE_DEVICE\
469(int) device_instance_write
470(device_instance *instance,
471 const void *addr,
472 unsigned_word len);
93fac324 473
30c87b55
MM
474INLINE_DEVICE\
475(int) device_instance_seek
476(device_instance *instance,
477 unsigned_word pos_hi,
478 unsigned_word pos_lo);
93fac324 479
30c87b55 480INLINE_DEVICE\
5c04f4f7 481(int) device_instance_call_method
30c87b55 482(device_instance *instance,
5c04f4f7
MM
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*/]);
93fac324 488
30c87b55
MM
489INLINE_DEVICE\
490(device *) device_instance_device
491(device_instance *instance);
93fac324 492
30c87b55
MM
493INLINE_DEVICE\
494(const char *) device_instance_path
495(device_instance *instance);
93fac324 496
30c87b55
MM
497INLINE_DEVICE\
498(void *) device_instance_data
499(device_instance *instance);
93fac324 500
93fac324 501
30c87b55 502/* Interrupts:
93fac324 503
30c87b55 504 */
93fac324 505
30c87b55 506/* Interrupt Source
93fac324 507
30c87b55 508 A device drives its interrupt line using the call
93fac324 509
30c87b55 510 */
93fac324 511
30c87b55
MM
512INLINE_DEVICE\
513(void) device_interrupt_event
514(device *me,
515 int my_port,
516 int value,
517 cpu *processor,
518 unsigned_word cia);
93fac324 519
30c87b55
MM
520/* This interrupt event will then be propogated to any attached
521 interrupt destinations.
93fac324 522
30c87b55
MM
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.
93fac324 529
93fac324 530
30c87b55 531 Interrupt Destinations
93fac324 532
30c87b55
MM
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. */
93fac324 537
30c87b55
MM
538INLINE_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
546INLINE_DEVICE\
547(void) device_interrupt_detach
548(device *me,
549 int my_port,
550 device *dest,
551 int dest_port);
93fac324 552
5c04f4f7
MM
553typedef void (device_interrupt_traverse_function)
554 (device *me,
555 int my_port,
556 device *dest,
557 int my_dest,
558 void *data);
559
560INLINE_DEVICE\
561(void) device_interrupt_traverse
562(device *me,
563 device_interrupt_traverse_function *handler,
564 void *data);
565
566
30c87b55 567/* DESTINATION is attached (detached) to LINE of the device ME
93fac324 568
93fac324 569
30c87b55 570 Interrupt conversion
93fac324 571
30c87b55
MM
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.
93fac324 575
30c87b55
MM
576 To convert to/from the symbolic and internal representation of a
577 port name/number. The following functions are available. */
578
579INLINE_DEVICE\
580(int) device_interrupt_decode
93fac324 581(device *me,
5c04f4f7
MM
582 const char *symbolic_name,
583 port_direction direction);
93fac324 584
30c87b55
MM
585INLINE_DEVICE\
586(int) device_interrupt_encode
93fac324 587(device *me,
30c87b55
MM
588 int port_number,
589 char *buf,
5c04f4f7
MM
590 int sizeof_buf,
591 port_direction direction);
30c87b55 592
93fac324 593
30c87b55
MM
594/* Hardware operations:
595
596 */
597
598INLINE_DEVICE\
599(unsigned) device_io_read_buffer
93fac324
MM
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
30c87b55
MM
608INLINE_DEVICE\
609(unsigned) device_io_write_buffer
93fac324
MM
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
30c87b55
MM
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
625INLINE_DEVICE\
626(unsigned) device_dma_read_buffer
93fac324
MM
627(device *me,
628 void *dest,
629 int space,
630 unsigned_word addr,
631 unsigned nr_bytes);
632
30c87b55
MM
633INLINE_DEVICE\
634(unsigned) device_dma_write_buffer
93fac324
MM
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
30c87b55
MM
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. */
93fac324 647
30c87b55
MM
648/* Address access attributes */
649typedef 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;
93fac324 659
30c87b55
MM
660/* Address attachement types */
661typedef enum _attach_type {
662 attach_invalid,
663 attach_raw_memory,
664 attach_callback,
665 /* ... */
666} attach_type;
93fac324 667
30c87b55
MM
668INLINE_DEVICE\
669(void) device_attach_address
670(device *me,
30c87b55
MM
671 attach_type attach,
672 int space,
673 unsigned_word addr,
674 unsigned nr_bytes,
675 access_type access,
5c04f4f7 676 device *client); /*callback/default*/
93fac324 677
30c87b55
MM
678INLINE_DEVICE\
679(void) device_detach_address
680(device *me,
30c87b55
MM
681 attach_type attach,
682 int space,
683 unsigned_word addr,
684 unsigned nr_bytes,
685 access_type access,
5c04f4f7 686 device *client); /*callback/default*/
93fac324 687
30c87b55 688/* Utilities:
93fac324
MM
689
690 */
691
30c87b55 692/* IOCTL::
93fac324 693
30c87b55
MM
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()>>.
93fac324 699
30c87b55
MM
700 */
701
5c04f4f7
MM
702typedef 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
30c87b55
MM
710EXTERN_DEVICE\
711(int) device_ioctl
93fac324 712(device *me,
93fac324 713 cpu *processor,
30c87b55 714 unsigned_word cia,
5c04f4f7 715 device_ioctl_request request,
30c87b55 716 ...);
93fac324 717
93fac324 718
30c87b55 719/* Error reporting::
93fac324 720
30c87b55
MM
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
93fac324 724
30c87b55
MM
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 */
93fac324 730
979c3c25 731EXTERN_DEVICE\
30c87b55 732(void volatile) device_error
93fac324 733(device *me,
30c87b55
MM
734 const char *fmt,
735 ...) __attribute__ ((format (printf, 2, 3)));
93fac324 736
30c87b55 737INLINE_DEVICE\
5c04f4f7
MM
738(int) device_trace
739(device *me);
30c87b55 740
30c87b55
MM
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
757INLINE_DEVICE\
758(device *) external_to_device
759(device *tree_member,
5c04f4f7 760 unsigned_cell phandle);
30c87b55
MM
761
762INLINE_DEVICE\
5c04f4f7 763(unsigned_cell) device_to_external
30c87b55
MM
764(device *me);
765
766INLINE_DEVICE\
767(device_instance *) external_to_device_instance
768(device *tree_member,
5c04f4f7 769 unsigned_cell ihandle);
30c87b55
MM
770
771INLINE_DEVICE\
5c04f4f7 772(unsigned_cell) device_instance_to_external
30c87b55
MM
773(device_instance *me);
774
5c04f4f7
MM
775
776/* Event queue:
777
778 The device inherets certain event queue operations from the main
779 simulation. */
780
781typedef void device_event_handler(void *data);
782
783INLINE_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
790INLINE_EVENTS\
791(void) device_event_queue_deschedule
792(device *me,
793 event_entry_tag event_to_remove);
794
795INLINE_EVENTS\
796(signed64) device_event_queue_time
797(device *me);
798
30c87b55 799#endif /* _DEVICE_H_ */
This page took 0.094795 seconds and 4 git commands to generate.