hw-device.h revision 1.1.1.1 1 /* The common simulator framework for GDB, the GNU Debugger.
2
3 Copyright 2002-2014 Free Software Foundation, Inc.
4
5 Contributed by Andrew Cagney and Red Hat.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21
22
23 #ifndef HW_DEVICE_H
24 #define HW_DEVICE_H
25
26 /* declared in sim-basics.h, this object is used everywhere */
27 /* typedef struct _device device; */
28
29
30 /* Introduction:
31
32 As explained in earlier sections, the device, device instance,
33 property and ports lie at the heart of PSIM's device model.
34
35 In the below a synopsis of the device object and the operations it
36 supports are given.
37 */
38
39
40 /* Creation:
41
42 The devices are created using a sequence of steps. In particular:
43
44 o A tree framework is created.
45
46 At this point, properties can be modified and extra
47 devices inserted (or removed?).
48
49 #if LATER
50
51 Any properties that have a run-time value (eg ihandle
52 or device instance pointer properties) are entered
53 into the device tree using a named reference to the
54 corresponding runtime object that is to be created.
55
56 #endif
57
58 o Real devices are created for all the dummy devices.
59
60 A device can assume that all of its parents have been
61 initialized.
62
63 A device can assume that all non run-time properties
64 have been initialized.
65
66 As part of being created, the device normally attaches
67 itself to its parent bus.
68
69 #if LATER
70
71 Device instance data is initialized.
72
73 #endif
74
75 #if LATER
76
77 o Any run-time properties are created.
78
79 #endif
80
81 #if MUCH_MUCH_LATER
82
83 o Some devices, as part of their initialization
84 might want to refer to ihandle properties
85 in the device tree.
86
87 #endif
88
89 NOTES:
90
91 o It is important to separate the creation
92 of an actual device from the creation
93 of the tree. The alternative creating
94 the device in two stages: As a separate
95 entity and then as a part of the tree.
96
97 #if LATER
98 o Run-time properties can not be created
99 until after the devices in the tree
100 have been created. Hence an extra pass
101 for handling them.
102 #endif
103
104 */
105
106 /* Relationships:
107
108 A device is able to determine its relationship to other devices
109 within the tree. Operations include querying for a devices parent,
110 sibling, child, name, and path (from the root).
111
112 */
113
114
115 #define hw_parent(hw) ((hw)->parent_of_hw + 0)
116
117 #define hw_sibling(hw) ((hw)->sibling_of_hw + 0)
118
119 #define hw_child(hw) ((hw)->child_of_hw + 0)
120
121
122
123 /* Herritage:
124
125 */
126
127 #define hw_family(hw) ((hw)->family_of_hw + 0)
128
129 #define hw_name(hw) ((hw)->name_of_hw + 0)
130
131 #define hw_args(hw) ((hw)->args_of_hw + 0)
132
133 #define hw_path(hw) ((hw)->path_of_hw + 0)
134
135
136
137 /* Short cut to the root node of the tree */
138
139 #define hw_root(hw) ((hw)->root_of_hw + 0)
140
141 /* Short cut back to the simulator object */
142
143 #define hw_system(hw) ((hw)->system_of_hw)
144
145 /* For requests initiated by a CPU the cpu that initiated the request */
146
147 struct _sim_cpu *hw_system_cpu (struct hw *hw);
148
149
150 /* Device private data */
151
152 #define hw_data(hw) ((hw)->data_of_hw)
153
154 #define set_hw_data(hw, value) \
155 ((hw)->data_of_hw = (value))
156
157
158
159 /* Perform a soft reset of the device */
161
162 typedef unsigned (hw_reset_method)
163 (struct hw *me);
164
165 #define hw_reset(hw) ((hw)->to_reset (hw))
166
167 #define set_hw_reset(hw, method) \
168 ((hw)->to_reset = method)
169
170
171 /* Hardware operations:
173
174 Connecting a parent to its children is a common bus. The parent
175 node is described as the bus owner and is responisble for
176 co-ordinating bus operations. On the bus, a SPACE:ADDR pair is used
177 to specify an address. A device that is both a bus owner (parent)
178 and bus client (child) are referred to as a bridging device.
179
180 A child performing a data (DMA) transfer will pass its request to
181 the bus owner (the devices parent). The bus owner will then either
182 reflect the request to one of the other devices attached to the bus
183 (a child of the bus owner) or bridge the request up the tree to the
184 next bus. */
185
186
187 /* Children attached to a bus can register (attach) themselves to
188 specific addresses on their attached bus.
189
190 (A device may also be implicitly attached to certain bus
191 addresses).
192
193 The SPACE:ADDR pair specify an address on the common bus that
194 connects the parent and child devices. */
195
196 typedef void (hw_attach_address_method)
197 (struct hw *me,
198 int level,
199 int space,
200 address_word addr,
201 address_word nr_bytes,
202 struct hw *client); /*callback/default*/
203
204 #define hw_attach_address(me, level, space, addr, nr_bytes, client) \
205 ((me)->to_attach_address (me, level, space, addr, nr_bytes, client))
206
207 #define set_hw_attach_address(hw, method) \
208 ((hw)->to_attach_address = (method))
209
210 typedef void (hw_detach_address_method)
211 (struct hw *me,
212 int level,
213 int space,
214 address_word addr,
215 address_word nr_bytes,
216 struct hw *client); /*callback/default*/
217
218 #define hw_detach_address(me, level, space, addr, nr_bytes, client) \
219 ((me)->to_detach_address (me, level, space, addr, nr_bytes, client))
220
221 #define set_hw_detach_address(hw, method) \
222 ((hw)->to_detach_address = (method))
223
224
225 /* An IO operation from a parent to a child via the conecting bus.
226
227 The SPACE:ADDR pair specify an address on the bus shared between
228 the parent and child devices. */
229
230 typedef unsigned (hw_io_read_buffer_method)
231 (struct hw *me,
232 void *dest,
233 int space,
234 unsigned_word addr,
235 unsigned nr_bytes);
236
237 #define hw_io_read_buffer(hw, dest, space, addr, nr_bytes) \
238 ((hw)->to_io_read_buffer (hw, dest, space, addr, nr_bytes))
239
240 #define set_hw_io_read_buffer(hw, method) \
241 ((hw)->to_io_read_buffer = (method))
242
243 typedef unsigned (hw_io_write_buffer_method)
244 (struct hw *me,
245 const void *source,
246 int space,
247 unsigned_word addr,
248 unsigned nr_bytes);
249
250 #define hw_io_write_buffer(hw, src, space, addr, nr_bytes) \
251 ((hw)->to_io_write_buffer (hw, src, space, addr, nr_bytes))
252
253 #define set_hw_io_write_buffer(hw, method) \
254 ((hw)->to_io_write_buffer = (method))
255
256
257 /* Conversly, the device pci1000,1@1 may need to perform a dma transfer
258 into the cpu/memory core. Just as I/O moves towards the leaves,
259 dma transfers move towards the core via the initiating devices
260 parent nodes. The root device (special) converts the DMA transfer
261 into reads/writes to memory.
262
263 The SPACE:ADDR pair specify an address on the common bus connecting
264 the parent and child devices. */
265
266 typedef unsigned (hw_dma_read_buffer_method)
267 (struct hw *bus,
268 void *dest,
269 int space,
270 unsigned_word addr,
271 unsigned nr_bytes);
272
273 #define hw_dma_read_buffer(bus, dest, space, addr, nr_bytes) \
274 ((bus)->to_dma_read_buffer (bus, dest, space, addr, nr_bytes))
275
276 #define set_hw_dma_read_buffer(me, method) \
277 ((me)->to_dma_read_buffer = (method))
278
279 typedef unsigned (hw_dma_write_buffer_method)
280 (struct hw *bus,
281 const void *source,
282 int space,
283 unsigned_word addr,
284 unsigned nr_bytes,
285 int violate_read_only_section);
286
287 #define hw_dma_write_buffer(bus, src, space, addr, nr_bytes, violate_ro) \
288 ((bus)->to_dma_write_buffer (bus, src, space, addr, nr_bytes, violate_ro))
289
290 #define set_hw_dma_write_buffer(me, method) \
291 ((me)->to_dma_write_buffer = (method))
292
293 /* Address/size specs for devices are encoded following a convention
295 similar to that used by OpenFirmware. In particular, an
296 address/size is packed into a sequence of up to four cell words.
297 The number of words determined by the number of {address,size}
298 cells attributes of the device. */
299
300 typedef struct _hw_unit
301 {
302 int nr_cells;
303 unsigned_cell cells[4]; /* unused cells are zero */
304 } hw_unit;
305
306
307 /* For the given bus, the number of address and size cells used in a
308 hw_unit. */
309
310 #define hw_unit_nr_address_cells(bus) ((bus)->nr_address_cells_of_hw_unit + 0)
311
312 #define hw_unit_nr_size_cells(bus) ((bus)->nr_size_cells_of_hw_unit + 0)
313
314
315 /* For the given device, its identifying hw_unit address.
316
317 Each device has an identifying hw_unit address. That address is
318 used when identifying one of a number of identical devices on a
319 common controller bus. ex fd0&fd1. */
320
321 const hw_unit *hw_unit_address
322 (struct hw *me);
323
324
325 /* Convert between a textual and the internal representation of a
326 hw_unit address/size.
327
328 NOTE: A device asks its parent to translate between a hw_unit and
329 textual representation. This is because the textual address of a
330 device is specified using the parent busses notation. */
331
332 typedef int (hw_unit_decode_method)
333 (struct hw *bus,
334 const char *encoded,
335 hw_unit *unit);
336
337 #define hw_unit_decode(bus, encoded, unit) \
338 ((bus)->to_unit_decode (bus, encoded, unit))
339
340 #define set_hw_unit_decode(hw, method) \
341 ((hw)->to_unit_decode = (method))
342
343 typedef int (hw_unit_encode_method)
344 (struct hw *bus,
345 const hw_unit *unit,
346 char *encoded,
347 int sizeof_buf);
348
349 #define hw_unit_encode(bus, unit, encoded, sizeof_encoded) \
350 ((bus)->to_unit_encode (bus, unit, encoded, sizeof_encoded))
351
352 #define set_hw_unit_encode(hw, method) \
353 ((hw)->to_unit_encode = (method))
354
355
356 /* As the bus that the device is attached too, to translate a devices
357 hw_unit address/size into a form suitable for an attach address
358 call.
359
360 Return a zero result if the address should be ignored when looking
361 for attach addresses. */
362
363 typedef int (hw_unit_address_to_attach_address_method)
364 (struct hw *bus,
365 const hw_unit *unit_addr,
366 int *attach_space,
367 unsigned_word *attach_addr,
368 struct hw *client);
369
370 #define hw_unit_address_to_attach_address(bus, unit_addr, attach_space, attach_addr, client) \
371 ((bus)->to_unit_address_to_attach_address (bus, unit_addr, attach_space, attach_addr, client))
372
373 #define set_hw_unit_address_to_attach_address(hw, method) \
374 ((hw)->to_unit_address_to_attach_address = (method))
375
376 typedef int (hw_unit_size_to_attach_size_method)
377 (struct hw *bus,
378 const hw_unit *unit_size,
379 unsigned *attach_size,
380 struct hw *client);
381
382 #define hw_unit_size_to_attach_size(bus, unit_size, attach_size, client) \
383 ((bus)->to_unit_size_to_attach_size (bus, unit_size, attach_size, client))
384
385 #define set_hw_unit_size_to_attach_size(hw, method) \
386 ((hw)->to_unit_size_to_attach_size = (method))
387
388
389 extern char *hw_strdup (struct hw *me, const char *str);
391
392
393 /* Utilities:
395
396 */
397
398 /* IOCTL::
399
400 Often devices require `out of band' operations to be performed.
401 For instance a pal device may need to notify a PCI bridge device
402 that an interrupt ack cycle needs to be performed on the PCI bus.
403 Within PSIM such operations are performed by using the generic
404 ioctl call <<hw_ioctl()>>.
405
406 */
407
408 typedef enum
409 {
410 hw_ioctl_break, /* unsigned_word requested_break */
411 hw_ioctl_set_trace, /* void */
412 hw_ioctl_create_stack, /* unsigned_word *sp, char **argv, char **envp */
413 hw_ioctl_change_media, /* const char *new_image (possibly NULL) */
414 nr_hw_ioctl_requests,
415 } hw_ioctl_request;
416
417 typedef int (hw_ioctl_method)
418 (struct hw *me,
419 hw_ioctl_request request,
420 va_list ap);
421
422 int hw_ioctl
423 (struct hw *me,
424 hw_ioctl_request request,
425 ...);
426
427
428 /* Error reporting::
429
430 So that errors originating from devices appear in a consistent
431 format, the <<hw_abort()>> function can be used. Formats and
432 outputs the error message before aborting the simulation
433
434 Devices should use this function to abort the simulation except
435 when the abort reason leaves the simulation in a hazardous
436 condition (for instance a failed malloc).
437
438 */
439
440 void hw_abort
441 (struct hw *me,
442 const char *fmt,
443 ...) __attribute__ ((format (printf, 2, 3), noreturn));
444
445 void hw_vabort
446 (struct hw *me,
447 const char *fmt,
448 va_list ap) __attribute__ ((noreturn));
449
450 void hw_halt
451 (struct hw *me,
452 int reason,
453 int status) __attribute__ ((noreturn));
454
455
456 #define hw_trace_p(hw) ((hw)->trace_of_hw_p + 0)
457
458 void hw_trace
459 (struct hw *me,
460 const char *fmt,
461 ...) __attribute__ ((format (printf, 2, 3)));
462
463 #define HW_TRACE(ARGS) \
464 do { \
465 if (hw_trace_p (me)) \
466 { \
467 hw_trace ARGS; \
468 } \
469 } while (0)
470
471
472 /* Some of the related functions require specific types */
473
474 struct hw_property_data;
475 struct hw_port_data;
476 struct hw_base_data;
477 struct hw_alloc_data;
478 struct hw_event_data;
479 struct hw_handle_data;
480 struct hw_instance_data;
481
482 /* Finally the hardware device - keep your grubby little mits off of
483 these internals! :-) */
484
485 struct hw
486 {
487
488 /* our relatives */
489 struct hw *parent_of_hw;
490 struct hw *sibling_of_hw;
491 struct hw *child_of_hw;
492
493 /* our identity */
494 const char *name_of_hw;
495 const char *family_of_hw;
496 const char *args_of_hw;
497 const char *path_of_hw;
498
499 /* our data */
500 void *data_of_hw;
501
502 /* hot links */
503 struct hw *root_of_hw;
504 struct sim_state *system_of_hw;
505
506 /* identifying data */
507 hw_unit unit_address_of_hw;
508 int nr_address_cells_of_hw_unit;
509 int nr_size_cells_of_hw_unit;
510
511 /* Soft reset */
512 hw_reset_method *to_reset;
513
514 /* Basic callbacks */
515 hw_io_read_buffer_method *to_io_read_buffer;
516 hw_io_write_buffer_method *to_io_write_buffer;
517 hw_dma_read_buffer_method *to_dma_read_buffer;
518 hw_dma_write_buffer_method *to_dma_write_buffer;
519 hw_attach_address_method *to_attach_address;
520 hw_detach_address_method *to_detach_address;
521
522 /* More complicated callbacks */
523 hw_ioctl_method *to_ioctl;
524 int trace_of_hw_p;
525
526 /* address callbacks */
527 hw_unit_decode_method *to_unit_decode;
528 hw_unit_encode_method *to_unit_encode;
529 hw_unit_address_to_attach_address_method *to_unit_address_to_attach_address;
530 hw_unit_size_to_attach_size_method *to_unit_size_to_attach_size;
531
532 /* related data */
533 struct hw_property_data *properties_of_hw;
534 struct hw_port_data *ports_of_hw;
535 struct hw_base_data *base_of_hw;
536 struct hw_alloc_data *alloc_of_hw;
537 struct hw_event_data *events_of_hw;
538 struct hw_handle_data *handles_of_hw;
539 struct hw_instance_data *instances_of_hw;
540
541 };
542
543
544 #endif
545