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 device INLINE_DEVICE
*device_sibling
45 device INLINE_DEVICE
*device_child
48 device INLINE_DEVICE
*device_parent
51 const char INLINE_DEVICE
*device_name
54 void INLINE_DEVICE
*device_data
58 /* Grow the device tree adding either a specific device or
59 alternativly a device found in the device table */
61 device INLINE_DEVICE
*device_tree_add_device
64 device
*new_sub_tree
);
66 device INLINE_DEVICE
*device_tree_add_found
71 device INLINE_DEVICE
*device_tree_add_found_c
77 device INLINE_DEVICE
*device_tree_add_found_c_uw
84 device INLINE_DEVICE
*device_tree_add_found_uw_u
91 device INLINE_DEVICE
*device_tree_add_found_uw_u_u
99 device INLINE_DEVICE
*device_tree_add_found_uw_u_u_c
108 device INLINE_DEVICE
*device_tree_add_found_uw_uw_u_u_c
118 device INLINE_DEVICE
*device_tree_add_found_uw_uw_u_u_u
129 /* Query the device tree, null is returned if the specified device is
132 device INLINE_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 void INLINE_DEVICE 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 void INLINE_DEVICE 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 const char INLINE_DEVICE
*device_find_next_property
192 const char *previous
);
194 void INLINE_DEVICE device_set_property
196 const char *property
,
201 /* INLINE_DEVICE void device_add_property
202 No such external function, all properties, when added are explictly
205 void INLINE_DEVICE device_add_array_property
207 const char *property
,
211 void INLINE_DEVICE device_add_integer_property
213 const char *property
,
214 signed_word integer
);
216 void INLINE_DEVICE device_add_boolean_property
218 const char *property
,
221 void INLINE_DEVICE device_add_null_property
223 const char *property
);
225 void INLINE_DEVICE device_add_string_property
227 const char *property
,
231 /* Locate a property returning its description. Return NULL if the
232 named property is not found */
234 const device_property INLINE_DEVICE
*device_find_property
236 const char *property
);
239 /* Process all properties attached to the named device */
241 typedef void (device_traverse_property_function
)
246 void INLINE_DEVICE device_traverse_properties
248 device_traverse_property_function
*traverse
,
252 /* Similar to above except that the property *must* be in the device
253 tree and *must* be of the specified type. */
255 const device_property INLINE_DEVICE
*device_find_array_property
257 const char *property
);
259 signed_word INLINE_DEVICE device_find_integer_property
261 const char *property
);
263 const char INLINE_DEVICE
*device_find_string_property
265 const char *property
);
267 int INLINE_DEVICE device_find_boolean_property
269 const char *property
);
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
280 /* Address access attributes that can be attached to a devices address
282 typedef enum _access_type
{
286 access_read_write
= 3,
288 access_read_exec
= 5,
289 access_write_exec
= 6,
290 access_read_write_exec
= 7,
294 /* Address attachement types */
295 typedef enum _attach_type
{
305 A device is made fully functional in two stages.
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.
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
318 device INLINE_DEVICE
*device_create
322 /* some external functions want to create things */
323 typedef struct _device_callbacks device_callbacks
;
325 device INLINE_DEVICE
*device_create_from
328 const device_callbacks
*callbacks
,
331 void INLINE_DEVICE device_init
335 /* initialize the entire tree */
337 void INLINE_DEVICE device_tree_init
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.
349 Similarly, a device may initiate a data transfer (DMA) by passing
350 such a request up to its parent.
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.
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.
364 To perform these operations, a device will call upon its parent
365 using either device_attach_address or device_detach_address.
367 * Any address specified is according to what the device expects to
370 * Any detach operation must exactly match a previous attach.
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.
376 * at any time, at most one device can have a default mapping
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.
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.
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
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.
403 * Any exception situtation trigered by a non IO operation
404 (processor == NULL) is handled buy returning 0.
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.
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.
415 This function is subject to change ...
419 void INLINE_DEVICE device_attach_address
427 device
*who
); /*callback/default*/
429 void INLINE_DEVICE device_detach_address
437 device
*who
); /*callback/default*/
439 unsigned INLINE_DEVICE device_io_read_buffer
448 unsigned INLINE_DEVICE device_io_write_buffer
457 unsigned INLINE_DEVICE device_dma_read_buffer
464 unsigned INLINE_DEVICE device_dma_write_buffer
470 int violate_read_only_section
);
475 As mentioned above. Instead of handling an interrupt directly, a
476 device may instead pass the need to interrupt on to its parent.
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.
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.
492 void INLINE_DEVICE device_attach_interrupt
498 void INLINE_DEVICE device_detach_interrupt
504 void INLINE_DEVICE device_interrupt
508 int interrupt_status
,
512 void INLINE_DEVICE device_interrupt_ack
515 int interrupt_status
);
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. */
523 void EXTERN_DEVICE device_ioctl
532 /* Device software - the instance
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 */
541 device_instance INLINE_DEVICE
*device_instance_open
543 const char *device_specifier
);
545 void INLINE_DEVICE device_instance_close
546 (device_instance
*instance
);
548 int INLINE_DEVICE device_instance_read
549 (device_instance
*instance
,
553 int INLINE_DEVICE device_instance_write
554 (device_instance
*instance
,
558 int INLINE_DEVICE device_instance_seek
559 (device_instance
*instance
,
560 unsigned_word pos_hi
,
561 unsigned_word pos_lo
);
563 device INLINE_DEVICE
*device_instance_device
564 (device_instance
*instance
);
566 const char INLINE_DEVICE
*device_instance_name
567 (device_instance
*instance
);
573 /* Device dregs... */
575 /* Parse a device name */
577 void INLINE_DEVICE device_tree_parse_name
579 const char **driver_name
,
580 const char **unit_address
,
581 const char **device_arguments
,
585 /* Parse a device name, various formats:
591 int INLINE_DEVICE scand_c
596 int INLINE_DEVICE scand_c_uw_u
603 int INLINE_DEVICE scand_uw
607 int INLINE_DEVICE scand_uw_c
613 int INLINE_DEVICE scand_uw_u
618 int INLINE_DEVICE scand_uw_u_u
624 int INLINE_DEVICE scand_uw_u_u_c
632 int INLINE_DEVICE scand_uw_uw
637 int INLINE_DEVICE scand_uw_uw_u
643 int INLINE_DEVICE scand_uw_uw_u_u_c
652 int INLINE_DEVICE scand_uw_uw_u_u_u
660 #endif /* _DEVICE_TREE_H_ */