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_
25 #ifndef INLINE_DEVICE_TREE
26 #define INLINE_DEVICE_TREE
30 /* forward declaration of types */
32 typedef struct _device_node device_node
;
33 typedef struct _device_address device_address
;
34 typedef struct _device_callbacks device_callbacks
;
37 /* Device callbacks: */
40 /* Memory operations: transfer data to/from a processor.
42 These callbacks pass/return data in *host* byte order.
44 Should a memory read/write operation cause an interrupt (external
45 exception) then a device would typically pass an interrupt message
46 to the devices parent. Hopefully that is an interrupt controler
47 and will know what to do with it.
49 Devices normally never either restart a processor or issue an
50 interrupt directly. The only exception I've thought of could be
51 machine check type event. */
53 typedef unsigned64 (device_reader_callback
)
60 typedef void (device_writer_callback
)
70 A child device uses the below to pass on to its parent changes in
71 the state of a child devices interrupt lines.
73 Typically, the parent being an interrupt control device, would, in
74 responce, schedule an event at the start of the next clock cycle.
75 On this event, the state of any cpu could be changed. Other
76 devices could either ignore or pass on the interrupt message */
78 typedef void (device_interrupt_callback
)
87 DEVICE_CREATOR is called once, as part of building the device tree.
88 This function gives the device the chance to attach any additional
89 data to this particular device instance.
91 DEVICE_INIT_CALLBACK is (re)called when ever the system is
94 typedef device_node
*(device_creator
)
98 typedef void (device_init_callback
)
99 (device_node
*device
);
103 /* constructs to describe the hardware's tree of devices */
105 typedef enum _device_type
{
108 /* typical devices */
114 /* atypical devices, these are for data being loaded into ram/rom */
117 /* types of primative nodes containing just data */
124 typedef enum _device_access
{
125 device_is_readable
= 1,
126 device_is_writeable
= 2,
127 device_is_read_write
= 3,
128 device_is_executable
= 4,
129 device_is_read_exec
= 5,
130 device_is_write_exec
= 6,
131 device_is_read_write_exec
= 7,
134 struct _device_address
{
135 unsigned_word lower_bound
;
136 unsigned_word upper_bound
;
137 unsigned size
; /* host limited */
138 void *init
; /* initial data */
139 device_access access
;
140 device_address
*next_address
;
143 struct _device_callbacks
{
144 device_reader_callback
*read_callback
;
145 device_writer_callback
*write_callback
;
146 device_interrupt_callback
*interrupt_callback
;
147 /* device_init_callback *init_callback; */
148 /* device_init_hander *post_init_handler; */
151 struct _device_node
{
154 device_node
*children
;
155 device_node
*sibling
;
157 char *name
; /* eg rom@0x1234,0x40 */
159 device_callbacks
*callbacks
;
160 device_address
*addresses
;
165 /* given the image to run, return its device tree */
167 INLINE_DEVICE_TREE device_node
*device_tree_create
168 (const char *hardware_description
);
171 /* traverse the tree eiter pre or post fix */
173 typedef void (device_tree_traverse_function
)
174 (device_node
*device
,
177 INLINE_DEVICE_TREE
void device_tree_traverse
179 device_tree_traverse_function
*prefix
,
180 device_tree_traverse_function
*postfix
,
184 /* query the device tree */
186 INLINE_DEVICE_TREE device_node
*device_tree_find_node
190 INLINE_DEVICE_TREE device_node
*device_tree_find_next_node
195 INLINE_DEVICE_TREE signed_word device_tree_find_int
199 INLINE_DEVICE_TREE
const char *device_tree_find_string
203 INLINE_DEVICE_TREE
int device_tree_find_boolean
207 INLINE_DEVICE_TREE
void *device_tree_find_bytes
211 /* add to the device tree */
213 INLINE_DEVICE_TREE device_node
*device_node_create
214 (device_node
*parent
,
217 device_callbacks
*callbacks
,
220 INLINE_DEVICE_TREE
void device_node_add_address
222 unsigned_word lower_bound
,
224 device_access access
,
227 /* dump a node, pass this to the device_tree_traverse() function to
230 INLINE_DEVICE_TREE
void device_tree_dump
231 (device_node
*device
,
232 void *ignore_data_argument
);
234 #endif /* _DEVICE_TREE_H_ */