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.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
Interrupts with APIC, I/O APIC
Re: Interrupts with APIC, I/O APIC
If a trainstation is where trains stop, what is a workstation ?
Re: Interrupts with APIC, I/O APIC
@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
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
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly
Re: Interrupts with APIC, I/O APIC
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 ?
Re: Interrupts with APIC, I/O APIC
[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.
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 ?
Re: Interrupts with APIC, I/O APIC
@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
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
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly
Re: Interrupts with APIC, I/O APIC
@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
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
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly
- Owen
- Member
- Posts: 1700
- Joined: Fri Jun 13, 2008 3:21 pm
- Location: Cambridge, United Kingdom
- Contact:
Re: Interrupts with APIC, I/O APIC
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.ReturnInfinity wrote:no checksum of ACPI
Re: Interrupts with APIC, I/O APIC
@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: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
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
Thanks,
-Ian
BareMetal OS - http://www.returninfinity.com/
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly
Re: Interrupts with APIC, I/O APIC
Code: Select all
mov al, 0x0B ; Status Register B
out 0x70, al
or al, 01000000b ; Set Periodic(6)
out 0x71, al
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.
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 ?
Re: Interrupts with APIC, I/O APIC
Actually that code was not correct. What I used was this:
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
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
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
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly