1 /* This file is part of the program psim.
3 Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
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.
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.
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.
22 #ifndef _DEVICE_TREE_H_
23 #define _DEVICE_TREE_H_
31 /* declared in basics.h, this object is used everywhere */
32 /* typedef struct _device device; */
39 All the devices in this model live in a tree. The following allow
40 the location/manipulation of this tree */
42 INLINE_DEVICE(device
*) device_parent
45 INLINE_DEVICE(device
*) device_sibling
48 INLINE_DEVICE(device
*) device_child
51 INLINE_DEVICE(const char *) device_name
54 INLINE_DEVICE(void *) device_data
58 /* Grow the device tree adding either a specific device or
59 alternativly a device found in the device table */
61 INLINE_DEVICE(device
*)device_tree_add_device
64 device
*new_sub_tree
);
66 INLINE_DEVICE(device
*) device_tree_add_found
71 INLINE_DEVICE(device
*) device_tree_add_found_c
77 INLINE_DEVICE(device
*) device_tree_add_found_c_uw
84 INLINE_DEVICE(device
*) device_tree_add_found_uw_u
91 INLINE_DEVICE(device
*) device_tree_add_found_uw_u_u
99 INLINE_DEVICE(device
*) device_tree_add_found_uw_u_u_c
108 INLINE_DEVICE(device
*) device_tree_add_found_uw_uw_u_u_c
118 INLINE_DEVICE(device
*) device_tree_add_found_uw_uw_u_u_u
129 /* Query the device tree, null is returned if the specified device is
132 INLINE_DEVICE(device
*) device_tree_find_device
137 /* traverse the device tree visiting all notes (either pre or post
140 typedef void (device_tree_traverse_function
)
144 INLINE_DEVICE(void) device_tree_traverse
146 device_tree_traverse_function
*prefix
,
147 device_tree_traverse_function
*postfix
,
151 /* dump a node, this can be passed to the device_tree_traverse()
152 function to dump out the entire device tree */
154 INLINE_DEVICE(void) device_tree_dump
156 void *ignore_data_argument
);
161 /* Device Properties:
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 */
167 /* Each device can have associated properties. Internal to
168 psim those properties are strictly typed. Within the simulation,
169 no such control exists */
177 } device_property_type
;
179 typedef struct _device_property device_property
;
180 struct _device_property
{
182 device_property_type type
;
183 unsigned sizeof_array
;
188 /* Basic operations used by software */
190 INLINE_DEVICE(const char *) device_find_next_property
192 const char *previous
);
194 /* INLINE_DEVICE void device_add_property
195 No such external function, all properties, when added are explictly
198 INLINE_DEVICE(void) device_add_array_property
200 const char *property
,
204 INLINE_DEVICE(void) device_add_integer_property
206 const char *property
,
207 signed_word integer
);
209 INLINE_DEVICE(void) device_add_boolean_property
211 const char *property
,
214 INLINE_DEVICE(void) device_add_null_property
216 const char *property
);
218 INLINE_DEVICE(void) device_add_string_property
220 const char *property
,
224 /* Locate a property returning its description. Return NULL if the
225 named property is not found */
227 INLINE_DEVICE(const device_property
*) device_find_property
229 const char *property
);
232 /* Process all properties attached to the named device */
234 typedef void (device_traverse_property_function
)
239 INLINE_DEVICE(void) device_traverse_properties
241 device_traverse_property_function
*traverse
,
245 /* Similar to above except that the property *must* be in the device
246 tree and *must* be of the specified type. */
248 INLINE_DEVICE(const device_property
*) device_find_array_property
250 const char *property
);
252 INLINE_DEVICE(signed_word
) device_find_integer_property
254 const char *property
);
256 INLINE_DEVICE(const char *) device_find_string_property
258 const char *property
);
260 INLINE_DEVICE(int) device_find_boolean_property
262 const char *property
);
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
273 /* Address access attributes that can be attached to a devices address
275 typedef enum _access_type
{
279 access_read_write
= 3,
281 access_read_exec
= 5,
282 access_write_exec
= 6,
283 access_read_write_exec
= 7,
287 /* Address attachement types */
288 typedef enum _attach_type
{
298 A device is made fully functional in two stages.
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.
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
311 INLINE_DEVICE(device
*) device_create
315 /* some external functions want to create things */
316 typedef struct _device_callbacks device_callbacks
;
318 INLINE_DEVICE(device
*) device_create_from
321 const device_callbacks
*callbacks
,
324 INLINE_DEVICE(void) device_init
328 /* initialize the entire tree */
330 INLINE_DEVICE(void) device_tree_init
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.
342 Similarly, a device may initiate a data transfer (DMA) by passing
343 such a request up to its parent.
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.
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.
357 To perform these operations, a device will call upon its parent
358 using either device_attach_address or device_detach_address.
360 * Any address specified is according to what the device expects to
363 * Any detach operation must exactly match a previous attach.
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.
369 * at any time, at most one device can have a default mapping
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.
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.
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
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.
396 * Any exception situtation trigered by a non IO operation
397 (processor == NULL) is handled buy returning 0.
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.
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.
408 This function is subject to change ...
412 INLINE_DEVICE(void) device_attach_address
420 device
*who
); /*callback/default*/
422 INLINE_DEVICE(void) device_detach_address
430 device
*who
); /*callback/default*/
432 INLINE_DEVICE(unsigned) device_io_read_buffer
441 INLINE_DEVICE(unsigned) device_io_write_buffer
450 INLINE_DEVICE(unsigned) device_dma_read_buffer
457 INLINE_DEVICE(unsigned) device_dma_write_buffer
463 int violate_read_only_section
);
468 As mentioned above. Instead of handling an interrupt directly, a
469 device may instead pass the need to interrupt on to its parent.
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.
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.
485 INLINE_DEVICE(void) device_attach_interrupt
491 INLINE_DEVICE(void) device_detach_interrupt
497 INLINE_DEVICE(void) device_interrupt
501 int interrupt_status
,
505 INLINE_DEVICE(void) device_interrupt_ack
508 int interrupt_status
);
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. */
526 /* Device software - the instance
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 */
536 INLINE_DEVICE(device_instance
*)device_instance_open
538 const char *device_specifier
);
540 INLINE_DEVICE(void) device_instance_close
541 (device_instance
*instance
);
543 INLINE_DEVICE(int) device_instance_read
544 (device_instance
*instance
,
548 INLINE_DEVICE(int) device_instance_write
549 (device_instance
*instance
,
553 INLINE_DEVICE(int) device_instance_seek
554 (device_instance
*instance
,
555 unsigned_word pos_hi
,
556 unsigned_word pos_lo
);
558 INLINE_DEVICE(device
*) device_instance_device
559 (device_instance
*instance
);
561 INLINE_DEVICE(const char *) device_instance_name
562 (device_instance
*instance
);
568 /* Device dregs... */
570 /* Parse a device name, various formats:
576 INLINE_DEVICE(int) scand_c
581 INLINE_DEVICE(int) scand_c_uw_u
588 INLINE_DEVICE(int) scand_uw
592 INLINE_DEVICE(int) scand_uw_c
598 INLINE_DEVICE(int) scand_uw_u
603 INLINE_DEVICE(int) scand_uw_u_u
609 INLINE_DEVICE(int) scand_uw_u_u_c
617 INLINE_DEVICE(int) scand_uw_uw
622 INLINE_DEVICE(int) scand_uw_uw_u
628 INLINE_DEVICE(int) scand_uw_uw_u_u_c
637 INLINE_DEVICE(int) scand_uw_uw_u_u_u
645 #endif /* _DEVICE_TREE_H_ */