Home | History | Annotate | Line # | Download | only in common
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