| 1 | <html> |
| 2 | <head> |
| 3 | <title>SPARC Architectural Model: Device and Utility API</title> |
| 4 | </head> |
| 5 | <body bgcolor="#FFFFFF" LANG="en-US"> |
| 6 | |
| 7 | <h2>class PciDev : public Module, PciDevIf</h2> |
| 8 | common/pci_dev.cc: |
| 9 | <br> |
| 10 | <br>#include "pci.h" |
| 11 | <br>#include "pci_dev.h" |
| 12 | |
| 13 | <font size=-1> |
| 14 | <pre> |
| 15 | bool dev_check_args(); |
| 16 | bool dev_parse_arg(const char *arg); |
| 17 | bool dev_module_added(module_t *target, const char *target_name); |
| 18 | bool dev_module_deleted(module_t *target, const char *target_name); |
| 19 | int dev_cfg_access(uint64_t offset, bool_t wr, uint32_t size, uint64_t *buf); |
| 20 | int dev_interrupt_in(bool_t set, int dev_type, int dev_number, int line); |
| 21 | int dev_write_le(uint8_t* mem, uint64_t *buf, uint64_t offset, uint32_t size); |
| 22 | int dev_read_le(uint64_t *buf, uint8_t* mem, uint64_t offset, uint32_t size); |
| 23 | void dev_set_space(pci_space_t, uint64_t base, uint64_t size, int bar); |
| 24 | int dev_dma_out(uint64_t vaddr, void *data, long count); |
| 25 | int dev_dma_in(uint64_t vaddr, void *data, long count); |
| 26 | int dev_set_int_pin(int pin, bool raise); |
| 27 | int dev_set_int(bool raise); |
| 28 | const char *getBusName() { return bus_name ? bus_name : ""; }; |
| 29 | int getDevice() { return device; }; |
| 30 | int getFunction() { return function; }; |
| 31 | virtual bool_t dump(FILE *); |
| 32 | virtual bool_t restore(FILE *); |
| 33 | int *interrupt_device_number; |
| 34 | int slot_irl[4]; |
| 35 | |
| 36 | </pre> |
| 37 | </font> |
| 38 | |
| 39 | <h4>Description</h4> |
| 40 | This is the base class for all PCI devices. |
| 41 | (See <b>modules/sample</b> for an example.) |
| 42 | <p> |
| 43 | For example, the class hierarchy for device 'Sample' is shown below: |
| 44 | <p> |
| 45 | <pre> |
| 46 | Module |
| 47 | PciDev (+ PciDevIf) |
| 48 | Sample |
| 49 | </pre> |
| 50 | <p> |
| 51 | PciDev handles some of the PCI device interfaces. |
| 52 | Most interfaces, however, are handled in the device class (Sample). |
| 53 | It is the responsibility of the device to call PciDev functions at various places. |
| 54 | <p><b>dev_check_args</b> and <b>dev_parse_arg</b> handle common arguments. |
| 55 | <p><b>dev_module_added</b> and <b>dev_module_deleted</b> handle configuration changes related to the PCI bus connection. |
| 56 | <p><b>dev_cfg_access</b> handles configuration space accesses common to all devices. |
| 57 | <p><b>dev_interrupt_in</b> requests a CPU interrupt. |
| 58 | Interrupt resources are requested during initialization by setting <b>interrupt_device_number</b> and <b>slot_irl</b>. |
| 59 | (See <b>modules/serial/serial_mod.cc</b> for an example.) |
| 60 | <p><b>dev_set_int_pin</b> and <b>dev_set_int</b> request an interrupt on pin A, B, C, or D. |
| 61 | The second call uses the default pin set in configuration space (CONFIG_INTERRUPT_PIN, 0x3d). |
| 62 | Interrupt resources are allocated automatically for these four pins. |
| 63 | <p><b>dev_write_le</b> and <b>dev_read_le</b> are utilities that convert between big and little endian. |
| 64 | <p><b>dev_set_space</b> initializes a Base Address Register (BAR). |
| 65 | Devices typically have a fixed (or maximum) I/O or memory size. |
| 66 | This call associates a size and PCI space type with a BAR. |
| 67 | <p><b>dev_dma_out</b> and <b>dev_dma_in</b> request DMA I/O to or from physical memory. |
| 68 | The requests are passed upstream, through the PCI bus, to the host bridge |
| 69 | (for example, schizo). |
| 70 | The host bridge translates PCI addresses to physical memory addresses using its I/O MMU. |
| 71 | <p><b>dump</b> and <b>restore</b> handle DR for PCI devices. |
| 72 | If a device also defines <b>dump</b>, it must call <b>PciDev::dump()</b> explicitly. Same for restore. |
| 73 | See modules <b>ll</b>, <b>serial</b>, or <b>parrot</b> for examples. |
| 74 | </body> |
| 75 | </html> |