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