Interrupts with APIC, I/O APIC

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.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Interrupts with APIC, I/O APIC

Post by gerryg400 »

ReturnInfinity wrote:Anyone else out there getting interrupts from the RTC via the I/O APIC in VMware?

UPDATE: If I set the RTC I/O APIC entry to Level sensitive, Low active then it will fire once! However after that the system hangs.

-Ian
I tested my RTC code in VMware and it seems to work. My RTC comes on intr8 and I map it to the IOAPIC as rising edge.
If a trainstation is where trains stop, what is a workstation ?
User avatar
IanSeyler
Member
Member
Posts: 326
Joined: Mon Jul 28, 2008 9:46 am
Location: Ontario, Canada
Contact:

Re: Interrupts with APIC, I/O APIC

Post by IanSeyler »

@Brendan: Thanks for the post. It gives me a lot of information to search through.

It looks like it works in VMware with changing the rate of the RTC firing. With some quick testing any rate or 1024Hz or over do not work. Changed it to 512Hz and it is fine now.

And so... @gerryg400: What rate is your RTC set to? And would it be possible to test it at different rates under VMware. I would be curious to see your results.

Thanks,
-Ian
BareMetal OS - http://www.returninfinity.com/
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Interrupts with APIC, I/O APIC

Post by gerryg400 »

It's set to 1.024 kHz. I tested it on a few real boxes as well and had no problem. I'll try varying the rate as soon as I get a chance.
If a trainstation is where trains stop, what is a workstation ?
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Interrupts with APIC, I/O APIC

Post by gerryg400 »

[Update] I tried rates as high as 8.192 kHz in my kernel and they work fine on real hardware (2.83 GHz machine).

I also tried as high as 8.192 kHz in VMware on a windows machine and on a Mac. On both virtual machines the interrupts fired but the virtual machine couldn't keep up and the maximum interrupt rate that was generated was around 1.5 to 2 kHz.

It seems the only problem with VMware is one of performance.
If a trainstation is where trains stop, what is a workstation ?
User avatar
IanSeyler
Member
Member
Posts: 326
Joined: Mon Jul 28, 2008 9:46 am
Location: Ontario, Canada
Contact:

Re: Interrupts with APIC, I/O APIC

Post by IanSeyler »

@gerryg400: Thanks for testing that (I was using 1024Hz as well). Is you code public? I would be interested to see your initialization of the APIC and I/O APIC.

I need to test the RTC firing at 512Hz on a physical box to see if it works. Either way I still need to go through my I/O APIC code. Further testing shows the 512Hz "fix" is sporadic and not the real solution (Start up the VM and it doesn't work; reset the VM and it does work).

Thanks,
-Ian
BareMetal OS - http://www.returninfinity.com/
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly
User avatar
IanSeyler
Member
Member
Posts: 326
Joined: Mon Jul 28, 2008 9:46 am
Location: Ontario, Canada
Contact:

Re: Interrupts with APIC, I/O APIC

Post by IanSeyler »

@Brendan: I've verified the In-Service Registers that no other interrupts are active at the time. I can see that bit 33 is set when the keyboard interrupt is called (as it is interrupt 0x21).

Pure64 is for x86-64 only so no issues with the lower bits having to be set. I also check for and parse the ACPI tables only. No MP tables are used.

I know that some assumptions are being made (no checksum of ACPI, BSP APIC ID, only the legacy timer being redirected, only 1 I/O APIC, etc). Though I know from displaying the ACPI tables on-screen in VMware that the BSP is APIC ID 0, that there is only one I/O APIC, and only the timer is being redirected (to IRQ 2).

The odd part is that sometimes it works under VMware if I reset the host or mess with the rate. ](*,)

Thanks,
Ian
BareMetal OS - http://www.returninfinity.com/
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: Interrupts with APIC, I/O APIC

Post by Owen »

ReturnInfinity wrote:no checksum of ACPI
I know of BIOSes where the EBDA contains a set of broken ACPI tables with an invalid checksum - probably a set of templates for the tables actually generated on boot up. You might want to check this.
User avatar
IanSeyler
Member
Member
Posts: 326
Joined: Mon Jul 28, 2008 9:46 am
Location: Ontario, Canada
Contact:

Re: Interrupts with APIC, I/O APIC

Post by IanSeyler »

@Owen: Good point.. that would throw me off if I thought I was looking at legit entries.

I got the RTC running under VMware and on physical hardware. It looks to be due to the way I was initializing the RTC. I was setting the periodic flag at the start of the loader and then writing to the ISR table and enabling interrupts later on. Using trial and error I came up with this:

Code: Select all

	; Enable the RTC
	mov rcx, 8			; IRQ value
	mov rax, 0x28			; Interrupt value
	call ioapic_entry_write

	; Set the periodic flag in the RTC
	mov al, 0x0B			; Status Register B
	out 0x70, al
	or al, 01000000b		; Set Periodic(6)
	out 0x71, al

	sti				; Enable interrupts
So is there a specified way that the RTC should be started? Or should I acknowledge the RTC (read register C) before the STI?

Thanks,
-Ian
BareMetal OS - http://www.returninfinity.com/
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Interrupts with APIC, I/O APIC

Post by gerryg400 »

Code: Select all

   mov al, 0x0B         ; Status Register B
   out 0x70, al
   or al, 01000000b      ; Set Periodic(6)
   out 0x71, al
Are you sure that's what you mean to do ? Writing 0x1b to the B register ?

The approach I take with devices that are attached to an IOAPIC is
  • 1. Stop the device from producing interrupts.
    2. ACK possibly existing interrupts to ensure the INTR line is de-asserted.
    3. Make sure the ISR is ready.
    4. Map the interrupt in the IOAPIC and set up polarity, trigger, destination etc. according to the tables.
    5. Unmask interrupt in the IOAPIC.
    6. Enable the interrupts in the device that are needed.
I generally do this with interrupts enabled. Well almost, some of the IOAPIC access routines I use, call cli and take spinlocks so interrupts are temporarily disabled.

Code: Select all

    /* Disable intrs from the RTC by clearing bits 4, 5 and 6 in reg B */
    cmos_write(0x0b, cmos_read(0x0b) & ~0x70);
    /* Set the rate to 1024 Hz */
    cmos_write(0x0a, 0x26);
    /* Read reg C to clear pending interrupts */
    cmos_read(0x0c);

    /* Install an interrupt for the RTC */
    rtc_intr = intr_create(rtc_ifunc, NULL, 0);
    intr_install(rtc_intr, 0x55);
    ioapic_map_intr(0x55, 0, 0, 0, 0, 0, 8);
    ioapic_unmask_intr(8);

    /* Re-enable periodic intrs from the RTC by setting bit 6 in reg B */
    cmos_write(0x0b, cmos_read(0x0b) | 0x40);
If a trainstation is where trains stop, what is a workstation ?
User avatar
IanSeyler
Member
Member
Posts: 326
Joined: Mon Jul 28, 2008 9:46 am
Location: Ontario, Canada
Contact:

Re: Interrupts with APIC, I/O APIC

Post by IanSeyler »

Actually that code was not correct. What I used was this:

Code: Select all

	; Set the periodic flag in the RTC
	mov al, 0x0B			; Status Register B
	out 0x70, al			; Select the address
	in al, 0x71			; Read the current settings
	push rax
	mov al, 0x0B			; Status Register B
	out 0x70, al			; Select the address
	pop rax
	or al, 01000000b		; Set Periodic(6)
	out 0x71, al			; Write the new settings
Tested my IBM xSeries 336 via PXE with success!

Image

I also tried a brand new Dell PowerEdge T410 (1 Xeon 5660, 6 cores) but it hung. All of the ACPI CPU entries come back as APIC ID 0xFF. There were also X2APIC entries in the MADT table but I don't parse them yet. Time to read up on the X2APIC!

Thanks,
Ian
BareMetal OS - http://www.returninfinity.com/
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly
Post Reply