1.\" $NetBSD: pci_configure_bus.9,v 1.20 2020/08/27 14:14:00 fcambus Exp $ 2.\" 3.\" Copyright 2001 Wasabi Systems, Inc. 4.\" All rights reserved. 5.\" 6.\" Written by Allen Briggs for Wasabi Systems, Inc. 7.\" 8.\" Redistribution and use in source and binary forms, with or without 9.\" modification, are permitted provided that the following conditions 10.\" are met: 11.\" 1. Redistributions of source code must retain the above copyright 12.\" notice, this list of conditions and the following disclaimer. 13.\" 2. Redistributions in binary form must reproduce the above copyright 14.\" notice, this list of conditions and the following disclaimer in the 15.\" documentation and/or other materials provided with the distribution. 16.\" 3. All advertising materials mentioning features or use of this software 17.\" must display the following acknowledgement: 18.\" This product includes software developed for the NetBSD Project by 19.\" Wasabi Systems, Inc. 20.\" 4. The name of Wasabi Systems, Inc. may not be used to endorse 21.\" or promote products derived from this software without specific prior 22.\" written permission. 23.\" 24.\" THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 25.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 26.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 27.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 28.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 32.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34.\" POSSIBILITY OF SUCH DAMAGE. 35.\" 36.Dd July 7, 2020 37.Dt PCI_CONFIGURE_BUS 9 38.Os 39.Sh NAME 40.Nm pci_configure_bus , 41.Nm pci_conf_hook , 42.Nm pci_conf_interrupt , 43.Nm pciconf_resource_init , 44.Nm pciconf_resource_add , 45.Nm pciconf_resource_fini 46.Nd perform PCI bus configuration 47.Sh SYNOPSIS 48.In dev/pci/pciconf.h 49.Ft int 50.Fn pci_configure_bus "pci_chipset_tag_t pc" "struct pciconf_resources *res" \ 51 "int firstbus" "int cacheline_size" 52.Ft struct pciconf_resources * 53.Fn pciconf_resource_init "void" 54.Ft void 55.Fn pciconf_resource_add "struct pciconf_resources *res" "int type" \ 56 "bus_addr_t addr" "bus_size_t size" 57.Ft void 58.Fn pciconf_resource_fini "struct pciconf_resources *res" 59.Sh DESCRIPTION 60The 61.Fn pci_configure_bus 62function configures a PCI bus for use. 63This involves: 64.Bl -bullet 65.It 66Defining bus numbers for all busses on the system, 67.It 68Setting the Base Address Registers for all devices, 69.It 70Setting up the interrupt line register for all devices, 71.It 72Configuring bus latency timers for all devices, and 73.It 74Configuring cacheline sizes for all devices. 75.El 76.Pp 77In traditional PCs and Alpha systems, the BIOS or firmware takes care 78of this task, but that is not the case for all systems. 79.Fn pci_configure_bus 80should be called prior to the autoconfiguration of the bus. 81.Pp 82The 83.Fa pc 84argument is a machine-dependent tag used to specify the PCI chipset to the 85system. 86This should be the same value used with 87.Fn pci_make_tag . 88The 89.Fa res 90argument is a container for PCI bus resources that will be used to 91configure the bus. 92The 93.Fa firstbus 94argument indicates the number of the first bus to be configured. 95The 96.Fa cacheline_size 97argument is used to configure the PCI Cache Line Size Register; it 98should be the size, in bytes, of the largest D-cache line on the system. 99.Pp 100An implementation may choose to not have full configuration performed 101by 102.Fn pci_configure_bus 103on certain PCI devices, such as PCI host bridges or PCI bus analyzers 104which are instantiated as devices on the bus. 105In order for this to take place, the header 106.In machine/pci_machdep.h 107must define the 108.Dv __HAVE_PCI_CONF_HOOK 109symbol (without a value), and a machine-dependent function 110.Fn pci_conf_hook 111(declared in the same header) 112must be defined. 113The prototype for this function is: 114.Pp 115.Ft int 116.Fn "pci_conf_hook" "pci_chipset_tag_t pc" "int bus" \ 117 "int device" "int function" "pcireg_t id" ; 118.Pp 119In this function, 120.Fa bus , 121.Fa device , 122and 123.Fa function 124uniquely identify the item being configured; 125in addition to this, the value of the device's PCI identification 126register is passed in 127.Fa id . 128For each device 129.Fn pci_conf_hook 130can then decide upon the amount of configuration to be performed by 131returning a bitwise inclusive-or of the following flags: 132.Bl -tag -width PCI_CONF_ENABLE_MEM -offset indent 133.It Dv PCI_CONF_MAP_IO 134Configure Base Address Registers that map I/O space 135.It Dv PCI_CONF_MAP_MEM 136Configure Base Address Registers that map memory space 137.It Dv PCI_CONF_MAP_ROM 138Configure Expansion ROM Base Address register 139.It Dv PCI_CONF_ENABLE_IO 140Enable I/O space accesses 141.It Dv PCI_CONF_ENABLE_MEM 142Enable memory space accesses 143.It Dv PCI_CONF_ENABLE_BM 144Enable bus mastering 145.El 146.Pp 147In addition, 148.Dv PCI_CONF_ALL 149specifies all of the above. 150.Pp 151One of the functions of 152.Fn pci_configure_bus 153is to configure interrupt 154.Dq line 155information. 156This must be done on a machine-dependent basis, so a 157machine-dependent function 158.Fn pci_conf_interrupt 159must be defined. 160The prototype for this function is 161.Pp 162.Ft void 163.Fn "pci_conf_interrupt" "pci_chipset_tag_t pc" "int bus" \ 164 "int device" "int pin" "int swiz" "int *iline" 165.Pp 166In this function, 167.Fa bus , 168.Fa device , 169and 170.Fa pin , 171uniquely identify the item being configured. 172The 173.Fa swiz 174argument is a 175.Dq swizzle , 176a sum of the device numbers of the primary interface of the bridges between 177the host bridge and the current device. 178The function is responsible for setting the value of 179.Fa iline . 180See chapter 9 of the 181.Dq PCI-to-PCI Bridge Architecture Specification 182for more information on swizzling (also known as interrupt routing). 183.Pp 184The resources used to configure the PCI bus are encapsulated into a 185resource container. 186The 187.Fn pciconf_resource_init 188function allocates and initializes one of these containers, and the 189.Fn pciconf_resource_add 190function adds resources to the container, specifying the type, start 191address, and size of the resource being added. 192The following resource types are supported: 193.Bl -tag -width PCICONF_RESOURCE_PREFETCHABLE_MEM -offset indent 194.It Dv PCICONF_RESOURCE_IO 195An address region used for PCI I/O accesses. 196.It Dv PCICONF_RESOURCE_MEM 197An address region used for PCI memory accesses where reads may have side 198effects. 199.It Dv PCICONF_RESOURCE_PREFETCHABLE_MEM 200An address region used for PCI memory accesses where reads do not have 201side effects 202.Po 203e.g. ROMs, frame buffers, other memory-like regions that are marked as 204prefetchable in their BAR 205.Pc . 206.El 207.Pp 208If an implementation does not distinguish between prefetchable and 209non-prefetchable memory, then adding a 210.Dv PCICONF_RESOURCE_PREFETCHABLE_MEM 211resource is not required; 212.Dv PCICONF_RESOURCE_MEM 213resources will be used for ROMs and BARs that are marked as prefetchable. 214.Pp 215Once the bus has been successfully configured, the resource container should 216be disposed of by calling 217.Fn pciconf_resource_fini . 218.Sh RETURN VALUES 219If successful 220.Fn pci_configure_bus 221returns 0. 222A non-zero return value means that the bus was not completely 223configured for some reason. 224A description of the failure will be displayed on the console. 225.Sh ENVIRONMENT 226The 227.Fn pci_configure_bus 228function is only included in the kernel if the kernel is compiled with 229the 230.Dv PCI_NETBSD_CONFIGURE 231option enabled. 232.Sh EXAMPLES 233The 234.Fn pci_conf_hook 235function in evbppc's walnut implementation looks like: 236.Pp 237.Bd -literal -compact 238int 239pci_conf_hook(pci_chipset_tag_t pc, int bus, int dev, int func, 240 pcireg_t id) 241{ 242 243 if ((PCI_VENDOR(id) == PCI_VENDOR_IBM && 244 PCI_PRODUCT(id) == PCI_PRODUCT_IBM_405GP) || 245 (PCI_VENDOR(id) == PCI_VENDOR_INTEL && 246 PCI_PRODUCT(id) == PCI_PRODUCT_INTEL_80960_RP)) { 247 /* Don't configure the bridge and PCI probe. */ 248 return 0; 249 } 250 return (PCI_CONF_ALL & ~PCI_CONF_MAP_ROM); 251} 252.Ed 253.Pp 254The 255.Fn pci_conf_interrupt 256function in the sandpoint implementation looks like: 257.Pp 258.Bd -literal -compact 259void 260pci_conf_interrupt(pci_chipset_tag_t pc, int bus, int dev, int pin, 261 int swiz, int *iline) 262{ 263 if (bus == 0) { 264 *iline = dev; 265 } else { 266 *iline = 13 + ((swiz + dev + 3) & 3); 267 } 268} 269.Ed 270.Pp 271This configuration example is taken from the bebox port. 272.Pp 273.Bd -literal -compact 274#define PCI_IO_START 0x00008000 275#define PCI_IO_END 0x0000ffff 276#define PCI_IO_SIZE ((PCI_IO_END - PCI_IO_START) + 1) 277 278#define PCI_MEM_START 0x00000000 279#define PCI_MEM_END 0x0fffffff 280#define PCI_MEM_SIZE ((PCI_MEM_END - PCI_MEM_START) + 1) 281 ... 282 struct pciconf_resources *pcires; 283 ... 284 pcires = pciconf_resource_init(); 285 pciconf_resource_add(pcires, PCICONF_RESOURCE_IO, 286 PCI_IO_START, PCI_IO_SIZE); 287 pciconf_resource_add(pcires, PCICONF_RESOURCE_MEM, 288 PCI_MEM_START, PCI_MEM_SIZE); 289 ... 290 pci_configure_bus(pc, pcires, 0, CACHELINESIZE); 291 ... 292 pciconf_resource_fini(pcires); 293 ... 294.Ed 295.Pp 296Note that this must be called before the PCI bus is attached during 297autoconfiguration. 298.Sh SEE ALSO 299.Xr pci 4 300.Sh HISTORY 301.Fn pci_configure_bus 302was added in 303.Nx 1.6 . 304