xref: /netbsd-src/external/gpl3/gdb/dist/sim/ppc/device.h (revision c5e820cae412164fcbee52f470436200af5358ea)
1 /*  This file is part of the program psim.
2 
3     Copyright (C) 1994-1997, 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   const char *full_path;
295 } ihandle_runtime_property_spec;
296 
297 INLINE_DEVICE\
298 (void) device_add_ihandle_runtime_property
299 (device *me,
300  const char *property,
301  const ihandle_runtime_property_spec *ihandle);
302 
303 INLINE_DEVICE\
304 (void) device_find_ihandle_runtime_property
305 (device *me,
306  const char *property,
307  ihandle_runtime_property_spec *ihandle);
308 
309 INLINE_DEVICE\
310 (void) device_set_ihandle_property
311 (device *me,
312  const char *property,
313  device_instance *ihandle);
314 
315 INLINE_DEVICE\
316 (device_instance *) device_find_ihandle_property
317 (device *me,
318  const char *property);
319 
320 
321 
322 INLINE_DEVICE\
323 (void) device_add_integer_property
324 (device *me,
325  const char *property,
326  signed_cell integer);
327 
328 INLINE_DEVICE\
329 (signed_cell) device_find_integer_property
330 (device *me,
331  const char *property);
332 
333 INLINE_DEVICE\
334 (int) device_find_integer_array_property
335 (device *me,
336  const char *property,
337  unsigned index,
338  signed_cell *integer);
339 
340 
341 
342 typedef struct _range_property_spec {
343   device_unit child_address;
344   device_unit parent_address;
345   device_unit size;
346 } range_property_spec;
347 
348 INLINE_DEVICE\
349 (void) device_add_range_array_property
350 (device *me,
351  const char *property,
352  const range_property_spec *ranges,
353  unsigned nr_ranges);
354 
355 INLINE_DEVICE\
356 (int) device_find_range_array_property
357 (device *me,
358  const char *property,
359  unsigned index,
360  range_property_spec *range);
361 
362 
363 
364 typedef struct _reg_property_spec {
365   device_unit address;
366   device_unit size;
367 } reg_property_spec;
368 
369 INLINE_DEVICE\
370 (void) device_add_reg_array_property
371 (device *me,
372  const char *property,
373  const reg_property_spec *reg,
374  unsigned nr_regs);
375 
376 INLINE_DEVICE\
377 (int) device_find_reg_array_property
378 (device *me,
379  const char *property,
380  unsigned index,
381  reg_property_spec *reg);
382 
383 
384 
385 INLINE_DEVICE\
386 (void) device_add_string_property
387 (device *me,
388  const char *property,
389  const char *string);
390 
391 INLINE_DEVICE\
392 (const char *) device_find_string_property
393 (device *me,
394  const char *property);
395 
396 
397 
398 typedef const char *string_property_spec;
399 
400 INLINE_DEVICE\
401 (void) device_add_string_array_property
402 (device *me,
403  const char *property,
404  const string_property_spec *strings,
405  unsigned nr_strings);
406 
407 INLINE_DEVICE\
408 (int) device_find_string_array_property
409 (device *me,
410  const char *property,
411  unsigned index,
412  string_property_spec *string);
413 
414 
415 
416 INLINE_DEVICE\
417 (void) device_add_duplicate_property
418 (device *me,
419  const char *property,
420  const device_property *original);
421 
422 
423 
424 /* Instances:
425 
426    As with IEEE1275, a device can be opened, creating an instance.
427    Instances provide more abstract interfaces to the underlying
428    hardware.  For example, the instance methods for a disk may include
429    code that is able to interpret file systems found on disks.  Such
430    methods would there for allow the manipulation of files on the
431    disks file system.  The operations would be implemented using the
432    basic block I/O model provided by the disk.
433 
434    This model includes methods that faciliate the creation of device
435    instance and (should a given device support it) standard operations
436    on those instances.
437 
438    */
439 
440 typedef struct _device_instance_callbacks device_instance_callbacks;
441 
442 INLINE_DEVICE\
443 (device_instance *) device_create_instance_from
444 (device *me, /*OR*/ device_instance *parent,
445  void *data,
446  const char *path,
447  const char *args,
448  const device_instance_callbacks *callbacks);
449 
450 INLINE_DEVICE\
451 (device_instance *) device_create_instance
452 (device *me,
453  const char *full_path,
454  const char *args);
455 
456 INLINE_DEVICE\
457 (void) device_instance_delete
458 (device_instance *instance);
459 
460 INLINE_DEVICE\
461 (int) device_instance_read
462 (device_instance *instance,
463  void *addr,
464  unsigned_word len);
465 
466 INLINE_DEVICE\
467 (int) device_instance_write
468 (device_instance *instance,
469  const void *addr,
470  unsigned_word len);
471 
472 INLINE_DEVICE\
473 (int) device_instance_seek
474 (device_instance *instance,
475  unsigned_word pos_hi,
476  unsigned_word pos_lo);
477 
478 INLINE_DEVICE\
479 (int) device_instance_call_method
480 (device_instance *instance,
481  const char *method,
482  int n_stack_args,
483  unsigned_cell stack_args[/*n_stack_args*/],
484  int n_stack_returns,
485  unsigned_cell stack_returns[/*n_stack_returns*/]);
486 
487 INLINE_DEVICE\
488 (device *) device_instance_device
489 (device_instance *instance);
490 
491 INLINE_DEVICE\
492 (const char *) device_instance_path
493 (device_instance *instance);
494 
495 INLINE_DEVICE\
496 (void *) device_instance_data
497 (device_instance *instance);
498 
499 
500 /* Interrupts:
501 
502    */
503 
504 /* Interrupt Source
505 
506    A device drives its interrupt line using the call
507 
508    */
509 
510 INLINE_DEVICE\
511 (void) device_interrupt_event
512 (device *me,
513  int my_port,
514  int value,
515  cpu *processor,
516  unsigned_word cia);
517 
518 /* This interrupt event will then be propogated to any attached
519    interrupt destinations.
520 
521    Any interpretation of PORT and VALUE is model dependant.  However
522    as guidelines the following are recommended: PCI interrupts a-d
523    correspond to lines 0-3; level sensative interrupts be requested
524    with a value of one and withdrawn with a value of 0; edge sensative
525    interrupts always have a value of 1, the event its self is treated
526    as the interrupt.
527 
528 
529    Interrupt Destinations
530 
531    Attached to each interrupt line of a device can be zero or more
532    desitinations.  These destinations consist of a device/port pair.
533    A destination is attached/detached to a device line using the
534    attach and detach calls. */
535 
536 INLINE_DEVICE\
537 (void) device_interrupt_attach
538 (device *me,
539  int my_port,
540  device *dest,
541  int dest_port,
542  object_disposition disposition);
543 
544 INLINE_DEVICE\
545 (void) device_interrupt_detach
546 (device *me,
547  int my_port,
548  device *dest,
549  int dest_port);
550 
551 typedef void (device_interrupt_traverse_function)
552      (device *me,
553       int my_port,
554       device *dest,
555       int my_dest,
556       void *data);
557 
558 INLINE_DEVICE\
559 (void) device_interrupt_traverse
560 (device *me,
561  device_interrupt_traverse_function *handler,
562  void *data);
563 
564 
565 /* DESTINATION is attached (detached) to LINE of the device ME
566 
567 
568    Interrupt conversion
569 
570    Users refer to interrupt port numbers symbolically.  For instance a
571    device may refer to its `INT' signal which is internally
572    represented by port 3.
573 
574    To convert to/from the symbolic and internal representation of a
575    port name/number.  The following functions are available. */
576 
577 INLINE_DEVICE\
578 (int) device_interrupt_decode
579 (device *me,
580  const char *symbolic_name,
581  port_direction direction);
582 
583 INLINE_DEVICE\
584 (int) device_interrupt_encode
585 (device *me,
586  int port_number,
587  char *buf,
588  int sizeof_buf,
589  port_direction direction);
590 
591 
592 /* Hardware operations:
593 
594    */
595 
596 INLINE_DEVICE\
597 (unsigned) device_io_read_buffer
598 (device *me,
599  void *dest,
600  int space,
601  unsigned_word addr,
602  unsigned nr_bytes,
603  cpu *processor,
604  unsigned_word cia);
605 
606 INLINE_DEVICE\
607 (unsigned) device_io_write_buffer
608 (device *me,
609  const void *source,
610  int space,
611  unsigned_word addr,
612  unsigned nr_bytes,
613  cpu *processor,
614  unsigned_word cia);
615 
616 
617 /* Conversly, the device pci1000,1@1 my need to perform a dma transfer
618    into the cpu/memory core.  Just as I/O moves towards the leaves,
619    dma transfers move towards the core via the initiating devices
620    parent nodes.  The root device (special) converts the DMA transfer
621    into reads/writes to memory */
622 
623 INLINE_DEVICE\
624 (unsigned) device_dma_read_buffer
625 (device *me,
626  void *dest,
627  int space,
628  unsigned_word addr,
629  unsigned nr_bytes);
630 
631 INLINE_DEVICE\
632 (unsigned) device_dma_write_buffer
633 (device *me,
634  const void *source,
635  int space,
636  unsigned_word addr,
637  unsigned nr_bytes,
638  int violate_read_only_section);
639 
640 /* To avoid the need for an intermediate (bridging) node to ask each
641    of its child devices in turn if an IO access is intended for them,
642    parent nodes maintain a table mapping addresses directly to
643    specific devices.  When a device is `connected' to its bus it
644    attaches its self to its parent. */
645 
646 /* Address access attributes */
647 typedef enum _access_type {
648   access_invalid = 0,
649   access_read = 1,
650   access_write = 2,
651   access_read_write = 3,
652   access_exec = 4,
653   access_read_exec = 5,
654   access_write_exec = 6,
655   access_read_write_exec = 7,
656 } access_type;
657 
658 /* Address attachement types */
659 typedef enum _attach_type {
660   attach_invalid,
661   attach_raw_memory,
662   attach_callback,
663   /* ... */
664 } attach_type;
665 
666 INLINE_DEVICE\
667 (void) device_attach_address
668 (device *me,
669  attach_type attach,
670  int space,
671  unsigned_word addr,
672  unsigned nr_bytes,
673  access_type access,
674  device *client); /*callback/default*/
675 
676 INLINE_DEVICE\
677 (void) device_detach_address
678 (device *me,
679  attach_type attach,
680  int space,
681  unsigned_word addr,
682  unsigned nr_bytes,
683  access_type access,
684  device *client); /*callback/default*/
685 
686 /* Utilities:
687 
688    */
689 
690 /* IOCTL::
691 
692    Often devices require `out of band' operations to be performed.
693    For instance a pal device may need to notify a PCI bridge device
694    that an interrupt ack cycle needs to be performed on the PCI bus.
695    Within PSIM such operations are performed by using the generic
696    ioctl call <<device_ioctl()>>.
697 
698    */
699 
700 typedef enum {
701   device_ioctl_break, /* unsigned_word requested_break */
702   device_ioctl_set_trace, /* void */
703   device_ioctl_create_stack, /* unsigned_word *sp, char **argv, char **envp */
704   device_ioctl_change_media, /* const char *new_image (possibly NULL) */
705   nr_device_ioctl_requests,
706 } device_ioctl_request;
707 
708 EXTERN_DEVICE\
709 (int) device_ioctl
710 (device *me,
711  cpu *processor,
712  unsigned_word cia,
713  device_ioctl_request request,
714  ...);
715 
716 
717 /* Error reporting::
718 
719    So that errors originating from devices appear in a consistent
720    format, the <<device_error()>> function can be used.  Formats and
721    outputs the error message before aborting the simulation
722 
723    Devices should use this function to abort the simulation except
724    when the abort reason leaves the simulation in a hazardous
725    condition (for instance a failed malloc).
726 
727    */
728 
729 EXTERN_DEVICE\
730 (void volatile) device_error
731 (device *me,
732  const char *fmt,
733  ...) __attribute__ ((format (printf, 2, 3)));
734 
735 INLINE_DEVICE\
736 (int) device_trace
737 (device *me);
738 
739 
740 
741 /* External representation:
742 
743    Both device nodes and device instances, in OpenBoot firmware have
744    an external representation (phandles and ihandles) and these values
745    are both stored in the device tree in property nodes and passed
746    between the client program and the simulator during emulation
747    calls.
748 
749    To limit the potential risk associated with trusing `data' from the
750    client program, the following mapping operators `safely' convert
751    between the two representations
752 
753    */
754 
755 INLINE_DEVICE\
756 (device *) external_to_device
757 (device *tree_member,
758  unsigned_cell phandle);
759 
760 INLINE_DEVICE\
761 (unsigned_cell) device_to_external
762 (device *me);
763 
764 INLINE_DEVICE\
765 (device_instance *) external_to_device_instance
766 (device *tree_member,
767  unsigned_cell ihandle);
768 
769 INLINE_DEVICE\
770 (unsigned_cell) device_instance_to_external
771 (device_instance *me);
772 
773 
774 /* Event queue:
775 
776    The device inherets certain event queue operations from the main
777    simulation. */
778 
779 typedef void device_event_handler(void *data);
780 
781 INLINE_DEVICE\
782 (event_entry_tag) device_event_queue_schedule
783 (device *me,
784  signed64 delta_time,
785  device_event_handler *handler,
786  void *data);
787 
788 INLINE_EVENTS\
789 (void) device_event_queue_deschedule
790 (device *me,
791  event_entry_tag event_to_remove);
792 
793 INLINE_EVENTS\
794 (signed64) device_event_queue_time
795 (device *me);
796 
797 #endif /* _DEVICE_H_ */
798