1 1.1 christos /* This file is part of the program psim. 2 1.1 christos 3 1.1 christos Copyright (C) 1994-1997, Andrew Cagney <cagney (at) highland.com.au> 4 1.1 christos 5 1.1 christos This program is free software; you can redistribute it and/or modify 6 1.1 christos it under the terms of the GNU General Public License as published by 7 1.2 joerg the Free Software Foundation; either version 3 of the License, or 8 1.1 christos (at your option) any later version. 9 1.1 christos 10 1.1 christos This program is distributed in the hope that it will be useful, 11 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 12 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 1.1 christos GNU General Public License for more details. 14 1.1 christos 15 1.1 christos You should have received a copy of the GNU General Public License 16 1.2 joerg along with this program; if not, see <http://www.gnu.org/licenses/>. 17 1.1 christos 18 1.1 christos */ 19 1.1 christos 20 1.1 christos 21 1.1 christos #ifndef _DEVICE_H_ 22 1.1 christos #define _DEVICE_H_ 23 1.1 christos 24 1.1 christos #ifndef INLINE_DEVICE 25 1.1 christos #define INLINE_DEVICE 26 1.1 christos #endif 27 1.1 christos 28 1.1 christos /* declared in basics.h, this object is used everywhere */ 29 1.1 christos /* typedef struct _device device; */ 30 1.1 christos 31 1.1 christos 32 1.1 christos /* Introduction: 33 1.1 christos 34 1.1 christos As explained in earlier sections, the device, device instance, 35 1.1 christos property and interrupts lie at the heart of PSIM's device model. 36 1.1 christos 37 1.1 christos In the below a synopsis of the device object and the operations it 38 1.1 christos supports are given. Details of this object can be found in the 39 1.1 christos files <<device.h>> and <<device.c>>. 40 1.1 christos 41 1.1 christos */ 42 1.1 christos 43 1.1 christos 44 1.1 christos /* Device creation: */ 45 1.1 christos 46 1.1 christos INLINE_DEVICE\ 47 1.1 christos (device *) device_create 48 1.1 christos (device *parent, 49 1.1 christos const char *base, 50 1.1 christos const char *name, 51 1.1 christos const char *unit_address, 52 1.1 christos const char *args); 53 1.1 christos 54 1.1 christos INLINE_DEVICE\ 55 1.1 christos (void) device_usage 56 1.1 christos (int verbose); 57 1.1 christos 58 1.1 christos 59 1.1 christos /* Device initialization: */ 60 1.1 christos 61 1.1 christos INLINE_DEVICE\ 62 1.1 christos (void) device_clean 63 1.1 christos (device *root, 64 1.1 christos void *data); 65 1.1 christos 66 1.1 christos INLINE_DEVICE\ 67 1.1 christos (void) device_init_static_properties 68 1.1 christos (device *me, 69 1.1 christos void *data); 70 1.1 christos 71 1.1 christos INLINE_DEVICE\ 72 1.1 christos (void) device_init_address 73 1.1 christos (device *me, 74 1.1 christos void *data); 75 1.1 christos 76 1.1 christos INLINE_DEVICE\ 77 1.1 christos (void) device_init_runtime_properties 78 1.1 christos (device *me, 79 1.1 christos void *data); 80 1.1 christos 81 1.1 christos INLINE_DEVICE\ 82 1.1 christos (void) device_init_data 83 1.1 christos (device *me, 84 1.1 christos void *data); 85 1.1 christos 86 1.1 christos 87 1.1 christos /* Relationships: 88 1.1 christos 89 1.1 christos A device is able to determine its relationship to other devices 90 1.1 christos within the tree. Operations include querying for a devices parent, 91 1.1 christos sibling, child, name, and path (from the root). 92 1.1 christos 93 1.1 christos */ 94 1.1 christos 95 1.1 christos INLINE_DEVICE\ 96 1.1 christos (device *) device_parent 97 1.1 christos (device *me); 98 1.1 christos 99 1.1 christos INLINE_DEVICE\ 100 1.1 christos (device *) device_root 101 1.1 christos (device *me); 102 1.1 christos 103 1.1 christos INLINE_DEVICE\ 104 1.1 christos (device *) device_sibling 105 1.1 christos (device *me); 106 1.1 christos 107 1.1 christos INLINE_DEVICE\ 108 1.1 christos (device *) device_child 109 1.1 christos (device *me); 110 1.1 christos 111 1.1 christos INLINE_DEVICE\ 112 1.1 christos (const char *) device_name 113 1.1 christos (device *me); 114 1.1 christos 115 1.1 christos INLINE_DEVICE\ 116 1.1 christos (const char *) device_base 117 1.1 christos (device *me); 118 1.1 christos 119 1.1 christos INLINE_DEVICE\ 120 1.1 christos (const char *) device_path 121 1.1 christos (device *me); 122 1.1 christos 123 1.1 christos INLINE_DEVICE\ 124 1.1 christos (void *) device_data 125 1.1 christos (device *me); 126 1.1 christos 127 1.1 christos INLINE_DEVICE\ 128 1.1 christos (psim *) device_system 129 1.1 christos (device *me); 130 1.1 christos 131 1.1 christos typedef struct _device_unit { 132 1.1 christos int nr_cells; 133 1.1 christos unsigned_cell cells[4]; /* unused cells are zero */ 134 1.1 christos } device_unit; 135 1.1 christos 136 1.1 christos INLINE_DEVICE\ 137 1.1 christos (const device_unit *) device_unit_address 138 1.1 christos (device *me); 139 1.1 christos 140 1.1 christos INLINE_DEVICE\ 141 1.1 christos (int) device_decode_unit 142 1.1 christos (device *bus, 143 1.1 christos const char *unit, 144 1.1 christos device_unit *address); 145 1.1 christos 146 1.1 christos INLINE_DEVICE\ 147 1.1 christos (int) device_encode_unit 148 1.1 christos (device *bus, 149 1.1 christos const device_unit *unit_address, 150 1.1 christos char *buf, 151 1.1 christos int sizeof_buf); 152 1.1 christos 153 1.1 christos 154 1.1 christos /* Convert an Open Firmware size into a form suitable for attach 155 1.1 christos address calls. 156 1.1 christos 157 1.1 christos Return a zero result if the address should be ignored when looking 158 1.1 christos for attach addresses */ 159 1.1 christos 160 1.1 christos INLINE_DEVICE\ 161 1.1 christos (int) device_address_to_attach_address 162 1.1 christos (device *me, 163 1.1 christos const device_unit *address, 164 1.1 christos int *attach_space, 165 1.1 christos unsigned_word *attach_address, 166 1.1 christos device *client); 167 1.1 christos 168 1.1 christos 169 1.1 christos /* Convert an Open Firmware size into a form suitable for attach 170 1.1 christos address calls 171 1.1 christos 172 1.1 christos Return a zero result if the address should be ignored */ 173 1.1 christos 174 1.1 christos INLINE_DEVICE\ 175 1.1 christos (int) device_size_to_attach_size 176 1.1 christos (device *me, 177 1.1 christos const device_unit *size, 178 1.1 christos unsigned *nr_bytes, 179 1.1 christos device *client); 180 1.1 christos 181 1.1 christos 182 1.1 christos INLINE_DEVICE\ 183 1.1 christos (unsigned) device_nr_address_cells 184 1.1 christos (device *me); 185 1.1 christos 186 1.1 christos INLINE_DEVICE\ 187 1.1 christos (unsigned) device_nr_size_cells 188 1.1 christos (device *me); 189 1.1 christos 190 1.1 christos 191 1.1 christos /* Properties: 192 1.1 christos 193 1.1 christos Attached to a device are a number of properties. Each property has 194 1.1 christos a size and type (both of which can be queried). A device is able 195 1.1 christos to iterate over or query and set a properties value. 196 1.1 christos 197 1.1 christos */ 198 1.1 christos 199 1.1 christos /* The following are valid property types. The property `array' is 200 1.1 christos for generic untyped data. */ 201 1.1 christos 202 1.1 christos typedef enum { 203 1.1 christos array_property, 204 1.1 christos boolean_property, 205 1.1 christos ihandle_property, /*runtime*/ 206 1.1 christos integer_property, 207 1.1 christos range_array_property, 208 1.1 christos reg_array_property, 209 1.1 christos string_property, 210 1.1 christos string_array_property, 211 1.1 christos } device_property_type; 212 1.1 christos 213 1.1 christos typedef struct _device_property device_property; 214 1.1 christos struct _device_property { 215 1.1 christos device *owner; 216 1.1 christos const char *name; 217 1.1 christos device_property_type type; 218 1.1 christos unsigned sizeof_array; 219 1.1 christos const void *array; 220 1.1 christos const device_property *original; 221 1.1 christos object_disposition disposition; 222 1.1 christos }; 223 1.1 christos 224 1.1 christos 225 1.1 christos /* iterate through the properties attached to a device */ 226 1.1 christos 227 1.1 christos INLINE_DEVICE\ 228 1.1 christos (const device_property *) device_next_property 229 1.1 christos (const device_property *previous); 230 1.1 christos 231 1.1 christos INLINE_DEVICE\ 232 1.1 christos (const device_property *) device_find_property 233 1.1 christos (device *me, 234 1.1 christos const char *property); /* NULL for first property */ 235 1.1 christos 236 1.1 christos 237 1.1 christos /* Manipulate the properties belonging to a given device. 238 1.1 christos 239 1.1 christos SET on the other hand will force the properties value. The 240 1.1 christos simulation is aborted if the property was present but of a 241 1.1 christos conflicting type. 242 1.1 christos 243 1.1 christos FIND returns the specified properties value, aborting the 244 1.1 christos simulation if the property is missing. Code locating a property 245 1.1 christos should first check its type (using device_find_property above) and 246 1.1 christos then obtain its value using the below. 247 1.1 christos 248 1.1 christos void device_add_<type>_property(device *, const char *, <type>) 249 1.1 christos void device_add_*_array_property(device *, const char *, const <type>*, int) 250 1.1 christos void device_set_*_property(device *, const char *, <type>) 251 1.1 christos void device_set_*_array_property(device *, const char *, const <type>*, int) 252 1.1 christos <type> device_find_*_property(device *, const char *) 253 1.1 christos int device_find_*_array_property(device *, const char *, int, <type>*) 254 1.1 christos 255 1.1 christos */ 256 1.1 christos 257 1.1 christos 258 1.1 christos INLINE_DEVICE\ 259 1.1 christos (void) device_add_array_property 260 1.1 christos (device *me, 261 1.1 christos const char *property, 262 1.1 christos const void *array, 263 1.1 christos int sizeof_array); 264 1.1 christos 265 1.1 christos INLINE_DEVICE\ 266 1.1 christos (void) device_set_array_property 267 1.1 christos (device *me, 268 1.1 christos const char *property, 269 1.1 christos const void *array, 270 1.1 christos int sizeof_array); 271 1.1 christos 272 1.1 christos INLINE_DEVICE\ 273 1.1 christos (const device_property *) device_find_array_property 274 1.1 christos (device *me, 275 1.1 christos const char *property); 276 1.1 christos 277 1.1 christos 278 1.1 christos 279 1.1 christos INLINE_DEVICE\ 280 1.1 christos (void) device_add_boolean_property 281 1.1 christos (device *me, 282 1.1 christos const char *property, 283 1.3 christos int boolean); 284 1.1 christos 285 1.1 christos INLINE_DEVICE\ 286 1.1 christos (int) device_find_boolean_property 287 1.1 christos (device *me, 288 1.1 christos const char *property); 289 1.1 christos 290 1.1 christos 291 1.1 christos 292 1.1 christos typedef struct _ihandle_runtime_property_spec { 293 1.1 christos const char *full_path; 294 1.1 christos } ihandle_runtime_property_spec; 295 1.1 christos 296 1.1 christos INLINE_DEVICE\ 297 1.1 christos (void) device_add_ihandle_runtime_property 298 1.1 christos (device *me, 299 1.1 christos const char *property, 300 1.1 christos const ihandle_runtime_property_spec *ihandle); 301 1.1 christos 302 1.1 christos INLINE_DEVICE\ 303 1.1 christos (void) device_find_ihandle_runtime_property 304 1.1 christos (device *me, 305 1.1 christos const char *property, 306 1.1 christos ihandle_runtime_property_spec *ihandle); 307 1.1 christos 308 1.1 christos INLINE_DEVICE\ 309 1.1 christos (void) device_set_ihandle_property 310 1.1 christos (device *me, 311 1.1 christos const char *property, 312 1.1 christos device_instance *ihandle); 313 1.1 christos 314 1.1 christos INLINE_DEVICE\ 315 1.1 christos (device_instance *) device_find_ihandle_property 316 1.1 christos (device *me, 317 1.1 christos const char *property); 318 1.1 christos 319 1.1 christos 320 1.1 christos 321 1.1 christos INLINE_DEVICE\ 322 1.1 christos (void) device_add_integer_property 323 1.1 christos (device *me, 324 1.1 christos const char *property, 325 1.1 christos signed_cell integer); 326 1.1 christos 327 1.1 christos INLINE_DEVICE\ 328 1.1 christos (signed_cell) device_find_integer_property 329 1.1 christos (device *me, 330 1.1 christos const char *property); 331 1.1 christos 332 1.1 christos INLINE_DEVICE\ 333 1.1 christos (int) device_find_integer_array_property 334 1.1 christos (device *me, 335 1.1 christos const char *property, 336 1.1 christos unsigned index, 337 1.1 christos signed_cell *integer); 338 1.1 christos 339 1.1 christos 340 1.1 christos 341 1.1 christos typedef struct _range_property_spec { 342 1.1 christos device_unit child_address; 343 1.1 christos device_unit parent_address; 344 1.1 christos device_unit size; 345 1.1 christos } range_property_spec; 346 1.1 christos 347 1.1 christos INLINE_DEVICE\ 348 1.1 christos (void) device_add_range_array_property 349 1.1 christos (device *me, 350 1.1 christos const char *property, 351 1.1 christos const range_property_spec *ranges, 352 1.1 christos unsigned nr_ranges); 353 1.1 christos 354 1.1 christos INLINE_DEVICE\ 355 1.1 christos (int) device_find_range_array_property 356 1.1 christos (device *me, 357 1.1 christos const char *property, 358 1.1 christos unsigned index, 359 1.1 christos range_property_spec *range); 360 1.1 christos 361 1.1 christos 362 1.1 christos 363 1.1 christos typedef struct _reg_property_spec { 364 1.1 christos device_unit address; 365 1.1 christos device_unit size; 366 1.1 christos } reg_property_spec; 367 1.1 christos 368 1.1 christos INLINE_DEVICE\ 369 1.1 christos (void) device_add_reg_array_property 370 1.1 christos (device *me, 371 1.1 christos const char *property, 372 1.1 christos const reg_property_spec *reg, 373 1.1 christos unsigned nr_regs); 374 1.1 christos 375 1.1 christos INLINE_DEVICE\ 376 1.1 christos (int) device_find_reg_array_property 377 1.1 christos (device *me, 378 1.1 christos const char *property, 379 1.1 christos unsigned index, 380 1.1 christos reg_property_spec *reg); 381 1.1 christos 382 1.1 christos 383 1.1 christos 384 1.1 christos INLINE_DEVICE\ 385 1.1 christos (void) device_add_string_property 386 1.1 christos (device *me, 387 1.1 christos const char *property, 388 1.1 christos const char *string); 389 1.1 christos 390 1.1 christos INLINE_DEVICE\ 391 1.1 christos (const char *) device_find_string_property 392 1.1 christos (device *me, 393 1.1 christos const char *property); 394 1.1 christos 395 1.1 christos 396 1.1 christos 397 1.1 christos typedef const char *string_property_spec; 398 1.1 christos 399 1.1 christos INLINE_DEVICE\ 400 1.1 christos (void) device_add_string_array_property 401 1.1 christos (device *me, 402 1.1 christos const char *property, 403 1.1 christos const string_property_spec *strings, 404 1.1 christos unsigned nr_strings); 405 1.1 christos 406 1.1 christos INLINE_DEVICE\ 407 1.1 christos (int) device_find_string_array_property 408 1.1 christos (device *me, 409 1.1 christos const char *property, 410 1.1 christos unsigned index, 411 1.1 christos string_property_spec *string); 412 1.1 christos 413 1.1 christos 414 1.1 christos 415 1.1 christos INLINE_DEVICE\ 416 1.1 christos (void) device_add_duplicate_property 417 1.1 christos (device *me, 418 1.1 christos const char *property, 419 1.1 christos const device_property *original); 420 1.1 christos 421 1.1 christos 422 1.1 christos 423 1.1 christos /* Instances: 424 1.1 christos 425 1.1 christos As with IEEE1275, a device can be opened, creating an instance. 426 1.1 christos Instances provide more abstract interfaces to the underlying 427 1.1 christos hardware. For example, the instance methods for a disk may include 428 1.1 christos code that is able to interpret file systems found on disks. Such 429 1.1 christos methods would there for allow the manipulation of files on the 430 1.1 christos disks file system. The operations would be implemented using the 431 1.1 christos basic block I/O model provided by the disk. 432 1.1 christos 433 1.4 christos This model includes methods that facilitate the creation of device 434 1.1 christos instance and (should a given device support it) standard operations 435 1.1 christos on those instances. 436 1.1 christos 437 1.1 christos */ 438 1.1 christos 439 1.1 christos typedef struct _device_instance_callbacks device_instance_callbacks; 440 1.1 christos 441 1.1 christos INLINE_DEVICE\ 442 1.1 christos (device_instance *) device_create_instance_from 443 1.1 christos (device *me, /*OR*/ device_instance *parent, 444 1.1 christos void *data, 445 1.1 christos const char *path, 446 1.1 christos const char *args, 447 1.1 christos const device_instance_callbacks *callbacks); 448 1.1 christos 449 1.1 christos INLINE_DEVICE\ 450 1.1 christos (device_instance *) device_create_instance 451 1.1 christos (device *me, 452 1.1 christos const char *full_path, 453 1.1 christos const char *args); 454 1.1 christos 455 1.1 christos INLINE_DEVICE\ 456 1.1 christos (void) device_instance_delete 457 1.1 christos (device_instance *instance); 458 1.1 christos 459 1.1 christos INLINE_DEVICE\ 460 1.1 christos (int) device_instance_read 461 1.1 christos (device_instance *instance, 462 1.1 christos void *addr, 463 1.1 christos unsigned_word len); 464 1.1 christos 465 1.1 christos INLINE_DEVICE\ 466 1.1 christos (int) device_instance_write 467 1.1 christos (device_instance *instance, 468 1.1 christos const void *addr, 469 1.1 christos unsigned_word len); 470 1.1 christos 471 1.1 christos INLINE_DEVICE\ 472 1.1 christos (int) device_instance_seek 473 1.1 christos (device_instance *instance, 474 1.1 christos unsigned_word pos_hi, 475 1.1 christos unsigned_word pos_lo); 476 1.1 christos 477 1.1 christos INLINE_DEVICE\ 478 1.1 christos (int) device_instance_call_method 479 1.1 christos (device_instance *instance, 480 1.1 christos const char *method, 481 1.1 christos int n_stack_args, 482 1.1 christos unsigned_cell stack_args[/*n_stack_args*/], 483 1.1 christos int n_stack_returns, 484 1.1 christos unsigned_cell stack_returns[/*n_stack_returns*/]); 485 1.1 christos 486 1.1 christos INLINE_DEVICE\ 487 1.1 christos (device *) device_instance_device 488 1.1 christos (device_instance *instance); 489 1.1 christos 490 1.1 christos INLINE_DEVICE\ 491 1.1 christos (const char *) device_instance_path 492 1.1 christos (device_instance *instance); 493 1.1 christos 494 1.1 christos INLINE_DEVICE\ 495 1.1 christos (void *) device_instance_data 496 1.1 christos (device_instance *instance); 497 1.1 christos 498 1.1 christos 499 1.1 christos /* Interrupts: 500 1.1 christos 501 1.1 christos */ 502 1.1 christos 503 1.1 christos /* Interrupt Source 504 1.1 christos 505 1.1 christos A device drives its interrupt line using the call 506 1.1 christos 507 1.1 christos */ 508 1.1 christos 509 1.1 christos INLINE_DEVICE\ 510 1.1 christos (void) device_interrupt_event 511 1.1 christos (device *me, 512 1.1 christos int my_port, 513 1.1 christos int value, 514 1.1 christos cpu *processor, 515 1.1 christos unsigned_word cia); 516 1.1 christos 517 1.1 christos /* This interrupt event will then be propogated to any attached 518 1.1 christos interrupt destinations. 519 1.1 christos 520 1.1 christos Any interpretation of PORT and VALUE is model dependant. However 521 1.1 christos as guidelines the following are recommended: PCI interrupts a-d 522 1.1 christos correspond to lines 0-3; level sensative interrupts be requested 523 1.1 christos with a value of one and withdrawn with a value of 0; edge sensative 524 1.1 christos interrupts always have a value of 1, the event its self is treated 525 1.1 christos as the interrupt. 526 1.1 christos 527 1.1 christos 528 1.1 christos Interrupt Destinations 529 1.1 christos 530 1.1 christos Attached to each interrupt line of a device can be zero or more 531 1.1 christos desitinations. These destinations consist of a device/port pair. 532 1.1 christos A destination is attached/detached to a device line using the 533 1.1 christos attach and detach calls. */ 534 1.1 christos 535 1.1 christos INLINE_DEVICE\ 536 1.1 christos (void) device_interrupt_attach 537 1.1 christos (device *me, 538 1.1 christos int my_port, 539 1.1 christos device *dest, 540 1.1 christos int dest_port, 541 1.1 christos object_disposition disposition); 542 1.1 christos 543 1.1 christos INLINE_DEVICE\ 544 1.1 christos (void) device_interrupt_detach 545 1.1 christos (device *me, 546 1.1 christos int my_port, 547 1.1 christos device *dest, 548 1.1 christos int dest_port); 549 1.1 christos 550 1.1 christos typedef void (device_interrupt_traverse_function) 551 1.1 christos (device *me, 552 1.1 christos int my_port, 553 1.1 christos device *dest, 554 1.1 christos int my_dest, 555 1.1 christos void *data); 556 1.1 christos 557 1.1 christos INLINE_DEVICE\ 558 1.1 christos (void) device_interrupt_traverse 559 1.1 christos (device *me, 560 1.1 christos device_interrupt_traverse_function *handler, 561 1.1 christos void *data); 562 1.1 christos 563 1.1 christos 564 1.1 christos /* DESTINATION is attached (detached) to LINE of the device ME 565 1.1 christos 566 1.1 christos 567 1.1 christos Interrupt conversion 568 1.1 christos 569 1.1 christos Users refer to interrupt port numbers symbolically. For instance a 570 1.1 christos device may refer to its `INT' signal which is internally 571 1.1 christos represented by port 3. 572 1.1 christos 573 1.1 christos To convert to/from the symbolic and internal representation of a 574 1.1 christos port name/number. The following functions are available. */ 575 1.1 christos 576 1.1 christos INLINE_DEVICE\ 577 1.1 christos (int) device_interrupt_decode 578 1.1 christos (device *me, 579 1.1 christos const char *symbolic_name, 580 1.1 christos port_direction direction); 581 1.1 christos 582 1.1 christos INLINE_DEVICE\ 583 1.1 christos (int) device_interrupt_encode 584 1.1 christos (device *me, 585 1.1 christos int port_number, 586 1.1 christos char *buf, 587 1.1 christos int sizeof_buf, 588 1.1 christos port_direction direction); 589 1.1 christos 590 1.1 christos 591 1.1 christos /* Hardware operations: 592 1.1 christos 593 1.1 christos */ 594 1.1 christos 595 1.1 christos INLINE_DEVICE\ 596 1.1 christos (unsigned) device_io_read_buffer 597 1.1 christos (device *me, 598 1.1 christos void *dest, 599 1.1 christos int space, 600 1.1 christos unsigned_word addr, 601 1.1 christos unsigned nr_bytes, 602 1.1 christos cpu *processor, 603 1.1 christos unsigned_word cia); 604 1.1 christos 605 1.1 christos INLINE_DEVICE\ 606 1.1 christos (unsigned) device_io_write_buffer 607 1.1 christos (device *me, 608 1.1 christos const void *source, 609 1.1 christos int space, 610 1.1 christos unsigned_word addr, 611 1.1 christos unsigned nr_bytes, 612 1.1 christos cpu *processor, 613 1.1 christos unsigned_word cia); 614 1.1 christos 615 1.1 christos 616 1.1 christos /* Conversly, the device pci1000,1@1 my need to perform a dma transfer 617 1.1 christos into the cpu/memory core. Just as I/O moves towards the leaves, 618 1.1 christos dma transfers move towards the core via the initiating devices 619 1.1 christos parent nodes. The root device (special) converts the DMA transfer 620 1.1 christos into reads/writes to memory */ 621 1.1 christos 622 1.1 christos INLINE_DEVICE\ 623 1.1 christos (unsigned) device_dma_read_buffer 624 1.1 christos (device *me, 625 1.1 christos void *dest, 626 1.1 christos int space, 627 1.1 christos unsigned_word addr, 628 1.1 christos unsigned nr_bytes); 629 1.1 christos 630 1.1 christos INLINE_DEVICE\ 631 1.1 christos (unsigned) device_dma_write_buffer 632 1.1 christos (device *me, 633 1.1 christos const void *source, 634 1.1 christos int space, 635 1.1 christos unsigned_word addr, 636 1.1 christos unsigned nr_bytes, 637 1.1 christos int violate_read_only_section); 638 1.1 christos 639 1.1 christos /* To avoid the need for an intermediate (bridging) node to ask each 640 1.1 christos of its child devices in turn if an IO access is intended for them, 641 1.1 christos parent nodes maintain a table mapping addresses directly to 642 1.1 christos specific devices. When a device is `connected' to its bus it 643 1.1 christos attaches its self to its parent. */ 644 1.1 christos 645 1.1 christos /* Address access attributes */ 646 1.1 christos typedef enum _access_type { 647 1.1 christos access_invalid = 0, 648 1.1 christos access_read = 1, 649 1.1 christos access_write = 2, 650 1.1 christos access_read_write = 3, 651 1.1 christos access_exec = 4, 652 1.1 christos access_read_exec = 5, 653 1.1 christos access_write_exec = 6, 654 1.1 christos access_read_write_exec = 7, 655 1.1 christos } access_type; 656 1.1 christos 657 1.1 christos /* Address attachement types */ 658 1.1 christos typedef enum _attach_type { 659 1.1 christos attach_invalid, 660 1.1 christos attach_raw_memory, 661 1.1 christos attach_callback, 662 1.1 christos /* ... */ 663 1.1 christos } attach_type; 664 1.1 christos 665 1.1 christos INLINE_DEVICE\ 666 1.1 christos (void) device_attach_address 667 1.1 christos (device *me, 668 1.1 christos attach_type attach, 669 1.1 christos int space, 670 1.1 christos unsigned_word addr, 671 1.1 christos unsigned nr_bytes, 672 1.1 christos access_type access, 673 1.1 christos device *client); /*callback/default*/ 674 1.1 christos 675 1.1 christos INLINE_DEVICE\ 676 1.1 christos (void) device_detach_address 677 1.1 christos (device *me, 678 1.1 christos attach_type attach, 679 1.1 christos int space, 680 1.1 christos unsigned_word addr, 681 1.1 christos unsigned nr_bytes, 682 1.1 christos access_type access, 683 1.1 christos device *client); /*callback/default*/ 684 1.1 christos 685 1.1 christos /* Utilities: 686 1.1 christos 687 1.1 christos */ 688 1.1 christos 689 1.1 christos /* IOCTL:: 690 1.1 christos 691 1.1 christos Often devices require `out of band' operations to be performed. 692 1.1 christos For instance a pal device may need to notify a PCI bridge device 693 1.1 christos that an interrupt ack cycle needs to be performed on the PCI bus. 694 1.1 christos Within PSIM such operations are performed by using the generic 695 1.1 christos ioctl call <<device_ioctl()>>. 696 1.1 christos 697 1.1 christos */ 698 1.1 christos 699 1.1 christos typedef enum { 700 1.1 christos device_ioctl_break, /* unsigned_word requested_break */ 701 1.1 christos device_ioctl_set_trace, /* void */ 702 1.1 christos device_ioctl_create_stack, /* unsigned_word *sp, char **argv, char **envp */ 703 1.1 christos device_ioctl_change_media, /* const char *new_image (possibly NULL) */ 704 1.1 christos nr_device_ioctl_requests, 705 1.1 christos } device_ioctl_request; 706 1.1 christos 707 1.1 christos EXTERN_DEVICE\ 708 1.1 christos (int) device_ioctl 709 1.1 christos (device *me, 710 1.1 christos cpu *processor, 711 1.1 christos unsigned_word cia, 712 1.1 christos device_ioctl_request request, 713 1.1 christos ...); 714 1.1 christos 715 1.1 christos 716 1.1 christos /* Error reporting:: 717 1.1 christos 718 1.1 christos So that errors originating from devices appear in a consistent 719 1.1 christos format, the <<device_error()>> function can be used. Formats and 720 1.1 christos outputs the error message before aborting the simulation 721 1.1 christos 722 1.1 christos Devices should use this function to abort the simulation except 723 1.1 christos when the abort reason leaves the simulation in a hazardous 724 1.1 christos condition (for instance a failed malloc). 725 1.1 christos 726 1.1 christos */ 727 1.1 christos 728 1.1 christos EXTERN_DEVICE\ 729 1.2 joerg (void) device_error 730 1.1 christos (device *me, 731 1.1 christos const char *fmt, 732 1.3 christos ...) ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF_2; 733 1.1 christos 734 1.1 christos INLINE_DEVICE\ 735 1.1 christos (int) device_trace 736 1.1 christos (device *me); 737 1.1 christos 738 1.1 christos 739 1.1 christos 740 1.1 christos /* External representation: 741 1.1 christos 742 1.1 christos Both device nodes and device instances, in OpenBoot firmware have 743 1.1 christos an external representation (phandles and ihandles) and these values 744 1.1 christos are both stored in the device tree in property nodes and passed 745 1.1 christos between the client program and the simulator during emulation 746 1.1 christos calls. 747 1.1 christos 748 1.1 christos To limit the potential risk associated with trusing `data' from the 749 1.1 christos client program, the following mapping operators `safely' convert 750 1.1 christos between the two representations 751 1.1 christos 752 1.1 christos */ 753 1.1 christos 754 1.1 christos INLINE_DEVICE\ 755 1.1 christos (device *) external_to_device 756 1.1 christos (device *tree_member, 757 1.1 christos unsigned_cell phandle); 758 1.1 christos 759 1.1 christos INLINE_DEVICE\ 760 1.1 christos (unsigned_cell) device_to_external 761 1.1 christos (device *me); 762 1.1 christos 763 1.1 christos INLINE_DEVICE\ 764 1.1 christos (device_instance *) external_to_device_instance 765 1.1 christos (device *tree_member, 766 1.1 christos unsigned_cell ihandle); 767 1.1 christos 768 1.1 christos INLINE_DEVICE\ 769 1.1 christos (unsigned_cell) device_instance_to_external 770 1.1 christos (device_instance *me); 771 1.1 christos 772 1.1 christos 773 1.1 christos /* Event queue: 774 1.1 christos 775 1.1 christos The device inherets certain event queue operations from the main 776 1.1 christos simulation. */ 777 1.1 christos 778 1.1 christos typedef void device_event_handler(void *data); 779 1.1 christos 780 1.1 christos INLINE_DEVICE\ 781 1.1 christos (event_entry_tag) device_event_queue_schedule 782 1.1 christos (device *me, 783 1.3 christos int64_t delta_time, 784 1.1 christos device_event_handler *handler, 785 1.1 christos void *data); 786 1.1 christos 787 1.3 christos INLINE_DEVICE\ 788 1.1 christos (void) device_event_queue_deschedule 789 1.1 christos (device *me, 790 1.1 christos event_entry_tag event_to_remove); 791 1.1 christos 792 1.3 christos INLINE_DEVICE\ 793 1.3 christos (int64_t) device_event_queue_time 794 1.1 christos (device *me); 795 1.1 christos 796 1.1 christos #endif /* _DEVICE_H_ */ 797