OSDev.org https://forum.osdev.org/ |
|
IO APIC and GPF exception https://forum.osdev.org/viewtopic.php?f=1&t=33577 |
Page 1 of 1 |
Author: | akasei [ Tue Mar 12, 2019 8:32 am ] |
Post subject: | IO APIC and GPF exception |
Hey! I configured LAPIC, IO APIC, IDT, RTC and Keyboard. Up to now everything seems to working great but... only when there is only one I/O Redirection Table entry IO APIC configuration (nasm style): Code: mov rdi, qword [kernel_ioapic_base_address] ; keyboard mov dword [edi + 0x0000], 0x12 ; IRQ1 low mov dword [edi + 0x0010], 0x20 + 0x01 ; IDT descriptor/vector 33 mov dword [edi + 0x0000], 0x13 ; IRQ1 high mov dword [edi + 0x0010], 0x00 ; rtc mov dword [edi + 0x0000], 0x20 ; IRQ8 low mov dword [edi + 0x0010], 0x20 + 0x08 ; IDT descriptor/vector 40 mov dword [edi + 0x0000], 0x21 ; IRQ8 high mov dword [edi + 0x0010], 0x00 ; PIC interrupts are masked ; all above has the same configuration ; delivery mode (fixed) ; destination mode (physical destination) ; delivery status (relaxed) ; pin polarity (active high) ; trigger mode (edge) ; mask (interrupt enabled) ; destination (apic id 0, so only BSP core will receive this interrupts at now) LAPIC configuration (nasm style): Code: mov rsi, qword [kernel_lapic_table_address] ; task priority mov dword [rsi + 0x0080], 0x00000000 ; flat mode mov dword [rsi + 0x00E0], 0xFFFFFFFF ; target cpu mov dword [rsi + 0x00D0], 0x01000000 ; enable lapic, spurious vector mov eax, dword [rsi + 0x00F0] or eax, 100000000b | 011111111b mov dword [rsi + 0x00F0], eax ; unmask interrupts mov eax, dword [rsi + 0x0320] and eax, ~0x00010000 mov dword [rsi + 0x0320], eax If both entrys are enabled in IO APIC, it is possible to catch General Protection Fault exception :/ and I don't know where to look at |
Author: | akasei [ Tue Mar 12, 2019 8:49 am ] |
Post subject: | Re: IO APIC and GPF exception |
Ok, I found the answer so the respond will be with new post. The culprit was Spurious Interrupt, because I didn't make IDT entry at descriptor 255 (which was configured in LAPIC). Right now, this is the code for Spurious Interrupt Code: kernel_idt_spurious_interrupt: xchg bx,bx ; debug nop nop nop nop iretq How should the procedure for handling this interrupt look like? |
Author: | Korona [ Wed Mar 13, 2019 12:00 am ] |
Post subject: | Re: IO APIC and GPF exception |
Do you really encounter the spurious IRQ (double check that indeed comes from that source)? Is this on real HW or on qemu (or some other VM)? If spurious IRQs happen frequently (e.g. on every boot) that suggests that something might be wrong with your hardware configuration. |
Author: | akasei [ Wed Mar 13, 2019 1:18 am ] |
Post subject: | Re: IO APIC and GPF exception |
Yes, I'm sure of that. This interrupt exist only in Bochs environment, Qemu was fine (I dont use real hardware). After a deeper analysis, I come to the conclusion that this may be a PIT controller that I do not use. Thus unhandled interrupt could trigger "spurious interrupt". The frequency of occurrence is very close to 18 Hz |
Author: | Korona [ Thu Mar 14, 2019 1:09 am ] |
Post subject: | Re: IO APIC and GPF exception |
That sounds very suspicious. Spurious IRQs happen when an IRQ cannot be delivered correctly. For example, (to my understanding) this happens if the I/O APIC tells the CPU to raise an IRQ but is unable to deliver the vector number due to noise on the wires. Normal devices like the PIT should never be able to cause spurious IRQs (reliably). Before concluding that the PIT really causes a spurious IRQ, you should make sure that: (i) the IRQ is really maked in the (legacy) XT-PIC, (ii) the IRQ is masked in the I/O APIC and (iii) it's not just caused by a possible default (or BIOS-configured) value of 0xFF in the I/O APIC's vector register. To further diagnose the issue: did you call the AML _PIC method? If you are sure that this is really a spurious IRQ, it probably makes sense to file a bug report to Bochs. |
Author: | akasei [ Thu Mar 14, 2019 1:35 am ] |
Post subject: | Re: IO APIC and GPF exception |
Hmm, I redirected interrupts to higher ones (0x20..0x2F) on PIC controller and masked all of them. but, after I mounted interrupt procedure for PIT to IO APIC register no 0x14, the spurious interrupt dissapeared Quote: To further diagnose the issue: did you call the AML _PIC method? No, I thought that masking the interrupts on the PIC controller would solve the problem.Is it difficult to use AML? I'm asking because I only work in assembler language and creating my own interpreter is not going to my mind. |
Author: | nullplan [ Thu Mar 14, 2019 9:52 am ] |
Post subject: | Re: IO APIC and GPF exception |
akasei wrote: Is it difficult to use AML? I'm asking because I only work in assembler language and creating my own interpreter is not going to my mind. Your options are to make or use an AML interpreter to do these things, or to dump the AML code for all the mainboards you wish to support, and use a mainboard driver for each one. If you wish to pursue the former route, I suggest taking a look at ACPICA. Though it is written in C, you can easily fulfill its interface needs even from assembly. I mean, it only needs a few functions. If you wish to pursue the latter route, I again suggest taking a look at ACPICA. The package comes with tools you can execute under Linux, and you can use the output to reverse-engineer the AML of a given mainboard (it obviously must be executed on the target mainboard). Then you don't have to "execute the PIC method", but rather can do "the equivalent of executing the PIC method". On my laptop, for example, the PIC method does this: Code: Method (_PIC, 1, NotSerialized) // _PIC: Interrupt Model { GPIC = Arg0 PICM = Arg0 } Remember, you are supposed to call this with 1 for APIC. OK, so what are these two identifiers? GPIC is a field in an OperationRegion: Code: OperationRegion (GNVS, SystemMemory, 0x9CFBCC18, 0x0383) Field (GNVS, AnyAcc, Lock, Preserve) { [...] Offset (0x7C), GPIC, 8, [...] } So that means, if I am not mistaken, that in order to use the APIC, I am supposed to set the qword at 0x9cfbcc18+0x7c to 1, using locking. But I'd have to read up on what that means specifically. PICM is just a name, basically an internal variable. It is referenced in all the _PRT methods. So I can now execute these methods under the assumption that PICM = 1. So for instance: Code: Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table { If (PICM) { Return (AR00 ()) } Return (PR00 ()) } Means I have to look up the routing information for that particular device in AR00. And that rabbit hole just keeps going. |
Author: | Korona [ Thu Mar 14, 2019 10:34 am ] |
Post subject: | Re: IO APIC and GPF exception |
So the APIC issue was that you did not initialize the vector? Yes, if you do not modify it, it will be left in whatever state the BIOS set up, which may be not what you want. Thus, it makes sense to mask all I/O APIC vectors before you start using it. --- Regarding _PIC: what nullplan posted is entirely correct. Let me just add that for Intel mainboards, the registers affected by _PIC are actually documented. Luckily, there is no need to disassemble the AML, you can find their descriptions in the ICH/PCH data sheets. Also, you could always use Omar's LAI library (library / usage example) to execute the AML. Disclaimer: I contributed a lot to that project ;D. |
Page 1 of 1 | All times are UTC - 6 hours |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |