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
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);
54
55INLINE_DEVICE\
56(void) device_usage
57(int verbose);
58
59
60/* Device initialization: */
61
62INLINE_DEVICE\
63(void) device_clean
64(device *root,
65 void *data);
66
67INLINE_DEVICE\
68(void) device_init_static_properties
69(device *me,
70 void *data);
71
72INLINE_DEVICE\
73(void) device_init_address
74(device *me,
75 void *data);
76
77INLINE_DEVICE\
78(void) device_init_runtime_properties
79(device *me,
80 void *data);
81
82INLINE_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
96INLINE_DEVICE\
97(device *) device_parent
98(device *me);
99
100INLINE_DEVICE\
101(device *) device_root
102(device *me);
103
104INLINE_DEVICE\
105(device *) device_sibling
106(device *me);
107
108INLINE_DEVICE\
109(device *) device_child
110(device *me);
111
112INLINE_DEVICE\
113(const char *) device_name
114(device *me);
115
116INLINE_DEVICE\
117(const char *) device_base
118(device *me);
119
120INLINE_DEVICE\
121(const char *) device_path
122(device *me);
123
124INLINE_DEVICE\
125(void *) device_data
126(device *me);
127
128INLINE_DEVICE\
129(psim *) device_system
130(device *me);
131
132typedef struct _device_unit {
133  int nr_cells;
134  unsigned_cell cells[4]; /* unused cells are zero */
135} device_unit;
136
137INLINE_DEVICE\
138(const device_unit *) device_unit_address
139(device *me);
140
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
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
203typedef 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
214typedef struct _device_property device_property;
215struct _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
228INLINE_DEVICE\
229(const device_property *) device_next_property
230(const device_property *previous);
231
232INLINE_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
259INLINE_DEVICE\
260(void) device_add_array_property
261(device *me,
262 const char *property,
263 const void *array,
264 int sizeof_array);
265
266INLINE_DEVICE\
267(void) device_set_array_property
268(device *me,
269 const char *property,
270 const void *array,
271 int sizeof_array);
272
273INLINE_DEVICE\
274(const device_property *) device_find_array_property
275(device *me,
276 const char *property);
277
278
279
280INLINE_DEVICE\
281(void) device_add_boolean_property
282(device *me,
283 const char *property,
284 int bool);
285
286INLINE_DEVICE\
287(int) device_find_boolean_property
288(device *me,
289 const char *property);
290
291
292
293typedef struct _ihandle_runtime_property_spec {
294  const char *full_path;
295} ihandle_runtime_property_spec;
296
297INLINE_DEVICE\
298(void) device_add_ihandle_runtime_property
299(device *me,
300 const char *property,
301 const ihandle_runtime_property_spec *ihandle);
302
303INLINE_DEVICE\
304(void) device_find_ihandle_runtime_property
305(device *me,
306 const char *property,
307 ihandle_runtime_property_spec *ihandle);
308
309INLINE_DEVICE\
310(void) device_set_ihandle_property
311(device *me,
312 const char *property,
313 device_instance *ihandle);
314
315INLINE_DEVICE\
316(device_instance *) device_find_ihandle_property
317(device *me,
318 const char *property);
319
320
321
322INLINE_DEVICE\
323(void) device_add_integer_property
324(device *me,
325 const char *property,
326 signed_cell integer);
327
328INLINE_DEVICE\
329(signed_cell) device_find_integer_property
330(device *me,
331 const char *property);
332
333INLINE_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
342typedef struct _range_property_spec {
343  device_unit child_address;
344  device_unit parent_address;
345  device_unit size;
346} range_property_spec;
347
348INLINE_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
355INLINE_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
364typedef struct _reg_property_spec {
365  device_unit address;
366  device_unit size;
367} reg_property_spec;
368
369INLINE_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
376INLINE_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
385INLINE_DEVICE\
386(void) device_add_string_property
387(device *me,
388 const char *property,
389 const char *string);
390
391INLINE_DEVICE\
392(const char *) device_find_string_property
393(device *me,
394 const char *property);
395
396
397
398typedef const char *string_property_spec;
399
400INLINE_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
407INLINE_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
416INLINE_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
440typedef struct _device_instance_callbacks device_instance_callbacks;
441
442INLINE_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
450INLINE_DEVICE\
451(device_instance *) device_create_instance
452(device *me,
453 const char *full_path,
454 const char *args);
455
456INLINE_DEVICE\
457(void) device_instance_delete
458(device_instance *instance);
459
460INLINE_DEVICE\
461(int) device_instance_read
462(device_instance *instance,
463 void *addr,
464 unsigned_word len);
465
466INLINE_DEVICE\
467(int) device_instance_write
468(device_instance *instance,
469 const void *addr,
470 unsigned_word len);
471
472INLINE_DEVICE\
473(int) device_instance_seek
474(device_instance *instance,
475 unsigned_word pos_hi,
476 unsigned_word pos_lo);
477
478INLINE_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
487INLINE_DEVICE\
488(device *) device_instance_device
489(device_instance *instance);
490
491INLINE_DEVICE\
492(const char *) device_instance_path
493(device_instance *instance);
494
495INLINE_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
510INLINE_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
536INLINE_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
544INLINE_DEVICE\
545(void) device_interrupt_detach
546(device *me,
547 int my_port,
548 device *dest,
549 int dest_port);
550
551typedef void (device_interrupt_traverse_function)
552     (device *me,
553      int my_port,
554      device *dest,
555      int my_dest,
556      void *data);
557
558INLINE_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
577INLINE_DEVICE\
578(int) device_interrupt_decode
579(device *me,
580 const char *symbolic_name,
581 port_direction direction);
582
583INLINE_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
596INLINE_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
606INLINE_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
623INLINE_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
631INLINE_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 */
647typedef 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 */
659typedef enum _attach_type {
660  attach_invalid,
661  attach_raw_memory,
662  attach_callback,
663  /* ... */
664} attach_type;
665
666INLINE_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
676INLINE_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
700typedef 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
708EXTERN_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
729EXTERN_DEVICE\
730(void volatile) device_error
731(device *me,
732 const char *fmt,
733 ...) __attribute__ ((format (printf, 2, 3)));
734
735INLINE_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
755INLINE_DEVICE\
756(device *) external_to_device
757(device *tree_member,
758 unsigned_cell phandle);
759
760INLINE_DEVICE\
761(unsigned_cell) device_to_external
762(device *me);
763
764INLINE_DEVICE\
765(device_instance *) external_to_device_instance
766(device *tree_member,
767 unsigned_cell ihandle);
768
769INLINE_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
779typedef void device_event_handler(void *data);
780
781INLINE_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
788INLINE_EVENTS\
789(void) device_event_queue_deschedule
790(device *me,
791 event_entry_tag event_to_remove);
792
793INLINE_EVENTS\
794(signed64) device_event_queue_time
795(device *me);
796
797#endif /* _DEVICE_H_ */
798