From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: To: 9fans@cse.psu.edu From: andrey mirtchovski MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Subject: [9fans] IRQs again... Date: Tue, 21 May 2002 10:45:57 -0600 Topicbox-Message-UUID: 98e9204e-eaca-11e9-9e20-41e7f4b1d025 We finally got around to looking at booting R4 without BIOS again (exploring the niceties of the 4th edition took a bit longer than expected) and have to report some problems with the way the new IRQ handling routines are, umm, handling IRQs in a BIOS-less environment. Here's the sequence of events as seen by /sys/src/9/pc/pci.c: The southbridge is recognized as ALI, the get and set routines become ali_get() and ali_set(). The pci routing table is found at 0xf0000 (LinuxBios puts it there -- a left over from our R3 work) and is printed as: % pcir PCI interrupt routing table version 1.0 at f0000 South Bridge 0.7.0, irqs 0000 compat 10B9/1533 miniport data: 00 00 00 00 0.12.0 01: [0] 01 1EB8 [1] 02 1EB8 [2] 03 1EB8 [3] 04 1EB8 0.11.0 02: [0] 02 1EB8 [1] 03 1EB8 [2] 04 1EB8 [3] 01 1EB8 0.10.0 03: [0] 03 1EB8 [1] 04 1EB8 [2] 01 1EB8 [3] 02 1EB8 0.9.0 04: [0] 04 1EB8 [1] 01 1EB8 [2] 02 1EB8 [3] 03 1EB8 0.13.0 05: [0] 04 1EB8 [1] 01 1EB8 [2] 02 1EB8 [3] 03 1EB8 0.14.0 06: [0] 03 1EB8 [1] 04 1EB8 [2] 01 1EB8 [3] 02 1EB8 0.6.0 00: [0] 08 1EB8 [1] 00 1EB8 [2] 00 1EB8 [3] 00 1EB8 0.20.0 00: [0] 59 1EB8 [1] 00 1EB8 [2] 00 1EB8 [3] 00 1EB8 1.0.0 00: [0] 01 1EB8 [1] 00 1EB8 [2] 00 1EB8 [3] 00 1EB8 % Then the code tries to set the IRQs according to the pci routing table, and that's where the problems start. The ali_get() routine seems to be very similar to the one linux uses, with several exceptions you can see below: plan9:ali_get(): pirq = pcicfgr8(router, 0x48 + ((link-1)>>1)); return (link & 1)? map[pirq&15]: map[pirq>>4]; linux:pirq_ali_get(): return irqmap[read_config_nybble(router, 0x48, pirq-1)]; I'm not sure what warrants these changes in plan9, but as an effect ali_get() returns '0' as the interrupt for all pci devices it is executed for. If changed to: pirq = pcicfgr8(router, 0x48 + (link-1)); returnmap[pirq]; (which corresponds more closely to the linux code), we end up with _some_ PCI devices having irqs as follows: bus dev type vid did intl memory 0 0/0 06 00 00 10b9 1621 0 0 1/0 06 04 00 10b9 5247 0 ->1 0 6/0 04 01 00 10b9 5451 6 0:00001001 256 1:81000000 4096 0 7/0 06 01 00 10b9 1533 0 0 11/0 02 00 00 10ec 8139 0 0:00001101 256 1:81001000 256 0 12/0 03 00 00 102b 0519 0 0:81004000 16384 1:84000008 8388608 0 16/0 01 01 fa 10b9 5229 0 0:000001f1 65040 1:000003f5 64528 2:00000171 65168 3:00000375 64656 4:00001201 16 0 17/0 00 00 00 10b9 7101 0 0 20/0 0c 03 10 10b9 5237 9 0:81008000 4096 1 0/0 03 00 00 10de 00a0 0 0:80000000 16777216 1:82000008 33554432 We had an almost working version of the above code written for R3. The crucial piece we (I) were missing was setting the the IRQ in the southbridge after obtaining it from the routing table. It was by no means comprehensive and was tailored to the motherboards we were testing on. The specification used was, ironically, obtained from microsoft's web site: http://www.microsoft.com/hwdev/archive/BUSBIOS/pciirq.asp The significant difference was that according to this specification the IRQs are to be obtained from the last two bytes of the info structure (pciinfo is the name linux and bsd use for it). The first byte is passed as 'link' to ali_get() in the plan9 code (m[0] is the variable), however m[1] and m[2] form another 16 bit variable, having 1 in the place of each IRQ which is routable on the board (1eb8 for our test motherboard). Going through the bits in search for ones gives us the interrupts we can use. We're not particularly sure this is the proper way of doing things (both linux and freebsd seem to be doing it at one stage or another of the pci routing code, but...). andrey ps: then again, i may have missed something important, in which case feel free to clue me in