xref: /netbsd-src/external/gpl3/gdb/dist/sim/common/hw-device.h (revision 88241920d21b339bf319c0e979ffda80c49a2936)
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