Index: arch/amd64/Makefile.inc
===================================================================
--- arch/amd64/Makefile.inc	(revision 9756131fa15f66c8ed4bfc1d5fccfc9dab372985)
+++ arch/amd64/Makefile.inc	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
@@ -21,3 +21,10 @@
 	arch/context.S \
 	arch/drivers/ega.c \
-	arch/supplib.c
+	arch/drivers/i8042.c \
+	arch/drivers/i8254.c \
+	arch/drivers/i8259.c \
+	arch/supplib.c \
+	arch/delay.S \
+	arch/amd64.c \
+	arch/bios/bios.c
+
Index: arch/amd64/include/asm.h
===================================================================
--- arch/amd64/include/asm.h	(revision 9756131fa15f66c8ed4bfc1d5fccfc9dab372985)
+++ arch/amd64/include/asm.h	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
@@ -35,4 +35,6 @@
 
 void asm_delay_loop(__u32 t);
+void asm_fake_loop(__u32 t);
+
 
 /* TODO: implement the real stuff */
@@ -55,5 +57,5 @@
 		:"=m"(out)
 		:"m"(port)
-		:"dx","al"
+		:"%dx","%al"
 		);
 	return out;
@@ -68,5 +70,5 @@
 		:
 		:"m"( port), "m" (b)
-		:"dx","al"
+		:"%dx","%al"
 		);
 }
@@ -116,4 +118,20 @@
 }
 
+/** Return raw priority level
+ *
+ * Return EFLAFS.
+ */
+static inline pri_t cpu_priority_read(void) {
+	pri_t v;
+	__asm__ volatile (
+		"pushfq\n"
+		"popq %0\n"
+		: "=r" (v)
+	);
+	return v;
+}
+
+extern size_t interrupt_handler_size;
+extern void interrupt_handlers(void);
 
 #endif
Index: arch/amd64/include/interrupt.h
===================================================================
--- arch/amd64/include/interrupt.h	(revision 9756131fa15f66c8ed4bfc1d5fccfc9dab372985)
+++ arch/amd64/include/interrupt.h	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
@@ -1,4 +1,4 @@
 /*
- * Copyright (C) 2005 Martin Decky
+ * Copyright (C) 2001-2004 Jakub Jermar
  * All rights reserved.
  *
@@ -27,8 +27,62 @@
  */
 
-#ifndef __amd64_INTERRUPT_H__
-#define __amd64_INTERRUPT_H__
+#ifndef __INTERRUPT_H__
+#define __INTERRUPT_H__
 
-extern void interrupt(void);
+#include <arch/types.h>
+#include <arch/pm.h>
+
+#define IVT_ITEMS		IDT_ITEMS
+
+#define IVT_EXCBASE		0
+#define EXCLAST			31
+
+#define IVT_IRQBASE		(IVT_EXCBASE+EXCLAST+1)
+#define IRQLAST			15
+
+#define IVT_FREEBASE		(IVT_IRQBASE+IRQLAST+1)
+
+#define IRQ_CLK		0
+#define IRQ_KBD		1
+#define IRQ_PIC1	2
+#define IRQ_PIC_SPUR	7
+
+/* this one must have four least significant bits set to ones */
+#define VECTOR_APIC_SPUR	(IVT_ITEMS-1)
+
+#if (((VECTOR_APIC_SPUR + 1)%16) || VECTOR_APIC_SPUR >= IVT_ITEMS)
+#error Wrong definition of VECTOR_APIC_SPUR
+#endif
+
+#define VECTOR_PIC_SPUR		(IVT_IRQBASE+IRQ_PIC_SPUR)
+#define VECTOR_CLK		(IVT_IRQBASE+IRQ_CLK)
+#define VECTOR_KBD		(IVT_IRQBASE+IRQ_KBD)
+
+#define VECTOR_SYSCALL			(IVT_FREEBASE+0)
+#define VECTOR_TLB_SHOOTDOWN_IPI	(IVT_FREEBASE+1)
+#define VECTOR_WAKEUP_IPI		(IVT_FREEBASE+2)
+
+typedef void (* iroutine)(__u8 n, __native stack[]);
+
+extern void (* disable_irqs_function)(__u16 irqmask);
+extern void (* enable_irqs_function)(__u16 irqmask);
+extern void (* eoi_function)(void);
+
+extern iroutine trap_register(__u8 n, iroutine f);
+
+extern void trap_dispatcher(__u8 n, __native stack[]);
+
+extern void null_interrupt(__u8 n, __native stack[]);
+extern void gp_fault(__u8 n, __native stack[]);
+extern void nm_fault(__u8 n, __native stack[]);
+extern void ss_fault(__u8 n, __native stack[]);
+extern void page_fault(__u8 n, __native stack[]);
+extern void syscall(__u8 n, __native stack[]);
+extern void tlb_shootdown_ipi(__u8 n, __native stack[]);
+extern void wakeup_ipi(__u8 n, __native stack[]);
+
+extern void trap_virtual_enable_irqs(__u16 irqmask);
+extern void trap_virtual_disable_irqs(__u16 irqmask);
+extern void trap_virtual_eoi(void);
 
 #endif
Index: arch/amd64/include/pm.h
===================================================================
--- arch/amd64/include/pm.h	(revision 9756131fa15f66c8ed4bfc1d5fccfc9dab372985)
+++ arch/amd64/include/pm.h	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
@@ -37,5 +37,5 @@
 
 #define IDT_ITEMS 64
-#define GDT_ITEMS 7
+#define GDT_ITEMS 8
 
 #define NULL_DES	0
@@ -47,5 +47,6 @@
 #define TSS_DES		6
 
-#define selector(des)	((des)<<3)
+#define gdtselector(des)	((des)<<3)
+#define idtselector(des)        ((des)<<4)
 
 #define PL_KERNEL	0
@@ -57,6 +58,7 @@
 #define AR_WRITABLE	(1<<1)
 #define AR_READABLE     (1<<1)
-#define AR_INTERRUPT	(0xe)
 #define AR_TSS		(0x9)
+#define AR_INTERRUPT    (0xe)
+#define AR_TRAP         (0xf)
 
 #define DPL_KERNEL	(PL_KERNEL<<5)
@@ -66,9 +68,4 @@
 
 #ifndef __ASM__
-
-struct ptr_16_32 {
-	__u16 limit;
-	__u32 base;
-} __attribute__ ((packed));
 
 struct descriptor {
@@ -85,55 +82,57 @@
 } __attribute__ ((packed));
 
+struct tss_descriptor {
+	unsigned limit_0_15: 16;
+	unsigned base_0_15: 16;
+	unsigned base_16_23: 8;
+	unsigned type: 4;
+	unsigned reserve1 : 1;
+	unsigned dpl : 2;
+	unsigned present : 1;
+	unsigned limit_16_19: 4;
+	unsigned available: 1;
+	unsigned reserve2: 2;
+	unsigned granularity : 1;
+	unsigned base_24_31: 8;	
+	unsigned base_32_63 : 32;
+	unsigned reserve3 : 32;
+} __attribute__ ((packed));
+
 struct idescriptor {
 	unsigned offset_0_15: 16;
 	unsigned selector: 16;
-	unsigned unused: 8;
-	unsigned access: 8;
+	unsigned ist:3;
+	unsigned unused: 5;
+	unsigned type: 5;
+	unsigned dpl: 2;
+	unsigned present : 1;
 	unsigned offset_16_31: 16;
+	unsigned offset_32_63: 16;
+	unsigned reserved : 32;
 } __attribute__ ((packed));
 
+struct ptr_16_64 {
+	__u16 limit;
+	__u64 base;
+} __attribute__ ((packed));
 
 struct tss {
-	__u16 link;
-	unsigned : 16;
-	__u32 esp0;
-	__u16 ss0;
-	unsigned : 16;
-	__u32 esp1;
-	__u16 ss1;
-	unsigned : 16;
-	__u32 esp2;
-	__u16 ss2;
-	unsigned : 16;
-	__u32 cr3;
-	__u32 eip;
-	__u32 eflags;
-	__u32 eax;
-	__u32 ecx;
-	__u32 edx;
-	__u32 ebx;
-	__u32 esp;
-	__u32 ebp;
-	__u32 esi;
-	__u32 edi;
-	__u16 es;
-	unsigned : 16;
-	__u16 cs;
-	unsigned : 16;
-	__u16 ss;
-	unsigned : 16;
-	__u16 ds;
-	unsigned : 16;
-	__u16 fs;
-	unsigned : 16;
-	__u16 gs;
-	unsigned : 16;
-	__u16 ldtr;
-	unsigned : 16;
-	unsigned : 16;
-	__u16 io_map_base;
+	__u32 reserve1;
+	__u64 rsp0;
+	__u64 rsp1;
+	__u64 rsp2;
+	__u64 reserve2;
+	__u64 ist1;
+	__u64 ist2;
+	__u64 ist3;
+	__u64 ist4;
+	__u64 ist5;
+	__u64 ist6;
+	__u64 ist7;
+	__u64 reserve3;
+	__u16 reserve4;
+	__u16 iomap;
 } __attribute__ ((packed));
 
-extern struct ptr_16_32 gdtr;
 extern struct tss *tss_p;
 
@@ -141,8 +140,10 @@
 extern struct idescriptor idt[];
 
+extern struct ptr_16_64 gdtr;
+
 extern void pm_init(void);
 
-extern void gdt_setbase(struct descriptor *d, __address base);
-extern void gdt_setlimit(struct descriptor *d, __u32 limit);
+extern void gdt_tss_setbase(struct descriptor *d, __address base);
+extern void gdt_tss_setlimit(struct descriptor *d, __u32 limit);
 
 extern void idt_init(void);
Index: arch/amd64/include/types.h
===================================================================
--- arch/amd64/include/types.h	(revision 9756131fa15f66c8ed4bfc1d5fccfc9dab372985)
+++ arch/amd64/include/types.h	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
@@ -37,5 +37,5 @@
 typedef unsigned short __u16;
 typedef unsigned int __u32;
-typedef long long __u64;
+typedef unsigned long long __u64;
 
 typedef __u64 __address;
Index: arch/amd64/src/amd64.c
===================================================================
--- arch/amd64/src/amd64.c	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
+++ arch/amd64/src/amd64.c	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2005 Ondrej Palkovsky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+
+#include <arch/types.h>
+
+#include <config.h>
+
+#include <arch/ega.h>
+#include <arch/i8042.h>
+#include <arch/i8254.h>
+#include <arch/i8259.h>
+
+#include <arch/bios/bios.h>
+
+void arch_pre_mm_init(void)
+{
+	pm_init();
+
+	if (config.cpu_active == 1) {
+		bios_init();
+		i8042_init();	/* a20 bit */
+		i8259_init();	/* PIC */
+		i8254_init();	/* hard clock */
+
+		trap_register(VECTOR_SYSCALL, syscall);
+		
+		#ifdef __SMP__
+		trap_register(VECTOR_TLB_SHOOTDOWN_IPI, tlb_shootdown_ipi);
+		trap_register(VECTOR_WAKEUP_IPI, wakeup_ipi);
+		#endif /* __SMP__ */
+	}
+}
+
+void arch_post_mm_init(void)
+{
+	if (config.cpu_active == 1) {
+		ega_init();	/* video */
+	}
+}
Index: arch/amd64/src/boot/boot.S
===================================================================
--- arch/amd64/src/boot/boot.S	(revision 9756131fa15f66c8ed4bfc1d5fccfc9dab372985)
+++ arch/amd64/src/boot/boot.S	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
@@ -67,4 +67,6 @@
 	# Load gdtr, idtr
 	lgdt gdtr_inst
+	# Load idtr, but it contains mess - we should not get interrupt
+	# anyway
 	lidt idtr_inst
 	
@@ -73,5 +75,5 @@
 	movl %eax,%cr0			# switch to protected mode
 
-	jmpl $selector(KTEXT32_DES), $now_in_prot
+	jmpl $gdtselector(KTEXT32_DES), $now_in_prot
 
 no_long_mode:
@@ -83,5 +85,5 @@
 now_in_prot:  
 	# Set up stack & data descriptors
-	movw $selector(KDATA_DES), %ax
+	movw $gdtselector(KDATA_DES), %ax
 	movw %ax, %ds
 	movw %ax, %fs
@@ -111,5 +113,5 @@
 	
 	# At this point we are in compatibility mode
-	jmpl $selector(KTEXT_DES), $start64
+	jmpl $gdtselector(KTEXT_DES), $start64
 
 .code64
@@ -117,13 +119,12 @@
 	movq START_STACK_64, %rsp
 	
-	lidt idtr_inst
-	
 	call main_bsp   # never returns
 1:
 	jmp 1b
-			
-
+				
 .section K_DATA_START
 .align 4096
+
+# Identical mapping of first 16MB and the same of -2GB -> 0	
 .global ptl_2
 ptl_2:	
@@ -154,9 +155,9 @@
 .global gdtr_inst				
 gdtr_inst:
-	.word selector(GDT_ITEMS)
+	.word gdtselector(GDT_ITEMS)
 	.long KA2PA(gdt)
 
 .global idtr_inst
 idtr_inst:
-	.word 0
+	.word idtselector(IDT_ITEMS)
 	.long KA2PA(idt)
Index: arch/amd64/src/delay.S
===================================================================
--- arch/amd64/src/delay.S	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
+++ arch/amd64/src/delay.S	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
@@ -0,0 +1,48 @@
+#
+# Copyright (C) 2001-2004 Jakub Jermar
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# Micro second delay loop functions.
+#
+
+.text
+
+.global asm_delay_loop
+.global asm_fake_loop
+
+asm_delay_loop:
+0:	lahf
+	dec %edi
+	jnz 0b
+	ret
+
+asm_fake_loop:
+0:	lahf
+	dec %edi
+	jz 0b
+	ret
Index: arch/amd64/src/dummy.s
===================================================================
--- arch/amd64/src/dummy.s	(revision 9756131fa15f66c8ed4bfc1d5fccfc9dab372985)
+++ arch/amd64/src/dummy.s	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
@@ -29,8 +29,4 @@
 .text
 
-.global cpu_priority_high
-.global cpu_priority_low
-.global cpu_priority_read
-.global cpu_priority_restore
 .global userspace
 .global before_thread_runs_arch
@@ -41,25 +37,49 @@
 .global cpu_print_report
 .global get_memory_size
-.global arch_pre_mm_init
-.global arch_post_mm_init
 .global arch_late_init
 .global calibrate_delay_loop
-.global asm_delay_loop
 .global cpu_halt
 .global page_arch_init
 .global frame_arch_init
 .global dummy
-.global asm_delay_loop
+.global trap_register
+.global trap_virtual_eoi
+.global trap_virtual_enable_irqs
+.global rdtsc
+.global trap_virtual_disable_irqs
+.global enable_irqs_function
+.global disable_irqs_function
+.global eoi_function
+.global syscall
+	
+.global null_interrupt
+.global interrupt_handler_size
+.global gp_fault
+.global nm_fault
+.global ss_fault
+.global tss_p
+.global interrupt_handlers
 .global memcpy
 
-cpu_priority_high:
-cpu_priority_low:
-cpu_priority_restore:
-cpu_priority_read:
-asm_delay_loop:	
+null_interrupt:
+interrupt_handler_size:
+interrupt_handlers:	
+gp_fault:
+nm_fault:
+ss_fault:
+tss_p:	
+	
+eoi_function:
+syscall:	
+enable_irqs_function:
+disable_irqs_function:	
+rdtsc:
+trap_virtual_eoi:
+trap_virtual_enable_irqs:
+trap_virtual_disable_irqs:	
+trap_register:	
 before_thread_runs_arch:
 userspace:
 calibrate_delay_loop:
-asm_delay_loop:
 panic_printf:
 cpu_identify:
@@ -68,6 +88,4 @@
 cpu_print_report:
 get_memory_size:
-arch_pre_mm_init:
-arch_post_mm_init:
 arch_late_init:
 calibrate_delay_loop:
Index: arch/amd64/src/pm.c
===================================================================
--- arch/amd64/src/pm.c	(revision 9756131fa15f66c8ed4bfc1d5fccfc9dab372985)
+++ arch/amd64/src/pm.c	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
@@ -30,5 +30,12 @@
 #include <arch/mm/page.h>
 #include <arch/types.h>
-
+#include <arch/interrupt.h>
+#include <arch/asm.h>
+
+#include <config.h>
+
+#include <memstr.h>
+#include <mm/heap.h>
+#include <debug.h>
 
 /*
@@ -72,5 +79,5 @@
 	  .longmode    = 1, 
 	  .special     = 0, 
-	  .granularity = 0, 
+	  .granularity = 1, 
 	  .base_24_31  = 0 },
 	/* UDATA descriptor */
@@ -96,12 +103,156 @@
 	  .granularity = 1, 
 	  .base_24_31  = 0 },
-	/* TSS descriptor - set up will be completed later */
+	/* TSS descriptor - set up will be completed later,
+	 * on AMD64 it is 64-bit - 2 items in table */
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
 };
 
+struct ptr_16_64 gdtr = {.limit = sizeof(gdtr), .base= (__u64) &gdtr };
+
 struct idescriptor idt[IDT_ITEMS];
 
 static struct tss tss;
 
-/* Does not compile correctly if it does not exist */
+/* TODO: Does not compile correctly if it does not exist ???? */
 int __attribute__ ((section ("K_DATA_START"))) __fake;
+
+void gdt_tss_setbase(struct descriptor *d, __address base)
+{
+	struct tss_descriptor *td = (struct tss_descriptor *) d;
+
+	td->base_0_15 = base & 0xffff;
+	td->base_16_23 = ((base) >> 16) & 0xff;
+	td->base_24_31 = ((base) >> 24) & 0xff;
+	td->base_32_63 = ((base) >> 32);
+}
+
+void gdt_tss_setlimit(struct descriptor *d, __u32 limit)
+{
+	struct tss_descriptor *td = (struct tss_descriptor *) d;
+
+	td->limit_0_15 = limit & 0xffff;
+	td->limit_16_19 = (limit >> 16) & 0xf;
+}
+
+void idt_setoffset(struct idescriptor *d, __address offset)
+{
+	/*
+	 * Offset is a linear address.
+	 */
+	d->offset_0_15 = offset & 0xffff;
+	d->offset_16_31 = offset >> 16 & 0xffff;
+	d->offset_32_63 = offset >> 32;
+}
+
+void tss_initialize(struct tss *t)
+{
+	memsetb((__address) t, sizeof(struct tss), 0);
+}
+
+/*
+ * This function takes care of proper setup of IDT and IDTR.
+ */
+void idt_init(void)
+{
+	struct idescriptor *d;
+	int i;
+
+	for (i = 0; i < IDT_ITEMS; i++) {
+		d = &idt[i];
+
+		d->unused = 0;
+		d->selector = idtselector(KTEXT_DES);
+
+		d->present = 1;
+		d->type = AR_INTERRUPT;	/* masking interrupt */
+
+		if (i == VECTOR_SYSCALL) {
+			/*
+			 * The syscall interrupt gate must be calleable from userland.
+			 */
+			d->dpl |= PL_USER;
+		}
+		
+		idt_setoffset(d, ((__address) interrupt_handlers) + i*interrupt_handler_size);
+		trap_register(i, null_interrupt);
+	}
+	trap_register(13, gp_fault);
+	trap_register( 7, nm_fault);
+	trap_register(12, ss_fault);
+}
+
+
+/* Clean IOPL(12,13) and NT(14) flags in EFLAGS register */
+static void clean_IOPL_NT_flags(void)
+{
+	asm
+	(
+		"pushfq;"
+		"pop %%rax;"
+		"and $~(0x7000),%%rax;"
+		"pushq %%rax;"
+		"popfq;"
+		:
+		:
+		:"%rax"
+	);
+}
+
+/* Clean AM(18) flag in CR0 register */
+static void clean_AM_flag(void)
+{
+	asm
+	(
+		"mov %%cr0,%%rax;"
+		"and $~(0x40000),%%rax;"
+		"mov %%rax,%%cr0;"
+		:
+		:
+		:"%rax"
+	);
+}
+
+void pm_init(void)
+{
+	struct descriptor *gdt_p = (struct descriptor *) PA2KA(gdtr.base);
+	struct tss_descriptor *tss_d;
+
+	/*
+	 * Each CPU has its private GDT and TSS.
+	 * All CPUs share one IDT.
+	 */
+
+	if (config.cpu_active == 1) {
+		idt_init();
+		/*
+		 * NOTE: bootstrap CPU has statically allocated TSS, because
+		 * the heap hasn't been initialized so far.
+		 */
+		tss_p = &tss;
+	}
+	else {
+		tss_p = (struct tss *) malloc(sizeof(struct tss));
+		if (!tss_p)
+			panic("could not allocate TSS\n");
+	}
+
+	tss_initialize(tss_p);
+
+	tss_d = (struct tss_descriptor *) &gdt_p[TSS_DES];
+	tss_d[TSS_DES].present = 1;
+	tss_d[TSS_DES].type = AR_TSS;
+	tss_d[TSS_DES].dpl = PL_KERNEL;
+	
+	gdt_tss_setbase(&gdt_p[TSS_DES], (__address) tss_p);
+	gdt_tss_setlimit(&gdt_p[TSS_DES], sizeof(struct tss) - 1);
+
+	/*
+	 * As of this moment, the current CPU has its own GDT pointing
+	 * to its own TSS. We just need to load the TR register.
+	 */
+	__asm__("ltr %0" : : "r" ((__u16) gdtselector(TSS_DES)));
+	
+	clean_IOPL_NT_flags();    /* Disable I/O on nonprivileged levels */
+	clean_AM_flag();          /* Disable alignment check */
+}
Index: arch/ia32/include/i8042.h
===================================================================
--- arch/ia32/include/i8042.h	(revision 9756131fa15f66c8ed4bfc1d5fccfc9dab372985)
+++ arch/ia32/include/i8042.h	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
@@ -33,5 +33,5 @@
 
 extern void i8042_init(void);
-extern void i8042_interrupt(__u8 n, __u32 stack[]);
+extern void i8042_interrupt(__u8 n, __native stack[]);
 
 #endif
Index: arch/ia32/include/i8254.h
===================================================================
--- arch/ia32/include/i8254.h	(revision 9756131fa15f66c8ed4bfc1d5fccfc9dab372985)
+++ arch/ia32/include/i8254.h	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
@@ -33,5 +33,5 @@
 
 extern void i8254_init(void);
-extern void i8254_interrupt(__u8 n, __u32 stack[]);
+extern void i8254_interrupt(__u8 n, __native stack[]);
 extern void i8254_calibrate_delay_loop(void);
 extern void i8254_normal_operation(void);
Index: arch/ia32/include/i8259.h
===================================================================
--- arch/ia32/include/i8259.h	(revision 9756131fa15f66c8ed4bfc1d5fccfc9dab372985)
+++ arch/ia32/include/i8259.h	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
@@ -47,5 +47,5 @@
 extern void pic_disable_irqs(__u16 irqmask);
 extern void pic_eoi(void);
-extern void pic_spurious(__u8 n, __u32 stack[]);
+extern void pic_spurious(__u8 n, __native stack[]);
 
 #endif
Index: arch/ia32/include/interrupt.h
===================================================================
--- arch/ia32/include/interrupt.h	(revision 9756131fa15f66c8ed4bfc1d5fccfc9dab372985)
+++ arch/ia32/include/interrupt.h	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
@@ -63,7 +63,5 @@
 #define VECTOR_WAKEUP_IPI		(IVT_FREEBASE+2)
 
-typedef void (* iroutine)(__u8 n, __u32 stack[]);
-
-extern iroutine ivt[IVT_ITEMS];
+typedef void (* iroutine)(__u8 n, __native stack[]);
 
 extern void (* disable_irqs_function)(__u16 irqmask);
@@ -73,14 +71,14 @@
 extern iroutine trap_register(__u8 n, iroutine f);
 
-extern void trap_dispatcher(__u8 n, __u32 stack[]);
+extern void trap_dispatcher(__u8 n, __native stack[]);
 
-extern void null_interrupt(__u8 n, __u32 stack[]);
-extern void gp_fault(__u8 n, __u32 stack[]);
-extern void nm_fault(__u8 n, __u32 stack[]);
-extern void ss_fault(__u8 n, __u32 stack[]);
-extern void page_fault(__u8 n, __u32 stack[]);
-extern void syscall(__u8 n, __u32 stack[]);
-extern void tlb_shootdown_ipi(__u8 n, __u32 stack[]);
-extern void wakeup_ipi(__u8 n, __u32 stack[]);
+extern void null_interrupt(__u8 n, __native stack[]);
+extern void gp_fault(__u8 n, __native stack[]);
+extern void nm_fault(__u8 n, __native stack[]);
+extern void ss_fault(__u8 n, __native stack[]);
+extern void page_fault(__u8 n, __native stack[]);
+extern void syscall(__u8 n, __native stack[]);
+extern void tlb_shootdown_ipi(__u8 n, __native stack[]);
+extern void wakeup_ipi(__u8 n, __native stack[]);
 
 extern void trap_virtual_enable_irqs(__u16 irqmask);
Index: arch/ia32/include/pm.h
===================================================================
--- arch/ia32/include/pm.h	(revision 9756131fa15f66c8ed4bfc1d5fccfc9dab372985)
+++ arch/ia32/include/pm.h	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
@@ -133,5 +133,4 @@
 
 extern struct descriptor gdt[];
-extern struct idescriptor idt[];
 
 extern void pm_init(void);
Index: arch/ia32/src/acpi/acpi.c
===================================================================
--- arch/ia32/src/acpi/acpi.c	(revision 9756131fa15f66c8ed4bfc1d5fccfc9dab372985)
+++ arch/ia32/src/acpi/acpi.c	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
@@ -42,5 +42,5 @@
 
 struct acpi_signature_map signature_map[] = { 
-	{ "APIC", (struct acpi_sdt_header **) &acpi_madt, "Multiple APIC Description Table" }
+	{ (__u8 *)"APIC", (struct acpi_sdt_header **) &acpi_madt, "Multiple APIC Description Table" }
 };
 
Index: arch/ia32/src/drivers/i8042.c
===================================================================
--- arch/ia32/src/drivers/i8042.c	(revision 9756131fa15f66c8ed4bfc1d5fccfc9dab372985)
+++ arch/ia32/src/drivers/i8042.c	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
@@ -49,5 +49,5 @@
 }
 
-void i8042_interrupt(__u8 n, __u32 stack[])
+void i8042_interrupt(__u8 n, __native stack[])
 {
 	__u8 x;
Index: arch/ia32/src/drivers/i8254.c
===================================================================
--- arch/ia32/src/drivers/i8254.c	(revision 9756131fa15f66c8ed4bfc1d5fccfc9dab372985)
+++ arch/ia32/src/drivers/i8254.c	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
@@ -123,5 +123,5 @@
 }
 
-void i8254_interrupt(__u8 n, __u32 stack[])
+void i8254_interrupt(__u8 n, __native stack[])
 {
 	trap_virtual_eoi();
Index: arch/ia32/src/drivers/i8259.c
===================================================================
--- arch/ia32/src/drivers/i8259.c	(revision 9756131fa15f66c8ed4bfc1d5fccfc9dab372985)
+++ arch/ia32/src/drivers/i8259.c	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
@@ -116,5 +116,5 @@
 }
 
-void pic_spurious(__u8 n, __u32 stack[])
+void pic_spurious(__u8 n, __native stack[])
 {
 	printf("cpu%d: PIC spurious interrupt\n", CPU->id);
Index: src/build.amd64
===================================================================
--- src/build.amd64	(revision 9756131fa15f66c8ed4bfc1d5fccfc9dab372985)
+++ src/build.amd64	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
@@ -5,6 +5,12 @@
 (cd ../arch/amd64/src;make gencontext;./gencontext)
 # Create links to ia32 architecture
-ln -sf ../../../arch/ia32/src/drivers ../arch/amd64/src/
-ln -sf ../../../arch/ia32/include/ega.h ../arch/amd64/include/
+for a in drivers bios; do
+  ln -sf ../../../arch/ia32/src/$a ../arch/amd64/src/
+done
 
+for a in ega.h i8042.h i8259.h i8254.h cpuid.h interrupt.h bios; do
+  ln -sf ../../../arch/ia32/include/$a ../arch/amd64/include/
+done
+
+make dist-clean ARCH=ia32
 make all ARCH=amd64
Index: src/clean.amd64
===================================================================
--- src/clean.amd64	(revision 9756131fa15f66c8ed4bfc1d5fccfc9dab372985)
+++ src/clean.amd64	(revision b9e97fb2772f7c034a63b8c019ca6396de53e556)
@@ -2,2 +2,6 @@
 
 make dist-clean ARCH=amd64
+make dist-clean ARCH=ia32
+
+find ../arch/amd64 -type l | xargs rm
+rm ../arch/amd64/src/context_offset.h
