class PciBusIf

#include "pci.h"
virtual int busif_access(pci_space_t, uint64_t paddr, uint64_t offset, bool_t wr, uint32_t size, uint64_t* buf);
virtual int busif_add_device(const char *devname, int device, int function);
virtual int busif_delete_device(const char *devname);
virtual int busif_map(const char *devname, pci_space_t, uint64_t base, uint64_t size);
virtual int busif_unmap(const char *devname, pci_space_t);
virtual int busif_add_interrupt(const char *device_name, int *device_number, int *slot_irl, const char **host);
virtual int busif_free_interrupt(int dev_number);
virtual int busif_interrupt_in(bool set, int dev_type, int dev_number, int line);
virtual int busif_set_int_pin(int pin, bool raise, int device, module_t *caller);
virtual int busif_dma_out(uint64_t vaddr, void *data, long count, module_t *caller);
virtual int busif_dma_in(uint64_t vaddr, void *data, long count, module_t *caller);

Description

This is an abstract class that defines the interface between modules connected to a PCI Bus. This configuration is an example:

schizo24 <-> schizo24A <-> sample24A1
         <-> schizo24B <-> sample24B1

schizo24   is a PCI host bridge at AID=24 (0x18).
schizo24A  is PCI bus#0 on leaf A of the schizo.
schizo24B  is PCI bus#0 on leaf B. (Leaf B is NOT bus#1!)
sample24A1 is PCI device 1 on schizo24A.
sample24B1 is PCI device 1 on schizo24B.

The configuration file looks like this:

sysconf schizo  schizo24   aid=24 pciA=schizo24A pciB=schizo24B
sysconf pci_bus schizo24A  bridge=schizo24
sysconf sample  sample24A1 bus=schizo24A dev=1 fun=0
sysconf pci_bus schizo24B  bridge=schizo24
sysconf sample  sample24B1 bus=schizo24B dev=1 fun=0

Both schizo and pci_bus export the PciBusIf interface.

PCI devices, like sample, call the PciBusIf interface, and they export a PciDevIf interface.

busif_access: I/O access in the downstream direction (from CPU to device). A CPU read or write first goes to a schizo based on the address range (determined by aid). The schizo routes the access to either pciA or pciB depending on the address range. The pci_bus routes the access to one of its devices depending on the device PCI address range (see PciDev::dev_set_space). The last access is done through the PciDevIf interface.

busif_dma_out and busif_dma_in: I/O access in the upstream direction. DMA works with PCI addresses. The host bridge (schizo) has an IOMMU which translates PCI addresses into physical memory addresses.

busif_add_device and busif_delete_device attach or detach devices on a bus. A device attaches itself to a bus when it detects that the bus has been configured. The bus maps the device into the PCI configuration space.

busif_map and busif_unmap manage PCI address space mappings for devices. This is used for PCI I/O, mem32, and mem64 spaces (but not config space.)

busif_add_interrupt and busif_free_interrupt manage interrupt resources in the host bridge (schizo). A PCI device makes a request for an interrupt vector. The pci_bus simply forwards it towards the bridge.

busif_interrupt_in requests an interrupt. Called by a PCI device.

busif_set_int_pin requests an interrupt on pin A, B, C, or D. The host bridge assigns interrupt resources automatically.