Index: arch/ia32/include/smp/apic.h
===================================================================
--- arch/ia32/include/smp/apic.h	(revision 8418c7d1885256e7d6e4cb637e377cbb2a1be321)
+++ arch/ia32/include/smp/apic.h	(revision f701b236f5ebbb10720568819a088c22b50a3475)
@@ -71,4 +71,18 @@
 #define POLARITY_HIGH	0x0
 #define POLARITY_LOW	0x1
+
+/** Divide Values. (Bit 2 is always 0) */
+#define DIVIDE_2	0x0
+#define DIVIDE_4	0x1
+#define DIVIDE_8	0x2
+#define DIVIDE_16	0x3
+#define DIVIDE_32	0x8
+#define DIVIDE_64	0x9
+#define DIVIDE_128	0xa
+#define DIVIDE_1	0xb
+
+/** Timer Modes. */
+#define TIMER_ONESHOT	0x0
+#define TIMER_PERIODIC	0x1
 
 #define SEND_PENDING	(1<<12)
@@ -106,7 +120,22 @@
 #define EOI		(0x0b0/sizeof(__u32))
 
-/* Error Status Register */
+/** Error Status Register. */
 #define ESR		(0x280/sizeof(__u32))
-#define ESRClear	((0xffffff<<8)|(1<<4))
+union esr {
+	__u32 value;
+	__u8 err_bitmap;
+	struct {
+		unsigned send_checksum_error : 1;
+		unsigned receive_checksum_error : 1;
+		unsigned send_accept_error : 1;
+		unsigned receive_accept_error : 1;
+		unsigned : 1;
+		unsigned send_illegal_vector : 1;
+		unsigned received_illegal_vector : 1;
+		unsigned illegal_register_address : 1;
+		unsigned : 24;
+	} __attribute__ ((packed));
+};
+typedef union esr esr_t;
 
 /* Task Priority Register */
@@ -127,7 +156,14 @@
 typedef union svr svr_t;
 
-/* Time Divide Configuration Register */
+/** Time Divide Configuration Register. */
 #define TDCR		(0x3e0/sizeof(__u32))
-#define TDCRClear	(~0xb)
+union tdcr {
+	__u32 value;
+	struct {
+		unsigned div_value : 4;		/**< Divide Value, bit 2 is always 0. */
+		unsigned : 28;			/**< Reserved. */
+	} __attribute__ ((packed));
+};
+typedef union tdcr tdcr_t;
 
 /* Initial Count Register for Timer */
@@ -136,8 +172,4 @@
 /* Current Count Register for Timer */
 #define CCRT		(0x390/sizeof(__u32))
-
-/** Timer Modes. */
-#define TIMER_ONESHOT	0x0
-#define TIMER_PERIODIC	0x1
 
 /** LVT Timer register. */
@@ -191,12 +223,14 @@
 typedef union lvt_error lvt_error_t;
 
-
-#define LVT_PCINT	(0x340/sizeof(__u32))
-
-/* Local APIC ID Register */
+/** 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
+union lapic_id {
+	__u32 value;
+	struct {
+		unsigned : 24;		/**< Reserved. */
+		__u8 apic_id;		/**< Local APIC ID. */
+	} __attribute__ ((packed));
+};
+typedef union lapic_id lapic_id_t;
 
 /* Local APIC Version Register */
@@ -215,4 +249,14 @@
 #define IOAPICARB	0x02
 #define IOREDTBL	0x10
+
+/** I/O Register Select Register. */
+union io_regsel {
+	__u32 value;
+	struct {
+		__u8 reg_addr;		/**< APIC Register Address. */
+		unsigned : 24;		/**< Reserved. */
+	} __attribute__ ((packed));
+};
+typedef union io_regsel io_regsel_t;
 
 /** I/O Redirection Register. */
@@ -262,5 +306,5 @@
 extern __u32 io_apic_read(__u8 address);
 extern void io_apic_write(__u8 address , __u32 x);
-extern void io_apic_change_ioredtbl(int signal, int dest, __u8 v, int flags);
+extern void io_apic_change_ioredtbl(int pin, int dest, __u8 v, int flags);
 extern void io_apic_disable_irqs(__u16 irqmask);
 extern void io_apic_enable_irqs(__u16 irqmask);
Index: arch/ia32/src/drivers/i8254.c
===================================================================
--- arch/ia32/src/drivers/i8254.c	(revision 8418c7d1885256e7d6e4cb637e377cbb2a1be321)
+++ arch/ia32/src/drivers/i8254.c	(revision f701b236f5ebbb10720568819a088c22b50a3475)
@@ -61,8 +61,8 @@
 {
 	outb(CLK_PORT4, 0x36);
-	trap_virtual_disable_irqs(1<<IRQ_CLK);
+	pic_disable_irqs(1<<IRQ_CLK);
 	outb(CLK_PORT1, (CLK_CONST/HZ) & 0xf);
 	outb(CLK_PORT1, (CLK_CONST/HZ) >> 8);
-	trap_virtual_enable_irqs(1<<IRQ_CLK);
+	pic_enable_irqs(1<<IRQ_CLK);
 	trap_register(VECTOR_CLK, i8254_interrupt);
 }
Index: arch/ia32/src/ia32.c
===================================================================
--- arch/ia32/src/ia32.c	(revision 8418c7d1885256e7d6e4cb637e377cbb2a1be321)
+++ arch/ia32/src/ia32.c	(revision f701b236f5ebbb10720568819a088c22b50a3475)
@@ -95,4 +95,10 @@
 {
 	i8254_calibrate_delay_loop();
-	i8254_normal_operation();
+	if (config.cpu_active == 1) {
+		/*
+		 * This has to be done only on UP.
+		 * On SMP, i8254 is not used for time keeping and its interrupt pin remains masked.
+		 */
+		i8254_normal_operation();
+	}
 }
Index: arch/ia32/src/smp/apic.c
===================================================================
--- arch/ia32/src/smp/apic.c	(revision 8418c7d1885256e7d6e4cb637e377cbb2a1be321)
+++ arch/ia32/src/smp/apic.c	(revision f701b236f5ebbb10720568819a088c22b50a3475)
@@ -63,5 +63,46 @@
 __u32 apic_id_mask = 0;
 
-int apic_poll_errors(void);
+static int apic_poll_errors(void);
+
+static char *delmod_str[] = {
+	"Fixed",
+	"Lowest Priority",
+	"SMI",
+	"Reserved",
+	"NMI",
+	"INIT",
+	"STARTUP",
+	"ExtInt"
+};
+
+static char *destmod_str[] = {
+	"Physical",
+	"Logical"
+};
+
+static char *trigmod_str[] = {
+	"Edge",
+	"Level"
+};
+
+static char *mask_str[] = {
+	"Unmasked",
+	"Masked"
+};
+
+static char *delivs_str[] = {
+	"Idle",
+	"Send Pending"
+};
+
+static char *tm_mode_str[] = {
+	"One-shot",
+	"Periodic"
+};
+
+static char *intpol_str[] = {
+	"Polarity High",
+	"Polarity Low"
+};
 
 /** Initialize APIC on BSP. */
@@ -115,4 +156,9 @@
 }
 
+/** APIC spurious interrupt handler.
+ *
+ * @param n Interrupt vector.
+ * @param stack Interrupted stack.
+ */
 void apic_spurious(__u8 n, __native stack[])
 {
@@ -120,30 +166,39 @@
 }
 
+/** Poll for APIC errors.
+ *
+ * Examine Error Status Register and report all errors found.
+ *
+ * @return 0 on error, 1 on success.
+ */
 int apic_poll_errors(void)
 {
-	__u32 esr;
-	
-	esr = l_apic[ESR] & ~ESRClear;
-	
-	if ((esr>>0) & 1)
+	esr_t esr;
+	
+	esr.value = l_apic[ESR];
+	
+	if (esr.send_checksum_error)
 		printf("Send CS Error\n");
-	if ((esr>>1) & 1)
+	if (esr.receive_checksum_error)
 		printf("Receive CS Error\n");
-	if ((esr>>2) & 1)
+	if (esr.send_accept_error)
 		printf("Send Accept Error\n");
-	if ((esr>>3) & 1)
+	if (esr.receive_accept_error)
 		printf("Receive Accept Error\n");
-	if ((esr>>5) & 1)
+	if (esr.send_illegal_vector)
 		printf("Send Illegal Vector\n");
-	if ((esr>>6) & 1)
+	if (esr.received_illegal_vector)
 		printf("Received Illegal Vector\n");
-	if ((esr>>7) & 1)
+	if (esr.illegal_register_address)
 		printf("Illegal Register Address\n");
 
-	return !esr;
-}
-
-/*
- * Send all CPUs excluding CPU IPI vector.
+	return !esr.err_bitmap;
+}
+
+/** Send all CPUs excluding CPU IPI vector.
+ *
+ * @param vector Interrupt vector to be sent.
+ *
+ * @return 0 on failure, 1 on success.
  */
 int l_apic_broadcast_custom_ipi(__u8 vector)
@@ -168,6 +223,9 @@
 }
 
-/*
- * Universal Start-up Algorithm for bringing up the AP processors.
+/** Universal Start-up Algorithm for bringing up the AP processors.
+ *
+ * @param apicid APIC ID of the processor to be brought up.
+ *
+ * @return 0 on failure, 1 on success.
  */
 int l_apic_send_init_ipi(__u8 apicid)
@@ -239,4 +297,5 @@
 }
 
+/** Initialize Local APIC. */
 void l_apic_init(void)
 {
@@ -244,6 +303,7 @@
 	lvt_lint_t lint;
 	svr_t svr;
+	icr_t icr;
+	tdcr_t tdcr;
 	lvt_tm_t tm;
-	icr_t icr;
 	__u32 t1, t2;
 
@@ -283,11 +343,10 @@
 	l_apic[ICRlo] = icr.lo;
 	
-	/*
-	 * Program the timer for periodic mode and respective vector.
-	 */
-
-	l_apic[TDCR] &= TDCRClear;
-	l_apic[TDCR] |= 0xb;
-
+	/* Timer Divide Configuration Register initialization. */
+	tdcr.value = l_apic[TDCR];
+	tdcr.div_value = DIVIDE_1;
+	l_apic[TDCR] = tdcr.value;
+
+	/* Program local timer. */
 	tm.value = l_apic[LVT_Tm];
 	tm.vector = VECTOR_CLK;
@@ -296,4 +355,5 @@
 	l_apic[LVT_Tm] = tm.value;
 
+	/* Measure and configure the timer to generate timer interrupt each ms. */
 	t1 = l_apic[CCRT];
 	l_apic[ICRT] = 0xffffffff;
@@ -310,4 +370,5 @@
 }
 
+/** Local APIC End of Interrupt. */
 void l_apic_eoi(void)
 {
@@ -315,58 +376,30 @@
 }
 
+/** Dump content of Local APIC registers. */
 void l_apic_debug(void)
 {
 #ifdef LAPIC_VERBOSE
-	int i, lint;
-
+	lvt_tm_t tm;
+	lvt_lint_t lint;
+	lvt_error_t error;	
+	
 	printf("LVT on cpu%d, LAPIC ID: %d\n", CPU->id, l_apic_id());
 
-	printf("LVT_Tm: ");
-	if (l_apic[LVT_Tm] & (1<<17)) printf("periodic"); else printf("one-shot"); putchar(',');	
-	if (l_apic[LVT_Tm] & (1<<16)) printf("masked");	else printf("not masked"); putchar(',');
-	if (l_apic[LVT_Tm] & (1<<12)) printf("send pending"); else printf("idle"); putchar(',');
-	printf("%B\n", l_apic[LVT_Tm] & 0xff);
-	
-	for (i=0; i<2; i++) {
-		lint = i ? LVT_LINT1 : LVT_LINT0;
-		printf("LVT_LINT%d: ", i);
-		if (l_apic[lint] & (1<<16)) printf("masked"); else printf("not masked"); putchar(',');
-		if (l_apic[lint] & (1<<15)) printf("level"); else printf("edge"); putchar(',');
-		printf("%d", l_apic[lint] & (1<<14)); putchar(',');
-		printf("%d", l_apic[lint] & (1<<13)); putchar(',');
-		if (l_apic[lint] & (1<<12)) printf("send pending"); else printf("idle"); putchar(',');
-	
-		switch ((l_apic[lint]>>8)&7) {
-		    case 0: printf("fixed"); break;
-		    case 4: printf("NMI"); break;
-		    case 7: printf("ExtINT"); break;
-		}
-		putchar(',');
-		printf("%B\n", l_apic[lint] & 0xff);	
-	}
-
-	printf("LVT_Err: ");
-	if (l_apic[LVT_Err] & (1<<16)) printf("masked"); else printf("not masked"); putchar(',');
-	if (l_apic[LVT_Err] & (1<<12)) printf("send pending"); else printf("idle"); putchar(',');
-	printf("%B\n", l_apic[LVT_Err] & 0xff);	
-
-	/*
-	 * This register is supported only on P6 and higher.
-	 */
-	if (CPU->arch.family > 5) {
-		printf("LVT_PCINT: ");
-		if (l_apic[LVT_PCINT] & (1<<16)) printf("masked"); else printf("not masked"); putchar(',');
-		if (l_apic[LVT_PCINT] & (1<<12)) printf("send pending"); else printf("idle"); putchar(',');
-		switch ((l_apic[LVT_PCINT] >> 8)&7) {
-		    case 0: printf("fixed"); break;
-		    case 4: printf("NMI"); break;
-		    case 7: printf("ExtINT"); break;
-		}
-		putchar(',');
-		printf("%B\n", l_apic[LVT_PCINT] & 0xff);
-	}
+	tm.value = l_apic[LVT_Tm];
+	printf("LVT Tm: vector=%B, %s, %s, %s\n", tm.vector, delivs_str[tm.delivs], mask_str[tm.masked], tm_mode_str[tm.mode]);
+	lint.value = l_apic[LVT_LINT0];
+	printf("LVT LINT0: vector=%B, %s, %s, %s, irr=%d, %s, %s\n", tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], mask_str[lint.masked]);
+	lint.value = l_apic[LVT_LINT1];	
+	printf("LVT LINT1: vector=%B, %s, %s, %s, irr=%d, %s, %s\n", tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], mask_str[lint.masked]);	
+	error.value = l_apic[LVT_Err];
+	printf("LVT Err: vector=%B, %s, %s\n", error.vector, delivs_str[error.delivs], mask_str[error.masked]);
 #endif
 }
 
+/** Local APIC Timer Interrupt.
+ *
+ * @param n Interrupt vector number.
+ * @param stack Interrupted stack.
+ */
 void l_apic_timer_interrupt(__u8 n, __native stack[])
 {
@@ -375,31 +408,58 @@
 }
 
+/** Get Local APIC ID.
+ *
+ * @return Local APIC ID.
+ */
 __u8 l_apic_id(void)
 {
-	return (l_apic[L_APIC_ID] >> L_APIC_IDShift)&L_APIC_IDMask;
-}
-
+	lapic_id_t lapic_id;
+	
+	lapic_id.value = l_apic[L_APIC_ID];
+	return lapic_id.apic_id;
+}
+
+/** Read from IO APIC register.
+ *
+ * @param address IO APIC register address.
+ *
+ * @return Content of the addressed IO APIC register.
+ */
 __u32 io_apic_read(__u8 address)
 {
-	__u32 tmp;
-	
-	tmp = io_apic[IOREGSEL] & ~0xf;
-	io_apic[IOREGSEL] = tmp | address;
+	io_regsel_t regsel;
+	
+	regsel.value = io_apic[IOREGSEL];
+	regsel.reg_addr = address;
+	io_apic[IOREGSEL] = regsel.value;
 	return io_apic[IOWIN];
 }
 
+/** Write to IO APIC register.
+ *
+ * @param address IO APIC register address.
+ * @param Content to be written to the addressed IO APIC register.
+ */
 void io_apic_write(__u8 address, __u32 x)
 {
-	__u32 tmp;
-
-	tmp = io_apic[IOREGSEL] & ~0xf;
-	io_apic[IOREGSEL] = tmp | address;
+	io_regsel_t regsel;
+	
+	regsel.value = io_apic[IOREGSEL];
+	regsel.reg_addr = address;
+	io_apic[IOREGSEL] = regsel.value;
 	io_apic[IOWIN] = x;
 }
 
-void io_apic_change_ioredtbl(int signal, int dest, __u8 v, int flags)
+/** Change some attributes of one item in I/O Redirection Table.
+ *
+ * @param pin IO APIC pin number.
+ * @param dest Interrupt destination address.
+ * @param v Interrupt vector to trigger.
+ * @param flags Flags.
+ */
+void io_apic_change_ioredtbl(int pin, int dest, __u8 v, int flags)
 {
 	io_redirection_reg_t reg;
-	int dlvr = 0;
+	int dlvr = DELMOD_FIXED;
 	
 	if (flags & LOPRI)
@@ -407,6 +467,6 @@
 
 	
-	reg.lo = io_apic_read(IOREDTBL + signal*2);
-	reg.hi = io_apic_read(IOREDTBL + signal*2 + 1);
+	reg.lo = io_apic_read(IOREDTBL + pin*2);
+	reg.hi = io_apic_read(IOREDTBL + pin*2 + 1);
 	
 	reg.dest =  dest;
@@ -417,8 +477,12 @@
 	reg.intvec = v;
 
-	io_apic_write(IOREDTBL + signal*2, reg.lo);
-	io_apic_write(IOREDTBL + signal*2 + 1, reg.hi);
-}
-
+	io_apic_write(IOREDTBL + pin*2, reg.lo);
+	io_apic_write(IOREDTBL + pin*2 + 1, reg.hi);
+}
+
+/** Mask IRQs in IO APIC.
+ *
+ * @param irqmask Bitmask of IRQs to be masked (0 = do not mask, 1 = mask).
+ */
 void io_apic_disable_irqs(__u16 irqmask)
 {
@@ -443,4 +507,8 @@
 }
 
+/** Unmask IRQs in IO APIC.
+ *
+ * @param irqmask Bitmask of IRQs to be unmasked (0 = do not unmask, 1 = unmask).
+ */
 void io_apic_enable_irqs(__u16 irqmask)
 {
