Commit 45fad661 authored by Randy Dunlap's avatar Randy Dunlap Committed by Linus Torvalds

[PATCH] Unionize IO-APIC registers

[ Registers of the world, unite! ]

This makes the IO-APIC data structures use unions, so that we can
cleanly access them both as flat "raw" values, and as the bitmap
sub-entries.
parent 1d8c1ffb
...@@ -1272,10 +1272,10 @@ static inline void UNEXPECTED_IO_APIC(void) ...@@ -1272,10 +1272,10 @@ static inline void UNEXPECTED_IO_APIC(void)
void __init print_IO_APIC(void) void __init print_IO_APIC(void)
{ {
int apic, i; int apic, i;
struct IO_APIC_reg_00 reg_00; union IO_APIC_reg_00 reg_00;
struct IO_APIC_reg_01 reg_01; union IO_APIC_reg_01 reg_01;
struct IO_APIC_reg_02 reg_02; union IO_APIC_reg_02 reg_02;
struct IO_APIC_reg_03 reg_03; union IO_APIC_reg_03 reg_03;
unsigned long flags; unsigned long flags;
printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries); printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
...@@ -1292,47 +1292,47 @@ void __init print_IO_APIC(void) ...@@ -1292,47 +1292,47 @@ void __init print_IO_APIC(void)
for (apic = 0; apic < nr_ioapics; apic++) { for (apic = 0; apic < nr_ioapics; apic++) {
spin_lock_irqsave(&ioapic_lock, flags); spin_lock_irqsave(&ioapic_lock, flags);
*(int *)&reg_00 = io_apic_read(apic, 0); reg_00.raw = io_apic_read(apic, 0);
*(int *)&reg_01 = io_apic_read(apic, 1); reg_01.raw = io_apic_read(apic, 1);
if (reg_01.version >= 0x10) if (reg_01.bits.version >= 0x10)
*(int *)&reg_02 = io_apic_read(apic, 2); reg_02.raw = io_apic_read(apic, 2);
if (reg_01.version >= 0x20) if (reg_01.bits.version >= 0x20)
*(int *)&reg_03 = io_apic_read(apic, 3); reg_03.raw = io_apic_read(apic, 3);
spin_unlock_irqrestore(&ioapic_lock, flags); spin_unlock_irqrestore(&ioapic_lock, flags);
printk("\n"); printk("\n");
printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mpc_apicid); printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mpc_apicid);
printk(KERN_DEBUG ".... register #00: %08X\n", *(int *)&reg_00); printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw);
printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.ID); printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID);
printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.delivery_type); printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.bits.delivery_type);
printk(KERN_DEBUG "....... : LTS : %X\n", reg_00.LTS); printk(KERN_DEBUG "....... : LTS : %X\n", reg_00.bits.LTS);
if (reg_00.ID >= APIC_BROADCAST_ID) if (reg_00.bits.ID >= APIC_BROADCAST_ID)
UNEXPECTED_IO_APIC(); UNEXPECTED_IO_APIC();
if (reg_00.__reserved_1 || reg_00.__reserved_2) if (reg_00.bits.__reserved_1 || reg_00.bits.__reserved_2)
UNEXPECTED_IO_APIC(); UNEXPECTED_IO_APIC();
printk(KERN_DEBUG ".... register #01: %08X\n", *(int *)&reg_01); printk(KERN_DEBUG ".... register #01: %08X\n", reg_01.raw);
printk(KERN_DEBUG "....... : max redirection entries: %04X\n", reg_01.entries); printk(KERN_DEBUG "....... : max redirection entries: %04X\n", reg_01.bits.entries);
if ( (reg_01.entries != 0x0f) && /* older (Neptune) boards */ if ( (reg_01.bits.entries != 0x0f) && /* older (Neptune) boards */
(reg_01.entries != 0x17) && /* typical ISA+PCI boards */ (reg_01.bits.entries != 0x17) && /* typical ISA+PCI boards */
(reg_01.entries != 0x1b) && /* Compaq Proliant boards */ (reg_01.bits.entries != 0x1b) && /* Compaq Proliant boards */
(reg_01.entries != 0x1f) && /* dual Xeon boards */ (reg_01.bits.entries != 0x1f) && /* dual Xeon boards */
(reg_01.entries != 0x22) && /* bigger Xeon boards */ (reg_01.bits.entries != 0x22) && /* bigger Xeon boards */
(reg_01.entries != 0x2E) && (reg_01.bits.entries != 0x2E) &&
(reg_01.entries != 0x3F) (reg_01.bits.entries != 0x3F)
) )
UNEXPECTED_IO_APIC(); UNEXPECTED_IO_APIC();
printk(KERN_DEBUG "....... : PRQ implemented: %X\n", reg_01.PRQ); printk(KERN_DEBUG "....... : PRQ implemented: %X\n", reg_01.bits.PRQ);
printk(KERN_DEBUG "....... : IO APIC version: %04X\n", reg_01.version); printk(KERN_DEBUG "....... : IO APIC version: %04X\n", reg_01.bits.version);
if ( (reg_01.version != 0x01) && /* 82489DX IO-APICs */ if ( (reg_01.bits.version != 0x01) && /* 82489DX IO-APICs */
(reg_01.version != 0x10) && /* oldest IO-APICs */ (reg_01.bits.version != 0x10) && /* oldest IO-APICs */
(reg_01.version != 0x11) && /* Pentium/Pro IO-APICs */ (reg_01.bits.version != 0x11) && /* Pentium/Pro IO-APICs */
(reg_01.version != 0x13) && /* Xeon IO-APICs */ (reg_01.bits.version != 0x13) && /* Xeon IO-APICs */
(reg_01.version != 0x20) /* Intel P64H (82806 AA) */ (reg_01.bits.version != 0x20) /* Intel P64H (82806 AA) */
) )
UNEXPECTED_IO_APIC(); UNEXPECTED_IO_APIC();
if (reg_01.__reserved_1 || reg_01.__reserved_2) if (reg_01.bits.__reserved_1 || reg_01.bits.__reserved_2)
UNEXPECTED_IO_APIC(); UNEXPECTED_IO_APIC();
/* /*
...@@ -1340,10 +1340,10 @@ void __init print_IO_APIC(void) ...@@ -1340,10 +1340,10 @@ void __init print_IO_APIC(void)
* but the value of reg_02 is read as the previous read register * but the value of reg_02 is read as the previous read register
* value, so ignore it if reg_02 == reg_01. * value, so ignore it if reg_02 == reg_01.
*/ */
if (reg_01.version >= 0x10 && *(int *)&reg_02 != *(int *)&reg_01) { if (reg_01.bits.version >= 0x10 && reg_02.raw != reg_01.raw) {
printk(KERN_DEBUG ".... register #02: %08X\n", *(int *)&reg_02); printk(KERN_DEBUG ".... register #02: %08X\n", reg_02.raw);
printk(KERN_DEBUG "....... : arbitration: %02X\n", reg_02.arbitration); printk(KERN_DEBUG "....... : arbitration: %02X\n", reg_02.bits.arbitration);
if (reg_02.__reserved_1 || reg_02.__reserved_2) if (reg_02.bits.__reserved_1 || reg_02.bits.__reserved_2)
UNEXPECTED_IO_APIC(); UNEXPECTED_IO_APIC();
} }
...@@ -1352,11 +1352,11 @@ void __init print_IO_APIC(void) ...@@ -1352,11 +1352,11 @@ void __init print_IO_APIC(void)
* or reg_03, but the value of reg_0[23] is read as the previous read * or reg_03, but the value of reg_0[23] is read as the previous read
* register value, so ignore it if reg_03 == reg_0[12]. * register value, so ignore it if reg_03 == reg_0[12].
*/ */
if (reg_01.version >= 0x20 && *(int *)&reg_03 != *(int *)&reg_02 && if (reg_01.bits.version >= 0x20 && reg_03.raw != reg_02.raw &&
*(int *)&reg_03 != *(int *)&reg_01) { reg_03.raw != reg_01.raw) {
printk(KERN_DEBUG ".... register #03: %08X\n", *(int *)&reg_03); printk(KERN_DEBUG ".... register #03: %08X\n", reg_03.raw);
printk(KERN_DEBUG "....... : Boot DT : %X\n", reg_03.boot_DT); printk(KERN_DEBUG "....... : Boot DT : %X\n", reg_03.bits.boot_DT);
if (reg_03.__reserved_1) if (reg_03.bits.__reserved_1)
UNEXPECTED_IO_APIC(); UNEXPECTED_IO_APIC();
} }
...@@ -1365,7 +1365,7 @@ void __init print_IO_APIC(void) ...@@ -1365,7 +1365,7 @@ void __init print_IO_APIC(void)
printk(KERN_DEBUG " NR Log Phy Mask Trig IRR Pol" printk(KERN_DEBUG " NR Log Phy Mask Trig IRR Pol"
" Stat Dest Deli Vect: \n"); " Stat Dest Deli Vect: \n");
for (i = 0; i <= reg_01.entries; i++) { for (i = 0; i <= reg_01.bits.entries; i++) {
struct IO_APIC_route_entry entry; struct IO_APIC_route_entry entry;
spin_lock_irqsave(&ioapic_lock, flags); spin_lock_irqsave(&ioapic_lock, flags);
...@@ -1546,7 +1546,7 @@ void /*__init*/ print_PIC(void) ...@@ -1546,7 +1546,7 @@ void /*__init*/ print_PIC(void)
static void __init enable_IO_APIC(void) static void __init enable_IO_APIC(void)
{ {
struct IO_APIC_reg_01 reg_01; union IO_APIC_reg_01 reg_01;
int i; int i;
unsigned long flags; unsigned long flags;
...@@ -1563,9 +1563,9 @@ static void __init enable_IO_APIC(void) ...@@ -1563,9 +1563,9 @@ static void __init enable_IO_APIC(void)
*/ */
for (i = 0; i < nr_ioapics; i++) { for (i = 0; i < nr_ioapics; i++) {
spin_lock_irqsave(&ioapic_lock, flags); spin_lock_irqsave(&ioapic_lock, flags);
*(int *)&reg_01 = io_apic_read(i, 1); reg_01.raw = io_apic_read(i, 1);
spin_unlock_irqrestore(&ioapic_lock, flags); spin_unlock_irqrestore(&ioapic_lock, flags);
nr_ioapic_registers[i] = reg_01.entries+1; nr_ioapic_registers[i] = reg_01.bits.entries+1;
} }
/* /*
...@@ -1597,7 +1597,7 @@ void disable_IO_APIC(void) ...@@ -1597,7 +1597,7 @@ void disable_IO_APIC(void)
#ifndef CONFIG_X86_NUMAQ #ifndef CONFIG_X86_NUMAQ
static void __init setup_ioapic_ids_from_mpc(void) static void __init setup_ioapic_ids_from_mpc(void)
{ {
struct IO_APIC_reg_00 reg_00; union IO_APIC_reg_00 reg_00;
unsigned long phys_id_present_map; unsigned long phys_id_present_map;
int apic; int apic;
int i; int i;
...@@ -1617,7 +1617,7 @@ static void __init setup_ioapic_ids_from_mpc(void) ...@@ -1617,7 +1617,7 @@ static void __init setup_ioapic_ids_from_mpc(void)
/* Read the register 0 value */ /* Read the register 0 value */
spin_lock_irqsave(&ioapic_lock, flags); spin_lock_irqsave(&ioapic_lock, flags);
*(int *)&reg_00 = io_apic_read(apic, 0); reg_00.raw = io_apic_read(apic, 0);
spin_unlock_irqrestore(&ioapic_lock, flags); spin_unlock_irqrestore(&ioapic_lock, flags);
old_id = mp_ioapics[apic].mpc_apicid; old_id = mp_ioapics[apic].mpc_apicid;
...@@ -1626,8 +1626,8 @@ static void __init setup_ioapic_ids_from_mpc(void) ...@@ -1626,8 +1626,8 @@ static void __init setup_ioapic_ids_from_mpc(void)
printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n", printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
apic, mp_ioapics[apic].mpc_apicid); apic, mp_ioapics[apic].mpc_apicid);
printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
reg_00.ID); reg_00.bits.ID);
mp_ioapics[apic].mpc_apicid = reg_00.ID; mp_ioapics[apic].mpc_apicid = reg_00.bits.ID;
} }
/* /*
...@@ -1671,18 +1671,18 @@ static void __init setup_ioapic_ids_from_mpc(void) ...@@ -1671,18 +1671,18 @@ static void __init setup_ioapic_ids_from_mpc(void)
printk(KERN_INFO "...changing IO-APIC physical APIC ID to %d ...", printk(KERN_INFO "...changing IO-APIC physical APIC ID to %d ...",
mp_ioapics[apic].mpc_apicid); mp_ioapics[apic].mpc_apicid);
reg_00.ID = mp_ioapics[apic].mpc_apicid; reg_00.bits.ID = mp_ioapics[apic].mpc_apicid;
spin_lock_irqsave(&ioapic_lock, flags); spin_lock_irqsave(&ioapic_lock, flags);
io_apic_write(apic, 0, *(int *)&reg_00); io_apic_write(apic, 0, reg_00.raw);
spin_unlock_irqrestore(&ioapic_lock, flags); spin_unlock_irqrestore(&ioapic_lock, flags);
/* /*
* Sanity check * Sanity check
*/ */
spin_lock_irqsave(&ioapic_lock, flags); spin_lock_irqsave(&ioapic_lock, flags);
*(int *)&reg_00 = io_apic_read(apic, 0); reg_00.raw = io_apic_read(apic, 0);
spin_unlock_irqrestore(&ioapic_lock, flags); spin_unlock_irqrestore(&ioapic_lock, flags);
if (reg_00.ID != mp_ioapics[apic].mpc_apicid) if (reg_00.bits.ID != mp_ioapics[apic].mpc_apicid)
panic("could not set ID!\n"); panic("could not set ID!\n");
else else
printk(" ok.\n"); printk(" ok.\n");
...@@ -2220,7 +2220,7 @@ late_initcall(io_apic_bug_finalize); ...@@ -2220,7 +2220,7 @@ late_initcall(io_apic_bug_finalize);
int __init io_apic_get_unique_id (int ioapic, int apic_id) int __init io_apic_get_unique_id (int ioapic, int apic_id)
{ {
struct IO_APIC_reg_00 reg_00; union IO_APIC_reg_00 reg_00;
static unsigned long apic_id_map = 0; static unsigned long apic_id_map = 0;
unsigned long flags; unsigned long flags;
int i = 0; int i = 0;
...@@ -2238,13 +2238,13 @@ int __init io_apic_get_unique_id (int ioapic, int apic_id) ...@@ -2238,13 +2238,13 @@ int __init io_apic_get_unique_id (int ioapic, int apic_id)
apic_id_map = phys_cpu_present_map; apic_id_map = phys_cpu_present_map;
spin_lock_irqsave(&ioapic_lock, flags); spin_lock_irqsave(&ioapic_lock, flags);
*(int *)&reg_00 = io_apic_read(ioapic, 0); reg_00.raw = io_apic_read(ioapic, 0);
spin_unlock_irqrestore(&ioapic_lock, flags); spin_unlock_irqrestore(&ioapic_lock, flags);
if (apic_id >= IO_APIC_MAX_ID) { if (apic_id >= IO_APIC_MAX_ID) {
printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying " printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying "
"%d\n", ioapic, apic_id, reg_00.ID); "%d\n", ioapic, apic_id, reg_00.bits.ID);
apic_id = reg_00.ID; apic_id = reg_00.bits.ID;
} }
/* /*
...@@ -2269,16 +2269,16 @@ int __init io_apic_get_unique_id (int ioapic, int apic_id) ...@@ -2269,16 +2269,16 @@ int __init io_apic_get_unique_id (int ioapic, int apic_id)
apic_id_map |= apicid_to_cpu_present(apic_id); apic_id_map |= apicid_to_cpu_present(apic_id);
if (reg_00.ID != apic_id) { if (reg_00.bits.ID != apic_id) {
reg_00.ID = apic_id; reg_00.bits.ID = apic_id;
spin_lock_irqsave(&ioapic_lock, flags); spin_lock_irqsave(&ioapic_lock, flags);
io_apic_write(ioapic, 0, *(int *)&reg_00); io_apic_write(ioapic, 0, reg_00.raw);
*(int *)&reg_00 = io_apic_read(ioapic, 0); reg_00.raw = io_apic_read(ioapic, 0);
spin_unlock_irqrestore(&ioapic_lock, flags); spin_unlock_irqrestore(&ioapic_lock, flags);
/* Sanity check */ /* Sanity check */
if (reg_00.ID != apic_id) if (reg_00.bits.ID != apic_id)
panic("IOAPIC[%d]: Unable change apic_id!\n", ioapic); panic("IOAPIC[%d]: Unable change apic_id!\n", ioapic);
} }
...@@ -2290,27 +2290,27 @@ int __init io_apic_get_unique_id (int ioapic, int apic_id) ...@@ -2290,27 +2290,27 @@ int __init io_apic_get_unique_id (int ioapic, int apic_id)
int __init io_apic_get_version (int ioapic) int __init io_apic_get_version (int ioapic)
{ {
struct IO_APIC_reg_01 reg_01; union IO_APIC_reg_01 reg_01;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&ioapic_lock, flags); spin_lock_irqsave(&ioapic_lock, flags);
*(int *)&reg_01 = io_apic_read(ioapic, 1); reg_01.raw = io_apic_read(ioapic, 1);
spin_unlock_irqrestore(&ioapic_lock, flags); spin_unlock_irqrestore(&ioapic_lock, flags);
return reg_01.version; return reg_01.bits.version;
} }
int __init io_apic_get_redir_entries (int ioapic) int __init io_apic_get_redir_entries (int ioapic)
{ {
struct IO_APIC_reg_01 reg_01; union IO_APIC_reg_01 reg_01;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&ioapic_lock, flags); spin_lock_irqsave(&ioapic_lock, flags);
*(int *)&reg_01 = io_apic_read(ioapic, 1); reg_01.raw = io_apic_read(ioapic, 1);
spin_unlock_irqrestore(&ioapic_lock, flags); spin_unlock_irqrestore(&ioapic_lock, flags);
return reg_01.entries; return reg_01.bits.entries;
} }
......
...@@ -22,32 +22,44 @@ ...@@ -22,32 +22,44 @@
/* /*
* The structure of the IO-APIC: * The structure of the IO-APIC:
*/ */
struct IO_APIC_reg_00 { union IO_APIC_reg_00 {
__u32 __reserved_2 : 14, u32 raw;
LTS : 1, struct {
delivery_type : 1, u32 __reserved_2 : 14,
__reserved_1 : 8, LTS : 1,
ID : 8; delivery_type : 1,
} __attribute__ ((packed)); __reserved_1 : 8,
ID : 8;
} __attribute__ ((packed)) bits;
};
struct IO_APIC_reg_01 { union IO_APIC_reg_01 {
__u32 version : 8, u32 raw;
__reserved_2 : 7, struct {
PRQ : 1, u32 version : 8,
entries : 8, __reserved_2 : 7,
__reserved_1 : 8; PRQ : 1,
} __attribute__ ((packed)); entries : 8,
__reserved_1 : 8;
} __attribute__ ((packed)) bits;
};
struct IO_APIC_reg_02 { union IO_APIC_reg_02 {
__u32 __reserved_2 : 24, u32 raw;
arbitration : 4, struct {
__reserved_1 : 4; u32 __reserved_2 : 24,
} __attribute__ ((packed)); arbitration : 4,
__reserved_1 : 4;
} __attribute__ ((packed)) bits;
};
struct IO_APIC_reg_03 { union IO_APIC_reg_03 {
__u32 boot_DT : 1, u32 raw;
__reserved_1 : 31; struct {
} __attribute__ ((packed)); u32 boot_DT : 1,
__reserved_1 : 31;
} __attribute__ ((packed)) bits;
};
/* /*
* # of IO-APICs and # of IRQ routing registers * # of IO-APICs and # of IRQ routing registers
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment