Strange IO-APIC register values.
Posted: Sun Nov 19, 2017 7:39 pm
I am learning IOAPIC in X86 system.
To do that, I used my vmware VM (Ubuntu 16.10, running in ESX).
I wrote a C program to dump IO-APIC registers, and tried to interpret the values according to IO-APIC page of OSDev.
Here is the output.
And, below is the output of 'cat /proc/interrupts | grep -i "IO-APIC"'.
To my surprise, the vector number shown by my C program did NOT match the output of /proc/interrupts.
I also got confused by my own output compared to the description of IO-APIC page in OSDev.
My code followed the IO-APIC page of OSdev, but I could NOT find out why my code showed the strange output.
Here is my C code for your reference.
Thanks,
-Tao
To do that, I used my vmware VM (Ubuntu 16.10, running in ESX).
I wrote a C program to dump IO-APIC registers, and tried to interpret the values according to IO-APIC page of OSDev.
Here is the output.
Code: Select all
# ./dumpioapic
Reg[0] = 0x01000000
Reg[1] = 0x00170011
Reg[2] = 0x01000000
Redir[12] = 300000000000931: vec = 31, d_mode = 1, dest_mode = 1, pin_pol = 0, tr_mode = 0
Redir[14] = 300000000000930: vec = 30, d_mode = 1, dest_mode = 1, pin_pol = 0, tr_mode = 0
Redir[16] = 300000000000933: vec = 33, d_mode = 1, dest_mode = 1, pin_pol = 0, tr_mode = 0
Redir[18] = 300000000000934: vec = 34, d_mode = 1, dest_mode = 1, pin_pol = 0, tr_mode = 0
Redir[1a] = 300000000000935: vec = 35, d_mode = 1, dest_mode = 1, pin_pol = 0, tr_mode = 0
Redir[1c] = 300000000000936: vec = 36, d_mode = 1, dest_mode = 1, pin_pol = 0, tr_mode = 0
Redir[1e] = 300000000000937: vec = 37, d_mode = 1, dest_mode = 1, pin_pol = 0, tr_mode = 0
Redir[20] = 300000000000938: vec = 38, d_mode = 1, dest_mode = 1, pin_pol = 0, tr_mode = 0
Redir[22] = 30000000000a939: vec = 39, d_mode = 1, dest_mode = 1, pin_pol = 1, tr_mode = 1
Redir[24] = 30000000000093a: vec = 3a, d_mode = 1, dest_mode = 1, pin_pol = 0, tr_mode = 0
Redir[26] = 30000000000093b: vec = 3b, d_mode = 1, dest_mode = 1, pin_pol = 0, tr_mode = 0
Redir[28] = 30000000000093c: vec = 3c, d_mode = 1, dest_mode = 1, pin_pol = 0, tr_mode = 0
Redir[2a] = 30000000000093d: vec = 3d, d_mode = 1, dest_mode = 1, pin_pol = 0, tr_mode = 0
Redir[2c] = 30000000000093e: vec = 3e, d_mode = 1, dest_mode = 1, pin_pol = 0, tr_mode = 0
Redir[2e] = 10000000000093f: vec = 3f, d_mode = 1, dest_mode = 1, pin_pol = 0, tr_mode = 0
Redir[30] = 30000000000a954: vec = 54, d_mode = 1, dest_mode = 1, pin_pol = 1, tr_mode = 1
Code: Select all
# cat /proc/interrupts | grep -i "IO-APIC"
0: 16 0 IO-APIC 2-edge timer
1: 2 7 IO-APIC 1-edge i8042
6: 4 0 IO-APIC 6-edge floppy
8: 1 0 IO-APIC 8-edge rtc0
9: 0 0 IO-APIC 9-fasteoi acpi
12: 148 3 IO-APIC 12-edge i8042
14: 0 0 IO-APIC 14-edge ata_piix
15: 227096 238 IO-APIC 15-edge ata_piix
16: 1 0 IO-APIC 16-fasteoi vmwgfx
17: 4330 29827 IO-APIC 17-fasteoi ioc0
I also got confused by my own output compared to the description of IO-APIC page in OSDev.
My code followed the IO-APIC page of OSdev, but I could NOT find out why my code showed the strange output.
Here is my C code for your reference.
Code: Select all
addr = mmap(0, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, 0xFEC00000);
if (addr == (void *)-1) {
printf("Failed to mmap\n");
goto out;
} else {
for (i = 0; i < 0x40; i ++) {
if ((i > 2) && (i < 0x10)) {
continue;
}
*(volatile uint32_t *)(addr) = i;
data = *(volatile uint32_t*)(addr + 0x10);
if (i >= 0x10) {
if ((i % 2) == 1) {
redir_reg.raw_reg |= (uint64_t)data << 32;
if (redir_reg.reg_bits.mask == 0) {
printf("Redir[%x] = %lx",
i - 0x1, redir_reg.raw_reg);
printf(": vec = %x, d_mode = %x, dest_mode = %x, pin_pol = %x, tr_mode = %x\n",
redir_reg.reg_bits.vector, redir_reg.reg_bits.deliver_mode, redir_reg.reg_bits.dest_mode,
redir_reg.reg_bits.pin_polarity, redir_reg.reg_bits.trigger_mode);
}
} else {
redir_reg.raw_reg = data;
}
} else {
printf("Reg[%x] = 0x%08x\n", i, data);
}
}
}
-Tao