OSDev.org

The Place to Start for Operating System Developers
It is currently Mon Mar 18, 2019 11:42 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: IO APIC and GPF exception
PostPosted: Tue Mar 12, 2019 8:32 am 
Offline
Member
Member
User avatar

Joined: Tue Feb 11, 2014 4:59 pm
Posts: 49
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 :(

_________________
wataha.net - system programming, my own 64 bit kernel and software.


Top
 Profile  
 
 Post subject: Re: IO APIC and GPF exception
PostPosted: Tue Mar 12, 2019 8:49 am 
Offline
Member
Member
User avatar

Joined: Tue Feb 11, 2014 4:59 pm
Posts: 49
Ok, I found the answer :D 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?

_________________
wataha.net - system programming, my own 64 bit kernel and software.


Top
 Profile  
 
 Post subject: Re: IO APIC and GPF exception
PostPosted: Wed Mar 13, 2019 12:00 am 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 537
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.

_________________
managarm: A microkernel-based OS that is capable of running a Wayland desktop


Top
 Profile  
 
 Post subject: Re: IO APIC and GPF exception
PostPosted: Wed Mar 13, 2019 1:18 am 
Offline
Member
Member
User avatar

Joined: Tue Feb 11, 2014 4:59 pm
Posts: 49
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 :)

_________________
wataha.net - system programming, my own 64 bit kernel and software.


Top
 Profile  
 
 Post subject: Re: IO APIC and GPF exception
PostPosted: Thu Mar 14, 2019 1:09 am 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 537
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.

_________________
managarm: A microkernel-based OS that is capable of running a Wayland desktop


Top
 Profile  
 
 Post subject: Re: IO APIC and GPF exception
PostPosted: Thu Mar 14, 2019 1:35 am 
Offline
Member
Member
User avatar

Joined: Tue Feb 11, 2014 4:59 pm
Posts: 49
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.

_________________
wataha.net - system programming, my own 64 bit kernel and software.


Top
 Profile  
 
 Post subject: Re: IO APIC and GPF exception
PostPosted: Thu Mar 14, 2019 9:52 am 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 166
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.


Top
 Profile  
 
 Post subject: Re: IO APIC and GPF exception
PostPosted: Thu Mar 14, 2019 10:34 am 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 537
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.

_________________
managarm: A microkernel-based OS that is capable of running a Wayland desktop


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: zity and 8 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group