Page 3 of 3
Re: Interrupts with APIC, I/O APIC
Posted: Sat Dec 10, 2011 3:54 pm
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.
Re: Interrupts with APIC, I/O APIC
Posted: Sun Dec 11, 2011 8:01 pm
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
Re: Interrupts with APIC, I/O APIC
Posted: Sun Dec 11, 2011 8:08 pm
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.
Re: Interrupts with APIC, I/O APIC
Posted: Mon Dec 12, 2011 5:40 am
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.
Re: Interrupts with APIC, I/O APIC
Posted: Mon Dec 12, 2011 10:10 am
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
Re: Interrupts with APIC, I/O APIC
Posted: Tue Dec 13, 2011 9:40 am
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
Re: Interrupts with APIC, I/O APIC
Posted: Tue Dec 13, 2011 2:51 pm
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.
Re: Interrupts with APIC, I/O APIC
Posted: Tue Dec 13, 2011 9:36 pm
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
Re: Interrupts with APIC, I/O APIC
Posted: Wed Dec 14, 2011 3:38 am
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);
Re: Interrupts with APIC, I/O APIC
Posted: Thu Dec 15, 2011 1:09 pm
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!
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