PCI(9) | Kernel Developer's Manual | PCI(9) |
int
pci_bus_devorder(pci_chipset_tag_t pc, int bus, uint8_t *devs, int maxdevs);
int
pci_activate(pci_chipset_tag_t pc, pcitag_t tag, device_t dev, int (*wakeup)(pci_chipset_tag_t pc, pcitag_t tag, ttdevice_t dev, pcireg_t reg));
int
pci_chipset_tag_create(pci_chipset_tag_t opc, uint64_t present, const struct pci_overrides *ov, void *ctx, pci_chipset_tag_t *pcp);
void
pci_chipset_tag_destroy(pci_chipset_tag_t pc);
pcireg_t
pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg);
void
pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t val);
void
pci_conf_print(pci_chipset_tag_t pc, pcitag_t tag, void (*func)(pci_chipset_tag_t, pcitag_t, const pcireg_t *));
void
pci_conf_capture(pci_chipset_tag_t pc, pcitag_t tag, struct pci_conf_state *);
void
pci_conf_restore(pci_chipset_tag_t pc, pcitag_t tag, struct pci_conf_state *);
int
pci_find_device(struct pci_attach_args *pa, int (*func)(const struct pci_attach_args *));
int
pci_get_capability(pci_chipset_tag_t pc, pcitag_t tag, int capid, int *offsetp, pcireg_t *valuep);
pcireg_t
pci_mapreg_type(pci_chipset_tag_t pc, pcitag_t tag, int reg);
int
pci_mapreg_map(const struct pci_attach_args *pa, int reg, pcireg_t type, int busflags, bus_space_tag_t *tagp, bus_space_handle_t *handlep, bus_addr_t *basep, bus_size_t *sizep);
int
pci_mapreg_info(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t type, bus_addr_t *basep, bus_size_t *sizep, int *flagsp);
int
pci_find_rom(const struct pci_attach_args *pa, bus_space_tag_t bst, bus_space_handle_t bsh, int code, bus_space_handle_t *handlep, bus_space_size_t *sizep);
int
pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ih);
const char *
pci_intr_string(pci_chipset_tag_t pc, pci_intr_handle_t ih);
const struct evcnt *
pci_intr_evcnt(pci_chipset_tag_t pc, pci_intr_handle_t ih);
void *
pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level, int (*handler)(void *), void *arg);
void
pci_intr_disestablish(pci_chipset_tag_t pc, void *ih);
int
pci_set_powerstate(pci_chipset_tag_t pc, pcitag_t tag, pcireg_t newstate);
int
pci_get_powerstate(pci_chipset_tag_t pc, pcitag_t tag, pcireg_t *state);
int
pci_vpd_read(pci_chipset_tag_t pc, pcitag_t tag, int offset, int count, pcireg_t *data);
int
pci_vpd_write(pci_chipset_tag_t pc, pcitag_t tag, int offset, int count, pcireg_t *data);
pcitag_t
pci_make_tag(pci_chipset_tag_t pc, int bus, int device, int function);
void
pci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag, int *busp, int *devicep, int *functionp);
char *
pci_findvendor(pcireg_t id);
void
pci_devinfo(pcireg_t id, pcireg_t class, int show, char *cp, size_t len);
void
pci_aprint_devinfo(struct pci_attach_args *pa, const char *naive);
int
PCI_VENDOR(pcireg_t id);
int
PCI_PRODUCT(pcireg_t id);
int
PCI_REVISION(pcireg_t id);
The PCI bus was initially developed by Intel in the early 1990's to replace the ISA bus for interfacing with their Pentium processor. The PCI specification is widely regarded as well designed, and the PCI bus has found widespread acceptance in machines ranging from Apple's PowerPC-based systems to Sun's UltraSPARC-based machines.
The PCI bus is a multiplexed bus, allowing addresses and data on the same pins for a reduced number of pins. Data transfers can be 8-bit, 16-bit or 32-bit. A 64-bit extended PCI bus is also defined. Multi-byte transfers are little-endian. The PCI bus operates up to 33MHz and any device on the bus can be the bus master.
AGP is a version of PCI optimised for high-throughput data rates, particularly for accelerated frame buffers.
The PCI bus is a "plug and play" bus, in the sense that devices can be configured dynamically by software. The PCI interface chip on a PCI device bus presents a small window of registers into the PCI configuration space. These registers contain information about the device such as the vendor and a product ID. The configuration registers can also be written to by software to alter how the device interfaces to the PCI bus. An important register in the configuration space is the Base Address Register (BAR). The BAR is written to by software to map the device registers into a window of processor address space. Once this mapping is done, the device registers can be accessed relative to the base address.
bus_space_tag_t pa_iot; /* pci i/o space tag */ bus_space_tag_t pa_memt; /* pci mem space tag */ bus_dma_tag_t pa_dmat; /* DMA tag */ pci_chipset_tag_t pa_pc; int pa_flags; /* flags */ pcitag_t pa_tag; pcireg_t pa_id; pcireg_t pa_class;
pcireg_t reg[16]; /* pci conf register */
pcireg_t (*ov_conf_read)(void *, pci_chipset_tag_t, pcitag_t, int); void (*ov_conf_write)(void *, pci_chipset_tag_t, pcitag_t, int, pcireg_t); int (*ov_intr_map)(void *, const struct pci_attach_args *, pci_intr_handle_t *); const char *(*ov_intr_string)(void *, pci_chipset_tag_t, pci_intr_handle_t); const struct evcnt *(*ov_intr_evcnt)(void *, pci_chipset_tag_t, pci_intr_handle_t); void *(*ov_intr_establish)(void *, pci_chipset_tag_t, pci_intr_handle_t, int, int (*)(void *), void *); void (*ov_intr_disestablish)(void *, pci_chipset_tag_t, void *); pcitag_t (*ov_make_tag)(void *, pci_chipset_tag_t, int, int, int); void (*ov_decompose_tag)(void *, pci_chipset_tag_t, pcitag_t, int *, int *, int *);
ov contains function pointers corresponding to PCI routines. Each function pointer has a corresponding bit in present, and if that bit is 1, the function pointer overrides the corresponding PCI call for the new tag. Any combination of these bits may be set in present:
pci_chipset_tag_create() does not copy ov. After a new tag is created by pci_chipset_tag_create(), ov must not be destroyed until after the tag is destroyed by pci_chipset_tag_destroy().
The first argument of every override-function is a void *, and ctx is passed in that argument.
Return 0 if the call succeeds. Return EOPNOTSUPP if the architecture does not support overrides. Return EINVAL if present is 0, if ov is NULL, or if present indicates that an override is present, but the corresponding override in ov is NULL.
If the call does not succeed, *pcp is undefined.
The argument tag is the PCI tag for the current device attached to PCI chipset pc.
The argument busflags are bus-space flags passed to bus_space_map() to perform the mapping (see bus_space(9)). The bus-space tag and handle for the mapped register window are returned in tagp and handlep respectively. The bus-address and size of the mapping are returned in basep and sizep respectively. If any of tagp, handlep, basep, or sizep are NULL then pci_mapreg_map() does not define their return value. This function returns zero on success and non-zero on error.
The created subregion will cover the entire selected ROM image, including header data. The handle to this subregion is returned in handlep. The size of the image (and the corresponding subregion) is returned in sizep. This function can only be used with expansion ROMs located at the PCI_MAPREG_ROM base address register (BAR).
During the driver attach step, drivers can read the device configuration space using pci_conf_read(). The meaning attached to registers in the PCI configuration space are device-dependent, but will usually contain physical addresses of the device register windows. Device options can also be stored into the PCI configuration space using pci_conf_write(). For example, the driver can request support for bus-mastering DMA by writing the option to the PCI configuration space.
Device capabilities can be queried using pci_get_capability(), and returns device-specific information which can be found in the PCI configuration space to alter device operation.
After reading the physical addresses of the device register windows from configuration space, these windows must be mapped into kernel virtual address space using pci_mapreg_map(). Device registers can now be accessed using the standard bus-space API (see bus_space(9)).
Details of using PCI interrupts is described in pci_intr(9).
During system shutdown, it is necessary to abort any DMA transfers in progress by registering a shutdown hook (see pmf(9)).
The database of known devices exists within the file sys/dev/pci/pcidevs_data.h and is generated automatically from the file sys/dev/pci/pcidevs. New vendor and product identifiers should be added to this file. The database can be regenerated using the Makefile sys/dev/pci/Makefile.pcidevs.
January 30, 2012 | NetBSD 6.1 |