Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / docs / mmi / PciDev.html
<html>
<head>
<title>SPARC Architectural Model: Device and Utility API</title>
</head>
<body bgcolor="#FFFFFF" LANG="en-US">
<h2>class PciDev : public Module, PciDevIf</h2>
common/pci_dev.cc:
<br>&nbsp;
<br>#include "pci.h"
<br>#include "pci_dev.h"
<font size=-1>
<pre>
bool dev_check_args();
bool dev_parse_arg(const char *arg);
bool dev_module_added(module_t *target, const char *target_name);
bool dev_module_deleted(module_t *target, const char *target_name);
int dev_cfg_access(uint64_t offset, bool_t wr, uint32_t size, uint64_t *buf);
int dev_interrupt_in(bool_t set, int dev_type, int dev_number, int line);
int dev_write_le(uint8_t* mem, uint64_t *buf, uint64_t offset, uint32_t size);
int dev_read_le(uint64_t *buf, uint8_t* mem, uint64_t offset, uint32_t size);
void dev_set_space(pci_space_t, uint64_t base, uint64_t size, int bar);
int dev_dma_out(uint64_t vaddr, void *data, long count);
int dev_dma_in(uint64_t vaddr, void *data, long count);
int dev_set_int_pin(int pin, bool raise);
int dev_set_int(bool raise);
const char *getBusName() { return bus_name ? bus_name : ""; };
int getDevice() { return device; };
int getFunction() { return function; };
virtual bool_t dump(FILE *);
virtual bool_t restore(FILE *);
int *interrupt_device_number;
int slot_irl[4];
</pre>
</font>
<h4>Description</h4>
This is the base class for all PCI devices.
(See <b>modules/sample</b> for an example.)
<p>
For example, the class hierarchy for device 'Sample' is shown below:
<p>
<pre>
Module
PciDev (+ PciDevIf)
Sample
</pre>
<p>
PciDev handles some of the PCI device interfaces.
Most interfaces, however, are handled in the device class (Sample).
It is the responsibility of the device to call PciDev functions at various places.
<p><b>dev_check_args</b> and <b>dev_parse_arg</b> handle common arguments.
<p><b>dev_module_added</b> and <b>dev_module_deleted</b> handle configuration changes related to the PCI bus connection.
<p><b>dev_cfg_access</b> handles configuration space accesses common to all devices.
<p><b>dev_interrupt_in</b> requests a CPU interrupt.
Interrupt resources are requested during initialization by setting <b>interrupt_device_number</b> and <b>slot_irl</b>.
(See <b>modules/serial/serial_mod.cc</b> for an example.)
<p><b>dev_set_int_pin</b> and <b>dev_set_int</b> request an interrupt on pin A, B, C, or D.
The second call uses the default pin set in configuration space (CONFIG_INTERRUPT_PIN, 0x3d).
Interrupt resources are allocated automatically for these four pins.
<p><b>dev_write_le</b> and <b>dev_read_le</b> are utilities that convert between big and little endian.
<p><b>dev_set_space</b> initializes a Base Address Register (BAR).
Devices typically have a fixed (or maximum) I/O or memory size.
This call associates a size and PCI space type with a BAR.
<p><b>dev_dma_out</b> and <b>dev_dma_in</b> request DMA I/O to or from physical memory.
The requests are passed upstream, through the PCI bus, to the host bridge
(for example, schizo).
The host bridge translates PCI addresses to physical memory addresses using its I/O MMU.
<p><b>dump</b> and <b>restore</b> handle DR for PCI devices.
If a device also defines <b>dump</b>, it must call <b>PciDev::dump()</b> explicitly. Same for restore.
See modules <b>ll</b>, <b>serial</b>, or <b>parrot</b> for examples.
</body>
</html>