Latest cagney update
[deliverable/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 INLINE_DEVICE(device *) device_parent
43 (device *me);
44
45 INLINE_DEVICE(device *) device_sibling
46 (device *me);
47
48 INLINE_DEVICE(device *) device_child
49 (device *me);
50
51 INLINE_DEVICE(const char *) device_name
52 (device *me);
53
54 INLINE_DEVICE(void *) 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 INLINE_DEVICE(device *)device_tree_add_device
62 (device *root,
63 const char *prefix,
64 device *new_sub_tree);
65
66 INLINE_DEVICE(device *) device_tree_add_found
67 (device *root,
68 const char *prefix,
69 const char *name);
70
71 INLINE_DEVICE(device *) device_tree_add_found_c
72 (device *root,
73 const char *prefix,
74 const char *name,
75 const char *c1);
76
77 INLINE_DEVICE(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 INLINE_DEVICE(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 INLINE_DEVICE(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 INLINE_DEVICE(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 INLINE_DEVICE(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 INLINE_DEVICE(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 INLINE_DEVICE(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 INLINE_DEVICE(void) 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 INLINE_DEVICE(void) 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 INLINE_DEVICE(const char *) device_find_next_property
191 (device *me,
192 const char *previous);
193
194 /* INLINE_DEVICE void device_add_property
195 No such external function, all properties, when added are explictly
196 typed */
197
198 INLINE_DEVICE(void) device_add_array_property
199 (device *me,
200 const char *property,
201 const void *array,
202 int sizeof_array);
203
204 INLINE_DEVICE(void) device_add_integer_property
205 (device *me,
206 const char *property,
207 signed_word integer);
208
209 INLINE_DEVICE(void) device_add_boolean_property
210 (device *me,
211 const char *property,
212 int bool);
213
214 INLINE_DEVICE(void) device_add_null_property
215 (device *me,
216 const char *property);
217
218 INLINE_DEVICE(void) device_add_string_property
219 (device *me,
220 const char *property,
221 const char *string);
222
223
224 /* Locate a property returning its description. Return NULL if the
225 named property is not found */
226
227 INLINE_DEVICE(const device_property *) device_find_property
228 (device *me,
229 const char *property);
230
231
232 /* Process all properties attached to the named device */
233
234 typedef void (device_traverse_property_function)
235 (device *me,
236 const char *name,
237 void *data);
238
239 INLINE_DEVICE(void) device_traverse_properties
240 (device *me,
241 device_traverse_property_function *traverse,
242 void *data);
243
244
245 /* Similar to above except that the property *must* be in the device
246 tree and *must* be of the specified type. */
247
248 INLINE_DEVICE(const device_property *) device_find_array_property
249 (device *me,
250 const char *property);
251
252 INLINE_DEVICE(signed_word) device_find_integer_property
253 (device *me,
254 const char *property);
255
256 INLINE_DEVICE(const char *) device_find_string_property
257 (device *me,
258 const char *property);
259
260 INLINE_DEVICE(int) device_find_boolean_property
261 (device *me,
262 const char *property);
263
264
265 \f
266 /* Device Hardware:
267
268 A device principaly is modeling real hardware that a processor can
269 directly interact with via load/stores dma's and interrupts. The
270 interface below is used by the hardware side of the device
271 model. */
272
273 /* Address access attributes that can be attached to a devices address
274 range */
275 typedef enum _access_type {
276 access_invalid = 0,
277 access_read = 1,
278 access_write = 2,
279 access_read_write = 3,
280 access_exec = 4,
281 access_read_exec = 5,
282 access_write_exec = 6,
283 access_read_write_exec = 7,
284 } access_type;
285
286
287 /* Address attachement types */
288 typedef enum _attach_type {
289 attach_invalid,
290 attach_callback,
291 attach_default,
292 attach_raw_memory,
293 } attach_type;
294
295
296 /* Initialization:
297
298 A device is made fully functional in two stages.
299
300 1. It is created. A device is created _before_ it is entered into
301 the device tree. During creation any permenant structures needed
302 by the device should be created/initialized.
303
304 2. It is initialized. Before a simulation run, each device in the
305 device tree is initialized in prefix order. As part of this
306 initialization, a device should (re)attach its self to its parent
307 as needed.
308
309 */
310
311 INLINE_DEVICE(device *) device_create
312 (const char *name,
313 device *parent);
314
315 /* some external functions want to create things */
316 typedef struct _device_callbacks device_callbacks;
317
318 INLINE_DEVICE(device *) device_create_from
319 (const char *name,
320 void *data,
321 const device_callbacks *callbacks,
322 device *parent);
323
324 INLINE_DEVICE(void) device_init
325 (device *me,
326 psim *system);
327
328 /* initialize the entire tree */
329
330 INLINE_DEVICE(void) device_tree_init
331 (device *root,
332 psim *system);
333
334
335 /* Data transfers:
336
337 A device may permit the reading/writing (IO) of its registers in
338 one or more address spaces. For instance, a PCI device may have
339 config registers in its config space and control registers in both
340 the io and memory spaces of a PCI bus.
341
342 Similarly, a device may initiate a data transfer (DMA) by passing
343 such a request up to its parent.
344
345 Init:
346
347 As part of its initialization (not creation) and possibly also as a
348 consequence of IO a device may attach its self to one or more of
349 the address spaces of its parent device.
350
351 For instance, a PCI device, during initialization would attach its
352 config registers (space=0?, base=0, nr_bytes=64) to its parent PCI
353 bridge. Later, due to a write to this config space, the same
354 device may in turn find it necessary to also attach its self to
355 it's parent's `memory' or `io' space.
356
357 To perform these operations, a device will call upon its parent
358 using either device_attach_address or device_detach_address.
359
360 * Any address specified is according to what the device expects to
361 see.
362
363 * Any detach operation must exactly match a previous attach.
364
365 * included with the attach or detach is the devices name, the
366 parent may use this as part of determining how to map map between a
367 child's address + space and its own.
368
369 * at any time, at most one device can have a default mapping
370 registered.
371
372
373 IO:
374
375 A device receives requests to perform reads/writes to its registers
376 or memory either A. from a processor or B. from a parent device.
377
378 The device may then in turn either A. resolve the IO request
379 locally by processing the data or trigering an exception or
380 B. re-mapping the access onto one of its local address spaces and
381 then in turn passing that on to one of its children.
382
383 * Any address passed is relative to the local device. Eg for PCI
384 config registers, the address would (normally) be in the range of 0
385 to 63.
386
387 * Any exception situtation triggered by an IO operation (processor
388 != NULL) is handled in one of the following ways: 1. Machine check
389 (and similar): issued immediatly by restarting the cpu; 2. External
390 exception: issue delayed (using events.h) until the current
391 instruction execution cycle is completed; 3. Slave device (and
392 similar): the need for the interrupt is passed on to the devices
393 parent (which being an interrupt control unit will in turn take one
394 of the actions described here); 4. Forget it.
395
396 * Any exception situtation trigered by a non IO operation
397 (processor == NULL) is handled buy returning 0.
398
399 * Transfers of size <= 8 and of a power of 2 *must* be correctly
400 aligned and should be treated as a `single cycle' transfer.
401
402 DMA:
403
404 A device initiates a DMA transfer by calling its parent with the
405 request. At the top level (if not done earlier) this is reflected
406 back down the tree as io read/writes to the target device.
407
408 This function is subject to change ...
409
410 */
411
412 INLINE_DEVICE(void) device_attach_address
413 (device *me,
414 const char *name,
415 attach_type attach,
416 int space,
417 unsigned_word addr,
418 unsigned nr_bytes,
419 access_type access,
420 device *who); /*callback/default*/
421
422 INLINE_DEVICE(void) device_detach_address
423 (device *me,
424 const char *name,
425 attach_type attach,
426 int space,
427 unsigned_word addr,
428 unsigned nr_bytes,
429 access_type access,
430 device *who); /*callback/default*/
431
432 INLINE_DEVICE(unsigned) device_io_read_buffer
433 (device *me,
434 void *dest,
435 int space,
436 unsigned_word addr,
437 unsigned nr_bytes,
438 cpu *processor,
439 unsigned_word cia);
440
441 INLINE_DEVICE(unsigned) device_io_write_buffer
442 (device *me,
443 const void *source,
444 int space,
445 unsigned_word addr,
446 unsigned nr_bytes,
447 cpu *processor,
448 unsigned_word cia);
449
450 INLINE_DEVICE(unsigned) device_dma_read_buffer
451 (device *me,
452 void *dest,
453 int space,
454 unsigned_word addr,
455 unsigned nr_bytes);
456
457 INLINE_DEVICE(unsigned) device_dma_write_buffer
458 (device *me,
459 const void *source,
460 int space,
461 unsigned_word addr,
462 unsigned nr_bytes,
463 int violate_read_only_section);
464
465
466 /* Interrupts:
467
468 As mentioned above. Instead of handling an interrupt directly, a
469 device may instead pass the need to interrupt on to its parent.
470
471 Init:
472
473 Before passing interrupts up to is parent, a device must first
474 attach its interrupt lines to the parent device. To do this, the
475 device uses the parents attach/detach calls.
476
477 Interrupts:
478
479 A child notifies a parent of a change in an interrupt lines status
480 using the interrupt call. Similarly, a parent may notify a child
481 of any `interrupt ack' sequence using the interrupt_ack call.
482
483 */
484
485 INLINE_DEVICE(void) device_attach_interrupt
486 (device *me,
487 device *who,
488 int interrupt_line,
489 const char *name);
490
491 INLINE_DEVICE(void) device_detach_interrupt
492 (device *me,
493 device *who,
494 int interrupt_line,
495 const char *name);
496
497 INLINE_DEVICE(void) device_interrupt
498 (device *me,
499 device *who,
500 int interrupt_line,
501 int interrupt_status,
502 cpu *processor,
503 unsigned_word cia);
504
505 INLINE_DEVICE(void) device_interrupt_ack
506 (device *me,
507 int interrupt_line,
508 int interrupt_status);
509
510
511 /* IOCTL:
512
513 Very simply, a catch all for any thing that turns up that until now
514 either hasn't been thought of or doesn't justify an extra function. */
515
516 EXTERN_DEVICE\
517 (void) device_ioctl
518 (device *me,
519 psim *system,
520 cpu *processor,
521 unsigned_word cia,
522 ...);
523
524
525 \f
526 /* Device software - the instance
527
528 Under development
529
530 In addition to the processor directly manipulating a device via
531 read/write operations. A program may manipulate a device
532 indirectly via OpenBoot calls. The following provide a higher
533 level software interface to the devices */
534
535 #if 0
536 INLINE_DEVICE(device_instance *)device_instance_open
537 (device *me,
538 const char *device_specifier);
539
540 INLINE_DEVICE(void) device_instance_close
541 (device_instance *instance);
542
543 INLINE_DEVICE(int) device_instance_read
544 (device_instance *instance,
545 void *addr,
546 unsigned_word len);
547
548 INLINE_DEVICE(int) device_instance_write
549 (device_instance *instance,
550 const void *addr,
551 unsigned_word len);
552
553 INLINE_DEVICE(int) device_instance_seek
554 (device_instance *instance,
555 unsigned_word pos_hi,
556 unsigned_word pos_lo);
557
558 INLINE_DEVICE(device *) device_instance_device
559 (device_instance *instance);
560
561 INLINE_DEVICE(const char *) device_instance_name
562 (device_instance *instance);
563 #endif
564
565
566
567 \f
568 /* Device dregs... */
569
570 /* Parse a device name, various formats:
571
572 uw: unsigned_word
573 u: unsigned
574 c: string */
575
576 INLINE_DEVICE(int) scand_c
577 (const char *name,
578 char *c1,
579 unsigned c1size);
580
581 INLINE_DEVICE(int) scand_c_uw_u
582 (const char *name,
583 char *c1,
584 unsigned c1size,
585 unsigned_word *uw2,
586 unsigned *u3);
587
588 INLINE_DEVICE(int) scand_uw
589 (const char *name,
590 unsigned_word *uw1);
591
592 INLINE_DEVICE(int) scand_uw_c
593 (const char *name,
594 unsigned_word *uw1,
595 char *c2,
596 unsigned c2size);
597
598 INLINE_DEVICE(int) scand_uw_u
599 (const char *name,
600 unsigned_word *uw1,
601 unsigned *u2);
602
603 INLINE_DEVICE(int) scand_uw_u_u
604 (const char *name,
605 unsigned_word *uw1,
606 unsigned *u2,
607 unsigned *u3);
608
609 INLINE_DEVICE(int) scand_uw_u_u_c
610 (const char *name,
611 unsigned_word *uw1,
612 unsigned *u2,
613 unsigned *u3,
614 char *c4,
615 unsigned c4size);
616
617 INLINE_DEVICE(int) scand_uw_uw
618 (const char *name,
619 unsigned_word *uw1,
620 unsigned_word *uw2);
621
622 INLINE_DEVICE(int) scand_uw_uw_u
623 (const char *name,
624 unsigned_word *uw1,
625 unsigned_word *uw2,
626 unsigned *u3);
627
628 INLINE_DEVICE(int) scand_uw_uw_u_u_c
629 (const char *name,
630 unsigned_word *uw1,
631 unsigned_word *uw2,
632 unsigned *u3,
633 unsigned *u4,
634 char *c5,
635 unsigned c5size);
636
637 INLINE_DEVICE(int) scand_uw_uw_u_u_u
638 (const char *name,
639 unsigned_word *uw1,
640 unsigned_word *uw2,
641 unsigned *u3,
642 unsigned *u4,
643 unsigned *u5);
644
645 #endif /* _DEVICE_TREE_H_ */
This page took 0.043365 seconds and 5 git commands to generate.