chapter 15: overview of peripheral buses bus architectures a bus has 1. an electrical i/f 2. a programming interface, focus in this chapter primary focus on PCI peripherals PCI interface how can pci driver finds its hardware and gain access probing is possible but not necessary pci designed as ISA replacement goals: 1. to get better performance for data xfer 2. to be platform independent 3. simplify addition/removal of peripherals PCI clockrates may be: 25/33/66/133 Mhz thruput therefore: 33 mhz * 32 bits = 133mbytes per sec 32 bit and 64 bit extensions exists PCI used on: ia-32, alpha, powerpc, sparc64, and ia-64 pci devices allow auto-detection, and are jumperless. pci addressing pci peripheral has this tuple: (bus number, device number, function number) bus: 8 bits device: 5 bits function: 3 bits note above is 2-bytes, 16 bit word. device may have multiple functions (audio board with cdrom) struct pci_dev has details on linux, in workstations typically have at least 2 pci buses: bridges (a pci device): bridge connects one pci bus to another overall layout is a tree, with bus 0 at top See Figure 15-1, with 4 bridges, two++ busses On linux if you have pciutils installed: # lspci or /proc/pci and /proc/bus/pci may have useful info E.g., part of /proc/pci Bus 0, device 31, function 5: Multimedia audio controller: Intel Corporation 82801BA(M) AC'97 Audio (rev 4 ). IRQ 9. I/O at 0xe800 [0xe8ff]. I/O at 0xef00 [0xef3f]. Bus 1, device 0, function 0: VGA compatible controller: ATI Technologies Inc Rage 128 PF (rev 0). IRQ 11. Master Capable. Latency=32. Min Gnt=8. Prefetchable 32 bit memory at 0xf0000000 [0xf3ffffff]. I/O at 0xc800 [0xc8ff]. Non-prefetchable 32 bit memory at 0xff8fc000 [0xff8fffff]. Bus 2, device 8, function 0: Ethernet controller: Intel Corporation 82801BA(M) Ethernet (rev 3). IRQ 11. Master Capable. Latency=32. Min Gnt=8.Max Lat=56. Non-prefetchable 32 bit memory at 0xff9ff000 [0xff9fffff]. I/O at 0xdf00 [0xdf3f]. Bus 2, device 13, function 0: Ethernet controller: PCI device 8086:100c (Intel Corporation) (rev 2). IRQ 11. Master Capable. Latency=32. Min Gnt=255. Non-prefetchable 32 bit memory at 0xff9c0000 [0xff9dffff]. Non-prefetchable 32 bit memory at 0xff9a0000 [0xff9bffff]. I/O at 0xdf80 [0xdf9f]. #lspci [root@zymurgy root]# lspci 00:00.0 Host bridge: Intel Corporation 82850 850 (Tehama) Chipset Host Bridge (MCH) (rev 04) 00:01.0 PCI bridge: Intel Corporation 82850 850 (Tehama) Chipset AGP Bridge (rev 04) 00:1e.0 PCI bridge: Intel Corporation 82801BAM PCI (rev 04) 00:1f.0 ISA bridge: Intel Corporation 82801BA ISA Bridge (ICH2) (rev 04) 00:1f.1 IDE interface: Intel Corporation 82801BA IDE U100 (rev 04) 00:1f.2 USB Controller: Intel Corporation 82801BA(M) USB (Hub A) (rev 04) 00:1f.3 SMBus: Intel Corporation 82801BA(M) SMBus (rev 04) 00:1f.4 USB Controller: Intel Corporation 82801BA(M) USB (Hub B) (rev 04) 00:1f.5 Multimedia audio controller: Intel Corporation 82801BA(M) AC'97 Audio (rev 04) 01:00.0 VGA compatible controller: ATI Technologies Inc Rage 128 PF 02:08.0 Ethernet controller: Intel Corporation 82801BA(M) Ethernet (rev 03) 02:0d.0 Ethernet controller: Intel Corporation: Unknown device 100c (rev 02) 0x128 for number, would mean 01:05:0 when split up hw answers queries for 3 spaces: 1. memory 2. ports 3. config registers all devices share memory/ports, and can have collisions for access inb/readb used above ... config space uses "geographical addressing", only one slot at a time is addressed. no collisions possible address from driver POV: (bus #, device/slot #) every PCI slot has 4 interrupt pins, how this is routed is done outside of the PCI bus (up to CPU) as PCI insists on sharing, PCI devices can share limited 16 irqs I/O space in PCI bus uses 32-bit address bus (4 G) memory space can use either 32-bit or 64-bit addresses firmware at boot maps each region to a different address space to avoid collisions address to which regions are mapped can be read from config space driver need only read config registers ... PCI config space: 256 bytes for each device function standard layout 4 bytes hold a unique function ID, so driver can ID its space by looking for that function ID E.g., see /usr/src/linux/driver/pci/pci.ids in 2.4 kernel one important difference PCI/ISA is this configuration space ... boot time at power on, device has no memory, no ports mapped in. PCI board has PCI firmware, "bios" ... firmware firmware offers access to device config space, by reading/ writing registers in PCI controller firmware performs config transactions with every PCI peripheral in order to allocate memory/ports/interrupts /proc/bus/pci/*/* has a snapshot of config registers for each device, one file per device config registers and initialization See Figure 15-2 1st 64 bytes are standard, remainder is device dependent required fields assert whether optional fields are useful PCI registers are little-endian may need to use vendorID, deviceID, and class id a device, RO registers vendorID - 16 bits, Intel devices have value 0x8086 deviceID - 16 bits, paired with vendor ID class - every device belongs to a class, top 8 bits are group or base class, (ethernet/token ring belong to network class) See p. 477 for older PCI driver interface includes/macros 2.4 kernel has concept of PCI driver though as abstraction See old init code, p. 478 accessing the config space drive post device detection, needs to read/write 3 address space memory/port/configuration linux offers a standard interface to access config space 8/16/32 bit data xfers, from pci_read_config_byte() pci_read_config_word() pci_read_config_dword() 4 bytes and write functions too, see p. 480-481 debug assistance with config: looking at a config snapshot /proc/bus/pci, or write your own code e.g., get pci/pcidata.c as sample code pcidata.c creates dynamic /proc/pcidata that contains config snapshot or alternatively use pcidump which formats info p. 482-483 accessing the i/o and memory spaces a device may have up to 6 i/o address regions each region is either: memory or i/o ports most devices use memory which should not be cached by cpu peripherals can mark region as nonprefetable config registers used to report size/loation of regions siz 32-bit registers should in Figure 15-2 PCI_BASE_ADDRESS_0..5 2.4 interface for PCI I/O resources integrated with generic resource management see functions, p 484. peeking at base address registers if you want < 2.4 compat, you must deal with hw directly. device must have programmable decoder for any memory region usually number of bytes in region is on power of 2 boundary 1 MB address regions usually align at an address that is a multiple of 1 MB, etc. 2 at 2 MB, 32-byte regions at multiple of 32. mapping a PCI region in the physical address space is performed by setting a value in the high bits of a config register. E.g., a 1 MB region, has 20 bits of address space, and is remapped by setting the high 12 bits of the register. If you write 0x40xxxxx it will be set at 64-MB. In practice, only high addresses are used. code follows for reproting location and size of PCI regions PCI interrupts at boottime, firmware has assigned a unique interrupt number to the device. driver needs to get it and use it. interrupt number is stored in config register 60, PCI_INTERRUPT_LINE, which is one byte wide. see code snipper p. 488 hot-pluggable devices/cardbus basic idea: all device drivers must check to see if a new object belongs to them. hot-plug-aware device driver must register an object with the kernel, and its probe function will be asked to see if the device belongs to it or no a process is needed to monitor the bus, and load any driver if necessary struct pci_driver defined in is basis: defines set of operations and a list of supported devices see. p.. 490 see functions: pci_register_driver - used by compiled-in non modular functions pci_module_init - wrapper over previous function, used by modules see top of p. 491 pci_driver structure pci_device_id *id_table: which devices are supported by this driver note suspend/resume functions hardware abstractions pci for the most part focuses on config registers ... remainder simply uses memory regions accessed by cpu isa: old slow, cheap, and quite common ... hardware resources i/o ports, memory areas, interrupt lines usable address space may be limited to only 1st 1k ports, due to old pc using only lowest 10 address lines. isa device can use only memory between 640KB and 1 MB, and 15..16MB. interrupt lines, 1st 16. interrupt sharing is possible. ISA programming most techniques shown in the book are ISA techniques. plug/play special init sequence intended to help config of add-on interface boards. "PNP" PNP goal roughly to give same flexibility as with PCI. geographical addressing works by assigning a small int, called Card Select Number (CSN) to each PnP peripheral. each device has 64 bit serial id, that is hardwired. CSN uses serial number to id device. BIOS must be PnP aware. other bussen: PC/104 and PC/104+ industrial and ISA more or less MCA - micro channel architecture, an old IBM standard used in PS/2 EISA - extended ISA, 32 bit extension. ISA cards can be plugged in. designed to host jumperlesss devices. Similar to MCA VLB - VESA Local bus, similar to ISA SBus - older SPARC bus NuBUS - old mac bus External Buses USB/Firewire/older SCSI/GPIB (serial) software split into 2-levels 1. driver for hw controller 2. specific client device USB - universal serial bus USB laid out as tree built out of point-to-point links. links are 4-wire cables (ground, power, two signal wire) may connect device and hub giving star topology PC usually has "root hub", and two plugs. host computer polls various devices. device can request fixed bandwidth for its data xfers in order to reliably support audio/video max. xfer rate is 12 Mbytes per sec. writing a USB driver similar to PCI device registers its driver object with the USB subsystem #include static struct usb_driver ... see code p. 500 probe called on new device plugged in, or driver loaded in case devices are not recognized device id comes from providing system with vendor, device, and class id, a la PCI. probe should look at info, and decide if device belongs to it then you talk to usb bus support, fill out struct urb, and pass it in with usb_submit_urb()