14e98e3e1Schristos /* The common simulator framework for GDB, the GNU Debugger. 24e98e3e1Schristos 3*88241920Schristos Copyright 2002-2024 Free Software Foundation, Inc. 44e98e3e1Schristos 54e98e3e1Schristos Contributed by Andrew Cagney and Red Hat. 64e98e3e1Schristos 74e98e3e1Schristos This file is part of GDB. 84e98e3e1Schristos 94e98e3e1Schristos This program is free software; you can redistribute it and/or modify 104e98e3e1Schristos it under the terms of the GNU General Public License as published by 114e98e3e1Schristos the Free Software Foundation; either version 3 of the License, or 124e98e3e1Schristos (at your option) any later version. 134e98e3e1Schristos 144e98e3e1Schristos This program is distributed in the hope that it will be useful, 154e98e3e1Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 164e98e3e1Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 174e98e3e1Schristos GNU General Public License for more details. 184e98e3e1Schristos 194e98e3e1Schristos You should have received a copy of the GNU General Public License 204e98e3e1Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 214e98e3e1Schristos 224e98e3e1Schristos 234e98e3e1Schristos #ifndef HW_DEVICE_H 244e98e3e1Schristos #define HW_DEVICE_H 254e98e3e1Schristos 264b169a6bSchristos #include <stdarg.h> 274b169a6bSchristos 284b169a6bSchristos #include "ansidecl.h" 294e98e3e1Schristos 304e98e3e1Schristos /* Introduction: 314e98e3e1Schristos 324e98e3e1Schristos As explained in earlier sections, the device, device instance, 334e98e3e1Schristos property and ports lie at the heart of PSIM's device model. 344e98e3e1Schristos 354e98e3e1Schristos In the below a synopsis of the device object and the operations it 364e98e3e1Schristos supports are given. 374e98e3e1Schristos */ 384e98e3e1Schristos 394e98e3e1Schristos 404e98e3e1Schristos /* Creation: 414e98e3e1Schristos 424e98e3e1Schristos The devices are created using a sequence of steps. In particular: 434e98e3e1Schristos 444e98e3e1Schristos o A tree framework is created. 454e98e3e1Schristos 464e98e3e1Schristos At this point, properties can be modified and extra 474e98e3e1Schristos devices inserted (or removed?). 484e98e3e1Schristos 494e98e3e1Schristos #if LATER 504e98e3e1Schristos 514e98e3e1Schristos Any properties that have a run-time value (eg ihandle 524e98e3e1Schristos or device instance pointer properties) are entered 534e98e3e1Schristos into the device tree using a named reference to the 544e98e3e1Schristos corresponding runtime object that is to be created. 554e98e3e1Schristos 564e98e3e1Schristos #endif 574e98e3e1Schristos 584e98e3e1Schristos o Real devices are created for all the dummy devices. 594e98e3e1Schristos 604e98e3e1Schristos A device can assume that all of its parents have been 614e98e3e1Schristos initialized. 624e98e3e1Schristos 634e98e3e1Schristos A device can assume that all non run-time properties 644e98e3e1Schristos have been initialized. 654e98e3e1Schristos 664e98e3e1Schristos As part of being created, the device normally attaches 674e98e3e1Schristos itself to its parent bus. 684e98e3e1Schristos 694e98e3e1Schristos #if LATER 704e98e3e1Schristos 714e98e3e1Schristos Device instance data is initialized. 724e98e3e1Schristos 734e98e3e1Schristos #endif 744e98e3e1Schristos 754e98e3e1Schristos #if LATER 764e98e3e1Schristos 774e98e3e1Schristos o Any run-time properties are created. 784e98e3e1Schristos 794e98e3e1Schristos #endif 804e98e3e1Schristos 814e98e3e1Schristos #if MUCH_MUCH_LATER 824e98e3e1Schristos 834e98e3e1Schristos o Some devices, as part of their initialization 844e98e3e1Schristos might want to refer to ihandle properties 854e98e3e1Schristos in the device tree. 864e98e3e1Schristos 874e98e3e1Schristos #endif 884e98e3e1Schristos 894e98e3e1Schristos NOTES: 904e98e3e1Schristos 914e98e3e1Schristos o It is important to separate the creation 924e98e3e1Schristos of an actual device from the creation 934e98e3e1Schristos of the tree. The alternative creating 944e98e3e1Schristos the device in two stages: As a separate 954e98e3e1Schristos entity and then as a part of the tree. 964e98e3e1Schristos 974e98e3e1Schristos #if LATER 984e98e3e1Schristos o Run-time properties can not be created 994e98e3e1Schristos until after the devices in the tree 1004e98e3e1Schristos have been created. Hence an extra pass 1014e98e3e1Schristos for handling them. 1024e98e3e1Schristos #endif 1034e98e3e1Schristos 1044e98e3e1Schristos */ 1054e98e3e1Schristos 1064e98e3e1Schristos /* Relationships: 1074e98e3e1Schristos 1084e98e3e1Schristos A device is able to determine its relationship to other devices 1094e98e3e1Schristos within the tree. Operations include querying for a devices parent, 1104e98e3e1Schristos sibling, child, name, and path (from the root). 1114e98e3e1Schristos 1124e98e3e1Schristos */ 1134e98e3e1Schristos 1144e98e3e1Schristos 1154e98e3e1Schristos #define hw_parent(hw) ((hw)->parent_of_hw + 0) 1164e98e3e1Schristos 1174e98e3e1Schristos #define hw_sibling(hw) ((hw)->sibling_of_hw + 0) 1184e98e3e1Schristos 1194e98e3e1Schristos #define hw_child(hw) ((hw)->child_of_hw + 0) 1204e98e3e1Schristos 1214e98e3e1Schristos 1224e98e3e1Schristos 1234e98e3e1Schristos /* Herritage: 1244e98e3e1Schristos 1254e98e3e1Schristos */ 1264e98e3e1Schristos 1274e98e3e1Schristos #define hw_family(hw) ((hw)->family_of_hw + 0) 1284e98e3e1Schristos 1294e98e3e1Schristos #define hw_name(hw) ((hw)->name_of_hw + 0) 1304e98e3e1Schristos 1314e98e3e1Schristos #define hw_args(hw) ((hw)->args_of_hw + 0) 1324e98e3e1Schristos 1334e98e3e1Schristos #define hw_path(hw) ((hw)->path_of_hw + 0) 1344e98e3e1Schristos 1354e98e3e1Schristos 1364e98e3e1Schristos 1374e98e3e1Schristos /* Short cut to the root node of the tree */ 1384e98e3e1Schristos 1394e98e3e1Schristos #define hw_root(hw) ((hw)->root_of_hw + 0) 1404e98e3e1Schristos 1414e98e3e1Schristos /* Short cut back to the simulator object */ 1424e98e3e1Schristos 1434e98e3e1Schristos #define hw_system(hw) ((hw)->system_of_hw) 1444e98e3e1Schristos 1454e98e3e1Schristos /* For requests initiated by a CPU the cpu that initiated the request */ 1464e98e3e1Schristos 1474e98e3e1Schristos struct _sim_cpu *hw_system_cpu (struct hw *hw); 1484e98e3e1Schristos 1494e98e3e1Schristos 1504e98e3e1Schristos /* Device private data */ 1514e98e3e1Schristos 1524e98e3e1Schristos #define hw_data(hw) ((hw)->data_of_hw) 1534e98e3e1Schristos 1544e98e3e1Schristos #define set_hw_data(hw, value) \ 1554e98e3e1Schristos ((hw)->data_of_hw = (value)) 1564e98e3e1Schristos 1574e98e3e1Schristos 1584e98e3e1Schristos 1594e98e3e1Schristos /* Perform a soft reset of the device */ 1604e98e3e1Schristos 1614e98e3e1Schristos typedef unsigned (hw_reset_method) 1624e98e3e1Schristos (struct hw *me); 1634e98e3e1Schristos 1644e98e3e1Schristos #define hw_reset(hw) ((hw)->to_reset (hw)) 1654e98e3e1Schristos 1664e98e3e1Schristos #define set_hw_reset(hw, method) \ 1674e98e3e1Schristos ((hw)->to_reset = method) 1684e98e3e1Schristos 1694e98e3e1Schristos 1704e98e3e1Schristos /* Hardware operations: 1714e98e3e1Schristos 1724e98e3e1Schristos Connecting a parent to its children is a common bus. The parent 1734e98e3e1Schristos node is described as the bus owner and is responisble for 1744e98e3e1Schristos co-ordinating bus operations. On the bus, a SPACE:ADDR pair is used 1754e98e3e1Schristos to specify an address. A device that is both a bus owner (parent) 1764e98e3e1Schristos and bus client (child) are referred to as a bridging device. 1774e98e3e1Schristos 1784e98e3e1Schristos A child performing a data (DMA) transfer will pass its request to 1794e98e3e1Schristos the bus owner (the devices parent). The bus owner will then either 1804e98e3e1Schristos reflect the request to one of the other devices attached to the bus 1814e98e3e1Schristos (a child of the bus owner) or bridge the request up the tree to the 1824e98e3e1Schristos next bus. */ 1834e98e3e1Schristos 1844e98e3e1Schristos 1854e98e3e1Schristos /* Children attached to a bus can register (attach) themselves to 1864e98e3e1Schristos specific addresses on their attached bus. 1874e98e3e1Schristos 1884e98e3e1Schristos (A device may also be implicitly attached to certain bus 1894e98e3e1Schristos addresses). 1904e98e3e1Schristos 1914e98e3e1Schristos The SPACE:ADDR pair specify an address on the common bus that 1924e98e3e1Schristos connects the parent and child devices. */ 1934e98e3e1Schristos 1944e98e3e1Schristos typedef void (hw_attach_address_method) 1954e98e3e1Schristos (struct hw *me, 1964e98e3e1Schristos int level, 1974e98e3e1Schristos int space, 1984e98e3e1Schristos address_word addr, 1994e98e3e1Schristos address_word nr_bytes, 2004e98e3e1Schristos struct hw *client); /*callback/default*/ 2014e98e3e1Schristos 2024e98e3e1Schristos #define hw_attach_address(me, level, space, addr, nr_bytes, client) \ 2034e98e3e1Schristos ((me)->to_attach_address (me, level, space, addr, nr_bytes, client)) 2044e98e3e1Schristos 2054e98e3e1Schristos #define set_hw_attach_address(hw, method) \ 2064e98e3e1Schristos ((hw)->to_attach_address = (method)) 2074e98e3e1Schristos 2084e98e3e1Schristos typedef void (hw_detach_address_method) 2094e98e3e1Schristos (struct hw *me, 2104e98e3e1Schristos int level, 2114e98e3e1Schristos int space, 2124e98e3e1Schristos address_word addr, 2134e98e3e1Schristos address_word nr_bytes, 2144e98e3e1Schristos struct hw *client); /*callback/default*/ 2154e98e3e1Schristos 2164e98e3e1Schristos #define hw_detach_address(me, level, space, addr, nr_bytes, client) \ 2174e98e3e1Schristos ((me)->to_detach_address (me, level, space, addr, nr_bytes, client)) 2184e98e3e1Schristos 2194e98e3e1Schristos #define set_hw_detach_address(hw, method) \ 2204e98e3e1Schristos ((hw)->to_detach_address = (method)) 2214e98e3e1Schristos 2224e98e3e1Schristos 2234e98e3e1Schristos /* An IO operation from a parent to a child via the conecting bus. 2244e98e3e1Schristos 2254e98e3e1Schristos The SPACE:ADDR pair specify an address on the bus shared between 2264e98e3e1Schristos the parent and child devices. */ 2274e98e3e1Schristos 2284e98e3e1Schristos typedef unsigned (hw_io_read_buffer_method) 2294e98e3e1Schristos (struct hw *me, 2304e98e3e1Schristos void *dest, 2314e98e3e1Schristos int space, 2324e98e3e1Schristos unsigned_word addr, 2334e98e3e1Schristos unsigned nr_bytes); 2344e98e3e1Schristos 2354e98e3e1Schristos #define hw_io_read_buffer(hw, dest, space, addr, nr_bytes) \ 2364e98e3e1Schristos ((hw)->to_io_read_buffer (hw, dest, space, addr, nr_bytes)) 2374e98e3e1Schristos 2384e98e3e1Schristos #define set_hw_io_read_buffer(hw, method) \ 2394e98e3e1Schristos ((hw)->to_io_read_buffer = (method)) 2404e98e3e1Schristos 2414e98e3e1Schristos typedef unsigned (hw_io_write_buffer_method) 2424e98e3e1Schristos (struct hw *me, 2434e98e3e1Schristos const void *source, 2444e98e3e1Schristos int space, 2454e98e3e1Schristos unsigned_word addr, 2464e98e3e1Schristos unsigned nr_bytes); 2474e98e3e1Schristos 2484e98e3e1Schristos #define hw_io_write_buffer(hw, src, space, addr, nr_bytes) \ 2494e98e3e1Schristos ((hw)->to_io_write_buffer (hw, src, space, addr, nr_bytes)) 2504e98e3e1Schristos 2514e98e3e1Schristos #define set_hw_io_write_buffer(hw, method) \ 2524e98e3e1Schristos ((hw)->to_io_write_buffer = (method)) 2534e98e3e1Schristos 2544e98e3e1Schristos 2554e98e3e1Schristos /* Conversly, the device pci1000,1@1 may need to perform a dma transfer 2564e98e3e1Schristos into the cpu/memory core. Just as I/O moves towards the leaves, 2574e98e3e1Schristos dma transfers move towards the core via the initiating devices 2584e98e3e1Schristos parent nodes. The root device (special) converts the DMA transfer 2594e98e3e1Schristos into reads/writes to memory. 2604e98e3e1Schristos 2614e98e3e1Schristos The SPACE:ADDR pair specify an address on the common bus connecting 2624e98e3e1Schristos the parent and child devices. */ 2634e98e3e1Schristos 2644e98e3e1Schristos typedef unsigned (hw_dma_read_buffer_method) 2654e98e3e1Schristos (struct hw *bus, 2664e98e3e1Schristos void *dest, 2674e98e3e1Schristos int space, 2684e98e3e1Schristos unsigned_word addr, 2694e98e3e1Schristos unsigned nr_bytes); 2704e98e3e1Schristos 2714e98e3e1Schristos #define hw_dma_read_buffer(bus, dest, space, addr, nr_bytes) \ 2724e98e3e1Schristos ((bus)->to_dma_read_buffer (bus, dest, space, addr, nr_bytes)) 2734e98e3e1Schristos 2744e98e3e1Schristos #define set_hw_dma_read_buffer(me, method) \ 2754e98e3e1Schristos ((me)->to_dma_read_buffer = (method)) 2764e98e3e1Schristos 2774e98e3e1Schristos typedef unsigned (hw_dma_write_buffer_method) 2784e98e3e1Schristos (struct hw *bus, 2794e98e3e1Schristos const void *source, 2804e98e3e1Schristos int space, 2814e98e3e1Schristos unsigned_word addr, 2824e98e3e1Schristos unsigned nr_bytes, 2834e98e3e1Schristos int violate_read_only_section); 2844e98e3e1Schristos 2854e98e3e1Schristos #define hw_dma_write_buffer(bus, src, space, addr, nr_bytes, violate_ro) \ 2864e98e3e1Schristos ((bus)->to_dma_write_buffer (bus, src, space, addr, nr_bytes, violate_ro)) 2874e98e3e1Schristos 2884e98e3e1Schristos #define set_hw_dma_write_buffer(me, method) \ 2894e98e3e1Schristos ((me)->to_dma_write_buffer = (method)) 2904e98e3e1Schristos 2914e98e3e1Schristos /* Address/size specs for devices are encoded following a convention 2924e98e3e1Schristos similar to that used by OpenFirmware. In particular, an 2934e98e3e1Schristos address/size is packed into a sequence of up to four cell words. 2944e98e3e1Schristos The number of words determined by the number of {address,size} 2954e98e3e1Schristos cells attributes of the device. */ 2964e98e3e1Schristos 2974e98e3e1Schristos typedef struct _hw_unit 2984e98e3e1Schristos { 2994e98e3e1Schristos int nr_cells; 3004e98e3e1Schristos unsigned_cell cells[4]; /* unused cells are zero */ 3014e98e3e1Schristos } hw_unit; 3024e98e3e1Schristos 3034e98e3e1Schristos 3044e98e3e1Schristos /* For the given bus, the number of address and size cells used in a 3054e98e3e1Schristos hw_unit. */ 3064e98e3e1Schristos 3074e98e3e1Schristos #define hw_unit_nr_address_cells(bus) ((bus)->nr_address_cells_of_hw_unit + 0) 3084e98e3e1Schristos 3094e98e3e1Schristos #define hw_unit_nr_size_cells(bus) ((bus)->nr_size_cells_of_hw_unit + 0) 3104e98e3e1Schristos 3114e98e3e1Schristos 3124e98e3e1Schristos /* For the given device, its identifying hw_unit address. 3134e98e3e1Schristos 3144e98e3e1Schristos Each device has an identifying hw_unit address. That address is 3154e98e3e1Schristos used when identifying one of a number of identical devices on a 3164e98e3e1Schristos common controller bus. ex fd0&fd1. */ 3174e98e3e1Schristos 3184e98e3e1Schristos const hw_unit *hw_unit_address 3194e98e3e1Schristos (struct hw *me); 3204e98e3e1Schristos 3214e98e3e1Schristos 3224e98e3e1Schristos /* Convert between a textual and the internal representation of a 3234e98e3e1Schristos hw_unit address/size. 3244e98e3e1Schristos 3254e98e3e1Schristos NOTE: A device asks its parent to translate between a hw_unit and 3264e98e3e1Schristos textual representation. This is because the textual address of a 3274e98e3e1Schristos device is specified using the parent busses notation. */ 3284e98e3e1Schristos 3294e98e3e1Schristos typedef int (hw_unit_decode_method) 3304e98e3e1Schristos (struct hw *bus, 3314e98e3e1Schristos const char *encoded, 3324e98e3e1Schristos hw_unit *unit); 3334e98e3e1Schristos 3344e98e3e1Schristos #define hw_unit_decode(bus, encoded, unit) \ 3354e98e3e1Schristos ((bus)->to_unit_decode (bus, encoded, unit)) 3364e98e3e1Schristos 3374e98e3e1Schristos #define set_hw_unit_decode(hw, method) \ 3384e98e3e1Schristos ((hw)->to_unit_decode = (method)) 3394e98e3e1Schristos 3404e98e3e1Schristos typedef int (hw_unit_encode_method) 3414e98e3e1Schristos (struct hw *bus, 3424e98e3e1Schristos const hw_unit *unit, 3434e98e3e1Schristos char *encoded, 3444e98e3e1Schristos int sizeof_buf); 3454e98e3e1Schristos 3464e98e3e1Schristos #define hw_unit_encode(bus, unit, encoded, sizeof_encoded) \ 3474e98e3e1Schristos ((bus)->to_unit_encode (bus, unit, encoded, sizeof_encoded)) 3484e98e3e1Schristos 3494e98e3e1Schristos #define set_hw_unit_encode(hw, method) \ 3504e98e3e1Schristos ((hw)->to_unit_encode = (method)) 3514e98e3e1Schristos 3524e98e3e1Schristos 3534e98e3e1Schristos /* As the bus that the device is attached too, to translate a devices 3544e98e3e1Schristos hw_unit address/size into a form suitable for an attach address 3554e98e3e1Schristos call. 3564e98e3e1Schristos 3574e98e3e1Schristos Return a zero result if the address should be ignored when looking 3584e98e3e1Schristos for attach addresses. */ 3594e98e3e1Schristos 3604e98e3e1Schristos typedef int (hw_unit_address_to_attach_address_method) 3614e98e3e1Schristos (struct hw *bus, 3624e98e3e1Schristos const hw_unit *unit_addr, 3634e98e3e1Schristos int *attach_space, 3644e98e3e1Schristos unsigned_word *attach_addr, 3654e98e3e1Schristos struct hw *client); 3664e98e3e1Schristos 3674e98e3e1Schristos #define hw_unit_address_to_attach_address(bus, unit_addr, attach_space, attach_addr, client) \ 3684e98e3e1Schristos ((bus)->to_unit_address_to_attach_address (bus, unit_addr, attach_space, attach_addr, client)) 3694e98e3e1Schristos 3704e98e3e1Schristos #define set_hw_unit_address_to_attach_address(hw, method) \ 3714e98e3e1Schristos ((hw)->to_unit_address_to_attach_address = (method)) 3724e98e3e1Schristos 3734e98e3e1Schristos typedef int (hw_unit_size_to_attach_size_method) 3744e98e3e1Schristos (struct hw *bus, 3754e98e3e1Schristos const hw_unit *unit_size, 3764e98e3e1Schristos unsigned *attach_size, 3774e98e3e1Schristos struct hw *client); 3784e98e3e1Schristos 3794e98e3e1Schristos #define hw_unit_size_to_attach_size(bus, unit_size, attach_size, client) \ 3804e98e3e1Schristos ((bus)->to_unit_size_to_attach_size (bus, unit_size, attach_size, client)) 3814e98e3e1Schristos 3824e98e3e1Schristos #define set_hw_unit_size_to_attach_size(hw, method) \ 3834e98e3e1Schristos ((hw)->to_unit_size_to_attach_size = (method)) 3844e98e3e1Schristos 3854e98e3e1Schristos 3864e98e3e1Schristos extern char *hw_strdup (struct hw *me, const char *str); 3874e98e3e1Schristos 3884e98e3e1Schristos 3894e98e3e1Schristos /* Utilities: 3904e98e3e1Schristos 3914e98e3e1Schristos */ 3924e98e3e1Schristos 3934e98e3e1Schristos /* IOCTL:: 3944e98e3e1Schristos 3954e98e3e1Schristos Often devices require `out of band' operations to be performed. 3964e98e3e1Schristos For instance a pal device may need to notify a PCI bridge device 3974e98e3e1Schristos that an interrupt ack cycle needs to be performed on the PCI bus. 3984e98e3e1Schristos Within PSIM such operations are performed by using the generic 3994e98e3e1Schristos ioctl call <<hw_ioctl()>>. 4004e98e3e1Schristos 4014e98e3e1Schristos */ 4024e98e3e1Schristos 4034e98e3e1Schristos typedef enum 4044e98e3e1Schristos { 4054e98e3e1Schristos hw_ioctl_break, /* unsigned_word requested_break */ 4064e98e3e1Schristos hw_ioctl_set_trace, /* void */ 4074e98e3e1Schristos hw_ioctl_create_stack, /* unsigned_word *sp, char **argv, char **envp */ 4084e98e3e1Schristos hw_ioctl_change_media, /* const char *new_image (possibly NULL) */ 4094e98e3e1Schristos nr_hw_ioctl_requests, 4104e98e3e1Schristos } hw_ioctl_request; 4114e98e3e1Schristos 4124e98e3e1Schristos typedef int (hw_ioctl_method) 4134e98e3e1Schristos (struct hw *me, 4144e98e3e1Schristos hw_ioctl_request request, 4154e98e3e1Schristos va_list ap); 4164e98e3e1Schristos 4174e98e3e1Schristos int hw_ioctl 4184e98e3e1Schristos (struct hw *me, 4194e98e3e1Schristos hw_ioctl_request request, 4204e98e3e1Schristos ...); 4214e98e3e1Schristos 4224e98e3e1Schristos 4234e98e3e1Schristos /* Error reporting:: 4244e98e3e1Schristos 4254e98e3e1Schristos So that errors originating from devices appear in a consistent 4264e98e3e1Schristos format, the <<hw_abort()>> function can be used. Formats and 4274e98e3e1Schristos outputs the error message before aborting the simulation 4284e98e3e1Schristos 4294e98e3e1Schristos Devices should use this function to abort the simulation except 4304e98e3e1Schristos when the abort reason leaves the simulation in a hazardous 4314e98e3e1Schristos condition (for instance a failed malloc). 4324e98e3e1Schristos 4334e98e3e1Schristos */ 4344e98e3e1Schristos 4354e98e3e1Schristos void hw_abort 4364e98e3e1Schristos (struct hw *me, 4374e98e3e1Schristos const char *fmt, 4384b169a6bSchristos ...) ATTRIBUTE_PRINTF (2, 3) ATTRIBUTE_NORETURN; 4394e98e3e1Schristos 4404b169a6bSchristos extern void hw_vabort (struct hw *me, const char *fmt, va_list ap) 4414b169a6bSchristos ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 0); 4424e98e3e1Schristos 4434e98e3e1Schristos void hw_halt 4444e98e3e1Schristos (struct hw *me, 4454e98e3e1Schristos int reason, 4464b169a6bSchristos int status) ATTRIBUTE_NORETURN; 4474e98e3e1Schristos 4484e98e3e1Schristos 4494e98e3e1Schristos #define hw_trace_p(hw) ((hw)->trace_of_hw_p + 0) 4504e98e3e1Schristos 4514e98e3e1Schristos void hw_trace 4524e98e3e1Schristos (struct hw *me, 4534e98e3e1Schristos const char *fmt, 4544b169a6bSchristos ...) ATTRIBUTE_PRINTF (2, 3); 4554e98e3e1Schristos 4564e98e3e1Schristos #define HW_TRACE(ARGS) \ 4574e98e3e1Schristos do { \ 4584e98e3e1Schristos if (hw_trace_p (me)) \ 4594e98e3e1Schristos { \ 4604e98e3e1Schristos hw_trace ARGS; \ 4614e98e3e1Schristos } \ 4624e98e3e1Schristos } while (0) 4634e98e3e1Schristos 4644e98e3e1Schristos 4654e98e3e1Schristos /* Some of the related functions require specific types */ 4664e98e3e1Schristos 4674e98e3e1Schristos struct hw_property_data; 4684e98e3e1Schristos struct hw_port_data; 4694e98e3e1Schristos struct hw_base_data; 4704e98e3e1Schristos struct hw_alloc_data; 4714e98e3e1Schristos struct hw_event_data; 4724e98e3e1Schristos struct hw_handle_data; 4734e98e3e1Schristos struct hw_instance_data; 4744e98e3e1Schristos 4754e98e3e1Schristos /* Finally the hardware device - keep your grubby little mits off of 4764e98e3e1Schristos these internals! :-) */ 4774e98e3e1Schristos 4784e98e3e1Schristos struct hw 4794e98e3e1Schristos { 4804e98e3e1Schristos 4814e98e3e1Schristos /* our relatives */ 4824e98e3e1Schristos struct hw *parent_of_hw; 4834e98e3e1Schristos struct hw *sibling_of_hw; 4844e98e3e1Schristos struct hw *child_of_hw; 4854e98e3e1Schristos 4864e98e3e1Schristos /* our identity */ 4874e98e3e1Schristos const char *name_of_hw; 4884e98e3e1Schristos const char *family_of_hw; 4894e98e3e1Schristos const char *args_of_hw; 4904e98e3e1Schristos const char *path_of_hw; 4914e98e3e1Schristos 4924e98e3e1Schristos /* our data */ 4934e98e3e1Schristos void *data_of_hw; 4944e98e3e1Schristos 4954e98e3e1Schristos /* hot links */ 4964e98e3e1Schristos struct hw *root_of_hw; 4974e98e3e1Schristos struct sim_state *system_of_hw; 4984e98e3e1Schristos 4994e98e3e1Schristos /* identifying data */ 5004e98e3e1Schristos hw_unit unit_address_of_hw; 5014e98e3e1Schristos int nr_address_cells_of_hw_unit; 5024e98e3e1Schristos int nr_size_cells_of_hw_unit; 5034e98e3e1Schristos 5044e98e3e1Schristos /* Soft reset */ 5054e98e3e1Schristos hw_reset_method *to_reset; 5064e98e3e1Schristos 5074e98e3e1Schristos /* Basic callbacks */ 5084e98e3e1Schristos hw_io_read_buffer_method *to_io_read_buffer; 5094e98e3e1Schristos hw_io_write_buffer_method *to_io_write_buffer; 5104e98e3e1Schristos hw_dma_read_buffer_method *to_dma_read_buffer; 5114e98e3e1Schristos hw_dma_write_buffer_method *to_dma_write_buffer; 5124e98e3e1Schristos hw_attach_address_method *to_attach_address; 5134e98e3e1Schristos hw_detach_address_method *to_detach_address; 5144e98e3e1Schristos 5154e98e3e1Schristos /* More complicated callbacks */ 5164e98e3e1Schristos hw_ioctl_method *to_ioctl; 5174e98e3e1Schristos int trace_of_hw_p; 5184e98e3e1Schristos 5194e98e3e1Schristos /* address callbacks */ 5204e98e3e1Schristos hw_unit_decode_method *to_unit_decode; 5214e98e3e1Schristos hw_unit_encode_method *to_unit_encode; 5224e98e3e1Schristos hw_unit_address_to_attach_address_method *to_unit_address_to_attach_address; 5234e98e3e1Schristos hw_unit_size_to_attach_size_method *to_unit_size_to_attach_size; 5244e98e3e1Schristos 5254e98e3e1Schristos /* related data */ 5264e98e3e1Schristos struct hw_property_data *properties_of_hw; 5274e98e3e1Schristos struct hw_port_data *ports_of_hw; 5284e98e3e1Schristos struct hw_base_data *base_of_hw; 5294e98e3e1Schristos struct hw_alloc_data *alloc_of_hw; 5304e98e3e1Schristos struct hw_event_data *events_of_hw; 5314e98e3e1Schristos struct hw_handle_data *handles_of_hw; 5324e98e3e1Schristos struct hw_instance_data *instances_of_hw; 5334e98e3e1Schristos 5344e98e3e1Schristos }; 5354e98e3e1Schristos 5364e98e3e1Schristos 5374e98e3e1Schristos #endif 538