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