pci_configure_bus(9)
- NetBSD Manual Pages
PCI_CONFIGURE_BUS(9) NetBSD Kernel Developer's Manual PCI_CONFIGURE_BUS(9)
NAME
pci_configure_bus, pci_conf_hook, pci_conf_interrupt,
pciconf_resource_init, pciconf_resource_add, pciconf_resource_fini --
perform PCI bus configuration
SYNOPSIS
#include <dev/pci/pciconf.h>
int
pci_configure_bus(pci_chipset_tag_t pc, struct pciconf_resources *res,
int firstbus, int cacheline_size);
struct pciconf_resources *
pciconf_resource_init(void);
void
pciconf_resource_add(struct pciconf_resources *res, int type,
bus_addr_t addr, bus_size_t size);
void
pciconf_resource_fini(struct pciconf_resources *res);
DESCRIPTION
The pci_configure_bus() function configures a PCI bus for use. This
involves:
· Defining bus numbers for all busses on the system,
· Setting the Base Address Registers for all devices,
· Setting up the interrupt line register for all devices,
· Configuring bus latency timers for all devices, and
· Configuring cacheline sizes for all devices.
In traditional PCs and Alpha systems, the BIOS or firmware takes care of
this task, but that is not the case for all systems. pci_configure_bus()
should be called prior to the autoconfiguration of the bus.
The pc argument is a machine-dependent tag used to specify the PCI
chipset to the system. This should be the same value used with
pci_make_tag(). The res argument is a container for PCI bus resources
that will be used to configure the bus. The firstbus argument indicates
the number of the first bus to be configured. The cacheline_size argu-
ment is used to configure the PCI Cache Line Size Register; it should be
the size, in bytes, of the largest D-cache line on the system.
An implementation may choose to not have full configuration performed by
pci_configure_bus() on certain PCI devices, such as PCI host bridges or
PCI bus analyzers which are instantiated as devices on the bus. In order
for this to take place, the header <machine/pci_machdep.h> must define
the __HAVE_PCI_CONF_HOOK symbol (without a value), and a machine-depen-
dent function pci_conf_hook() (declared in the same header) must be
defined. The prototype for this function is:
int pci_conf_hook(pci_chipset_tag_t pc, int bus, int device, int
function, pcireg_t id);
In this function, bus, device, and function uniquely identify the item
being configured; in addition to this, the value of the device's PCI
identification register is passed in id. For each device pci_conf_hook()
can then decide upon the amount of configuration to be performed by
returning a bitwise inclusive-or of the following flags:
PCI_CONF_MAP_IO Configure Base Address Registers that map I/O
space
PCI_CONF_MAP_MEM Configure Base Address Registers that map mem-
ory space
PCI_CONF_MAP_ROM Configure Expansion ROM Base Address register
PCI_CONF_ENABLE_IO Enable I/O space accesses
PCI_CONF_ENABLE_MEM Enable memory space accesses
PCI_CONF_ENABLE_BM Enable bus mastering
In addition, PCI_CONF_ALL specifies all of the above.
One of the functions of pci_configure_bus() is to configure interrupt
``line'' information. This must be done on a machine-dependent basis, so
a machine-dependent function pci_conf_interrupt() must be defined. The
prototype for this function is
void pci_conf_interrupt(pci_chipset_tag_t pc, int bus, int device, int
pin, int swiz, int *iline)
In this function, bus, device, and pin, uniquely identify the item being
configured. The swiz argument is a ``swizzle'', a sum of the device num-
bers of the primary interface of the bridges between the host bridge and
the current device. The function is responsible for setting the value of
iline. See chapter 9 of the ``PCI-to-PCI Bridge Architecture
Specification'' for more information on swizzling (also known as inter-
rupt routing).
The resources used to configure the PCI bus are encapsulated into a
resource container. The pciconf_resource_init() function allocates and
initializes one of these containers, and the pciconf_resource_add() func-
tion adds resources to the container, specifying the type, start address,
and size of the resource being added. The following resource types are
supported:
PCICONF_RESOURCE_IO An address region used for PCI
I/O accesses.
PCICONF_RESOURCE_MEM An address region used for PCI
memory accesses where reads may
have side effects.
PCICONF_RESOURCE_PREFETCHABLE_MEM An address region used for PCI
memory accesses where reads do
not have side effects (e.g.
ROMs, frame buffers, other
memory-like regions that are
marked as prefetchable in their
BAR).
If an implementation does not distinguish between prefetchable and non-
prefetchable memory, then adding a PCICONF_RESOURCE_PREFETCHABLE_MEM
resource is not required; PCICONF_RESOURCE_MEM resources will be used for
ROMs and BARs that are marked as prefetchable.
Once the bus has been successfully configured, the resource container
should be disposed of by calling pciconf_resource_fini().
RETURN VALUES
If successful pci_configure_bus() returns 0. A non-zero return value
means that the bus was not completely configured for some reason. A
description of the failure will be displayed on the console.
ENVIRONMENT
The pci_configure_bus() function is only included in the kernel if the
kernel is compiled with the PCI_NETBSD_CONFIGURE option enabled.
EXAMPLES
The pci_conf_hook() function in evbppc's walnut implementation looks
like:
int
pci_conf_hook(pci_chipset_tag_t pc, int bus, int dev, int func,
pcireg_t id)
{
if ((PCI_VENDOR(id) == PCI_VENDOR_IBM &&
PCI_PRODUCT(id) == PCI_PRODUCT_IBM_405GP) ||
(PCI_VENDOR(id) == PCI_VENDOR_INTEL &&
PCI_PRODUCT(id) == PCI_PRODUCT_INTEL_80960_RP)) {
/* Don't configure the bridge and PCI probe. */
return 0;
}
return (PCI_CONF_ALL & ~PCI_CONF_MAP_ROM);
}
The pci_conf_interrupt() function in the sandpoint implementation looks
like:
void
pci_conf_interrupt(pci_chipset_tag_t pc, int bus, int dev, int pin,
int swiz, int *iline)
{
if (bus == 0) {
*iline = dev;
} else {
*iline = 13 + ((swiz + dev + 3) & 3);
}
}
This configuration example is taken from the bebox port.
#define PCI_IO_START 0x00008000
#define PCI_IO_END 0x0000ffff
#define PCI_IO_SIZE ((PCI_IO_END - PCI_IO_START) + 1)
#define PCI_MEM_START 0x00000000
#define PCI_MEM_END 0x0fffffff
#define PCI_MEM_SIZE ((PCI_MEM_END - PCI_MEM_START) + 1)
...
struct pciconf_resources *pcires;
...
pcires = pciconf_resource_init();
pciconf_resource_add(pcires, PCICONF_RESOURCE_IO,
PCI_IO_START, PCI_IO_SIZE);
pciconf_resource_add(pcires, PCICONF_RESOURCE_MEM,
PCI_MEM_START, PCI_MEM_SIZE);
...
pci_configure_bus(pc, pcires, 0, CACHELINESIZE);
...
pciconf_resource_fini(pcires);
...
Note that this must be called before the PCI bus is attached during auto-
configuration.
SEE ALSO
pci(4)
HISTORY
pci_configure_bus() was added in NetBSD 1.6.
NetBSD 10.99 July 7, 2020 NetBSD 10.99
Powered by man-cgi (2021-06-01).
Maintained for NetBSD
by Kimmo Suominen.
Based on man-cgi by Panagiotis Christias.