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 3 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, see <http://www.gnu.org/licenses/>.
17 
18     */
19 
20 
21 #ifndef _DEVICE_H_
22 #define _DEVICE_H_
23 
24 #ifndef INLINE_DEVICE
25 #define INLINE_DEVICE
26 #endif
27 
28 /* declared in basics.h, this object is used everywhere */
29 /* typedef struct _device device; */
30 
31 
32 /* Introduction:
33 
34    As explained in earlier sections, the device, device instance,
35    property and interrupts lie at the heart of PSIM's device model.
36 
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>>.
40 
41    */
42 
43 
44 /* Device creation: */
45 
46 INLINE_DEVICE\
47 (device *) device_create
48 (device *parent,
49  const char *base,
50  const char *name,
51  const char *unit_address,
52  const char *args);
53 
54 INLINE_DEVICE\
55 (void) device_usage
56 (int verbose);
57 
58 
59 /* Device initialization: */
60 
61 INLINE_DEVICE\
62 (void) device_clean
63 (device *root,
64  void *data);
65 
66 INLINE_DEVICE\
67 (void) device_init_static_properties
68 (device *me,
69  void *data);
70 
71 INLINE_DEVICE\
72 (void) device_init_address
73 (device *me,
74  void *data);
75 
76 INLINE_DEVICE\
77 (void) device_init_runtime_properties
78 (device *me,
79  void *data);
80 
81 INLINE_DEVICE\
82 (void) device_init_data
83 (device *me,
84  void *data);
85 
86 
87 /* Relationships:
88 
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).
92 
93    */
94 
95 INLINE_DEVICE\
96 (device *) device_parent
97 (device *me);
98 
99 INLINE_DEVICE\
100 (device *) device_root
101 (device *me);
102 
103 INLINE_DEVICE\
104 (device *) device_sibling
105 (device *me);
106 
107 INLINE_DEVICE\
108 (device *) device_child
109 (device *me);
110 
111 INLINE_DEVICE\
112 (const char *) device_name
113 (device *me);
114 
115 INLINE_DEVICE\
116 (const char *) device_base
117 (device *me);
118 
119 INLINE_DEVICE\
120 (const char *) device_path
121 (device *me);
122 
123 INLINE_DEVICE\
124 (void *) device_data
125 (device *me);
126 
127 INLINE_DEVICE\
128 (psim *) device_system
129 (device *me);
130 
131 typedef struct _device_unit {
132   int nr_cells;
133   unsigned_cell cells[4]; /* unused cells are zero */
134 } device_unit;
135 
136 INLINE_DEVICE\
137 (const device_unit *) device_unit_address
138 (device *me);
139 
140 INLINE_DEVICE\
141 (int) device_decode_unit
142 (device *bus,
143  const char *unit,
144  device_unit *address);
145 
146 INLINE_DEVICE\
147 (int) device_encode_unit
148 (device *bus,
149  const device_unit *unit_address,
150  char *buf,
151  int sizeof_buf);
152 
153 
154 /* Convert an Open Firmware size into a form suitable for attach
155    address calls.
156 
157    Return a zero result if the address should be ignored when looking
158    for attach addresses */
159 
160 INLINE_DEVICE\
161 (int) device_address_to_attach_address
162 (device *me,
163  const device_unit *address,
164  int *attach_space,
165  unsigned_word *attach_address,
166  device *client);
167 
168 
169 /* Convert an Open Firmware size into a form suitable for attach
170    address calls
171 
172    Return a zero result if the address should be ignored */
173 
174 INLINE_DEVICE\
175 (int) device_size_to_attach_size
176 (device *me,
177  const device_unit *size,
178  unsigned *nr_bytes,
179  device *client);
180 
181 
182 INLINE_DEVICE\
183 (unsigned) device_nr_address_cells
184 (device *me);
185 
186 INLINE_DEVICE\
187 (unsigned) device_nr_size_cells
188 (device *me);
189 
190 
191 /* Properties:
192 
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.
196 
197    */
198 
199 /* The following are valid property types.  The property `array' is
200    for generic untyped data. */
201 
202 typedef enum {
203   array_property,
204   boolean_property,
205   ihandle_property, /*runtime*/
206   integer_property,
207   range_array_property,
208   reg_array_property,
209   string_property,
210   string_array_property,
211 } device_property_type;
212 
213 typedef struct _device_property device_property;
214 struct _device_property {
215   device *owner;
216   const char *name;
217   device_property_type type;
218   unsigned sizeof_array;
219   const void *array;
220   const device_property *original;
221   object_disposition disposition;
222 };
223 
224 
225 /* iterate through the properties attached to a device */
226 
227 INLINE_DEVICE\
228 (const device_property *) device_next_property
229 (const device_property *previous);
230 
231 INLINE_DEVICE\
232 (const device_property *) device_find_property
233 (device *me,
234  const char *property); /* NULL for first property */
235 
236 
237 /* Manipulate the properties belonging to a given device.
238 
239    SET on the other hand will force the properties value.  The
240    simulation is aborted if the property was present but of a
241    conflicting type.
242 
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.
247 
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>*)
254 
255    */
256 
257 
258 INLINE_DEVICE\
259 (void) device_add_array_property
260 (device *me,
261  const char *property,
262  const void *array,
263  int sizeof_array);
264 
265 INLINE_DEVICE\
266 (void) device_set_array_property
267 (device *me,
268  const char *property,
269  const void *array,
270  int sizeof_array);
271 
272 INLINE_DEVICE\
273 (const device_property *) device_find_array_property
274 (device *me,
275  const char *property);
276 
277 
278 
279 INLINE_DEVICE\
280 (void) device_add_boolean_property
281 (device *me,
282  const char *property,
283  int bool);
284 
285 INLINE_DEVICE\
286 (int) device_find_boolean_property
287 (device *me,
288  const char *property);
289 
290 
291 
292 typedef struct _ihandle_runtime_property_spec {
293   const char *full_path;
294 } ihandle_runtime_property_spec;
295 
296 INLINE_DEVICE\
297 (void) device_add_ihandle_runtime_property
298 (device *me,
299  const char *property,
300  const ihandle_runtime_property_spec *ihandle);
301 
302 INLINE_DEVICE\
303 (void) device_find_ihandle_runtime_property
304 (device *me,
305  const char *property,
306  ihandle_runtime_property_spec *ihandle);
307 
308 INLINE_DEVICE\
309 (void) device_set_ihandle_property
310 (device *me,
311  const char *property,
312  device_instance *ihandle);
313 
314 INLINE_DEVICE\
315 (device_instance *) device_find_ihandle_property
316 (device *me,
317  const char *property);
318 
319 
320 
321 INLINE_DEVICE\
322 (void) device_add_integer_property
323 (device *me,
324  const char *property,
325  signed_cell integer);
326 
327 INLINE_DEVICE\
328 (signed_cell) device_find_integer_property
329 (device *me,
330  const char *property);
331 
332 INLINE_DEVICE\
333 (int) device_find_integer_array_property
334 (device *me,
335  const char *property,
336  unsigned index,
337  signed_cell *integer);
338 
339 
340 
341 typedef struct _range_property_spec {
342   device_unit child_address;
343   device_unit parent_address;
344   device_unit size;
345 } range_property_spec;
346 
347 INLINE_DEVICE\
348 (void) device_add_range_array_property
349 (device *me,
350  const char *property,
351  const range_property_spec *ranges,
352  unsigned nr_ranges);
353 
354 INLINE_DEVICE\
355 (int) device_find_range_array_property
356 (device *me,
357  const char *property,
358  unsigned index,
359  range_property_spec *range);
360 
361 
362 
363 typedef struct _reg_property_spec {
364   device_unit address;
365   device_unit size;
366 } reg_property_spec;
367 
368 INLINE_DEVICE\
369 (void) device_add_reg_array_property
370 (device *me,
371  const char *property,
372  const reg_property_spec *reg,
373  unsigned nr_regs);
374 
375 INLINE_DEVICE\
376 (int) device_find_reg_array_property
377 (device *me,
378  const char *property,
379  unsigned index,
380  reg_property_spec *reg);
381 
382 
383 
384 INLINE_DEVICE\
385 (void) device_add_string_property
386 (device *me,
387  const char *property,
388  const char *string);
389 
390 INLINE_DEVICE\
391 (const char *) device_find_string_property
392 (device *me,
393  const char *property);
394 
395 
396 
397 typedef const char *string_property_spec;
398 
399 INLINE_DEVICE\
400 (void) device_add_string_array_property
401 (device *me,
402  const char *property,
403  const string_property_spec *strings,
404  unsigned nr_strings);
405 
406 INLINE_DEVICE\
407 (int) device_find_string_array_property
408 (device *me,
409  const char *property,
410  unsigned index,
411  string_property_spec *string);
412 
413 
414 
415 INLINE_DEVICE\
416 (void) device_add_duplicate_property
417 (device *me,
418  const char *property,
419  const device_property *original);
420 
421 
422 
423 /* Instances:
424 
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.
432 
433    This model includes methods that faciliate the creation of device
434    instance and (should a given device support it) standard operations
435    on those instances.
436 
437    */
438 
439 typedef struct _device_instance_callbacks device_instance_callbacks;
440 
441 INLINE_DEVICE\
442 (device_instance *) device_create_instance_from
443 (device *me, /*OR*/ device_instance *parent,
444  void *data,
445  const char *path,
446  const char *args,
447  const device_instance_callbacks *callbacks);
448 
449 INLINE_DEVICE\
450 (device_instance *) device_create_instance
451 (device *me,
452  const char *full_path,
453  const char *args);
454 
455 INLINE_DEVICE\
456 (void) device_instance_delete
457 (device_instance *instance);
458 
459 INLINE_DEVICE\
460 (int) device_instance_read
461 (device_instance *instance,
462  void *addr,
463  unsigned_word len);
464 
465 INLINE_DEVICE\
466 (int) device_instance_write
467 (device_instance *instance,
468  const void *addr,
469  unsigned_word len);
470 
471 INLINE_DEVICE\
472 (int) device_instance_seek
473 (device_instance *instance,
474  unsigned_word pos_hi,
475  unsigned_word pos_lo);
476 
477 INLINE_DEVICE\
478 (int) device_instance_call_method
479 (device_instance *instance,
480  const char *method,
481  int n_stack_args,
482  unsigned_cell stack_args[/*n_stack_args*/],
483  int n_stack_returns,
484  unsigned_cell stack_returns[/*n_stack_returns*/]);
485 
486 INLINE_DEVICE\
487 (device *) device_instance_device
488 (device_instance *instance);
489 
490 INLINE_DEVICE\
491 (const char *) device_instance_path
492 (device_instance *instance);
493 
494 INLINE_DEVICE\
495 (void *) device_instance_data
496 (device_instance *instance);
497 
498 
499 /* Interrupts:
500 
501    */
502 
503 /* Interrupt Source
504 
505    A device drives its interrupt line using the call
506 
507    */
508 
509 INLINE_DEVICE\
510 (void) device_interrupt_event
511 (device *me,
512  int my_port,
513  int value,
514  cpu *processor,
515  unsigned_word cia);
516 
517 /* This interrupt event will then be propogated to any attached
518    interrupt destinations.
519 
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
525    as the interrupt.
526 
527 
528    Interrupt Destinations
529 
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. */
534 
535 INLINE_DEVICE\
536 (void) device_interrupt_attach
537 (device *me,
538  int my_port,
539  device *dest,
540  int dest_port,
541  object_disposition disposition);
542 
543 INLINE_DEVICE\
544 (void) device_interrupt_detach
545 (device *me,
546  int my_port,
547  device *dest,
548  int dest_port);
549 
550 typedef void (device_interrupt_traverse_function)
551      (device *me,
552       int my_port,
553       device *dest,
554       int my_dest,
555       void *data);
556 
557 INLINE_DEVICE\
558 (void) device_interrupt_traverse
559 (device *me,
560  device_interrupt_traverse_function *handler,
561  void *data);
562 
563 
564 /* DESTINATION is attached (detached) to LINE of the device ME
565 
566 
567    Interrupt conversion
568 
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.
572 
573    To convert to/from the symbolic and internal representation of a
574    port name/number.  The following functions are available. */
575 
576 INLINE_DEVICE\
577 (int) device_interrupt_decode
578 (device *me,
579  const char *symbolic_name,
580  port_direction direction);
581 
582 INLINE_DEVICE\
583 (int) device_interrupt_encode
584 (device *me,
585  int port_number,
586  char *buf,
587  int sizeof_buf,
588  port_direction direction);
589 
590 
591 /* Hardware operations:
592 
593    */
594 
595 INLINE_DEVICE\
596 (unsigned) device_io_read_buffer
597 (device *me,
598  void *dest,
599  int space,
600  unsigned_word addr,
601  unsigned nr_bytes,
602  cpu *processor,
603  unsigned_word cia);
604 
605 INLINE_DEVICE\
606 (unsigned) device_io_write_buffer
607 (device *me,
608  const void *source,
609  int space,
610  unsigned_word addr,
611  unsigned nr_bytes,
612  cpu *processor,
613  unsigned_word cia);
614 
615 
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 */
621 
622 INLINE_DEVICE\
623 (unsigned) device_dma_read_buffer
624 (device *me,
625  void *dest,
626  int space,
627  unsigned_word addr,
628  unsigned nr_bytes);
629 
630 INLINE_DEVICE\
631 (unsigned) device_dma_write_buffer
632 (device *me,
633  const void *source,
634  int space,
635  unsigned_word addr,
636  unsigned nr_bytes,
637  int violate_read_only_section);
638 
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. */
644 
645 /* Address access attributes */
646 typedef enum _access_type {
647   access_invalid = 0,
648   access_read = 1,
649   access_write = 2,
650   access_read_write = 3,
651   access_exec = 4,
652   access_read_exec = 5,
653   access_write_exec = 6,
654   access_read_write_exec = 7,
655 } access_type;
656 
657 /* Address attachement types */
658 typedef enum _attach_type {
659   attach_invalid,
660   attach_raw_memory,
661   attach_callback,
662   /* ... */
663 } attach_type;
664 
665 INLINE_DEVICE\
666 (void) device_attach_address
667 (device *me,
668  attach_type attach,
669  int space,
670  unsigned_word addr,
671  unsigned nr_bytes,
672  access_type access,
673  device *client); /*callback/default*/
674 
675 INLINE_DEVICE\
676 (void) device_detach_address
677 (device *me,
678  attach_type attach,
679  int space,
680  unsigned_word addr,
681  unsigned nr_bytes,
682  access_type access,
683  device *client); /*callback/default*/
684 
685 /* Utilities:
686 
687    */
688 
689 /* IOCTL::
690 
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()>>.
696 
697    */
698 
699 typedef enum {
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;
706 
707 EXTERN_DEVICE\
708 (int) device_ioctl
709 (device *me,
710  cpu *processor,
711  unsigned_word cia,
712  device_ioctl_request request,
713  ...);
714 
715 
716 /* Error reporting::
717 
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
721 
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).
725 
726    */
727 
728 EXTERN_DEVICE\
729 (void volatile) device_error
730 (device *me,
731  const char *fmt,
732  ...) __attribute__ ((format (printf, 2, 3)));
733 
734 INLINE_DEVICE\
735 (int) device_trace
736 (device *me);
737 
738 
739 
740 /* External representation:
741 
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
746    calls.
747 
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
751 
752    */
753 
754 INLINE_DEVICE\
755 (device *) external_to_device
756 (device *tree_member,
757  unsigned_cell phandle);
758 
759 INLINE_DEVICE\
760 (unsigned_cell) device_to_external
761 (device *me);
762 
763 INLINE_DEVICE\
764 (device_instance *) external_to_device_instance
765 (device *tree_member,
766  unsigned_cell ihandle);
767 
768 INLINE_DEVICE\
769 (unsigned_cell) device_instance_to_external
770 (device_instance *me);
771 
772 
773 /* Event queue:
774 
775    The device inherets certain event queue operations from the main
776    simulation. */
777 
778 typedef void device_event_handler(void *data);
779 
780 INLINE_DEVICE\
781 (event_entry_tag) device_event_queue_schedule
782 (device *me,
783  signed64 delta_time,
784  device_event_handler *handler,
785  void *data);
786 
787 INLINE_EVENTS\
788 (void) device_event_queue_deschedule
789 (device *me,
790  event_entry_tag event_to_remove);
791 
792 INLINE_EVENTS\
793 (signed64) device_event_queue_time
794 (device *me);
795 
796 #endif /* _DEVICE_H_ */
797