Changes from Andrew
[binutils-gdb.git] / sim / ppc / device.h
1 /* This file is part of the program psim.
2
3 Copyright (C) 1994-1995, 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_TREE_H_
23 #define _DEVICE_TREE_H_
24
25 #ifndef INLINE_DEVICE
26 #define INLINE_DEVICE
27 #endif
28
29
30
31 /* declared in basics.h, this object is used everywhere */
32 /* typedef struct _device device; */
33
34
35
36 \f
37 /* Device Tree:
38
39 All the devices in this model live in a tree. The following allow
40 the location/manipulation of this tree */
41
42 device INLINE_DEVICE *device_sibling
43 (device *me);
44
45 device INLINE_DEVICE *device_child
46 (device *me);
47
48 device INLINE_DEVICE *device_parent
49 (device *me);
50
51 const char INLINE_DEVICE *device_name
52 (device *me);
53
54 void INLINE_DEVICE *device_data
55 (device *me);
56
57
58 /* Grow the device tree adding either a specific device or
59 alternativly a device found in the device table */
60
61 device INLINE_DEVICE *device_tree_add_device
62 (device *root,
63 const char *prefix,
64 device *new_sub_tree);
65
66 device INLINE_DEVICE *device_tree_add_found
67 (device *root,
68 const char *prefix,
69 const char *name);
70
71 device INLINE_DEVICE *device_tree_add_found_c
72 (device *root,
73 const char *prefix,
74 const char *name,
75 const char *c1);
76
77 device INLINE_DEVICE *device_tree_add_found_c_uw
78 (device *root,
79 const char *prefix,
80 const char *name,
81 const char *c1,
82 unsigned_word uw2);
83
84 device INLINE_DEVICE *device_tree_add_found_uw_u
85 (device *root,
86 const char *prefix,
87 const char *name,
88 unsigned_word uw1,
89 unsigned u2);
90
91 device INLINE_DEVICE *device_tree_add_found_uw_u_u
92 (device *root,
93 const char *prefix,
94 const char *name,
95 unsigned_word uw1,
96 unsigned u2,
97 unsigned u3);
98
99 device INLINE_DEVICE *device_tree_add_found_uw_u_u_c
100 (device *root,
101 const char *prefix,
102 const char *name,
103 unsigned_word uw1,
104 unsigned u2,
105 unsigned u3,
106 const char *c4);
107
108 device INLINE_DEVICE *device_tree_add_found_uw_uw_u_u_c
109 (device *root,
110 const char *prefix,
111 const char *name,
112 unsigned_word uw1,
113 unsigned_word uw2,
114 unsigned u3,
115 unsigned u4,
116 const char *c5);
117
118 device INLINE_DEVICE *device_tree_add_found_uw_uw_u_u_u
119 (device *root,
120 const char *prefix,
121 const char *name,
122 unsigned_word uw1,
123 unsigned_word uw2,
124 unsigned u3,
125 unsigned u4,
126 unsigned u5);
127
128
129 /* Query the device tree, null is returned if the specified device is
130 not found */
131
132 device INLINE_DEVICE *device_tree_find_device
133 (device *root,
134 const char *path);
135
136
137 /* traverse the device tree visiting all notes (either pre or post
138 fix) */
139
140 typedef void (device_tree_traverse_function)
141 (device *device,
142 void *data);
143
144 void INLINE_DEVICE device_tree_traverse
145 (device *root,
146 device_tree_traverse_function *prefix,
147 device_tree_traverse_function *postfix,
148 void *data);
149
150
151 /* dump a node, this can be passed to the device_tree_traverse()
152 function to dump out the entire device tree */
153
154 void INLINE_DEVICE device_tree_dump
155 (device *device,
156 void *ignore_data_argument);
157
158
159
160 \f
161 /* Device Properties:
162
163 Attached to a device (typically by open boot firmware) are
164 properties that profile the devices features. The below allow the
165 manipulation of device properties */
166
167 /* Each device can have associated properties. Internal to
168 psim those properties are strictly typed. Within the simulation,
169 no such control exists */
170
171 typedef enum {
172 integer_property,
173 boolean_property,
174 string_property,
175 array_property,
176 null_property,
177 } device_property_type;
178
179 typedef struct _device_property device_property;
180 struct _device_property {
181 device *owner;
182 device_property_type type;
183 unsigned sizeof_array;
184 const void *array;
185 };
186
187
188 /* Basic operations used by software */
189
190 const char INLINE_DEVICE *device_find_next_property
191 (device *me,
192 const char *previous);
193
194 void INLINE_DEVICE device_set_property
195 (device *me,
196 const char *property,
197 const void *array,
198 int sizeof_array);
199
200
201 /* INLINE_DEVICE void device_add_property
202 No such external function, all properties, when added are explictly
203 typed */
204
205 void INLINE_DEVICE device_add_array_property
206 (device *me,
207 const char *property,
208 const void *array,
209 int sizeof_array);
210
211 void INLINE_DEVICE device_add_integer_property
212 (device *me,
213 const char *property,
214 signed_word integer);
215
216 void INLINE_DEVICE device_add_boolean_property
217 (device *me,
218 const char *property,
219 int bool);
220
221 void INLINE_DEVICE device_add_null_property
222 (device *me,
223 const char *property);
224
225 void INLINE_DEVICE device_add_string_property
226 (device *me,
227 const char *property,
228 const char *string);
229
230
231 /* Locate a property returning its description. Return NULL if the
232 named property is not found */
233
234 const device_property INLINE_DEVICE *device_find_property
235 (device *me,
236 const char *property);
237
238
239 /* Process all properties attached to the named device */
240
241 typedef void (device_traverse_property_function)
242 (device *me,
243 const char *name,
244 void *data);
245
246 void INLINE_DEVICE device_traverse_properties
247 (device *me,
248 device_traverse_property_function *traverse,
249 void *data);
250
251
252 /* Similar to above except that the property *must* be in the device
253 tree and *must* be of the specified type. */
254
255 const device_property INLINE_DEVICE *device_find_array_property
256 (device *me,
257 const char *property);
258
259 signed_word INLINE_DEVICE device_find_integer_property
260 (device *me,
261 const char *property);
262
263 const char INLINE_DEVICE *device_find_string_property
264 (device *me,
265 const char *property);
266
267 int INLINE_DEVICE device_find_boolean_property
268 (device *me,
269 const char *property);
270
271
272 \f
273 /* Device Hardware:
274
275 A device principaly is modeling real hardware that a processor can
276 directly interact with via load/stores dma's and interrupts. The
277 interface below is used by the hardware side of the device
278 model. */
279
280 /* Address access attributes that can be attached to a devices address
281 range */
282 typedef enum _access_type {
283 access_invalid = 0,
284 access_read = 1,
285 access_write = 2,
286 access_read_write = 3,
287 access_exec = 4,
288 access_read_exec = 5,
289 access_write_exec = 6,
290 access_read_write_exec = 7,
291 } access_type;
292
293
294 /* Address attachement types */
295 typedef enum _attach_type {
296 attach_invalid,
297 attach_callback,
298 attach_default,
299 attach_raw_memory,
300 } attach_type;
301
302
303 /* Initialization:
304
305 A device is made fully functional in two stages.
306
307 1. It is created. A device is created _before_ it is entered into
308 the device tree. During creation any permenant structures needed
309 by the device should be created/initialized.
310
311 2. It is initialized. Before a simulation run, each device in the
312 device tree is initialized in prefix order. As part of this
313 initialization, a device should (re)attach its self to its parent
314 as needed.
315
316 */
317
318 device INLINE_DEVICE *device_create
319 (const char *name,
320 device *parent);
321
322 /* some external functions want to create things */
323 typedef struct _device_callbacks device_callbacks;
324
325 device INLINE_DEVICE *device_create_from
326 (const char *name,
327 void *data,
328 const device_callbacks *callbacks,
329 device *parent);
330
331 void INLINE_DEVICE device_init
332 (device *me,
333 psim *system);
334
335 /* initialize the entire tree */
336
337 void INLINE_DEVICE device_tree_init
338 (device *root,
339 psim *system);
340
341
342 /* Data transfers:
343
344 A device may permit the reading/writing (IO) of its registers in
345 one or more address spaces. For instance, a PCI device may have
346 config registers in its config space and control registers in both
347 the io and memory spaces of a PCI bus.
348
349 Similarly, a device may initiate a data transfer (DMA) by passing
350 such a request up to its parent.
351
352 Init:
353
354 As part of its initialization (not creation) and possibly also as a
355 consequence of IO a device may attach its self to one or more of
356 the address spaces of its parent device.
357
358 For instance, a PCI device, during initialization would attach its
359 config registers (space=0?, base=0, nr_bytes=64) to its parent PCI
360 bridge. Later, due to a write to this config space, the same
361 device may in turn find it necessary to also attach its self to
362 it's parent's `memory' or `io' space.
363
364 To perform these operations, a device will call upon its parent
365 using either device_attach_address or device_detach_address.
366
367 * Any address specified is according to what the device expects to
368 see.
369
370 * Any detach operation must exactly match a previous attach.
371
372 * included with the attach or detach is the devices name, the
373 parent may use this as part of determining how to map map between a
374 child's address + space and its own.
375
376 * at any time, at most one device can have a default mapping
377 registered.
378
379
380 IO:
381
382 A device receives requests to perform reads/writes to its registers
383 or memory either A. from a processor or B. from a parent device.
384
385 The device may then in turn either A. resolve the IO request
386 locally by processing the data or trigering an exception or
387 B. re-mapping the access onto one of its local address spaces and
388 then in turn passing that on to one of its children.
389
390 * Any address passed is relative to the local device. Eg for PCI
391 config registers, the address would (normally) be in the range of 0
392 to 63.
393
394 * Any exception situtation triggered by an IO operation (processor
395 != NULL) is handled in one of the following ways: 1. Machine check
396 (and similar): issued immediatly by restarting the cpu; 2. External
397 exception: issue delayed (using events.h) until the current
398 instruction execution cycle is completed; 3. Slave device (and
399 similar): the need for the interrupt is passed on to the devices
400 parent (which being an interrupt control unit will in turn take one
401 of the actions described here); 4. Forget it.
402
403 * Any exception situtation trigered by a non IO operation
404 (processor == NULL) is handled buy returning 0.
405
406 * Transfers of size <= 8 and of a power of 2 *must* be correctly
407 aligned and should be treated as a `single cycle' transfer.
408
409 DMA:
410
411 A device initiates a DMA transfer by calling its parent with the
412 request. At the top level (if not done earlier) this is reflected
413 back down the tree as io read/writes to the target device.
414
415 This function is subject to change ...
416
417 */
418
419 void INLINE_DEVICE device_attach_address
420 (device *me,
421 const char *name,
422 attach_type attach,
423 int space,
424 unsigned_word addr,
425 unsigned nr_bytes,
426 access_type access,
427 device *who); /*callback/default*/
428
429 void INLINE_DEVICE device_detach_address
430 (device *me,
431 const char *name,
432 attach_type attach,
433 int space,
434 unsigned_word addr,
435 unsigned nr_bytes,
436 access_type access,
437 device *who); /*callback/default*/
438
439 unsigned INLINE_DEVICE device_io_read_buffer
440 (device *me,
441 void *dest,
442 int space,
443 unsigned_word addr,
444 unsigned nr_bytes,
445 cpu *processor,
446 unsigned_word cia);
447
448 unsigned INLINE_DEVICE device_io_write_buffer
449 (device *me,
450 const void *source,
451 int space,
452 unsigned_word addr,
453 unsigned nr_bytes,
454 cpu *processor,
455 unsigned_word cia);
456
457 unsigned INLINE_DEVICE device_dma_read_buffer
458 (device *me,
459 void *dest,
460 int space,
461 unsigned_word addr,
462 unsigned nr_bytes);
463
464 unsigned INLINE_DEVICE device_dma_write_buffer
465 (device *me,
466 const void *source,
467 int space,
468 unsigned_word addr,
469 unsigned nr_bytes,
470 int violate_read_only_section);
471
472
473 /* Interrupts:
474
475 As mentioned above. Instead of handling an interrupt directly, a
476 device may instead pass the need to interrupt on to its parent.
477
478 Init:
479
480 Before passing interrupts up to is parent, a device must first
481 attach its interrupt lines to the parent device. To do this, the
482 device uses the parents attach/detach calls.
483
484 Interrupts:
485
486 A child notifies a parent of a change in an interrupt lines status
487 using the interrupt call. Similarly, a parent may notify a child
488 of any `interrupt ack' sequence using the interrupt_ack call.
489
490 */
491
492 void INLINE_DEVICE device_attach_interrupt
493 (device *me,
494 device *who,
495 int interrupt_line,
496 const char *name);
497
498 void INLINE_DEVICE device_detach_interrupt
499 (device *me,
500 device *who,
501 int interrupt_line,
502 const char *name);
503
504 void INLINE_DEVICE device_interrupt
505 (device *me,
506 device *who,
507 int interrupt_line,
508 int interrupt_status,
509 cpu *processor,
510 unsigned_word cia);
511
512 void INLINE_DEVICE device_interrupt_ack
513 (device *me,
514 int interrupt_line,
515 int interrupt_status);
516
517
518 /* IOCTL:
519
520 Very simply, a catch all for any thing that turns up that until now
521 either hasn't been thought of or doesn't justify an extra function. */
522
523 void EXTERN_DEVICE device_ioctl
524 (device *me,
525 psim *system,
526 cpu *processor,
527 unsigned_word cia,
528 ...);
529
530
531 \f
532 /* Device software - the instance
533
534 Under development
535
536 In addition to the processor directly manipulating a device via
537 read/write operations. A program may manipulate a device
538 indirectly via OpenBoot calls. The following provide a higher
539 level software interface to the devices */
540
541 device_instance INLINE_DEVICE *device_instance_open
542 (device *me,
543 const char *device_specifier);
544
545 void INLINE_DEVICE device_instance_close
546 (device_instance *instance);
547
548 int INLINE_DEVICE device_instance_read
549 (device_instance *instance,
550 void *addr,
551 unsigned_word len);
552
553 int INLINE_DEVICE device_instance_write
554 (device_instance *instance,
555 const void *addr,
556 unsigned_word len);
557
558 int INLINE_DEVICE device_instance_seek
559 (device_instance *instance,
560 unsigned_word pos_hi,
561 unsigned_word pos_lo);
562
563 device INLINE_DEVICE *device_instance_device
564 (device_instance *instance);
565
566 const char INLINE_DEVICE *device_instance_name
567 (device_instance *instance);
568
569
570
571
572 \f
573 /* Device dregs... */
574
575 /* Parse a device name */
576
577 void INLINE_DEVICE device_tree_parse_name
578 (const char *name,
579 const char **driver_name,
580 const char **unit_address,
581 const char **device_arguments,
582 const char **end);
583
584
585 /* Parse a device name, various formats:
586
587 uw: unsigned_word
588 u: unsigned
589 c: string */
590
591 int INLINE_DEVICE scand_c
592 (const char *name,
593 char *c1,
594 unsigned c1size);
595
596 int INLINE_DEVICE scand_c_uw_u
597 (const char *name,
598 char *c1,
599 unsigned c1size,
600 unsigned_word *uw2,
601 unsigned *u3);
602
603 int INLINE_DEVICE scand_uw
604 (const char *name,
605 unsigned_word *uw1);
606
607 int INLINE_DEVICE scand_uw_c
608 (const char *name,
609 unsigned_word *uw1,
610 char *c2,
611 unsigned c2size);
612
613 int INLINE_DEVICE scand_uw_u
614 (const char *name,
615 unsigned_word *uw1,
616 unsigned *u2);
617
618 int INLINE_DEVICE scand_uw_u_u
619 (const char *name,
620 unsigned_word *uw1,
621 unsigned *u2,
622 unsigned *u3);
623
624 int INLINE_DEVICE scand_uw_u_u_c
625 (const char *name,
626 unsigned_word *uw1,
627 unsigned *u2,
628 unsigned *u3,
629 char *c4,
630 unsigned c4size);
631
632 int INLINE_DEVICE scand_uw_uw
633 (const char *name,
634 unsigned_word *uw1,
635 unsigned_word *uw2);
636
637 int INLINE_DEVICE scand_uw_uw_u
638 (const char *name,
639 unsigned_word *uw1,
640 unsigned_word *uw2,
641 unsigned *u3);
642
643 int INLINE_DEVICE scand_uw_uw_u_u_c
644 (const char *name,
645 unsigned_word *uw1,
646 unsigned_word *uw2,
647 unsigned *u3,
648 unsigned *u4,
649 char *c5,
650 unsigned c5size);
651
652 int INLINE_DEVICE scand_uw_uw_u_u_u
653 (const char *name,
654 unsigned_word *uw1,
655 unsigned_word *uw2,
656 unsigned *u3,
657 unsigned *u4,
658 unsigned *u5);
659
660 #endif /* _DEVICE_TREE_H_ */