![]() | Sun System Handbook - ISO 4.1 October 2012 Internal/Partner Edition | ||
|
|
![]() |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Solution Type Technical Instruction Sure Solution 1009318.1 : How are interrupt levels assigned to PCI devices on SPARC[R] based machines?
PreviouslyPublishedAs 212898 Description This documents the mechanism that assigns processor interrupt levels to specific devices on a PCI bus attached to a SPARC[R] based machine. Steps to Follow The Solaris[TM] Operating System (OS) uses CPU interrupts in the range 1 to 15 with 15 being the highest priority to allow devices to communicate with their device drivers. As the system starts up it needs to assign interrupt levels for the different devices it finds on its PCI buses. This is done by OBP on SPARC systems and the BIOS on a x86 platform. Every PCI device has 256 bytes of configuration space, where it implements the standard PCI configuration register set. One of these mandatory registers is the 24 bit "Class Code" register, this register is programmed by the device designer to contain the "type" of the card. This 24 bit register is broken down into 3 8-bit sections. Bits 16 through 23 contain the most significant "Class Code", bits 8 through 15 contains the "Sub-Class Code" and bits 0 through 7 contain the "Programming Interface Version".
The "Sub-Class Code" is used to identify subsets of Classes, for example the Mass Storage Class (0x1) has the following Sub classes defined.
The section below deals with how OBP/Solaris OS uses this information on a SPARC system. At system power up OBP walks the available PCI buses probing every available bus/device/function for cards. When it finds one it will generate a PROM device node and insert it into the PROM device tree (as listed by prtconf -vp). This PROM node contains a variety of properties, one of these is the "class-code" property, which is an exact copy of the 24 bit "Class Code" register from the device configuration register set. When Solaris OS starts up this PROM device tree is walked and the nodes "compatible" property is matched in /etc/driver_aliases to find a device driver to manage the node and a solaris prototype devinfo node is copied from the PROM node. The relevant device driver's XXX_attach() function is then passed the prototype devinfo node to see if it can manage the node. As part of that process the driver will try and add any required interrupt service routes using the ddi_add_intr() function. This function calls down through the various ddi layers until it ends up in a routine that examines the device nodes "class-code" property and then applies some simple rules to devise a Processor Interrupt Level (PIL) for that interrupt. Different releases of Solaris OS have the rules encoded in different places. For an example lets look at the OpenSolaris[TM] Operating System version for the sun4u architecture: In: http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/sun4u/io/pci/pci_intr.c
360 /* default class to pil value mapping */ 361 PCI_class_val_t PCI_default_pil [] = { 362 {0x000000, 0xff0000, 0x1}, /* Class code for pre-2.0 devices */ 363 {0x010000, 0xff0000, 0x4}, /* Mass Storage Controller */ 364 {0x020000, 0xff0000, 0x6}, /* Network Controller */ 365 {0x030000, 0xff0000, 0x9}, /* Display Controller */ 366 {0x040000, 0xff0000, 0x9}, /* Multimedia Controller */ 367 {0x050000, 0xff0000, 0xb}, /* Memory Controller */ 368 {0x060000, 0xff0000, 0xb}, /* Bridge Controller */ 369 {0x0c0000, 0xffff00, 0x9}, /* Serial Bus, FireWire (IEEE 1394) */ 370 {0x0c0100, 0xffff00, 0x4}, /* Serial Bus, ACCESS.bus */ 371 {0x0c0200, 0xffff00, 0x4}, /* Serial Bus, SSA */ 372 {0x0c0300, 0xffff00, 0x9}, /* Serial Bus Universal Serial Bus */ 373 {0x0c0400, 0xffff00, 0x6}, /* Serial Bus, Fibre Channel */ 374 {0x0c0600, 0xffff00, 0x6} /* Serial Bus, Infiniband */ 375 }; So that gives us the value and mask to compare and the PIL to use if it matches. Lets look at an example of "prtconf -vp" output from a sun4u machine: Node 0xf13e0980 assigned-addresses: 81012010.00000000.00001000.00000000.00000100.82012014.00000000.09808000.00000000.00002000.82012030.00000000.09810000.00000000.00010000 model: 'QLGC,ISP1040B' scsi-initiator-id: 00000007 clock-frequency: 03938700 alternate-reg: 00000000.00000000.00000000.00000000.00000000.02012014.00000000.00000000.00000000.00000100.01012010.00000000.00000000.00000000.00000100 reg: 00012000.00000000.00000000.00000000.00000000.01012010.00000000.00000000.00000000.00000100.02012014.00000000.00000000.00000000.00001000.02012030.00000000.00000000.00000000.00010000 power-consumption: 00000000.00000000.00895440.00895440 version: '1.15' compatible: 'PCI1077,1020' + 'pciclass,010000' manufacturer: 'QLGC' device_type: 'scsi' name: 'SUNW,isptwo' fcode-rom-offset: 00000000 devsel-speed: 00000001 class-code: 00010000 interrupts: 00000001 latency-timer: 00000040 cache-line-size: 00000010 max-latency: 00000000 min-grant: 00000000 revision-id: 00000002 device-id: 00001020 vendor-id: 00001077 Node 0xf13c8290 device_type: 'block' name: 'sd' Node 0xf13c6b80 device_type: 'byte' name: 'st' So the "class-code" is 00010000 which matches the "Mass storage controller" line in the source above so that gives us a PIL of 4. Lets try another: Node 0xf13f9d70 assigned-addresses: 82010110.00000000.09800000.00000000.00008000.82010130.00000000.0b000000.00000000.01000000 local-mac-address: 080020f7.373e hm-rev: 000000c1 compatible: 'PCI108e,1001' has-fcode: ' ' version: '1.17' device_type: 'network' address-bits: 00000030 max-frame-size: 00004000 reg: 00010100.00000000.00000000.00000000.00000000.02010110.00000000.00000000.00000000.00007030 model: 'SUNW,cheerio' name: 'SUNW,hme' fcode-rom-offset: 00000000 fast-back-to-back: devsel-speed: 00000001 class-code: 00020000 interrupts: 00000002 latency-timer: 00000040 cache-line-size: 00000010 max-latency: 00000005 min-grant: 0000000a revision-id: 00000001 device-id: 00001001 vendor-id: 0000108e And the class code is 00020000 which matches the source line: {0x020000, 0xff0000, 0x6} so it should have a PIL of 6. Product Solaris 2.6 Operating System Solaris 7 Operating System Solaris 10 Operating System Solaris 8 Operating System Solaris 9 Operating System SPARC Platform Edition Internal Comments The following is strictly for the use of Sun employees: Need to add section about how a x86 BIOS does this mapping. This applies to all SPARC machines that have PCI buses. interrupt, interrupt level, PCI, SPARC Previously Published As 82522 Change History Date: 2009-11-24 Name: Volkmar Grote 117021 Action: Reviewed for ESG Content Team Comment: Polished it a bit, removed specific SPARC system, inserted Solaris versions since IMHO this is closer to reality; I tried to get Tim Uglow interested in reviewing yet he claimed total lack of IBIS skills. Date: 2005-09-11 User Name: 97961 Action: Approved Comment: Publishing. No further edits required. Version: 3 Date: 2005-09-11 User Name: 97961 Action: Add Comment Comment: - Applied trademarking - Converted to STM formatting for better readability - Made simple sentence/grammatical corrections Attachments This solution has no attachment |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|