Make simulator build again on SunOS and HP/US systems
[deliverable/binutils-gdb.git] / sim / ppc / device.h
CommitLineData
93fac324
MM
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
979c3c25 42INLINE_DEVICE(device *) device_parent
93fac324
MM
43(device *me);
44
979c3c25 45INLINE_DEVICE(device *) device_sibling
93fac324
MM
46(device *me);
47
979c3c25
MM
48INLINE_DEVICE(device *) device_child
49(device *me);
50
51INLINE_DEVICE(const char *) device_name
52(device *me);
53
54INLINE_DEVICE(void *) device_data
93fac324
MM
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
979c3c25 61INLINE_DEVICE(device *)device_tree_add_device
93fac324
MM
62(device *root,
63 const char *prefix,
64 device *new_sub_tree);
65
979c3c25 66INLINE_DEVICE(device *) device_tree_add_found
93fac324
MM
67(device *root,
68 const char *prefix,
69 const char *name);
70
979c3c25 71INLINE_DEVICE(device *) device_tree_add_found_c
93fac324
MM
72(device *root,
73 const char *prefix,
74 const char *name,
75 const char *c1);
76
979c3c25 77INLINE_DEVICE(device *) device_tree_add_found_c_uw
93fac324
MM
78(device *root,
79 const char *prefix,
80 const char *name,
81 const char *c1,
82 unsigned_word uw2);
83
979c3c25 84INLINE_DEVICE(device *) device_tree_add_found_uw_u
93fac324
MM
85(device *root,
86 const char *prefix,
87 const char *name,
88 unsigned_word uw1,
89 unsigned u2);
90
979c3c25 91INLINE_DEVICE(device *) device_tree_add_found_uw_u_u
93fac324
MM
92(device *root,
93 const char *prefix,
94 const char *name,
95 unsigned_word uw1,
96 unsigned u2,
97 unsigned u3);
98
979c3c25 99INLINE_DEVICE(device *) device_tree_add_found_uw_u_u_c
93fac324
MM
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
979c3c25 108INLINE_DEVICE(device *) device_tree_add_found_uw_uw_u_u_c
93fac324
MM
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
979c3c25 118INLINE_DEVICE(device *) device_tree_add_found_uw_uw_u_u_u
93fac324
MM
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
979c3c25 132INLINE_DEVICE(device *) device_tree_find_device
93fac324
MM
133(device *root,
134 const char *path);
135
136
137/* traverse the device tree visiting all notes (either pre or post
138 fix) */
139
140typedef void (device_tree_traverse_function)
141 (device *device,
142 void *data);
143
979c3c25 144INLINE_DEVICE(void) device_tree_traverse
93fac324
MM
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
979c3c25 154INLINE_DEVICE(void) device_tree_dump
93fac324
MM
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
171typedef enum {
172 integer_property,
173 boolean_property,
174 string_property,
175 array_property,
176 null_property,
177} device_property_type;
178
179typedef struct _device_property device_property;
180struct _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
979c3c25 190INLINE_DEVICE(const char *) device_find_next_property
93fac324
MM
191(device *me,
192 const char *previous);
193
93fac324
MM
194/* INLINE_DEVICE void device_add_property
195 No such external function, all properties, when added are explictly
196 typed */
197
979c3c25 198INLINE_DEVICE(void) device_add_array_property
93fac324
MM
199(device *me,
200 const char *property,
201 const void *array,
202 int sizeof_array);
203
979c3c25 204INLINE_DEVICE(void) device_add_integer_property
93fac324
MM
205(device *me,
206 const char *property,
207 signed_word integer);
208
979c3c25 209INLINE_DEVICE(void) device_add_boolean_property
93fac324
MM
210(device *me,
211 const char *property,
212 int bool);
213
979c3c25 214INLINE_DEVICE(void) device_add_null_property
93fac324
MM
215(device *me,
216 const char *property);
217
979c3c25 218INLINE_DEVICE(void) device_add_string_property
93fac324
MM
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
979c3c25 227INLINE_DEVICE(const device_property *) device_find_property
93fac324
MM
228(device *me,
229 const char *property);
230
231
232/* Process all properties attached to the named device */
233
234typedef void (device_traverse_property_function)
235 (device *me,
236 const char *name,
237 void *data);
238
979c3c25 239INLINE_DEVICE(void) device_traverse_properties
93fac324
MM
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
979c3c25 248INLINE_DEVICE(const device_property *) device_find_array_property
93fac324
MM
249(device *me,
250 const char *property);
251
979c3c25 252INLINE_DEVICE(signed_word) device_find_integer_property
93fac324
MM
253(device *me,
254 const char *property);
255
979c3c25 256INLINE_DEVICE(const char *) device_find_string_property
93fac324
MM
257(device *me,
258 const char *property);
259
979c3c25 260INLINE_DEVICE(int) device_find_boolean_property
93fac324
MM
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 */
275typedef 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 */
288typedef 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
979c3c25 311INLINE_DEVICE(device *) device_create
93fac324
MM
312(const char *name,
313 device *parent);
314
315/* some external functions want to create things */
316typedef struct _device_callbacks device_callbacks;
317
979c3c25 318INLINE_DEVICE(device *) device_create_from
93fac324
MM
319(const char *name,
320 void *data,
321 const device_callbacks *callbacks,
322 device *parent);
323
979c3c25 324INLINE_DEVICE(void) device_init
93fac324
MM
325(device *me,
326 psim *system);
327
328/* initialize the entire tree */
329
979c3c25 330INLINE_DEVICE(void) device_tree_init
93fac324
MM
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
979c3c25 412INLINE_DEVICE(void) device_attach_address
93fac324
MM
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
979c3c25 422INLINE_DEVICE(void) device_detach_address
93fac324
MM
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
979c3c25 432INLINE_DEVICE(unsigned) device_io_read_buffer
93fac324
MM
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
979c3c25 441INLINE_DEVICE(unsigned) device_io_write_buffer
93fac324
MM
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
979c3c25 450INLINE_DEVICE(unsigned) device_dma_read_buffer
93fac324
MM
451(device *me,
452 void *dest,
453 int space,
454 unsigned_word addr,
455 unsigned nr_bytes);
456
979c3c25 457INLINE_DEVICE(unsigned) device_dma_write_buffer
93fac324
MM
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
979c3c25 485INLINE_DEVICE(void) device_attach_interrupt
93fac324
MM
486(device *me,
487 device *who,
488 int interrupt_line,
489 const char *name);
490
979c3c25 491INLINE_DEVICE(void) device_detach_interrupt
93fac324
MM
492(device *me,
493 device *who,
494 int interrupt_line,
495 const char *name);
496
979c3c25 497INLINE_DEVICE(void) device_interrupt
93fac324
MM
498(device *me,
499 device *who,
500 int interrupt_line,
501 int interrupt_status,
502 cpu *processor,
503 unsigned_word cia);
504
979c3c25 505INLINE_DEVICE(void) device_interrupt_ack
93fac324
MM
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
979c3c25
MM
516EXTERN_DEVICE\
517(void) device_ioctl
93fac324
MM
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
669b4e1e 535#if 0
979c3c25 536INLINE_DEVICE(device_instance *)device_instance_open
93fac324
MM
537(device *me,
538 const char *device_specifier);
539
979c3c25 540INLINE_DEVICE(void) device_instance_close
93fac324
MM
541(device_instance *instance);
542
979c3c25 543INLINE_DEVICE(int) device_instance_read
93fac324
MM
544(device_instance *instance,
545 void *addr,
546 unsigned_word len);
547
979c3c25 548INLINE_DEVICE(int) device_instance_write
93fac324
MM
549(device_instance *instance,
550 const void *addr,
551 unsigned_word len);
552
979c3c25 553INLINE_DEVICE(int) device_instance_seek
93fac324
MM
554(device_instance *instance,
555 unsigned_word pos_hi,
556 unsigned_word pos_lo);
557
979c3c25 558INLINE_DEVICE(device *) device_instance_device
93fac324
MM
559(device_instance *instance);
560
979c3c25 561INLINE_DEVICE(const char *) device_instance_name
93fac324 562(device_instance *instance);
669b4e1e 563#endif
93fac324
MM
564
565
566
567\f
568/* Device dregs... */
569
93fac324
MM
570/* Parse a device name, various formats:
571
572 uw: unsigned_word
573 u: unsigned
574 c: string */
575
979c3c25 576INLINE_DEVICE(int) scand_c
93fac324
MM
577(const char *name,
578 char *c1,
579 unsigned c1size);
580
979c3c25 581INLINE_DEVICE(int) scand_c_uw_u
93fac324
MM
582(const char *name,
583 char *c1,
584 unsigned c1size,
585 unsigned_word *uw2,
586 unsigned *u3);
587
979c3c25 588INLINE_DEVICE(int) scand_uw
93fac324
MM
589(const char *name,
590 unsigned_word *uw1);
591
979c3c25 592INLINE_DEVICE(int) scand_uw_c
93fac324
MM
593(const char *name,
594 unsigned_word *uw1,
595 char *c2,
596 unsigned c2size);
597
979c3c25 598INLINE_DEVICE(int) scand_uw_u
93fac324
MM
599(const char *name,
600 unsigned_word *uw1,
601 unsigned *u2);
602
979c3c25 603INLINE_DEVICE(int) scand_uw_u_u
93fac324
MM
604(const char *name,
605 unsigned_word *uw1,
606 unsigned *u2,
607 unsigned *u3);
608
979c3c25 609INLINE_DEVICE(int) scand_uw_u_u_c
93fac324
MM
610(const char *name,
611 unsigned_word *uw1,
612 unsigned *u2,
613 unsigned *u3,
614 char *c4,
615 unsigned c4size);
616
979c3c25 617INLINE_DEVICE(int) scand_uw_uw
93fac324
MM
618(const char *name,
619 unsigned_word *uw1,
620 unsigned_word *uw2);
621
979c3c25 622INLINE_DEVICE(int) scand_uw_uw_u
93fac324
MM
623(const char *name,
624 unsigned_word *uw1,
625 unsigned_word *uw2,
626 unsigned *u3);
627
979c3c25 628INLINE_DEVICE(int) scand_uw_uw_u_u_c
93fac324
MM
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
979c3c25 637INLINE_DEVICE(int) scand_uw_uw_u_u_u
93fac324
MM
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.061588 seconds and 4 git commands to generate.