Index: arch/ia32/include/smp/apic.h
===================================================================
--- arch/ia32/include/smp/apic.h	(revision a83a80223db1510dfc272b8db5ac5069371b7b25)
+++ arch/ia32/include/smp/apic.h	(revision 8418c7d1885256e7d6e4cb637e377cbb2a1be321)
@@ -40,79 +40,4 @@
 #define IPI_STARTUP	0
 
-#define DLVRMODE_FIXED	(0<<8)
-#define DLVRMODE_INIT	(5<<8)
-#define DLVRMODE_STUP	(6<<8)
-#define DESTMODE_PHYS	(0<<11)
-#define DESTMODE_LOGIC	(1<<11)
-#define LEVEL_ASSERT	(1<<14)
-#define LEVEL_DEASSERT	(0<<14)
-#define TRGRMODE_LEVEL	(1<<15)
-#define TRGRMODE_EDGE	(0<<15)
-#define SHORTHAND_DEST	(0<<18)
-#define SHORTHAND_INCL	(2<<18)
-#define SHORTHAND_EXCL	(3<<18)
-
-#define SEND_PENDING	(1<<12)
-
-/* Interrupt Command Register */
-#define ICRlo		(0x300/sizeof(__u32))
-#define ICRhi		(0x310/sizeof(__u32))
-#define ICRloClear	((1<<13)|(3<<16)|(0xfff<<20))
-#define ICRhiClear	(0xffffff<<0)
-
-/* End Of Interrupt */
-#define EOI		(0x0b0/sizeof(__u32))
-
-/* Error Status Register */
-#define ESR		(0x280/sizeof(__u32))
-#define ESRClear	((0xffffff<<8)|(1<<4))
-
-/* Task Priority Register */
-#define TPR		(0x080/sizeof(__u32))
-#define TPRClear	0xffffff00
-
-/* Spurious Vector Register */
-#define SVR		(0x0f0/sizeof(__u32))
-#define SVRClear	(~0x3f0)
-
-/* Time Divide Configuratio Register */
-#define TDCR		(0x3e0/sizeof(__u32))
-#define TDCRClear	(~0xb)
-
-/* Initial Count Register for Timer */
-#define ICRT		(0x380/sizeof(__u32))
-
-/* Current Count Register for Timer */
-#define CCRT		(0x390/sizeof(__u32))
-
-/* LVT */
-#define LVT_Tm		(0x320/sizeof(__u32))
-#define LVT_LINT0	(0x350/sizeof(__u32))
-#define LVT_LINT1	(0x360/sizeof(__u32))
-#define LVT_Err		(0x370/sizeof(__u32))
-#define LVT_PCINT	(0x340/sizeof(__u32))
-
-/* Local APIC ID Register */
-#define L_APIC_ID	(0x020/sizeof(__u32))
-#define L_APIC_IDClear	(~(0xf<<24))
-#define L_APIC_IDShift	24
-#define L_APIC_IDMask	0xf
-
-/* Local APIC Version Register */
-#define LAVR		(0x030/sizeof(__u32))
-#define LAVR_Mask	0xff
-#define is_local_apic(x)	(((x)&LAVR_Mask&0xf0)==0x1)
-#define is_82489DX_apic(x)	((((x)&LAVR_Mask&0xf0)==0x0))
-#define is_local_xapic(x)	(((x)&LAVR_Mask)==0x14)
-
-/* IO APIC */
-#define IOREGSEL	(0x00/sizeof(__u32))
-#define IOWIN		(0x10/sizeof(__u32))
-
-#define IOAPICID	0x00
-#define IOAPICVER	0x01
-#define IOAPICARB	0x02
-#define IOREDTBL	0x10
-
 /** Delivery modes. */
 #define DELMOD_FIXED	0x0
@@ -122,5 +47,5 @@
 #define DELMOD_NMI	0x4
 #define DELMOD_INIT	0x5
-/* 0x6 reserved */
+#define DELMOD_STARTUP	0x6
 #define DELMOD_EXTINT	0x7
 
@@ -133,8 +58,162 @@
 #define TRIGMOD_LEVEL	0x1
 
+/** Levels. */
+#define LEVEL_DEASSERT	0x0
+#define LEVEL_ASSERT	0x1
+
+/** Destination Shorthands. */
+#define SHORTHAND_NONE		0x0
+#define SHORTHAND_SELF		0x1
+#define SHORTHAND_ALL_INCL	0x2
+#define SHORTHAND_ALL_EXCL	0x3
+
 /** Interrupt Input Pin Polarities. */
 #define POLARITY_HIGH	0x0
 #define POLARITY_LOW	0x1
 
+#define SEND_PENDING	(1<<12)
+
+/** Interrupt Command Register. */
+#define ICRlo		(0x300/sizeof(__u32))
+#define ICRhi		(0x310/sizeof(__u32))
+struct icr {
+	union {
+		__u32 lo;
+		struct {
+			__u8 vector;			/**< Interrupt Vector. */
+			unsigned delmod : 3;		/**< Delivery Mode. */
+			unsigned destmod : 1;		/**< Destination Mode. */
+			unsigned delivs : 1;		/**< Delivery status (RO). */
+			unsigned : 1;			/**< Reserved. */
+			unsigned level : 1;		/**< Level. */
+			unsigned trigger_mode : 1;	/**< Trigger Mode. */
+			unsigned : 2;			/**< Reserved. */
+			unsigned shorthand : 2;		/**< Destination Shorthand. */
+			unsigned : 12;			/**< Reserved. */
+		} __attribute__ ((packed));
+	};
+	union {
+		__u32 hi;
+		struct {
+			unsigned : 24;			/**< Reserved. */
+			__u8 dest;			/**< Destination field. */
+		} __attribute__ ((packed));
+	};
+} __attribute__ ((packed));
+typedef struct icr icr_t;
+
+/* End Of Interrupt */
+#define EOI		(0x0b0/sizeof(__u32))
+
+/* Error Status Register */
+#define ESR		(0x280/sizeof(__u32))
+#define ESRClear	((0xffffff<<8)|(1<<4))
+
+/* Task Priority Register */
+#define TPR		(0x080/sizeof(__u32))
+#define TPRClear	0xffffff00
+
+/** Spurious-Interrupt Vector Register. */
+#define SVR		(0x0f0/sizeof(__u32))
+union svr {
+	__u32 value;
+	struct {
+		__u8 vector;			/**< Spurious Vector */
+		unsigned lapic_enabled : 1;	/**< APIC Software Enable/Disable */
+		unsigned focus_checking : 1;	/**< Focus Processor Checking */
+		unsigned : 22;			/**< Reserved. */
+	} __attribute__ ((packed));
+};
+typedef union svr svr_t;
+
+/* Time Divide Configuration Register */
+#define TDCR		(0x3e0/sizeof(__u32))
+#define TDCRClear	(~0xb)
+
+/* Initial Count Register for Timer */
+#define ICRT		(0x380/sizeof(__u32))
+
+/* Current Count Register for Timer */
+#define CCRT		(0x390/sizeof(__u32))
+
+/** Timer Modes. */
+#define TIMER_ONESHOT	0x0
+#define TIMER_PERIODIC	0x1
+
+/** LVT Timer register. */
+#define LVT_Tm		(0x320/sizeof(__u32))
+union lvt_tm {
+	__u32 value;
+	struct {
+		__u8 vector;		/**< Local Timer Interrupt vector. */
+		unsigned : 4;		/**< Reserved. */
+		unsigned delivs : 1;	/**< Delivery status (RO). */
+		unsigned : 3;		/**< Reserved. */
+		unsigned masked : 1;	/**< Interrupt Mask. */
+		unsigned mode : 1;	/**< Timer Mode. */
+		unsigned : 14;		/**< Reserved. */
+	} __attribute__ ((packed));
+};
+typedef union lvt_tm lvt_tm_t;
+
+/** LVT LINT registers. */
+#define LVT_LINT0	(0x350/sizeof(__u32))
+#define LVT_LINT1	(0x360/sizeof(__u32))
+union lvt_lint {
+	__u32 value;
+	struct {
+		__u8 vector;			/**< LINT Interrupt vector. */
+		unsigned delmod : 3;		/**< Delivery Mode. */
+		unsigned : 1;			/**< Reserved. */
+		unsigned delivs : 1;		/**< Delivery status (RO). */
+		unsigned intpol : 1;		/**< Interrupt Input Pin Polarity. */
+		unsigned irr : 1;		/**< Remote IRR (RO). */
+		unsigned trigger_mode : 1;	/**< Trigger Mode. */
+		unsigned masked : 1;		/**< Interrupt Mask. */
+		unsigned : 15;			/**< Reserved. */
+	} __attribute__ ((packed));
+};
+typedef union lvt_lint lvt_lint_t;
+
+/** LVT Error register. */
+#define LVT_Err		(0x370/sizeof(__u32))
+union lvt_error {
+	__u32 value;
+	struct {
+		__u8 vector;		/**< Local Timer Interrupt vector. */
+		unsigned : 4;		/**< Reserved. */
+		unsigned delivs : 1;	/**< Delivery status (RO). */
+		unsigned : 3;		/**< Reserved. */
+		unsigned masked : 1;	/**< Interrupt Mask. */
+		unsigned : 15;		/**< Reserved. */
+	} __attribute__ ((packed));
+};
+typedef union lvt_error lvt_error_t;
+
+
+#define LVT_PCINT	(0x340/sizeof(__u32))
+
+/* Local APIC ID Register */
+#define L_APIC_ID	(0x020/sizeof(__u32))
+#define L_APIC_IDClear	(~(0xf<<24))
+#define L_APIC_IDShift	24
+#define L_APIC_IDMask	0xf
+
+/* Local APIC Version Register */
+#define LAVR		(0x030/sizeof(__u32))
+#define LAVR_Mask	0xff
+#define is_local_apic(x)	(((x)&LAVR_Mask&0xf0)==0x1)
+#define is_82489DX_apic(x)	((((x)&LAVR_Mask&0xf0)==0x0))
+#define is_local_xapic(x)	(((x)&LAVR_Mask)==0x14)
+
+/* IO APIC */
+#define IOREGSEL	(0x00/sizeof(__u32))
+#define IOWIN		(0x10/sizeof(__u32))
+
+#define IOAPICID	0x00
+#define IOAPICVER	0x01
+#define IOAPICARB	0x02
+#define IOREDTBL	0x10
+
 /** I/O Redirection Register. */
 struct io_redirection_reg {
@@ -142,5 +221,5 @@
 		__u32 lo;
 		struct {
-			unsigned intvec : 8;		/**< Interrupt Vector. */
+			__u8 intvec;			/**< Interrupt Vector. */
 			unsigned delmod : 3;		/**< Delivery Mode. */
 			unsigned destmod : 1; 		/**< Destination mode. */
@@ -151,5 +230,5 @@
 			unsigned masked : 1;		/**< Interrupt Mask. */
 			unsigned : 15;			/**< Reserved. */
-		};
+		} __attribute__ ((packed));
 	};
 	union {
@@ -157,6 +236,6 @@
 		struct {
 			unsigned : 24;			/**< Reserved. */
-			unsigned dest : 8;		/**< Destination Field. */
-		};
+			__u8 dest : 8;		/**< Destination Field. */
+		} __attribute__ ((packed));
 	};
 	
Index: arch/ia32/src/smp/apic.c
===================================================================
--- arch/ia32/src/smp/apic.c	(revision a83a80223db1510dfc272b8db5ac5069371b7b25)
+++ arch/ia32/src/smp/apic.c	(revision 8418c7d1885256e7d6e4cb637e377cbb2a1be321)
@@ -44,5 +44,5 @@
  * Tested on:
  *	Bochs 2.0.2 - Bochs 2.2 with 2-8 CPUs
- *	Simics 2.0.28 - Simics 2.2.14 2-4 CPUs
+ *	Simics 2.0.28 - Simics 2.2.19 2-8 CPUs
  *	ASUS P/I-P65UP5 + ASUS C-P55T2D REV. 1.41 with 2x 200Mhz Pentium CPUs
  *	ASUS PCH-DL with 2x 3000Mhz Pentium 4 Xeon (HT) CPUs
@@ -65,4 +65,5 @@
 int apic_poll_errors(void);
 
+/** Initialize APIC on BSP. */
 void apic_init(void)
 {
@@ -86,5 +87,5 @@
 	
 		if ((pin = smp_irq_to_pin(i)) != -1) {
-			io_apic_change_ioredtbl(pin,0xff,IVT_IRQBASE+i,LOPRI);
+			io_apic_change_ioredtbl(pin, 0xff, IVT_IRQBASE+i, LOPRI);
 		}
 	}
@@ -148,17 +149,18 @@
 int l_apic_broadcast_custom_ipi(__u8 vector)
 {
-	__u32 lo;
-
-	/*
-	 * Read the ICR register in and zero all non-reserved fields.
-	 */
-	lo = l_apic[ICRlo] & ICRloClear;
-
-	lo |= DLVRMODE_FIXED | DESTMODE_LOGIC | LEVEL_ASSERT | SHORTHAND_EXCL | TRGRMODE_LEVEL | vector;
-	
-	l_apic[ICRlo] = lo;
-
-	lo = l_apic[ICRlo] & ICRloClear;
-	if (lo & SEND_PENDING)
+	icr_t icr;
+
+	icr.lo = l_apic[ICRlo];
+	icr.delmod = DELMOD_FIXED;
+	icr.destmod = DESTMOD_LOGIC;
+	icr.level = LEVEL_ASSERT;
+	icr.shorthand = SHORTHAND_ALL_EXCL;
+	icr.trigger_mode = TRIGMOD_LEVEL;
+	icr.vector = vector;
+
+	l_apic[ICRlo] = icr.lo;
+
+	icr.lo = l_apic[ICRlo];
+	if (icr.lo & SEND_PENDING)
 		printf("IPI is pending.\n");
 
@@ -171,5 +173,5 @@
 int l_apic_send_init_ipi(__u8 apicid)
 {
-	__u32 lo, hi;
+	icr_t icr;
 	int i;
 
@@ -177,12 +179,17 @@
 	 * Read the ICR register in and zero all non-reserved fields.
 	 */
-	lo = l_apic[ICRlo] & ICRloClear;
-	hi = l_apic[ICRhi] & ICRhiClear;
-	
-	lo |= DLVRMODE_INIT | DESTMODE_PHYS | LEVEL_ASSERT | SHORTHAND_DEST | TRGRMODE_LEVEL;
-	hi |= apicid << 24;
-	
-	l_apic[ICRhi] = hi;
-	l_apic[ICRlo] = lo;
+	icr.lo = l_apic[ICRlo];
+	icr.hi = l_apic[ICRhi];
+	
+	icr.delmod = DELMOD_INIT;
+	icr.destmod = DESTMOD_PHYS;
+	icr.level = LEVEL_ASSERT;
+	icr.trigger_mode = TRIGMOD_LEVEL;
+	icr.shorthand = SHORTHAND_NONE;
+	icr.vector = 0;
+	icr.dest = apicid;
+	
+	l_apic[ICRhi] = icr.hi;
+	l_apic[ICRlo] = icr.lo;
 
 	/*
@@ -194,9 +201,15 @@
 	if (!apic_poll_errors()) return 0;
 
-	lo = l_apic[ICRlo] & ICRloClear;
-	if (lo & SEND_PENDING)
+	icr.lo = l_apic[ICRlo];
+	if (icr.lo & SEND_PENDING)
 		printf("IPI is pending.\n");
 
-	l_apic[ICRlo] = lo | DLVRMODE_INIT | DESTMODE_PHYS | LEVEL_DEASSERT | SHORTHAND_DEST | TRGRMODE_LEVEL;
+	icr.delmod = DELMOD_INIT;
+	icr.destmod = DESTMOD_PHYS;
+	icr.level = LEVEL_DEASSERT;
+	icr.shorthand = SHORTHAND_NONE;
+	icr.trigger_mode = TRIGMOD_LEVEL;
+	icr.vector = 0;
+	l_apic[ICRlo] = icr.lo;
 
 	/*
@@ -210,7 +223,12 @@
 		 */
 		for (i = 0; i<2; i++) {
-			lo = l_apic[ICRlo] & ICRloClear;
-			lo |= ((__address) ap_boot) / 4096; /* calculate the reset vector */
-			l_apic[ICRlo] = lo | DLVRMODE_STUP | DESTMODE_PHYS | LEVEL_ASSERT | SHORTHAND_DEST | TRGRMODE_LEVEL;
+			icr.lo = l_apic[ICRlo];
+			icr.vector = ((__address) ap_boot) / 4096; /* calculate the reset vector */
+			icr.delmod = DELMOD_STARTUP;
+			icr.destmod = DESTMOD_PHYS;
+			icr.level = LEVEL_ASSERT;
+			icr.shorthand = SHORTHAND_NONE;
+			icr.trigger_mode = TRIGMOD_LEVEL;
+			l_apic[ICRlo] = icr.lo;
 			delay(200);
 		}
@@ -223,12 +241,31 @@
 void l_apic_init(void)
 {
-	__u32 tmp, t1, t2;
-
-	l_apic[LVT_Err] |= (1<<16);
-	l_apic[LVT_LINT0] |= (1<<16);
-	l_apic[LVT_LINT1] |= (1<<16);
-
-	tmp = l_apic[SVR] & SVRClear;
-	l_apic[SVR] = tmp | (1<<8) | (VECTOR_APIC_SPUR);
+	lvt_error_t error;
+	lvt_lint_t lint;
+	svr_t svr;
+	lvt_tm_t tm;
+	icr_t icr;
+	__u32 t1, t2;
+
+	/* Initialize LVT Error register. */
+	error.value = l_apic[LVT_Err];
+	error.masked = true;
+	l_apic[LVT_Err] = error.value;
+
+	/* Initialize LVT LINT0 register. */
+	lint.value = l_apic[LVT_LINT0];
+	lint.masked = true;
+	l_apic[LVT_LINT0] = lint.value;
+
+	/* Initialize LVT LINT1 register. */
+	lint.value = l_apic[LVT_LINT1];
+	lint.masked = true;
+	l_apic[LVT_LINT1] = lint.value;
+	
+	/* Spurious-Interrupt Vector Register initialization. */
+	svr.value = l_apic[SVR];
+	svr.vector = VECTOR_APIC_SPUR;
+	svr.lapic_enabled = true;
+	l_apic[SVR] = svr.value;
 
 	l_apic[TPR] &= TPRClear;
@@ -237,6 +274,12 @@
 		enable_l_apic_in_msr();
 	
-	tmp = l_apic[ICRlo] & ICRloClear;
-	l_apic[ICRlo] = tmp | DLVRMODE_INIT | DESTMODE_PHYS | LEVEL_DEASSERT | SHORTHAND_INCL | TRGRMODE_LEVEL;
+	/* Interrupt Command Register initialization. */
+	icr.lo = l_apic[ICRlo];
+	icr.delmod = DELMOD_INIT;
+	icr.destmod = DESTMOD_PHYS;
+	icr.level = LEVEL_DEASSERT;
+	icr.shorthand = SHORTHAND_ALL_INCL;
+	icr.trigger_mode = TRIGMOD_LEVEL;
+	l_apic[ICRlo] = icr.lo;
 	
 	/*
@@ -246,6 +289,10 @@
 	l_apic[TDCR] &= TDCRClear;
 	l_apic[TDCR] |= 0xb;
-	tmp = l_apic[LVT_Tm] | (1<<17) | (VECTOR_CLK);
-	l_apic[LVT_Tm] = tmp & ~(1<<16);
+
+	tm.value = l_apic[LVT_Tm];
+	tm.vector = VECTOR_CLK;
+	tm.mode = TIMER_PERIODIC;
+	tm.masked = false;
+	l_apic[LVT_Tm] = tm.value;
 
 	t1 = l_apic[CCRT];
