IRQ's not working on Socket A computers

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

IRQ's not working on Socket A computers

Post by Combuster »

Hi,
In the context of compatability checks i have recently been testing my OS on my development machine. However, I do not get any IRQ's and consequently the kernel can not complete startup.

The problem is, all my other computers work perfectly (including 486s), except for this one. I've cross-checked it with one other AMD system, and my brother's computer also showed exactly the same symptoms. (No IRQs)

The only common denominator i can find between the two is that both are Socket A motherboards, and thus a similar generation of processors (Athlon XP vs Sempron). All my intels and my Athlon64 generate IRQs as expected.

Things i've tried:
- I've added some spare EOIs after the STI instruction in case the PIC was waiting for one
- I've checked that it isn't accidentally firing in the wrong range

Source code involved:
PIC initialisation

Code: Select all

InitializePIC:      MOV AL, PIC_ICW1_INIT | PIC_ICW1_ICW4
                    OUT PIC1_COMMAND, AL
                    Call HardwareDelay
                    MOV AL, 0x20          ; ICW 2 = base vector
                    OUT PIC1_DATA, AL
                    Call HardwareDelay
                    MOV AL, 1 << 2        ; ICW 3 = slaves connected
                    OUT PIC1_DATA, AL
                    Call HardwareDelay
                    MOV AL, PIC_ICW4_8086 ; ICW 4 = operation mode
                    OUT PIC1_DATA, AL
                    Call HardwareDelay
                    MOV AL, 0x0           ; OCW 1 = mask
                    OUT PIC1_DATA, AL
                    Call HardwareDelay
                    ; program chip: PIC2
                    MOV AL, PIC_ICW1_INIT | PIC_ICW1_ICW4
                    OUT PIC2_COMMAND, AL
                    Call HardwareDelay
                    MOV AL, 0x28          ; ICW 2 = base vector
                    OUT PIC2_DATA, AL
                    Call HardwareDelay
                    MOV AL, 0             ; ICW 3 = slaves connected
                    OUT PIC2_DATA, AL
                    Call HardwareDelay
                    MOV AL, PIC_ICW4_8086 ; ICW 4 = operation mode
                    OUT PIC2_DATA, AL
                    Call HardwareDelay
                    MOV AL, 0x0           ; OCW 1 = mask
                    OUT PIC2_DATA, AL
                    Call HardwareDelay
                    MOV EBX, [lpgTextPtr]
                    MOV word [EBX], 0x0750
                    ADD EBX, 2
                    MOV word [EBX], 0x0749
                    ADD EBX, 2
                    MOV word [EBX], 0x0743
                    ADD EBX, 2
                    MOV word [EBX], 0x0720
                    ADD EBX, 2
                    MOV [lpgTextPtr], EBX
                    RET
PIT code: (lpgTickCount returns the amount of IRQs from the PIT)

Code: Select all

InitializePIT:      MOV EBX, [lpgTextPtr]
                    MOV word [EBX], 0x0700 + 'P'    ; P: starting procedure
                    ADD EBX, 2

                    MOV AL, PIT_CW_CHAN0 | PIT_CW_LOHI | PIT_CW_RATE | PIT_CW_BINARY
                    OUT PIT_COMMAND, AL         ; write the mode to the PIT
                    Call HardwareDelay
                    MOV AX, 10000
                    OUT PIT_CHAN0, AL
                    Call HardwareDelay
                    MOV AL, AH
                    OUT PIT_CHAN0, AL
                    Call HardwareDelay

                    ; test if the PIT works
                    MOV dword [lpgTickCount], 0
                    MOV word [EBX], 0x0700 + '0'    ; P0: entering test
.check1:            CMP dword [lpgTickCount], 0
                    JE .check1

; The kernel does not reach this

                    MOV word [EBX], 0x0700 + '1'    ; P1: PIT fired once
.check2:            CMP dword [lpgTickCount], 1
                    JE .check2
                    MOV word [EBX], 0x0700 + '2'    ; P2: PIT fired twice
.check3:            CMP dword [lpgTickCount], 2
                    JE .check3
                    ; once we get here, the PIT is pretty much stable:

                    ; display completion
                    MOV word [EBX], 0x0700 + 'I'
                    ADD EBX, 2
                    MOV word [EBX], 0x0700 + 'T'    ; PIT: initialization ok
                    ADD EBX, 2
                    MOV word [EBX], 0x0720
                    ADD EBX, 2
                    MOV [lpgTextPtr], EBX
                    RET
All sources can be viewed online:
[ Source Browser ] [ Kernel ]
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Post by Brynet-Inc »

I've noticed a similar thing when installing OpenBSD on my Athlon systems, It had IRQ related problems with my Realtek 8139 clones.

When I went into the BIOS configuration utility, I disabled the plug-and-play option and the card was detected successfully.

You might also notice an option to change from APIC to PIC in the BIOS if it is at all relevant.
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

Tried both, neither works.
Apart from that, I don't really like being dependent on specific bios settings.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Post by Brynet-Inc »

Combuster wrote:Tried both, neither works.
Apart from that, I don't really like being dependent on specific bios settings.
Oh well then :P..

Other people manage coding for Intel/AMD systems without interoperability problems.. Learn to code more proficiently? :wink:
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
smbogan
Member
Member
Posts: 29
Joined: Tue Nov 21, 2006 3:17 pm

Post by smbogan »

Brynet-Inc wrote: Other people manage coding for Intel/AMD systems without interoperability problems.. Learn to code more proficiently? :wink:
Thanks for your sagelike advice...I'm fairly certain that is what he is trying to do here... :roll:
TheQuux
Member
Member
Posts: 73
Joined: Sun Oct 22, 2006 6:49 pm

Post by TheQuux »

Brynet-Inc wrote:I've noticed a similar thing when installing OpenBSD on my Athlon systems, It had IRQ related problems with my Realtek 8139 clones.
Brynet-Inc wrote:Other people manage coding for Intel/AMD systems without interoperability problems.. Learn to code more proficiently?
So... OpenBSD isn't coded proficiently?
My project: Xenon
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Post by Brynet-Inc »

TheQuux wrote:
Brynet-Inc wrote:I've noticed a similar thing when installing OpenBSD on my Athlon systems, It had IRQ related problems with my Realtek 8139 clones.
Brynet-Inc wrote:Other people manage coding for Intel/AMD systems without interoperability problems.. Learn to code more proficiently?
So... OpenBSD isn't coded proficiently?
The PnP feature was designed for Windows.. It causes chaos for other operating systems.

Watch out..
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Post by Brendan »

Hi,
Brynet-Inc wrote:The PnP feature was designed for Windows.. It causes chaos for other operating systems.
The ISA PnP specification was designed to remove the need for jumpers on the cards themselves, such that resources (I/O ports, IRQs, DMA channels, etc) can be automatically detected and set by software, and so that users can plug a new card in without worrying about resource conflicts.

Regardless of whether or not Microsoft was involved, it's a good idea that should have existed from the beginning. Unfortunately it didn't, which means you can have a mixture of hardware where some supports PnP and some doesn't.

If an OS handles PnP correctly, then it should have the same chance working correctly as Windows does - the PnP documentation contains all of the information necessary AFAIK (i.e. there is no hidden extensions that only Microsoft can use).

This makes me wonder what the Plug & Play option in the BIOS actually does. I would assume that the BIOS can sort out Plug & Play resource conflicts if the OS doesn't do it, and this option says something like "Plug & Play OS" or "Non-Plug & Play OS". If this is the case then problem is obvious - OpenBSD doesn't do the Plug & Play resource management and expects the BIOS to do it (while Windows has complete hardware support built-in).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

IIRC the Plug and Play os option indeed changes behavior as such:
If PnP OS enabled, the bios'll only initialize and configure the minimal set of devices needed for boot. The other devices remain unconfigured. If its disabled, all devices that the bios finds will be configured.

Still, I want my OS to be independent of specific bios settings (to some degree of reasonability obviously).
And since i'm not accessing anything beyond PIC, PIT and display before getting locked up I doubt this has any effect on these parts of my kernel.

In the meantime i've tried copying interleaving the PIC commands and increasing the delay with no success. I've compared my modified code with the linux 1.0 source without spotting any differences except for using longer delays.

If somebody has some KISS PIC and PIT setup code that works on a VIA socket-A motherboard, i'd like to borrow them to see where things go wrong.

As for the PIC/APIC option: has anybody got a clue about having to do something with the APIC (or related) components before getting classic interrupts working, since that'd be the last thing i was hoping for...
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Post by Candy »

Brendan wrote:This makes me wonder what the Plug & Play option in the BIOS actually does. I would assume that the BIOS can sort out Plug & Play resource conflicts if the OS doesn't do it, and this option says something like "Plug & Play OS" or "Non-Plug & Play OS". If this is the case then problem is obvious - OpenBSD doesn't do the Plug & Play resource management and expects the BIOS to do it (while Windows has complete hardware support built-in).
As far as I know, it tells the bios (when set to PnP) that your OS will handle the configuration of devices as such, including all x86-specifics. Linux does this (iirc), Windows does this (at times), OpenBSD apparently doesn't do this. Your own OS most likely doesn't do this yet. It's about in the same league as the "USB legacy support" option, it sounds like it's a bad idea but in fact it's the BIOS doing what it's supposed to do. Just stuck with that one since it ignores my USB keyboard since it's off - and I can't turn it on without using a PS2 keyboard.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Post by Brendan »

Hi,
Combuster wrote:IIRC the Plug and Play os option indeed changes behavior as such:
If PnP OS enabled, the bios'll only initialize and configure the minimal set of devices needed for boot. The other devices remain unconfigured. If its disabled, all devices that the bios finds will be configured.
Yes - this leaves a (theoretical, but extremely unlikely) problem of an ISA PnP card using default settings that conflict with something. In practice I doubt you've got any ISA PnP cards, and doubt any ISA PnP card would be so broken as to conflict with standard motherboard resources.
Combuster wrote:If somebody has some KISS PIC and PIT setup code that works on a VIA socket-A motherboard, i'd like to borrow them to see where things go wrong.
I don't think the PIC or PIT setup code is your problem - they look right to me, and I'm sure you've double checked them several times already.

After looking at your code the only thing I can find that may be wrong is the order things are done - e.g. enable all IRQs in the PIC, then create the IDT and enable interrupts (STI), then initialise the PIT chip (while leaving all other devices enabled but un-initialised).

I'd suggest using something like the following order:
  • - CLI
    - mask all IRQs in the PIC
    - STI
    - enter protected mode
    - build IDT
    - CLI
    - remap PIC IRQs (e.g. so that IRQ0 -> interrupt 0x20)
    - enable the cascade line in PIC1's IRQ mask (but leave all IRQs disabled)
    - STI
    - initialise the PIT chip
    - unmask the PIT IRQ in PIC1's IRQ mask
The idea here is to prevent "buffered IRQs"- for e.g. where an IRQ is sent to the PIC but isn't forwarded to the CPU because the CPU has interrupts disabled (and therefore blocks further IRQs from being sent).

The alternative is to send a series of EOI's to the PICs after the final STI (e.g. after your "InitializeIDT"). The problem here is working out how many EOI's are necessary for "worst case" - I'd guess 7 for PIC1 followed by 8 "EOI pairs" (to both PIC1 and PIC2) followed by N more EOI's to cancel any IRQs received while clearing the others, where N depends on how many devices can send an IRQ without any device specific interrupt acknowledgement - e.g. one for the PIT/IRQ0, but none for the PS/2 (IRQ1 and IRQ12, as the PS/2 controller won't send another IRQ to the PIC until it's internal buffer is cleared). There's probably a way to make this "IRQ purge" easier by reading the PIC chip's Interrupt Received Register (IRR), but you'd want to be careful of race conditions.

BTW Linux masks all IRQs in the PIC early during boot (in "setup.S"). GRUB does not (it does STI with no PIC masking) - lucky you wrote your own bootloader... ;)


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Post Reply