Index: kernel/arch/ia32/Makefile.inc
===================================================================
--- kernel/arch/ia32/Makefile.inc	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/Makefile.inc	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,142 @@
+#
+# Copyright (C) 2005 Martin Decky
+# 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.
+#
+
+## Toolchain configuration
+#
+
+BFD_NAME = elf32-i386
+BFD_ARCH = i386
+BFD = binary
+TARGET = i686-pc-linux-gnu
+TOOLCHAIN_DIR = /usr/local/i686/bin
+
+## Make some default assumptions
+#
+
+ifndef IA32_CPU
+	IA32_CPU = pentium4
+endif
+
+DEFS += -D_CPU=${IA32_CPU} -D__32_BITS__
+
+## Accepted CPUs
+#
+
+ifeq ($(IA32_CPU),athlon-xp)
+	CFLAGS += -march=athlon-xp -mmmx -msse -m3dnow
+	DEFS += -DCONFIG_FENCES_P3
+	CONFIG_SMP = n
+	CONFIG_HT = n
+endif
+ifeq ($(IA32_CPU),athlon-mp)
+	CFLAGS += -march=athlon-mp -mmmx -msse -m3dnow
+	DEFS += -DCONFIG_FENCES_P3
+	CONFIG_HT = n
+endif
+ifeq ($(IA32_CPU),pentium3)
+	CFLAGS += -march=pentium3 -mmmx -msse
+	DEFS += -DCONFIG_FENCES_P3
+	CONFIG_HT = n
+endif
+ifeq ($(IA32_CPU),prescott)
+	CFLAGS += -march=pentium4 -mfpmath=sse -mmmx -msse -msse2 -msse3
+	DEFS += -DCONFIG_FENCES_P4
+endif
+ifeq ($(IA32_CPU),pentium4)
+	CFLAGS += -march=pentium4 -mfpmath=sse -mmmx -msse -msse2
+	DEFS += -DCONFIG_FENCES_P4
+endif
+
+## Own configuration directives
+#
+
+CONFIG_ACPI = y
+
+## Compile with hierarchical page tables support.
+#
+
+CONFIG_PAGE_PT = y
+DEFS += -DCONFIG_PAGE_PT
+
+## Compile with i8042 controller support
+#
+
+CONFIG_I8042 = y
+
+
+## Accepted configuration directives
+#
+
+ifeq ($(CONFIG_SMP),y)
+	DEFS += -DCONFIG_SMP
+endif
+ifeq ($(CONFIG_HT),y)
+	DEFS += -DCONFIG_HT
+endif
+ifeq ($(CONFIG_SIMICS_FIX),y)
+	DEFS += -DCONFIG_SIMICS_FIX
+endif
+
+## Compile with support for software integer division.
+#
+
+CONFIG_SOFTINT = y
+
+ARCH_SOURCES = \
+	arch/$(ARCH)/src/context.s \
+	arch/$(ARCH)/src/debug/panic.s \
+	arch/$(ARCH)/src/delay.s \
+	arch/$(ARCH)/src/asm.S \
+	arch/$(ARCH)/src/proc/scheduler.c \
+	arch/$(ARCH)/src/proc/task.c \
+	arch/$(ARCH)/src/proc/thread.c \
+	arch/$(ARCH)/src/bios/bios.c \
+	arch/$(ARCH)/src/smp/ap.S \
+	arch/$(ARCH)/src/smp/apic.c \
+	arch/$(ARCH)/src/smp/mps.c \
+	arch/$(ARCH)/src/smp/smp.c \
+	arch/$(ARCH)/src/atomic.S \
+	arch/$(ARCH)/src/smp/ipi.c \
+	arch/$(ARCH)/src/ia32.c \
+	arch/$(ARCH)/src/interrupt.c \
+	arch/$(ARCH)/src/pm.c \
+	arch/$(ARCH)/src/userspace.c \
+	arch/$(ARCH)/src/cpu/cpu.c \
+	arch/$(ARCH)/src/mm/as.c \
+	arch/$(ARCH)/src/mm/frame.c \
+	arch/$(ARCH)/src/mm/memory_init.c \
+	arch/$(ARCH)/src/mm/page.c \
+	arch/$(ARCH)/src/mm/tlb.c \
+	arch/$(ARCH)/src/ddi/ddi.c \
+	arch/$(ARCH)/src/drivers/i8254.c \
+	arch/$(ARCH)/src/drivers/i8259.c \
+	arch/$(ARCH)/src/drivers/ega.c \
+	arch/$(ARCH)/src/drivers/vesa.c \
+	arch/$(ARCH)/src/boot/boot.S \
+	arch/$(ARCH)/src/fpu_context.c \
+	arch/$(ARCH)/src/debugger.c
Index: kernel/arch/ia32/_link.ld.in
===================================================================
--- kernel/arch/ia32/_link.ld.in	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/_link.ld.in	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,65 @@
+/** IA-32 linker script
+ *  
+ * umapped section:
+ * 	kernel text
+ * 	kernel data
+ * mapped section:
+ *	kernel text
+ *	kernel data 
+ */
+
+#define __ASM__
+#include <arch/boot/boot.h>
+#include <arch/mm/page.h>
+
+SECTIONS {
+	.unmapped BOOT_OFFSET: AT (0) {
+		unmapped_ktext_start = .;
+		*(K_TEXT_START);
+		unmapped_ktext_end = .;
+	
+		unmapped_kdata_start = .;
+		*(K_DATA_START);
+		unmapped_kdata_end = .;
+	}
+	
+	.mapped (PA2KA(BOOT_OFFSET)+SIZEOF(.unmapped)): AT (SIZEOF(.unmapped)) { 
+		ktext_start = .;
+		*(.text);
+		ktext_end = .;
+		
+		kdata_start = .;
+		*(.data);			/* initialized data */
+		*(.rodata*);			/* string literals */
+		*(COMMON);			/* global variables */
+		hardcoded_load_address = .;
+		LONG(PA2KA(BOOT_OFFSET));
+		hardcoded_ktext_size = .;
+		LONG((ktext_end - ktext_start) + (unmapped_ktext_end - unmapped_ktext_start));
+		hardcoded_kdata_size = .;
+		LONG((kdata_end - kdata_start) + (unmapped_kdata_end - unmapped_kdata_start));
+		hardcoded_unmapped_ktext_size = .;
+		LONG(unmapped_ktext_end - unmapped_ktext_start);
+		hardcoded_unmapped_kdata_size = .;
+		LONG(unmapped_kdata_end - unmapped_kdata_start);
+		symbol_table = .;
+		*(symtab.*);            	/* Symbol table, must be LAST symbol! */
+		*(.bss);			/* uninitialized static variables */
+		kdata_end = .;
+	}
+
+	/DISCARD/ : {
+		*(.note.GNU-stack);		
+		*(.comment);
+	}
+	
+#ifdef CONFIG_SMP	
+	
+	_hardcoded_unmapped_size = (unmapped_ktext_end - unmapped_ktext_start) + (unmapped_kdata_end - unmapped_kdata_start);
+	ap_boot = unmapped_ap_boot - BOOT_OFFSET + AP_BOOT_OFFSET;
+	ap_gdtr = unmapped_ap_gdtr - BOOT_OFFSET + AP_BOOT_OFFSET;
+	protected_ap_gdtr = PA2KA(ap_gdtr);
+
+#endif /* CONFIG_SMP */
+
+}
Index: kernel/arch/ia32/include/arch.h
===================================================================
--- kernel/arch/ia32/include/arch.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/arch.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2005 Martin Decky
+ * 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_ARCH_H__
+#define __ia32_ARCH_H__
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/arg.h
===================================================================
--- kernel/arch/ia32/include/arg.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/arg.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_ARG_H__
+#define __ia32_ARG_H__
+
+#include <stackarg.h>
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/asm.h
===================================================================
--- kernel/arch/ia32/include/asm.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/asm.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2001-2004 Jakub Jermar
+ * Copyright (C) 2005 Sergey Bondari
+ * 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_ASM_H__
+#define __ia32_ASM_H__
+
+#include <arch/pm.h>
+#include <arch/types.h>
+#include <config.h>
+
+extern uint32_t interrupt_handler_size;
+
+extern void paging_on(void);
+
+extern void interrupt_handlers(void);
+
+extern void enable_l_apic_in_msr(void);
+
+
+extern void asm_delay_loop(uint32_t t);
+extern void asm_fake_loop(uint32_t t);
+
+
+/** Halt CPU
+ *
+ * Halt the current CPU until interrupt event.
+ */
+static inline void cpu_halt(void) { __asm__("hlt\n"); };
+static inline void cpu_sleep(void) { __asm__("hlt\n"); };
+
+#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \
+    { \
+	unative_t res; \
+	__asm__ volatile ("movl %%" #reg ", %0" : "=r" (res) ); \
+	return res; \
+    }
+
+#define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \
+    { \
+	__asm__ volatile ("movl %0, %%" #reg : : "r" (regn)); \
+    }
+
+GEN_READ_REG(cr0);
+GEN_READ_REG(cr2);
+GEN_READ_REG(cr3);
+GEN_WRITE_REG(cr3);
+
+GEN_READ_REG(dr0);
+GEN_READ_REG(dr1);
+GEN_READ_REG(dr2);
+GEN_READ_REG(dr3);
+GEN_READ_REG(dr6);
+GEN_READ_REG(dr7);
+
+GEN_WRITE_REG(dr0);
+GEN_WRITE_REG(dr1);
+GEN_WRITE_REG(dr2);
+GEN_WRITE_REG(dr3);
+GEN_WRITE_REG(dr6);
+GEN_WRITE_REG(dr7);
+
+/** Byte to port
+ *
+ * Output byte to port
+ *
+ * @param port Port to write to
+ * @param val Value to write
+ */
+static inline void outb(uint16_t port, uint8_t val) { __asm__ volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port) ); }
+
+/** Word to port
+ *
+ * Output word to port
+ *
+ * @param port Port to write to
+ * @param val Value to write
+ */
+static inline void outw(uint16_t port, uint16_t val) { __asm__ volatile ("outw %w0, %w1\n" : : "a" (val), "d" (port) ); }
+
+/** Double word to port
+ *
+ * Output double word to port
+ *
+ * @param port Port to write to
+ * @param val Value to write
+ */
+static inline void outl(uint16_t port, uint32_t val) { __asm__ volatile ("outl %l0, %w1\n" : : "a" (val), "d" (port) ); }
+
+/** Byte from port
+ *
+ * Get byte from port
+ *
+ * @param port Port to read from
+ * @return Value read
+ */
+static inline uint8_t inb(uint16_t port) { uint8_t val; __asm__ volatile ("inb %w1, %b0 \n" : "=a" (val) : "d" (port) ); return val; }
+
+/** Word from port
+ *
+ * Get word from port
+ *
+ * @param port Port to read from
+ * @return Value read
+ */
+static inline uint16_t inw(uint16_t port) { uint16_t val; __asm__ volatile ("inw %w1, %w0 \n" : "=a" (val) : "d" (port) ); return val; }
+
+/** Double word from port
+ *
+ * Get double word from port
+ *
+ * @param port Port to read from
+ * @return Value read
+ */
+static inline uint32_t inl(uint16_t port) { uint32_t val; __asm__ volatile ("inl %w1, %l0 \n" : "=a" (val) : "d" (port) ); return val; }
+
+/** Enable interrupts.
+ *
+ * Enable interrupts and return previous
+ * value of EFLAGS.
+ *
+ * @return Old interrupt priority level.
+ */
+static inline ipl_t interrupts_enable(void)
+{
+	ipl_t v;
+	__asm__ volatile (
+		"pushf\n\t"
+		"popl %0\n\t"
+		"sti\n"
+		: "=r" (v)
+	);
+	return v;
+}
+
+/** Disable interrupts.
+ *
+ * Disable interrupts and return previous
+ * value of EFLAGS.
+ *
+ * @return Old interrupt priority level.
+ */
+static inline ipl_t interrupts_disable(void)
+{
+	ipl_t v;
+	__asm__ volatile (
+		"pushf\n\t"
+		"popl %0\n\t"
+		"cli\n"
+		: "=r" (v)
+	);
+	return v;
+}
+
+/** Restore interrupt priority level.
+ *
+ * Restore EFLAGS.
+ *
+ * @param ipl Saved interrupt priority level.
+ */
+static inline void interrupts_restore(ipl_t ipl)
+{
+	__asm__ volatile (
+		"pushl %0\n\t"
+		"popf\n"
+		: : "r" (ipl)
+	);
+}
+
+/** Return interrupt priority level.
+ *
+ * @return EFLAFS.
+ */
+static inline ipl_t interrupts_read(void)
+{
+	ipl_t v;
+	__asm__ volatile (
+		"pushf\n\t"
+		"popl %0\n"
+		: "=r" (v)
+	);
+	return v;
+}
+
+/** Return base address of current stack
+ *
+ * Return the base address of the current stack.
+ * The stack is assumed to be STACK_SIZE bytes long.
+ * The stack must start on page boundary.
+ */
+static inline uintptr_t get_stack_base(void)
+{
+	uintptr_t v;
+	
+	__asm__ volatile ("andl %%esp, %0\n" : "=r" (v) : "0" (~(STACK_SIZE-1)));
+	
+	return v;
+}
+
+static inline uint64_t rdtsc(void)
+{
+	uint64_t v;
+	
+	__asm__ volatile("rdtsc\n" : "=A" (v));
+	
+	return v;
+}
+
+/** Return current IP address */
+static inline uintptr_t * get_ip() 
+{
+	uintptr_t *ip;
+
+	__asm__ volatile (
+		"mov %%eip, %0"
+		: "=r" (ip)
+		);
+	return ip;
+}
+
+/** Invalidate TLB Entry.
+ *
+ * @param addr Address on a page whose TLB entry is to be invalidated.
+ */
+static inline void invlpg(uintptr_t addr)
+{
+	__asm__ volatile ("invlpg %0\n" :: "m" (*(unative_t *)addr));
+}
+
+/** Load GDTR register from memory.
+ *
+ * @param gdtr_reg Address of memory from where to load GDTR.
+ */
+static inline void gdtr_load(ptr_16_32_t *gdtr_reg)
+{
+	__asm__ volatile ("lgdtl %0\n" : : "m" (*gdtr_reg));
+}
+
+/** Store GDTR register to memory.
+ *
+ * @param gdtr_reg Address of memory to where to load GDTR.
+ */
+static inline void gdtr_store(ptr_16_32_t *gdtr_reg)
+{
+	__asm__ volatile ("sgdtl %0\n" : : "m" (*gdtr_reg));
+}
+
+/** Load IDTR register from memory.
+ *
+ * @param idtr_reg Address of memory from where to load IDTR.
+ */
+static inline void idtr_load(ptr_16_32_t *idtr_reg)
+{
+	__asm__ volatile ("lidtl %0\n" : : "m" (*idtr_reg));
+}
+
+/** Load TR from descriptor table.
+ *
+ * @param sel Selector specifying descriptor of TSS segment.
+ */
+static inline void tr_load(uint16_t sel)
+{
+	__asm__ volatile ("ltr %0" : : "r" (sel));
+}
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/atomic.h
===================================================================
--- kernel/arch/ia32/include/atomic.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/atomic.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_ATOMIC_H__
+#define __ia32_ATOMIC_H__
+
+#include <arch/types.h>
+#include <arch/barrier.h>
+#include <preemption.h>
+#include <typedefs.h>
+
+static inline void atomic_inc(atomic_t *val) {
+#ifdef CONFIG_SMP
+	__asm__ volatile ("lock incl %0\n" : "=m" (val->count));
+#else
+	__asm__ volatile ("incl %0\n" : "=m" (val->count));
+#endif /* CONFIG_SMP */
+}
+
+static inline void atomic_dec(atomic_t *val) {
+#ifdef CONFIG_SMP
+	__asm__ volatile ("lock decl %0\n" : "=m" (val->count));
+#else
+	__asm__ volatile ("decl %0\n" : "=m" (val->count));
+#endif /* CONFIG_SMP */
+}
+
+static inline long atomic_postinc(atomic_t *val) 
+{
+	long r = 1;
+
+	__asm__ volatile (
+		"lock xaddl %1, %0\n"
+		: "=m" (val->count), "+r" (r)
+	);
+
+	return r;
+}
+
+static inline long atomic_postdec(atomic_t *val) 
+{
+	long r = -1;
+	
+	__asm__ volatile (
+		"lock xaddl %1, %0\n"
+		: "=m" (val->count), "+r"(r)
+	);
+	
+	return r;
+}
+
+#define atomic_preinc(val) (atomic_postinc(val)+1)
+#define atomic_predec(val) (atomic_postdec(val)-1)
+
+static inline uint32_t test_and_set(atomic_t *val) {
+	uint32_t v;
+	
+	__asm__ volatile (
+		"movl $1, %0\n"
+		"xchgl %0, %1\n"
+		: "=r" (v),"=m" (val->count)
+	);
+	
+	return v;
+}
+
+/** ia32 specific fast spinlock */
+static inline void atomic_lock_arch(atomic_t *val)
+{
+	uint32_t tmp;
+
+	preemption_disable();
+	__asm__ volatile (
+		"0:;"
+#ifdef CONFIG_HT
+		"pause;" /* Pentium 4's HT love this instruction */
+#endif
+		"mov %0, %1;"
+		"testl %1, %1;"
+		"jnz 0b;"       /* Lightweight looping on locked spinlock */
+		
+		"incl %1;"      /* now use the atomic operation */
+		"xchgl %0, %1;"
+		"testl %1, %1;"
+		"jnz 0b;"
+                : "=m"(val->count),"=r"(tmp)
+		);
+	/*
+	 * Prevent critical section code from bleeding out this way up.
+	 */
+	CS_ENTER_BARRIER();
+}
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/barrier.h
===================================================================
--- kernel/arch/ia32/include/barrier.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/barrier.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_BARRIER_H__
+#define __ia32_BARRIER_H__
+
+/*
+ * NOTE:
+ * No barriers for critical section (i.e. spinlock) on IA-32 are needed:
+ * - spinlock_lock() and spinlock_trylock() use serializing XCHG instruction
+ * - writes cannot pass reads on IA-32 => spinlock_unlock() needs no barriers
+ */
+
+/*
+ * Provisions are made to prevent compiler from reordering instructions itself.
+ */
+
+#define CS_ENTER_BARRIER()	__asm__ volatile ("" ::: "memory")
+#define CS_LEAVE_BARRIER()	__asm__ volatile ("" ::: "memory")
+
+static inline void cpuid_serialization(void)
+{
+	__asm__ volatile (
+		"xorl %%eax, %%eax\n"
+		"cpuid\n"
+		::: "eax", "ebx", "ecx", "edx", "memory"
+	);
+}
+
+#ifdef CONFIG_FENCES_P4
+#	define memory_barrier()		__asm__ volatile ("mfence\n" ::: "memory")
+#	define read_barrier()		__asm__ volatile ("lfence\n" ::: "memory")
+#	ifdef CONFIG_WEAK_MEMORY
+#		define write_barrier()	__asm__ volatile ("sfence\n" ::: "memory")
+#	else
+#		define write_barrier()  __asm__ volatile( "" ::: "memory");
+#	endif
+#elif CONFIG_FENCES_P3
+#	define memory_barrier()		cpuid_serialization()
+#	define read_barrier()		cpuid_serialization()
+#	ifdef CONFIG_WEAK_MEMORY
+#		define write_barrier()	__asm__ volatile ("sfence\n" ::: "memory")
+#	else
+#		define write_barrier()  __asm__ volatile( "" ::: "memory");
+#	endif
+#else
+#	define memory_barrier()		cpuid_serialization()
+#	define read_barrier()		cpuid_serialization()
+#	ifdef CONFIG_WEAK_MEMORY
+#		define write_barrier()	cpuid_serialization()
+#	else
+#		define write_barrier()  __asm__ volatile( "" ::: "memory");
+#	endif
+#endif
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/bios/bios.h
===================================================================
--- kernel/arch/ia32/include/bios/bios.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/bios/bios.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __BIOS_H__
+#define __BIOS_H__
+
+#include <arch/types.h>
+
+#define BIOS_EBDA_PTR	0x40e
+
+extern uintptr_t ebda;
+
+extern void bios_init(void);
+
+#endif /* __BIOS_H__ */
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/boot/boot.h
===================================================================
--- kernel/arch/ia32/include/boot/boot.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/boot/boot.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2005 Martin Decky
+ * 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_BOOT_H__
+#define __ia32_BOOT_H__
+
+#define BOOT_OFFSET		0x108000
+#define AP_BOOT_OFFSET		0x8000
+#define BOOT_STACK_SIZE	0x400
+
+#define MULTIBOOT_HEADER_MAGIC	0x1BADB002
+#define MULTIBOOT_HEADER_FLAGS	0x00010003
+
+#define MULTIBOOT_LOADER_MAGIC	0x2BADB002
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/boot/memmap.h
===================================================================
--- kernel/arch/ia32/include/boot/memmap.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/boot/memmap.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2005 Josef Cejka
+ * 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_MEMMAP_H__
+#define __ia32_MEMMAP_H__
+
+/* E820h memory range types - other values*/
+	/* Free memory */
+#define MEMMAP_MEMORY_AVAILABLE	1
+	/* Not available for OS */
+#define MEMMAP_MEMORY_RESERVED	2 
+	/* OS may use it after reading ACPI table */
+#define MEMMAP_MEMORY_ACPI	3 
+	/* Unusable, required to be saved and restored across an NVS sleep */
+#define MEMMAP_MEMORY_NVS	4 
+	/* Corrupted memory */
+#define MEMMAP_MEMORY_UNUSABLE	5 
+
+	 /* size of one entry */
+#define MEMMAP_E820_RECORD_SIZE 20 
+	/* maximum entries */
+#define MEMMAP_E820_MAX_RECORDS 32 
+
+
+#ifndef __ASM__
+
+#include <arch/types.h>
+
+struct e820memmap_ {
+	uint64_t base_address;
+	uint64_t size;
+	uint32_t type;
+} __attribute__ ((packed));
+
+extern struct e820memmap_ e820table[MEMMAP_E820_MAX_RECORDS];
+
+extern uint8_t e820counter; 
+
+extern uint32_t e801memorysize; /**< Size of available memory in KB. */
+
+#endif
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/byteorder.h
===================================================================
--- kernel/arch/ia32/include/byteorder.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/byteorder.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_BYTEORDER_H__
+#define __ia32_BYTEORDER_H__
+
+/* IA-32 is little-endian */
+#define unative_t_le2host(n)		(n)
+#define uint64_t_le2host(n)		(n)
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/context.h
===================================================================
--- kernel/arch/ia32/include/context.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/context.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_CONTEXT_H__
+#define __ia32_CONTEXT_H__
+
+#include <arch/types.h>
+
+#define STACK_ITEM_SIZE	4
+
+/*
+ * Both context_save() and context_restore() eat two doublewords from the stack.
+ * First for pop of the saved register, second during ret instruction.
+ *
+ * One item is put onto stack to support get_stack_base().
+ */
+#define SP_DELTA	(8+STACK_ITEM_SIZE)
+
+/*
+ * Only save registers that must be preserved across
+ * function calls.
+ */
+struct context {
+	uintptr_t sp;
+	uintptr_t pc;
+	uint32_t ebx;
+	uint32_t esi;
+	uint32_t edi;
+	uint32_t ebp;
+	ipl_t ipl;
+} __attribute__ ((packed));
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/cpu.h
===================================================================
--- kernel/arch/ia32/include/cpu.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/cpu.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup ia32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_CPU_H__
+#define __ia32_CPU_H__
+
+#include <typedefs.h>
+#include <arch/pm.h>
+#include <arch/asm.h>
+
+#define EFLAGS_IF       (1 << 9)
+#define EFLAGS_RF       (1 << 16)
+
+struct cpu_arch {
+	int vendor;
+	int family;
+	int model;
+	int stepping;
+	struct tss *tss;
+	
+	count_t iomapver_copy;  /** Copy of TASK's I/O Permission bitmap generation count. */
+};
+
+
+#define CR4_OSFXSR_MASK (1<<9)
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/ia32/include/cpuid.h
===================================================================
--- kernel/arch/ia32/include/cpuid.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/cpuid.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup ia32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_CPUID_H__
+#define __ia32_CPUID_H__
+
+#include <arch/types.h>
+
+struct cpu_info {
+	uint32_t cpuid_eax;
+	uint32_t cpuid_ebx;
+	uint32_t cpuid_ecx;
+	uint32_t cpuid_edx;
+} __attribute__ ((packed));
+
+struct __cpuid_extended_feature_info {
+	unsigned sse3 :  1;
+	unsigned      : 31;
+} __attribute__ ((packed));
+
+typedef union cpuid_extended_feature_info 
+{
+	struct __cpuid_extended_feature_info bits;
+	uint32_t                                word;
+}cpuid_extended_feature_info;
+
+
+struct __cpuid_feature_info {
+	unsigned 			: 23;
+	unsigned mmx  :  1;
+	unsigned fxsr :  1;
+	unsigned sse  :  1;
+	unsigned sse2 :  1;
+	unsigned      :  5;
+} __attribute__ ((packed));
+
+typedef union cpuid_feature_info 
+{
+	struct __cpuid_feature_info bits;
+	uint32_t                word       ;
+}cpuid_feature_info;
+
+
+static inline uint32_t has_cpuid(void)
+{
+	uint32_t val, ret;
+	
+	__asm__ volatile (
+		"pushf\n"               /* read flags */
+		"popl %0\n"
+		"movl %0, %1\n"
+		
+		"btcl $21, %1\n"        /* swap the ID bit */
+		
+		"pushl %1\n"            /* propagate the change into flags */
+		"popf\n"
+		"pushf\n"
+		"popl %1\n"
+		
+		"andl $(1 << 21), %0\n" /* interrested only in ID bit */
+		"andl $(1 << 21), %1\n"
+		"xorl %1, %0\n"
+		: "=r" (ret), "=r" (val)
+	);
+	
+	return ret;
+}
+
+static inline void cpuid(uint32_t cmd, struct cpu_info *info)
+{
+	__asm__ volatile (
+		"movl %4, %%eax\n"
+		"cpuid\n"
+		
+		"movl %%eax, %0\n"
+		"movl %%ebx, %1\n"
+		"movl %%ecx, %2\n"
+		"movl %%edx, %3\n"
+		: "=m" (info->cpuid_eax), "=m" (info->cpuid_ebx), "=m" (info->cpuid_ecx), "=m" (info->cpuid_edx)
+		: "m" (cmd)
+		: "eax", "ebx", "ecx", "edx"
+	);
+}
+
+#endif
+
+/** @}
+ */
+
Index: kernel/arch/ia32/include/ddi/ddi.h
===================================================================
--- kernel/arch/ia32/include/ddi/ddi.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/ddi/ddi.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2006 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.
+ */
+
+/** @addtogroup ia32ddi
+ * @{
+ */
+/**
+ * @file
+ * @brief	ia32 specific DDI declarations and macros.
+ */
+
+#ifndef __ia32_DDI_H__
+#define __ia32_DDI_H__
+
+extern void io_perm_bitmap_install(void);
+
+#endif
+
+/** @}
+ */
+
Index: kernel/arch/ia32/include/debug.h
===================================================================
--- kernel/arch/ia32/include/debug.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/debug.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2005 Martin Decky
+ * 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.
+ */
+
+ /** @addtogroup amd64debug
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_DEBUG_H__
+#define __ia32_DEBUG_H__
+
+#include <arch/asm.h>
+
+#define HERE get_ip()
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/debugger.h
===================================================================
--- kernel/arch/ia32/include/debugger.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/debugger.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,1 @@
+../../amd64/include/debugger.h
Index: kernel/arch/ia32/include/drivers/ega.h
===================================================================
--- kernel/arch/ia32/include/drivers/ega.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/drivers/ega.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __EGA_H__
+#define __EGA_H__
+
+#define VIDEORAM	0xb8000
+#define ROW		80
+#define ROWS		25
+#define SCREEN		(ROW * ROWS)
+
+extern void ega_init(void);
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/drivers/i8042.h
===================================================================
--- kernel/arch/ia32/include/drivers/i8042.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/drivers/i8042.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2006 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+/**
+ * This file implements ia32 specific access to i8042 registers.
+ */
+
+#ifndef __ia32_I8042_H__
+#define __ia32_I8042_H__
+
+#include <arch/asm.h>
+#include <arch/types.h>
+
+#define i8042_DATA		0x60
+#define i8042_STATUS		0x64
+
+static inline void i8042_data_write(uint8_t data)
+{
+	outb(i8042_DATA, data);
+}
+
+static inline uint8_t i8042_data_read(void)
+{
+	return inb(i8042_DATA);
+}
+
+static inline uint8_t i8042_status_read(void)
+{
+	return inb(i8042_STATUS);
+}
+
+static inline void i8042_command_write(uint8_t command)
+{
+	outb(i8042_STATUS, command);
+}
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/drivers/i8254.h
===================================================================
--- kernel/arch/ia32/include/drivers/i8254.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/drivers/i8254.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __I8254_H__
+#define __I8254_H__
+
+#include <arch/types.h>
+
+extern void i8254_init(void);
+extern void i8254_calibrate_delay_loop(void);
+extern void i8254_normal_operation(void);
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/drivers/i8259.h
===================================================================
--- kernel/arch/ia32/include/drivers/i8259.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/drivers/i8259.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __I8259_H__
+#define __I8259_H__
+
+#include <arch/types.h>
+#include <arch/interrupt.h>
+
+#define PIC_PIC0PORT1	0x20
+#define PIC_PIC0PORT2	0x21
+#define PIC_PIC1PORT1	0xa0
+#define PIC_PIC1PORT2	0xa1
+
+#define PIC_NEEDICW4	(1<<0)
+#define	PIC_ICW1	(1<<4)
+
+extern void i8259_init(void);
+extern void pic_enable_irqs(uint16_t irqmask);
+extern void pic_disable_irqs(uint16_t irqmask);
+extern void pic_eoi(void);
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/drivers/vesa.h
===================================================================
--- kernel/arch/ia32/include/drivers/vesa.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/drivers/vesa.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2006 Jakub Vana
+ * 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __VESA_H__
+#define __VESA_H__
+
+extern int vesa_present(void);
+extern void vesa_init(void);
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/elf.h
===================================================================
--- kernel/arch/ia32/include/elf.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/elf.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2006 Sergey Bondari
+ * 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_ELF_H__
+#define __ia32_ELF_H__
+
+#define	ELF_MACHINE		EM_386
+#define ELF_DATA_ENCODING	ELFDATA2LSB
+#define ELF_CLASS		ELFCLASS32
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/faddr.h
===================================================================
--- kernel/arch/ia32/include/faddr.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/faddr.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_FADDR_H__
+#define __ia32_FADDR_H__
+
+#include <arch/types.h>
+
+#define FADDR(fptr)		((uintptr_t) (fptr))
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/fpu_context.h
===================================================================
--- kernel/arch/ia32/include/fpu_context.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/fpu_context.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2005 Jakub Vana
+ * 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_FPU_CONTEXT_H__
+#define __ia32_FPU_CONTEXT_H__
+
+#include <arch/types.h>
+
+#define ARCH_HAS_FPU
+#define FPU_CONTEXT_ALIGN 16
+
+void fpu_fxsr(void);
+void fpu_fsr(void);
+
+
+struct fpu_context {
+	uint8_t fpu[512]; 		/* FXSAVE & FXRSTOR storage area */
+};
+
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/interrupt.h
===================================================================
--- kernel/arch/ia32/include/interrupt.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/interrupt.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup ia32interrupt
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_INTERRUPT_H__
+#define __ia32_INTERRUPT_H__
+
+#include <arch/types.h>
+#include <arch/pm.h>
+
+#define IVT_ITEMS		IDT_ITEMS
+
+#define EXC_COUNT	32
+#define IRQ_COUNT	16
+
+#define IVT_EXCBASE		0
+#define IVT_IRQBASE		(IVT_EXCBASE+EXC_COUNT)
+#define IVT_FREEBASE		(IVT_IRQBASE+IRQ_COUNT)
+
+#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_DEBUG            1
+#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_DEBUG_IPI                (IVT_FREEBASE+2)
+
+struct istate {
+	uint32_t eax;
+	uint32_t ecx;
+	uint32_t edx;
+	uint32_t esi;
+	uint32_t edi;
+	uint32_t ebp;
+	uint32_t ebx;
+
+	uint32_t gs;
+	uint32_t fs;
+	uint32_t es;
+	uint32_t ds;
+
+	uint32_t error_word;
+	uint32_t eip;
+	uint32_t cs;
+	uint32_t eflags;
+	uint32_t stack[];
+};
+
+/** Return true if exception happened while in userspace */
+static inline int istate_from_uspace(istate_t *istate)
+{
+	return !(istate->eip & 0x80000000);
+}
+
+static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
+{
+	istate->eip = retaddr;
+}
+
+static inline unative_t istate_get_pc(istate_t *istate)
+{
+	return istate->eip;
+}
+
+extern void (* disable_irqs_function)(uint16_t irqmask);
+extern void (* enable_irqs_function)(uint16_t irqmask);
+extern void (* eoi_function)(void);
+
+extern void PRINT_INFO_ERRCODE(istate_t *istate);
+extern void null_interrupt(int n, istate_t *istate);
+extern void gp_fault(int n, istate_t *istate);
+extern void nm_fault(int n, istate_t *istate);
+extern void ss_fault(int n, istate_t *istate);
+extern void simd_fp_exception(int n, istate_t *istate);
+extern void syscall(int n, istate_t *istate);
+extern void tlb_shootdown_ipi(int n, istate_t *istate);
+
+extern void trap_virtual_enable_irqs(uint16_t irqmask);
+extern void trap_virtual_disable_irqs(uint16_t irqmask);
+extern void trap_virtual_eoi(void);
+
+#endif
+
+/** @}
+ */
+
Index: kernel/arch/ia32/include/memstr.h
===================================================================
--- kernel/arch/ia32/include/memstr.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/memstr.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2005 Sergey Bondari
+ * 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_MEMSTR_H__
+#define __ia32_MEMSTR_H__
+
+/** Copy memory
+ *
+ * Copy a given number of bytes (3rd argument)
+ * from the memory location defined by 2nd argument
+ * to the memory location defined by 1st argument.
+ * The memory areas cannot overlap.
+ *
+ * @param dst Destination
+ * @param src Source
+ * @param cnt Number of bytes
+ * @return Destination
+ */
+static inline void * memcpy(void * dst, const void * src, size_t cnt)
+{
+        unative_t d0, d1, d2;
+
+        __asm__ __volatile__(
+                /* copy all full dwords */
+                "rep movsl\n\t"
+                /* load count again */
+                "movl %4, %%ecx\n\t"
+                /* ecx = ecx mod 4 */
+                "andl $3, %%ecx\n\t"
+                /* are there last <=3 bytes? */
+                "jz 1f\n\t"
+                /* copy last <=3 bytes */
+                "rep movsb\n\t"
+                /* exit from asm block */
+                "1:\n"
+                : "=&c" (d0), "=&D" (d1), "=&S" (d2)
+                : "0" ((unative_t) (cnt / 4)), "g" ((unative_t) cnt), "1" ((unative_t) dst), "2" ((unative_t) src)
+                : "memory");
+
+        return dst;
+}
+
+
+/** Compare memory regions for equality
+ *
+ * Compare a given number of bytes (3rd argument)
+ * at memory locations defined by 1st and 2nd argument
+ * for equality. If bytes are equal function returns 0.
+ *
+ * @param src Region 1
+ * @param dst Region 2
+ * @param cnt Number of bytes
+ * @return Zero if bytes are equal, non-zero otherwise
+ */
+static inline int memcmp(const void * src, const void * dst, size_t cnt)
+{
+	uint32_t d0, d1, d2;
+	int ret;
+	
+	__asm__ (
+		"repe cmpsb\n\t"
+		"je 1f\n\t"
+		"movl %3, %0\n\t"
+		"addl $1, %0\n\t"
+		"1:\n"
+		: "=a" (ret), "=%S" (d0), "=&D" (d1), "=&c" (d2)
+		: "0" (0), "1" ((unative_t) src), "2" ((unative_t) dst), "3" ((unative_t) cnt)
+	);
+	
+	return ret;
+}
+
+/** Fill memory with words
+ * Fill a given number of words (2nd argument)
+ * at memory defined by 1st argument with the
+ * word value defined by 3rd argument.
+ *
+ * @param dst Destination
+ * @param cnt Number of words
+ * @param x Value to fill
+ */
+static inline void memsetw(uintptr_t dst, size_t cnt, uint16_t x)
+{
+	uint32_t d0, d1;
+	
+	__asm__ __volatile__ (
+		"rep stosw\n\t"
+		: "=&D" (d0), "=&c" (d1), "=a" (x)
+		: "0" (dst), "1" (cnt), "2" (x)
+		: "memory"
+	);
+
+}
+
+/** Fill memory with bytes
+ * Fill a given number of bytes (2nd argument)
+ * at memory defined by 1st argument with the
+ * word value defined by 3rd argument.
+ *
+ * @param dst Destination
+ * @param cnt Number of bytes
+ * @param x Value to fill
+ */
+static inline void memsetb(uintptr_t dst, size_t cnt, uint8_t x)
+{
+	uint32_t d0, d1;
+	
+	__asm__ __volatile__ (
+		"rep stosb\n\t"
+		: "=&D" (d0), "=&c" (d1), "=a" (x)
+		: "0" (dst), "1" (cnt), "2" (x)
+		: "memory"
+	);
+
+}
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/mm/as.h
===================================================================
--- kernel/arch/ia32/include/mm/as.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/mm/as.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+ /** @addtogroup ia32mm	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_AS_H__
+#define __ia32_AS_H__
+
+#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH	0
+
+#define KERNEL_ADDRESS_SPACE_START_ARCH		((unsigned long) 0x80000000)
+#define KERNEL_ADDRESS_SPACE_END_ARCH		((unsigned long) 0xffffffff)
+#define USER_ADDRESS_SPACE_START_ARCH		((unsigned long) 0x00000000)
+#define USER_ADDRESS_SPACE_END_ARCH		((unsigned long) 0x7fffffff)
+
+#define USTACK_ADDRESS_ARCH	(USER_ADDRESS_SPACE_END_ARCH-(PAGE_SIZE-1))
+
+#define as_install_arch(as)
+
+extern void as_arch_init(void);
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/mm/asid.h
===================================================================
--- kernel/arch/ia32/include/mm/asid.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/mm/asid.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+ /** @addtogroup ia32mm	
+ * @{
+ */
+/** @file
+ * @ingroup ia32mm, amd64mm
+ */
+
+/*
+ * ia32 has no hardware support for address space identifiers.
+ * This file is provided to do nop-implementation of mm/asid.h
+ * interface.
+ */
+
+#ifndef __ia32_ASID_H__
+#define __ia32_ASID_H__
+
+typedef int asid_t;
+
+#define ASID_MAX_ARCH		3
+
+#define asid_get()		(ASID_START+1)
+#define asid_put(asid)
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/mm/frame.h
===================================================================
--- kernel/arch/ia32/include/mm/frame.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/mm/frame.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+ /** @addtogroup ia32mm	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_FRAME_H__
+#define __ia32_FRAME_H__
+
+#define FRAME_WIDTH	12	/* 4K */
+#define FRAME_SIZE	(1<<FRAME_WIDTH)
+
+
+#ifdef KERNEL
+#ifndef __ASM__
+
+#include <arch/types.h>
+
+extern uintptr_t last_frame;
+
+extern void frame_arch_init(void);
+
+#endif /* __ASM__ */
+#endif /* KERNEL */
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/mm/memory_init.h
===================================================================
--- kernel/arch/ia32/include/mm/memory_init.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/mm/memory_init.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2005 Josef Cejka
+ * 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.
+ */
+
+ /** @addtogroup ia32mm	
+ * @{
+ */
+/** @file
+ * @ingroup ia32mm, am64mm
+ */
+
+#ifndef __ia32_MEMORY_INIT_H__
+#define __ia32_MEMORY_INIT_H__
+
+#include <typedefs.h>
+
+size_t get_memory_size(void);
+
+void memory_print_map(void);
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/mm/page.h
===================================================================
--- kernel/arch/ia32/include/mm/page.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/mm/page.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,173 @@
+/*
+ * 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.
+ */
+
+ /** @addtogroup ia32mm	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_PAGE_H__
+#define __ia32_PAGE_H__
+
+#include <arch/mm/frame.h>
+
+#define PAGE_WIDTH	FRAME_WIDTH
+#define PAGE_SIZE	FRAME_SIZE
+
+#ifdef KERNEL
+
+#ifndef __ASM__
+#	define KA2PA(x)	(((uintptr_t) (x)) - 0x80000000)
+#	define PA2KA(x)	(((uintptr_t) (x)) + 0x80000000)
+#else
+#	define KA2PA(x)	((x) - 0x80000000)
+#	define PA2KA(x)	((x) + 0x80000000)
+#endif
+
+/*
+ * Implementation of generic 4-level page table interface.
+ * IA-32 has 2-level page tables, so PTL1 and PTL2 are left out.
+ */
+#define PTL0_ENTRIES_ARCH	1024
+#define PTL1_ENTRIES_ARCH	0
+#define PTL2_ENTRIES_ARCH	0
+#define PTL3_ENTRIES_ARCH	1024
+
+#define PTL0_INDEX_ARCH(vaddr)	(((vaddr)>>22)&0x3ff)
+#define PTL1_INDEX_ARCH(vaddr)	0
+#define PTL2_INDEX_ARCH(vaddr)	0
+#define PTL3_INDEX_ARCH(vaddr)	(((vaddr)>>12)&0x3ff)
+
+#define GET_PTL1_ADDRESS_ARCH(ptl0, i)		((pte_t *)((((pte_t *)(ptl0))[(i)].frame_address)<<12))
+#define GET_PTL2_ADDRESS_ARCH(ptl1, i)		(ptl1)
+#define GET_PTL3_ADDRESS_ARCH(ptl2, i)		(ptl2)
+#define GET_FRAME_ADDRESS_ARCH(ptl3, i)		((uintptr_t)((((pte_t *)(ptl3))[(i)].frame_address)<<12))
+
+#define SET_PTL0_ADDRESS_ARCH(ptl0)		(write_cr3((uintptr_t) (ptl0)))
+#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a)	(((pte_t *)(ptl0))[(i)].frame_address = (a)>>12)
+#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
+#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
+#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a)	(((pte_t *)(ptl3))[(i)].frame_address = (a)>>12)
+
+#define GET_PTL1_FLAGS_ARCH(ptl0, i)		get_pt_flags((pte_t *)(ptl0), (index_t)(i))
+#define GET_PTL2_FLAGS_ARCH(ptl1, i)		PAGE_PRESENT
+#define GET_PTL3_FLAGS_ARCH(ptl2, i)		PAGE_PRESENT
+#define GET_FRAME_FLAGS_ARCH(ptl3, i)		get_pt_flags((pte_t *)(ptl3), (index_t)(i))
+
+#define SET_PTL1_FLAGS_ARCH(ptl0, i, x)		set_pt_flags((pte_t *)(ptl0), (index_t)(i), (x))
+#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
+#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
+#define SET_FRAME_FLAGS_ARCH(ptl3, i, x)	set_pt_flags((pte_t *)(ptl3), (index_t)(i), (x))
+
+#define PTE_VALID_ARCH(p)			(*((uint32_t *) (p)) != 0)
+#define PTE_PRESENT_ARCH(p)			((p)->present != 0)
+#define PTE_GET_FRAME_ARCH(p)			((p)->frame_address<<FRAME_WIDTH)
+#define PTE_WRITABLE_ARCH(p)			((p)->writeable != 0)
+#define PTE_EXECUTABLE_ARCH(p)			1
+
+#ifndef __ASM__
+
+#include <mm/page.h>
+#include <arch/types.h>
+#include <arch/mm/frame.h>
+#include <typedefs.h>
+
+/* Page fault error codes. */
+
+/** When bit on this position is 0, the page fault was caused by a not-present page. */
+#define PFERR_CODE_P		(1<<0)
+
+/** When bit on this position is 1, the page fault was caused by a write. */
+#define PFERR_CODE_RW		(1<<1)
+
+/** When bit on this position is 1, the page fault was caused in user mode. */
+#define PFERR_CODE_US		(1<<2)
+
+/** When bit on this position is 1, a reserved bit was set in page directory. */ 
+#define PFERR_CODE_RSVD		(1<<3)	
+
+/** Page Table Entry. */
+struct page_specifier {
+	unsigned present : 1;
+	unsigned writeable : 1;
+	unsigned uaccessible : 1;
+	unsigned page_write_through : 1;
+	unsigned page_cache_disable : 1;
+	unsigned accessed : 1;
+	unsigned dirty : 1;
+	unsigned pat : 1;
+	unsigned global : 1;
+	unsigned soft_valid : 1;	/**< Valid content even if the present bit is not set. */
+	unsigned avl : 2;
+	unsigned frame_address : 20;
+} __attribute__ ((packed));
+
+static inline int get_pt_flags(pte_t *pt, index_t i)
+{
+	pte_t *p = &pt[i];
+	
+	return (
+		(!p->page_cache_disable)<<PAGE_CACHEABLE_SHIFT |
+		(!p->present)<<PAGE_PRESENT_SHIFT |
+		p->uaccessible<<PAGE_USER_SHIFT |
+		1<<PAGE_READ_SHIFT |
+		p->writeable<<PAGE_WRITE_SHIFT |
+		1<<PAGE_EXEC_SHIFT |
+		p->global<<PAGE_GLOBAL_SHIFT
+	);
+}
+
+static inline void set_pt_flags(pte_t *pt, index_t i, int flags)
+{
+	pte_t *p = &pt[i];
+	
+	p->page_cache_disable = !(flags & PAGE_CACHEABLE);
+	p->present = !(flags & PAGE_NOT_PRESENT);
+	p->uaccessible = (flags & PAGE_USER) != 0;
+	p->writeable = (flags & PAGE_WRITE) != 0;
+	p->global = (flags & PAGE_GLOBAL) != 0;
+	
+	/*
+	 * Ensure that there is at least one bit set even if the present bit is cleared.
+	 */
+	p->soft_valid = true;
+}
+
+extern void page_arch_init(void);
+extern void page_fault(int n, istate_t *istate);
+
+#endif /* __ASM__ */
+
+#endif /* KERNEL */
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/mm/tlb.h
===================================================================
--- kernel/arch/ia32/include/mm/tlb.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/mm/tlb.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+ /** @addtogroup ia32mm	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_TLB_H__
+#define __ia32_TLB_H__
+
+#define tlb_arch_init()
+#define tlb_print()
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/pm.h
===================================================================
--- kernel/arch/ia32/include/pm.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/pm.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,183 @@
+/*
+ * 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __PM_H__
+#define __PM_H__
+
+#define IDT_ITEMS 64
+#define GDT_ITEMS 7
+
+#define VESA_INIT_SEGMENT 0x8000
+
+#define NULL_DES	0
+#define KTEXT_DES	1
+#define	KDATA_DES	2
+#define UTEXT_DES	3
+#define UDATA_DES	4
+#define TSS_DES		5
+#define TLS_DES         6 /* Pointer to Thread-Local-Storage data */
+
+#ifdef CONFIG_FB
+
+#define VESA_INIT_SEGMENT 0x8000
+#define VESA_INIT_DES 7
+#undef GDT_ITEMS
+#define GDT_ITEMS 8
+
+#endif /* CONFIG_FB */
+
+
+#define selector(des)	((des)<<3)
+
+#define PL_KERNEL	0
+#define PL_USER		3
+
+#define AR_PRESENT	(1<<7)
+#define AR_DATA		(2<<3)
+#define AR_CODE		(3<<3)
+#define AR_WRITABLE	(1<<1)
+#define AR_INTERRUPT	(0xe)
+#define AR_TSS		(0x9)
+
+#define DPL_KERNEL	(PL_KERNEL<<5)
+#define DPL_USER	(PL_USER<<5)
+
+#define TSS_BASIC_SIZE	104
+#define TSS_IOMAP_SIZE	(16*1024+1)	/* 16K for bitmap + 1 terminating byte for convenience */
+
+#define IO_PORTS	(64*1024)
+
+#ifndef __ASM__
+
+#include <arch/types.h>
+#include <typedefs.h>
+#include <arch/context.h>
+
+struct ptr_16_32 {
+	uint16_t limit;
+	uint32_t base;
+} __attribute__ ((packed));
+typedef struct ptr_16_32 ptr_16_32_t;
+
+struct descriptor {
+	unsigned limit_0_15: 16;
+	unsigned base_0_15: 16;
+	unsigned base_16_23: 8;
+	unsigned access: 8;
+	unsigned limit_16_19: 4;
+	unsigned available: 1;
+	unsigned unused: 1;
+	unsigned special: 1;
+	unsigned granularity : 1;
+	unsigned base_24_31: 8;
+} __attribute__ ((packed));
+typedef struct descriptor  descriptor_t;
+
+struct idescriptor {
+	unsigned offset_0_15: 16;
+	unsigned selector: 16;
+	unsigned unused: 8;
+	unsigned access: 8;
+	unsigned offset_16_31: 16;
+} __attribute__ ((packed));
+typedef struct idescriptor idescriptor_t;
+
+struct tss {
+	uint16_t link;
+	unsigned : 16;
+	uint32_t esp0;
+	uint16_t ss0;
+	unsigned : 16;
+	uint32_t esp1;
+	uint16_t ss1;
+	unsigned : 16;
+	uint32_t esp2;
+	uint16_t ss2;
+	unsigned : 16;
+	uint32_t cr3;
+	uint32_t eip;
+	uint32_t eflags;
+	uint32_t eax;
+	uint32_t ecx;
+	uint32_t edx;
+	uint32_t ebx;
+	uint32_t esp;
+	uint32_t ebp;
+	uint32_t esi;
+	uint32_t edi;
+	uint16_t es;
+	unsigned : 16;
+	uint16_t cs;
+	unsigned : 16;
+	uint16_t ss;
+	unsigned : 16;
+	uint16_t ds;
+	unsigned : 16;
+	uint16_t fs;
+	unsigned : 16;
+	uint16_t gs;
+	unsigned : 16;
+	uint16_t ldtr;
+	unsigned : 16;
+	unsigned : 16;
+	uint16_t iomap_base;
+	uint8_t iomap[TSS_IOMAP_SIZE];
+} __attribute__ ((packed));
+typedef struct tss tss_t;
+
+extern ptr_16_32_t gdtr;
+extern ptr_16_32_t bootstrap_gdtr;
+extern ptr_16_32_t protected_ap_gdtr;
+extern struct tss *tss_p;
+
+extern descriptor_t gdt[];
+
+extern void pm_init(void);
+
+extern void gdt_setbase(descriptor_t *d, uintptr_t base);
+extern void gdt_setlimit(descriptor_t *d, uint32_t limit);
+
+extern void idt_init(void);
+extern void idt_setoffset(idescriptor_t *d, uintptr_t offset);
+
+extern void tss_initialize(tss_t *t);
+extern void set_tls_desc(uintptr_t tls);
+
+#endif /* __ASM__ */
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/proc/task.h
===================================================================
--- kernel/arch/ia32/include/proc/task.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/proc/task.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2006 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.
+ */
+
+ /** @addtogroup ia32proc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_TASK_H__
+#define __ia32_TASK_H__
+
+#include <typedefs.h>
+#include <arch/types.h>
+#include <adt/bitmap.h>
+
+typedef struct {
+	count_t iomapver;	/**< I/O Permission bitmap Generation counter. */
+	bitmap_t iomap;		/**< I/O Permission bitmap. */
+} task_arch_t;
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/proc/thread.h
===================================================================
--- kernel/arch/ia32/include/proc/thread.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/proc/thread.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -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.
+ */
+
+ /** @addtogroup ia32proc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_THREAD_H__
+#define __ia32_THREAD_H__
+
+#include <arch/types.h>
+
+typedef struct {
+	unative_t tls;
+} thread_arch_t;
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/smp/ap.h
===================================================================
--- kernel/arch/ia32/include/smp/ap.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/smp/ap.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __AP_H__
+#define __AP_H__
+
+extern void ap_boot(void);
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/smp/apic.h
===================================================================
--- kernel/arch/ia32/include/smp/apic.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/smp/apic.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,371 @@
+/*
+ * 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __APIC_H__
+#define __APIC_H__
+
+#include <arch/types.h>
+#include <cpu.h>
+
+#define FIXED		(0<<0)
+#define LOPRI		(1<<0)
+
+#define APIC_ID_COUNT	16
+
+/* local APIC macros */
+#define IPI_INIT 	0
+#define IPI_STARTUP	0
+
+/** Delivery modes. */
+#define DELMOD_FIXED	0x0
+#define DELMOD_LOWPRI	0x1
+#define DELMOD_SMI	0x2
+/* 0x3 reserved */
+#define DELMOD_NMI	0x4
+#define DELMOD_INIT	0x5
+#define DELMOD_STARTUP	0x6
+#define DELMOD_EXTINT	0x7
+
+/** Destination modes. */
+#define DESTMOD_PHYS	0x0
+#define DESTMOD_LOGIC	0x1
+
+/** Trigger Modes. */
+#define TRIGMOD_EDGE	0x0
+#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
+
+/** 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
+
+/** Delivery status. */
+#define DELIVS_IDLE	0x0
+#define DELIVS_PENDING	0x1
+
+/** Destination masks. */
+#define DEST_ALL	0xff
+
+/** Dest format models. */
+#define MODEL_FLAT	0xf
+#define MODEL_CLUSTER	0x0
+
+/** Interrupt Command Register. */
+#define ICRlo		(0x300/sizeof(uint32_t))
+#define ICRhi		(0x310/sizeof(uint32_t))
+struct icr {
+	union {
+		uint32_t lo;
+		struct {
+			uint8_t 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 {
+		uint32_t hi;
+		struct {
+			unsigned : 24;			/**< Reserved. */
+			uint8_t dest;			/**< Destination field. */
+		} __attribute__ ((packed));
+	};
+} __attribute__ ((packed));
+typedef struct icr icr_t;
+
+/* End Of Interrupt. */
+#define EOI		(0x0b0/sizeof(uint32_t))
+
+/** Error Status Register. */
+#define ESR		(0x280/sizeof(uint32_t))
+union esr {
+	uint32_t value;
+	uint8_t 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 */
+#define TPR		(0x080/sizeof(uint32_t))
+union tpr {
+	uint32_t value;
+	struct {
+		unsigned pri_sc : 4;		/**< Task Priority Sub-Class. */
+		unsigned pri : 4;		/**< Task Priority. */
+	} __attribute__ ((packed));
+};
+typedef union tpr tpr_t;
+
+/** Spurious-Interrupt Vector Register. */
+#define SVR		(0x0f0/sizeof(uint32_t))
+union svr {
+	uint32_t value;
+	struct {
+		uint8_t 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(uint32_t))
+union tdcr {
+	uint32_t 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 */
+#define ICRT		(0x380/sizeof(uint32_t))
+
+/* Current Count Register for Timer */
+#define CCRT		(0x390/sizeof(uint32_t))
+
+/** LVT Timer register. */
+#define LVT_Tm		(0x320/sizeof(uint32_t))
+union lvt_tm {
+	uint32_t value;
+	struct {
+		uint8_t 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(uint32_t))
+#define LVT_LINT1	(0x360/sizeof(uint32_t))
+union lvt_lint {
+	uint32_t value;
+	struct {
+		uint8_t 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(uint32_t))
+union lvt_error {
+	uint32_t value;
+	struct {
+		uint8_t 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;
+
+/** Local APIC ID Register. */
+#define L_APIC_ID	(0x020/sizeof(uint32_t))
+union l_apic_id {
+	uint32_t value;
+	struct {
+		unsigned : 24;		/**< Reserved. */
+		uint8_t apic_id;		/**< Local APIC ID. */
+	} __attribute__ ((packed));
+};
+typedef union l_apic_id l_apic_id_t;
+
+/** Local APIC Version Register */
+#define LAVR		(0x030/sizeof(uint32_t))
+#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)
+
+/** Logical Destination Register. */
+#define  LDR		(0x0d0/sizeof(uint32_t))
+union ldr {
+	uint32_t value;
+	struct {
+		unsigned : 24;		/**< Reserved. */
+		uint8_t id;		/**< Logical APIC ID. */
+	} __attribute__ ((packed));
+};
+typedef union ldr ldr_t;
+
+/** Destination Format Register. */
+#define DFR		(0x0e0/sizeof(uint32_t))
+union dfr {
+	uint32_t value;
+	struct {
+		unsigned : 28;		/**< Reserved, all ones. */
+		unsigned model : 4;	/**< Model. */
+	} __attribute__ ((packed));
+};
+typedef union dfr dfr_t;
+
+/* IO APIC */
+#define IOREGSEL	(0x00/sizeof(uint32_t))
+#define IOWIN		(0x10/sizeof(uint32_t))
+
+#define IOAPICID	0x00
+#define IOAPICVER	0x01
+#define IOAPICARB	0x02
+#define IOREDTBL	0x10
+
+/** I/O Register Select Register. */
+union io_regsel {
+	uint32_t value;
+	struct {
+		uint8_t reg_addr;		/**< APIC Register Address. */
+		unsigned : 24;		/**< Reserved. */
+	} __attribute__ ((packed));
+};
+typedef union io_regsel io_regsel_t;
+
+/** I/O Redirection Register. */
+struct io_redirection_reg {
+	union {
+		uint32_t lo;
+		struct {
+			uint8_t intvec;			/**< Interrupt Vector. */
+			unsigned delmod : 3;		/**< Delivery Mode. */
+			unsigned destmod : 1; 		/**< Destination mode. */
+			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));
+	};
+	union {
+		uint32_t hi;
+		struct {
+			unsigned : 24;			/**< Reserved. */
+			uint8_t dest : 8;			/**< Destination Field. */
+		} __attribute__ ((packed));
+	};
+	
+} __attribute__ ((packed));
+typedef struct io_redirection_reg io_redirection_reg_t;
+
+
+/** IO APIC Identification Register. */
+union io_apic_id {
+	uint32_t value;
+	struct {
+		unsigned : 24;		/**< Reserved. */
+		unsigned apic_id : 4;	/**< IO APIC ID. */
+		unsigned : 4;		/**< Reserved. */
+	} __attribute__ ((packed));
+};
+typedef union io_apic_id io_apic_id_t;
+
+extern volatile uint32_t *l_apic;
+extern volatile uint32_t *io_apic;
+
+extern uint32_t apic_id_mask;
+
+extern void apic_init(void);
+
+extern void l_apic_init(void);
+extern void l_apic_eoi(void);
+extern int l_apic_broadcast_custom_ipi(uint8_t vector);
+extern int l_apic_send_init_ipi(uint8_t apicid);
+extern void l_apic_debug(void);
+extern uint8_t l_apic_id(void);
+
+extern uint32_t io_apic_read(uint8_t address);
+extern void io_apic_write(uint8_t address , uint32_t x);
+extern void io_apic_change_ioredtbl(int pin, int dest, uint8_t v, int flags);
+extern void io_apic_disable_irqs(uint16_t irqmask);
+extern void io_apic_enable_irqs(uint16_t irqmask);
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/smp/mps.h
===================================================================
--- kernel/arch/ia32/include/smp/mps.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/smp/mps.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __MPS_H__
+#define __MPS_H__
+
+#include <arch/types.h>
+#include <typedefs.h>
+#include <synch/waitq.h>
+#include <config.h>
+#include <arch/smp/smp.h>
+
+#define CT_EXT_ENTRY_TYPE		0
+#define CT_EXT_ENTRY_LEN		1
+
+struct mps_fs {
+	uint32_t signature;
+	uint32_t configuration_table;
+	uint8_t length;
+	uint8_t revision;
+	uint8_t checksum;
+	uint8_t config_type;
+	uint8_t mpfib2;
+	uint8_t mpfib3;
+	uint8_t mpfib4;
+	uint8_t mpfib5;
+} __attribute__ ((packed));
+
+struct mps_ct {
+	uint32_t signature;
+	uint16_t base_table_length;
+	uint8_t revision;
+	uint8_t checksum;
+	uint8_t oem_id[8];
+	uint8_t product_id[12];
+	uint32_t oem_table;
+	uint16_t oem_table_size;
+	uint16_t entry_count;
+	uint32_t l_apic;
+	uint16_t ext_table_length;
+	uint8_t ext_table_checksum;
+	uint8_t xxx;
+	uint8_t base_table[0];
+} __attribute__ ((packed));
+
+struct __processor_entry {
+	uint8_t type;
+	uint8_t l_apic_id;
+	uint8_t l_apic_version;
+	uint8_t cpu_flags;
+	uint8_t cpu_signature[4];
+	uint32_t feature_flags;
+	uint32_t xxx[2];
+} __attribute__ ((packed));
+
+struct __bus_entry {
+	uint8_t type;
+	uint8_t bus_id;
+	uint8_t bus_type[6];
+} __attribute__ ((packed));
+
+struct __io_apic_entry {
+	uint8_t type;
+	uint8_t io_apic_id;
+	uint8_t io_apic_version;
+	uint8_t io_apic_flags;
+	uint32_t io_apic;
+} __attribute__ ((packed));
+
+struct __io_intr_entry {
+	uint8_t type;
+	uint8_t intr_type;
+	uint8_t poel;
+	uint8_t xxx;
+	uint8_t src_bus_id;
+	uint8_t src_bus_irq;
+	uint8_t dst_io_apic_id;
+	uint8_t dst_io_apic_pin;
+} __attribute__ ((packed));
+
+struct __l_intr_entry {
+	uint8_t type;
+	uint8_t intr_type;
+	uint8_t poel;
+	uint8_t xxx;
+	uint8_t src_bus_id;
+	uint8_t src_bus_irq;
+	uint8_t dst_l_apic_id;
+	uint8_t dst_l_apic_pin;
+} __attribute__ ((packed));
+
+
+extern waitq_t ap_completion_wq;
+
+extern struct smp_config_operations mps_config_operations;
+
+extern void mps_init(void);
+extern void kmp(void *arg);
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/smp/smp.h
===================================================================
--- kernel/arch/ia32/include/smp/smp.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/smp/smp.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __ia32_SMP_H__
+#define __ia32_SMP_H__
+
+#include <arch/types.h>
+#include <typedefs.h>
+
+/** SMP config opertaions interface. */
+struct smp_config_operations {
+	count_t (* cpu_count)(void);		/**< Return number of detected processors. */
+	bool (* cpu_enabled)(index_t i);	/**< Check whether the processor of index i is enabled. */
+	bool (*cpu_bootstrap)(index_t i);	/**< Check whether the processor of index i is BSP. */
+	uint8_t (*cpu_apic_id)(index_t i);		/**< Return APIC ID of the processor of index i. */
+	int (*irq_to_pin)(int irq);		/**< Return mapping between irq and APIC pin. */
+};
+
+extern int smp_irq_to_pin(int irq);
+
+#endif
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/include/types.h
===================================================================
--- kernel/arch/ia32/include/types.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/include/types.h	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __TYPES_H__
+#define __TYPES_H__
+
+#define NULL 0
+
+typedef signed char int8_t;
+typedef signed short int16_t;
+typedef signed long int32_t;
+typedef signed long long int64_t;
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned long uint32_t;
+typedef unsigned long long uint64_t;
+
+typedef uint32_t uintptr_t;
+typedef uint32_t pfn_t;
+
+typedef uint32_t ipl_t;
+
+typedef uint32_t unative_t;
+typedef int32_t native_t;
+
+typedef struct page_specifier pte_t;
+
+#endif
+
+/** @}
+ */
+
Index: kernel/arch/ia32/src/asm.S
===================================================================
--- kernel/arch/ia32/src/asm.S	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/asm.S	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,276 @@
+#
+# 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.
+#
+
+## very low and hardware-level functions
+
+# Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word
+# and 1 means interrupt with error word
+#define ERROR_WORD_INTERRUPT_LIST 0x00027D00
+
+.text
+
+.global paging_on
+.global enable_l_apic_in_msr
+.global interrupt_handlers
+.global memcpy
+.global memcpy_from_uspace
+.global memcpy_from_uspace_failover_address
+.global memcpy_to_uspace
+.global memcpy_to_uspace_failover_address
+
+
+#define MEMCPY_DST	4
+#define MEMCPY_SRC	8
+#define MEMCPY_SIZE	12
+
+/** Copy memory to/from userspace.
+ *
+ * This is almost conventional memcpy().
+ * The difference is that there is a failover part
+ * to where control is returned from a page fault
+ * if the page fault occurs during copy_from_uspace()
+ * or copy_to_uspace().
+ *
+ * @param MEMCPY_DST(%esp)	Destination address.
+ * @param MEMCPY_SRC(%esp)	Source address.
+ * @param MEMCPY_SIZE(%esp)	Size.
+ *
+ * @return MEMCPY_SRC(%esp) on success and 0 on failure.
+ */
+memcpy:
+memcpy_from_uspace:
+memcpy_to_uspace:
+	movl %edi, %edx				/* save %edi */
+	movl %esi, %eax				/* save %esi */
+	
+	movl MEMCPY_SIZE(%esp), %ecx
+	shrl $2, %ecx				/* size / 4 */
+	
+	movl MEMCPY_DST(%esp), %edi
+	movl MEMCPY_SRC(%esp), %esi
+	
+	rep movsl				/* copy as much as possible word by word */
+
+	movl MEMCPY_SIZE(%esp), %ecx
+	andl $3, %ecx				/* size % 4 */
+	jz 0f
+	
+	rep movsb				/* copy the rest byte by byte */
+
+0:
+	movl %edx, %edi
+	movl %eax, %esi
+	movl MEMCPY_SRC(%esp), %eax		/* MEMCPY_SRC(%esp), success */
+	ret
+	
+/*
+ * We got here from as_page_fault() after the memory operations
+ * above had caused a page fault.
+ */
+memcpy_from_uspace_failover_address:
+memcpy_to_uspace_failover_address:
+	movl %edx, %edi
+	movl %eax, %esi
+	xorl %eax, %eax				/* return 0, failure */
+	ret
+
+## Turn paging on
+#
+# Enable paging and write-back caching in CR0.
+#
+paging_on:
+	movl %cr0,%edx
+	orl $(1<<31),%edx		# paging on
+	andl $~((1<<30)|(1<<29)),%edx	# clear Cache Disable and not Write Though
+	movl %edx,%cr0
+	jmp 0f
+0:
+	ret
+
+
+## Enable local APIC
+#
+# Enable local APIC in MSR.
+#
+enable_l_apic_in_msr:
+	push %eax
+
+	movl $0x1b, %ecx
+	rdmsr
+	orl $(1<<11),%eax
+	orl $(0xfee00000),%eax
+	wrmsr
+
+	pop %eax
+	ret
+
+# Clear nested flag
+# overwrites %ecx
+.macro CLEAR_NT_FLAG
+	pushfl
+	pop %ecx
+	and $0xffffbfff,%ecx
+	push %ecx
+	popfl
+.endm	
+
+## Declare interrupt handlers
+#
+# Declare interrupt handlers for n interrupt
+# vectors starting at vector i.
+#
+# The handlers setup data segment registers
+# and call exc_dispatch().
+#
+#define INTERRUPT_ALIGN 64
+.macro handler i n
+
+.ifeq \i-0x30     # Syscall handler
+	push %ds
+	push %es
+	push %fs
+	push %gs
+
+	# Push arguments on stack
+	push %edi
+	push %esi
+	push %edx
+	push %ecx
+	push %eax
+	
+	# we must fill the data segment registers
+	movw $16,%ax
+	movw %ax,%ds
+	movw %ax,%es
+	
+	sti
+	
+	call syscall_handler   # syscall_handler(ax,cx,dx,si,di)
+	cli
+	addl $20, %esp         # clean-up of parameters
+	
+	pop %gs
+	pop %fs
+	pop %es
+	pop %ds
+	
+	CLEAR_NT_FLAG
+	iret
+.else	
+	/*
+	 * This macro distinguishes between two versions of ia32 exceptions.
+	 * One version has error word and the other does not have it.
+	 * The latter version fakes the error word on the stack so that the
+	 * handlers and istate_t can be the same for both types.
+	 */
+	.iflt \i-32
+		.if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
+			/* 
+			 * With error word, do nothing
+			 */
+                .else
+                        /*
+                         * Version without error word,
+                         */
+			subl $4, %esp
+                .endif
+        .else
+                /*
+                 * Version without error word,
+                 */
+		subl $4, %esp
+	.endif
+	
+	push %ds
+	push %es
+	push %fs
+	push %gs
+
+#ifdef CONFIG_DEBUG_ALLREGS
+	push %ebx
+	push %ebp
+	push %edi
+	push %esi
+#else
+	sub $16, %esp
+#endif
+	push %edx
+	push %ecx
+	push %eax
+	
+	# we must fill the data segment registers
+	movw $16,%ax
+	movw %ax,%ds
+	movw %ax,%es
+
+	pushl %esp          # *istate
+	pushl $(\i)         # intnum
+	call exc_dispatch   # excdispatch(intnum, *istate)
+	addl $8,%esp        # Clear arguments from stack
+
+	CLEAR_NT_FLAG # Modifies %ecx
+	
+	pop %eax
+	pop %ecx
+	pop %edx
+#ifdef CONFIG_DEBUG_ALLREGS
+	pop %esi
+	pop %edi
+	pop %ebp
+	pop %ebx
+#else
+	add $16, %esp
+#endif	
+	
+	pop %gs
+	pop %fs
+	pop %es
+	pop %ds
+
+	addl $4,%esp	# Skip error word, no matter whether real or fake.
+	iret
+.endif
+
+	.align INTERRUPT_ALIGN
+	.if (\n-\i)-1
+	handler "(\i+1)",\n
+	.endif
+.endm
+
+# keep in sync with pm.h !!!
+IDT_ITEMS=64
+.align INTERRUPT_ALIGN
+interrupt_handlers:
+h_start:
+	handler 0 IDT_ITEMS
+h_end:
+
+.data
+.global interrupt_handler_size
+
+interrupt_handler_size: .long (h_end-h_start)/IDT_ITEMS
Index: kernel/arch/ia32/src/atomic.S
===================================================================
--- kernel/arch/ia32/src/atomic.S	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/atomic.S	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,60 @@
+#
+# 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.
+#
+
+.text
+
+#ifdef CONFIG_SMP
+
+.global spinlock_arch
+
+#
+# This is a bus-and-hyperthreading-friendly implementation of spinlock 
+#
+spinlock_arch:
+	pushl %eax
+	pushl %ebx
+	
+	movl 12(%esp),%ebx
+
+0:	
+	#ifdef CONFIG_HT
+	pause			# Pentium 4's with HT love this instruction
+	#endif
+	movl (%ebx),%eax
+	testl %eax,%eax
+	jnz 0b			# lightweight looping while it is locked
+	incl %eax
+	xchgl %eax,(%ebx)	# now use the atomic operation
+	testl %eax,%eax
+	jnz 0b
+
+	popl %ebx
+	popl %eax
+	ret
+	
+#endif
Index: kernel/arch/ia32/src/bios/bios.c
===================================================================
--- kernel/arch/ia32/src/bios/bios.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/bios/bios.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/bios/bios.h>
+#include <arch/types.h>
+
+uintptr_t ebda = 0;
+
+void bios_init(void)
+{
+	/* Copy the EBDA address out from BIOS Data Area */
+	ebda = *((uint16_t *) BIOS_EBDA_PTR) * 0x10;
+}
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/src/boot/boot.S
===================================================================
--- kernel/arch/ia32/src/boot/boot.S	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/boot/boot.S	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,431 @@
+#
+# Copyright (C) 2001-2004 Jakub Jermar
+# Copyright (C) 2005-2006 Martin Decky
+# 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/boot/boot.h>
+#include <arch/boot/memmap.h>
+#include <arch/mm/page.h>
+#include <arch/pm.h>
+
+#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
+
+.section K_TEXT_START, "ax"
+
+KTEXT=8
+KDATA=16
+
+.code32
+.align 4
+.global multiboot_image_start
+multiboot_header:
+	.long MULTIBOOT_HEADER_MAGIC
+	.long MULTIBOOT_HEADER_FLAGS
+	.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)	# checksum
+	.long multiboot_header
+	.long unmapped_ktext_start
+	.long 0
+	.long 0
+	.long multiboot_image_start
+	
+multiboot_image_start:
+	movl $START_STACK, %esp			# initialize stack pointer
+	lgdt KA2PA(bootstrap_gdtr)		# initialize Global Descriptor Table register
+
+	movw $KDATA, %cx
+	movw %cx, %es
+	movw %cx, %fs
+	movw %cx, %gs
+	movw %cx, %ds					# kernel data + stack
+	movw %cx, %ss
+	
+	jmpl $KTEXT, $multiboot_meeting_point
+	multiboot_meeting_point:
+	
+	pushl %ebx							# save parameters from GRUB
+	pushl %eax
+	
+#ifdef CONFIG_FB
+	mov $vesa_init, %esi
+	mov $VESA_INIT_SEGMENT << 4, %edi
+	mov $e_vesa_init - vesa_init, %ecx
+	cld
+	rep movsb
+
+	mov $VESA_INIT_SEGMENT << 4, %edi
+	jmpl %edi
+	
+	vesa_meeting_point:
+	
+	mov %esi, KA2PA(vesa_ph_addr)
+	mov %di, KA2PA(vesa_height)
+	shr $16, %edi
+	mov %di, KA2PA(vesa_width)
+	mov %bx, KA2PA(vesa_scanline)
+	shr $16, %ebx
+	mov %bx, KA2PA(vesa_bpp)
+#endif	
+	
+	call map_kernel							# map kernel and turn paging on
+	
+	popl %eax
+	popl %ebx
+	cmpl $MULTIBOOT_LOADER_MAGIC, %eax				# compare GRUB signature
+	je valid_boot
+		
+		xorl %ecx, %ecx							# no memory size or map available
+		movl %ecx, e801memorysize
+		movl %ecx, e820counter
+		
+		jmp invalid_boot
+		
+	valid_boot:
+		
+		movl (%ebx), %eax						# ebx = physical address of struct multiboot_info
+		
+		bt $0, %eax								# mbi->flags[0] (mem_lower, mem_upper valid)
+		jc mem_valid
+			
+			xorl %ecx, %ecx
+			jmp mem_invalid
+			
+		mem_valid:
+		movl 4(%ebx), %ecx						# mbi->mem_lower
+		addl 8(%ebx), %ecx						# mbi->mem_upper
+		
+		mem_invalid:
+		movl %ecx, e801memorysize
+		
+		bt $3, %eax								# mbi->flags[3] (mods_count, mods_addr valid)
+		jc mods_valid
+			
+			xorl %ecx, %ecx
+			movl %ecx, init
+			jmp mods_end
+		
+		mods_valid:
+		
+		movl 20(%ebx), %ecx						# mbi->mods_count
+		movl %ecx, init
+		
+		cmpl $0, %ecx
+		je mods_end
+		
+		movl 24(%ebx), %esi						# mbi->mods_addr
+		movl $init, %edi
+		
+		mods_loop:
+		
+			movl 0(%esi), %edx					# mods->mod_start
+			addl $0x80000000, %edx
+			movl %edx, 4(%edi)
+			
+			movl 4(%esi), %edx
+			subl 0(%esi), %edx					# mods->mod_end - mods->mod_start
+			movl %edx, 8(%edi)
+			
+			addl $16, %esi
+			addl $8	, %edi
+			
+			loop mods_loop
+			
+		mods_end:
+		
+		bt $6, %eax								# mbi->flags[6] (mmap_length, mmap_addr valid)	
+		jc mmap_valid
+			
+			xorl %edx, %edx
+			jmp mmap_invalid
+			
+		mmap_valid:
+		movl 44(%ebx), %ecx						# mbi->mmap_length
+		movl 48(%ebx), %esi						# mbi->mmap_addr
+		movl $e820table, %edi
+		xorl %edx, %edx
+		
+		mmap_loop:
+			cmpl $0, %ecx
+			jle mmap_end
+			
+			movl 4(%esi), %eax					# mmap->base_addr_low
+			movl %eax, (%edi)
+			
+			movl 8(%esi), %eax					# mmap->base_addr_high
+			movl %eax, 4(%edi)
+			
+			movl 12(%esi), %eax					# mmap->length_low
+			movl %eax, 8(%edi)
+			
+			movl 16(%esi), %eax					# mmap->length_high
+			movl %eax, 12(%edi)
+			
+			movl 20(%esi), %eax					# mmap->type
+			movl %eax, 16(%edi)
+			
+			movl (%esi), %eax					# mmap->size
+			addl $0x4, %eax
+			addl %eax, %esi
+			subl %eax, %ecx
+			addl $MEMMAP_E820_RECORD_SIZE, %edi
+			incl %edx
+			jmp mmap_loop
+		
+		mmap_end:
+		
+		mmap_invalid:
+		movl %edx, e820counter
+		
+	invalid_boot:
+	
+#ifdef CONFIG_SMP
+	
+	# copy AP bootstrap routines below 1 MB
+	
+	movl $BOOT_OFFSET, %esi
+	movl $AP_BOOT_OFFSET, %edi
+	movl $_hardcoded_unmapped_size, %ecx
+	cld
+	rep movsb
+	
+#endif
+	
+	call main_bsp								# never returns
+
+	cli
+	hlt
+
+.global map_kernel
+map_kernel:
+	#
+	# Here we setup mapping for both the unmapped and mapped sections of the kernel.
+	# For simplicity, we map the entire 4G space.
+	#
+	movl %cr4, %ecx
+	orl $(1<<4), %ecx
+	movl %ecx, %cr4							# turn PSE on
+	
+	movl $(page_directory+0), %esi
+	movl $(page_directory+2048), %edi
+	xorl %ecx, %ecx
+	xorl %ebx, %ebx
+0:
+	movl $((1<<7)|(1<<0)), %eax
+	orl %ebx, %eax
+	movl %eax, (%esi,%ecx,4)					# mapping 0x00000000+%ecx*4M => 0x00000000+%ecx*4M
+	movl %eax, (%edi,%ecx,4)					# mapping 0x80000000+%ecx*4M => 0x00000000+%ecx*4M
+	addl $(4*1024*1024), %ebx
+
+	incl %ecx
+	cmpl $512, %ecx
+	jl 0b
+
+	movl %esi, %cr3
+	
+	# turn paging on
+	movl %cr0, %ebx
+	orl $(1<<31), %ebx
+	movl %ebx, %cr0
+	ret
+
+#ifdef CONFIG_FB
+vesa_init:
+	jmp $selector(VESA_INIT_DES), $vesa_init_real - vesa_init
+	
+.code16
+vesa_init_real:
+	
+	mov %cr0, %eax
+	and $~1, %eax
+	mov %eax, %cr0
+	
+	jmp $VESA_INIT_SEGMENT, $vesa_init_real2 - vesa_init
+	
+vesa_init_real2:
+	
+	mov $VESA_INIT_SEGMENT, %bx
+	
+	mov %bx, %es
+	mov %bx, %fs
+	mov %bx, %gs
+	mov %bx, %ds
+	mov %bx, %ss
+	
+	movl %esp, %eax
+	movl $0x0000fffc, %esp
+	movl $0x0000fffc, %ebp
+	pushl %eax
+	
+#define VESA_INFO_SIZE 1024
+
+#define VESA_MODE_LIST_PTR_OFFSET 14
+#define VESA_MODE_WIDTH_OFFSET 18
+#define VESA_MODE_HEIGHT_OFFSET 20
+#define VESA_MODE_BPP_OFFSET 25
+#define VESA_MODE_SCANLINE_OFFSET 16
+#define VESA_MODE_PHADDR_OFFSET 40
+
+#define VESA_END_OF_MODES 0xffff
+
+#define VESA_OK 0x4f
+
+#define VESA_GET_INFO 0x4f00
+#define VESA_GET_MODE_INFO 0x4f01
+#define VESA_SET_MODE 0x4f02
+
+#define CONFIG_VESA_BPP_a 255
+
+#if CONFIG_VESA_BPP == 24
+#undef CONFIG_VESA_BPP_a
+#define CONFIG_VESA_BPP_a 32
+#endif
+
+	mov $VESA_GET_INFO, %ax
+	mov $e_vesa_init - vesa_init, %di
+	push %di
+	int $0x10
+	
+	pop %di
+	cmp $VESA_OK, %al
+	jnz 0f
+	
+	mov 2 + VESA_MODE_LIST_PTR_OFFSET(%di), %si
+	mov %si, %gs
+	mov VESA_MODE_LIST_PTR_OFFSET(%di), %si
+	
+	add $VESA_INFO_SIZE, %di
+
+1:# Try next mode
+	mov %gs:(%si), %cx
+	cmp $VESA_END_OF_MODES, %cx
+	jz 0f
+	
+	inc %si
+	inc %si
+	push %cx
+	push %di
+	push %si
+	mov $VESA_GET_MODE_INFO, %ax
+	int $0x10
+	
+	pop %si
+	pop %di
+	pop %cx
+	cmp $VESA_OK, %al
+	jnz 0f
+	
+	mov $CONFIG_VESA_WIDTH, %ax
+	cmp VESA_MODE_WIDTH_OFFSET(%di), %ax
+	jnz 1b
+	
+	mov $CONFIG_VESA_HEIGHT,%ax
+	cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax
+	jnz 1b
+	
+	mov $CONFIG_VESA_BPP, %al
+	cmp VESA_MODE_BPP_OFFSET(%di), %al
+	jz 2f
+	
+	mov $CONFIG_VESA_BPP_a, %al
+	cmp VESA_MODE_BPP_OFFSET(%di), %al
+	jnz 1b
+	
+2:
+	
+	mov %cx, %bx
+	or $0xc000, %bx
+	push %di
+	mov $VESA_SET_MODE, %ax
+	int $0x10
+	
+	pop %di
+	cmp $VESA_OK, %al
+	jnz 0f
+	
+	mov VESA_MODE_PHADDR_OFFSET(%di), %esi
+	mov VESA_MODE_WIDTH_OFFSET(%di), %ax
+	shl $16, %eax
+	mov VESA_MODE_HEIGHT_OFFSET(%di), %ax
+	mov VESA_MODE_BPP_OFFSET(%di), %bl
+	xor %bh, %bh
+	shl $16, %ebx
+	mov VESA_MODE_SCANLINE_OFFSET(%di), %bx
+	mov %eax, %edi
+	
+8:	
+	
+	mov %cr0, %eax
+	or $1, %eax
+	mov %eax, %cr0
+	
+	jmp 9f
+9:
+	
+	ljmpl $KTEXT, $(vesa_init_protect - vesa_init + VESA_INIT_SEGMENT << 4)
+
+0:# No prefered mode found
+	mov $0x111, %cx
+	push %di
+	push %cx
+	mov $VESA_GET_MODE_INFO, %ax
+	int $0x10
+	
+	pop %cx
+	pop %di
+	cmp $VESA_OK, %al
+	jnz 1f
+	jz 2b						# Force relative jump
+	
+1:
+	mov $0x0003, %ax
+	int $0x10
+	mov $0xffffffff, %edi		# EGA text mode used, because of problems with VESA
+	xor %ax, %ax
+	jz 8b						# Force relative jump
+	
+
+.code32
+vesa_init_protect:
+	popl %esp
+
+	movw $KDATA, %cx
+	movw %cx, %es
+	movw %cx, %fs
+	movw %cx, %gs
+	movw %cx, %ds					# kernel data + stack
+	movw %cx, %ss
+	
+	jmpl $KTEXT, $vesa_meeting_point
+
+.align 4
+e_vesa_init:
+#endif	
+
+.section K_DATA_START, "aw", @progbits
+
+.align 4096
+page_directory:
+	.space 4096, 0
Index: kernel/arch/ia32/src/context.s
===================================================================
--- kernel/arch/ia32/src/context.s	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/context.s	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,72 @@
+#
+# 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.
+#
+
+.text
+
+.global context_save_arch
+.global context_restore_arch
+
+
+## Save current CPU context
+#
+# Save CPU context to the context_t variable
+# pointed by the 1st argument. Returns 1 in EAX.
+#
+context_save_arch:
+	movl 0(%esp),%eax	# the caller's return %eip
+	movl 4(%esp),%edx	# address of the kernel_context variable to save context to
+
+	movl %esp,0(%edx)	# %esp -> ctx->sp
+	movl %eax,4(%edx)	# %eip -> ctx->pc
+	movl %ebx,8(%edx)	# %ebx -> ctx->ebx
+	movl %esi,12(%edx)	# %esi -> ctx->esi
+	movl %edi,16(%edx)	# %edi -> ctx->edi
+	movl %ebp,20(%edx)	# %ebp -> ctx->ebp
+
+	xorl %eax,%eax		# context_save returns 1
+	incl %eax
+	ret
+
+
+## Restore saved CPU context
+#
+# Restore CPU context from context_t variable
+# pointed by the 1st argument. Returns 0 in EAX.
+#
+context_restore_arch:
+	movl 4(%esp),%eax	# address of the kernel_context variable to restore context from
+	movl 0(%eax),%esp	# ctx->sp -> %esp
+	movl 4(%eax),%edx	# ctx->pc -> %edx
+	movl 8(%eax),%ebx	# ctx->ebx -> %ebx
+	movl 12(%eax),%esi	# ctx->esi -> %esi
+	movl 16(%eax),%edi	# ctx->edi -> %edi
+	movl 20(%eax),%ebp	# ctx->ebp -> %ebp
+
+	movl %edx,0(%esp)	# ctx->pc -> saver's return %eip
+	xorl %eax,%eax		# context_restore returns 0
+	ret
Index: kernel/arch/ia32/src/cpu/cpu.c
===================================================================
--- kernel/arch/ia32/src/cpu/cpu.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/cpu/cpu.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,166 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup ia32
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/cpu.h>
+#include <arch/cpuid.h>
+#include <arch/pm.h>
+
+#include <arch.h>
+#include <arch/types.h>
+#include <print.h>
+#include <typedefs.h>
+#include <fpu_context.h>
+
+#include <arch/smp/apic.h>
+
+/*
+ * Identification of CPUs.
+ * Contains only non-MP-Specification specific SMP code.
+ */
+#define AMD_CPUID_EBX	0x68747541
+#define AMD_CPUID_ECX 	0x444d4163
+#define AMD_CPUID_EDX 	0x69746e65
+
+#define INTEL_CPUID_EBX	0x756e6547
+#define INTEL_CPUID_ECX 0x6c65746e
+#define INTEL_CPUID_EDX 0x49656e69
+
+
+enum vendor {
+	VendorUnknown=0,
+	VendorAMD,
+	VendorIntel
+};
+
+static char *vendor_str[] = {
+	"Unknown Vendor",
+	"AuthenticAMD",
+	"GenuineIntel"
+};
+
+void fpu_disable(void)
+{
+	__asm__ volatile (
+		"mov %%cr0,%%eax;"
+		"or $8,%%eax;"
+		"mov %%eax,%%cr0;"
+		:
+		:
+		:"%eax"
+	);
+}
+
+void fpu_enable(void)
+{
+	__asm__ volatile (
+		"mov %%cr0,%%eax;"
+		"and $0xffFFffF7,%%eax;"
+		"mov %%eax,%%cr0;"
+		:
+		:
+		:"%eax"
+	);	
+}
+
+void cpu_arch_init(void)
+{
+	cpuid_feature_info fi;
+	cpuid_extended_feature_info efi;
+	cpu_info_t info;
+	uint32_t help = 0;
+	
+	CPU->arch.tss = tss_p;
+	CPU->arch.tss->iomap_base = &CPU->arch.tss->iomap[0] - ((uint8_t *) CPU->arch.tss);
+
+	CPU->fpu_owner = NULL;
+
+	cpuid(1, &info);
+
+	fi.word = info.cpuid_edx;
+	efi.word = info.cpuid_ecx;
+	
+	if (fi.bits.fxsr)
+		fpu_fxsr();
+	else
+		fpu_fsr();	
+	
+	if (fi.bits.sse) {
+		asm volatile (
+			"mov %%cr4,%0\n"
+			"or %1,%0\n"
+			"mov %0,%%cr4\n"
+			: "+r" (help)
+			: "i" (CR4_OSFXSR_MASK|(1<<10)) 
+		);
+	}
+}
+
+void cpu_identify(void)
+{
+	cpu_info_t info;
+
+	CPU->arch.vendor = VendorUnknown;
+	if (has_cpuid()) {
+		cpuid(0, &info);
+
+		/*
+		 * Check for AMD processor.
+		 */
+		if (info.cpuid_ebx==AMD_CPUID_EBX && info.cpuid_ecx==AMD_CPUID_ECX && info.cpuid_edx==AMD_CPUID_EDX) {
+			CPU->arch.vendor = VendorAMD;
+		}
+
+		/*
+		 * Check for Intel processor.
+		 */		
+		if (info.cpuid_ebx==INTEL_CPUID_EBX && info.cpuid_ecx==INTEL_CPUID_ECX && info.cpuid_edx==INTEL_CPUID_EDX) {
+			CPU->arch.vendor = VendorIntel;
+		}
+				
+		cpuid(1, &info);
+		CPU->arch.family = (info.cpuid_eax>>8)&0xf;
+		CPU->arch.model = (info.cpuid_eax>>4)&0xf;
+		CPU->arch.stepping = (info.cpuid_eax>>0)&0xf;						
+	}
+}
+
+void cpu_print_report(cpu_t* m)
+{
+	printf("cpu%d: (%s family=%d model=%d stepping=%d) %dMHz\n",
+		m->id, vendor_str[m->arch.vendor], m->arch.family, m->arch.model, m->arch.stepping,
+		m->frequency_mhz);
+}
+
+/** @}
+ */
Index: kernel/arch/ia32/src/ddi/ddi.c
===================================================================
--- kernel/arch/ia32/src/ddi/ddi.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/ddi/ddi.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2006 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.
+ */
+
+/** @addtogroup ia32ddi
+ * @{
+ */
+/** @file
+ */
+
+#include <ddi/ddi.h>
+#include <arch/ddi/ddi.h>
+#include <proc/task.h>
+#include <arch/types.h>
+#include <typedefs.h>
+#include <adt/bitmap.h>
+#include <mm/slab.h>
+#include <arch/pm.h>
+#include <errno.h>
+#include <arch/cpu.h>
+#include <cpu.h>
+#include <arch.h>
+#include <align.h>
+
+/** Enable I/O space range for task.
+ *
+ * Interrupts are disabled and task is locked.
+ *
+ * @param task Task.
+ * @param ioaddr Startign I/O space address.
+ * @param size Size of the enabled I/O range.
+ *
+ * @return 0 on success or an error code from errno.h.
+ */
+int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
+{
+	count_t bits;
+
+	bits = ioaddr + size;
+	if (bits > IO_PORTS)
+		return ENOENT;
+
+	if (task->arch.iomap.bits < bits) {
+		bitmap_t oldiomap;
+		uint8_t *newmap;
+	
+		/*
+		 * The I/O permission bitmap is too small and needs to be grown.
+		 */
+		
+		newmap = (uint8_t *) malloc(BITS2BYTES(bits), FRAME_ATOMIC);
+		if (!newmap)
+			return ENOMEM;
+		
+		bitmap_initialize(&oldiomap, task->arch.iomap.map, task->arch.iomap.bits);
+		bitmap_initialize(&task->arch.iomap, newmap, bits);
+
+		/*
+		 * Mark the new range inaccessible.
+		 */
+		bitmap_set_range(&task->arch.iomap, oldiomap.bits, bits - oldiomap.bits);
+
+		/*
+		 * In case there really existed smaller iomap,
+		 * copy its contents and deallocate it.
+		 */		
+		if (oldiomap.bits) {
+			bitmap_copy(&task->arch.iomap, &oldiomap, oldiomap.bits);
+			free(oldiomap.map);
+		}
+	}
+
+	/*
+	 * Enable the range and we are done.
+	 */
+	bitmap_clear_range(&task->arch.iomap, (index_t) ioaddr, (count_t) size);
+
+	/*
+	 * Increment I/O Permission bitmap generation counter.
+	 */
+	task->arch.iomapver++;
+
+	return 0;
+}
+
+/** Install I/O Permission bitmap.
+ *
+ * Current task's I/O permission bitmap, if any, is installed
+ * in the current CPU's TSS.
+ *
+ * Interrupts must be disabled prior this call.
+ */
+void io_perm_bitmap_install(void)
+{
+	count_t bits;
+	ptr_16_32_t cpugdtr;
+	descriptor_t *gdt_p;
+	count_t ver;
+
+	/* First, copy the I/O Permission Bitmap. */
+	spinlock_lock(&TASK->lock);
+	ver = TASK->arch.iomapver;
+	if ((bits = TASK->arch.iomap.bits)) {
+		bitmap_t iomap;
+	
+		ASSERT(TASK->arch.iomap.map);
+		bitmap_initialize(&iomap, CPU->arch.tss->iomap, TSS_IOMAP_SIZE * 8);
+		bitmap_copy(&iomap, &TASK->arch.iomap, TASK->arch.iomap.bits);
+		/*
+		 * It is safe to set the trailing eight bits because of the extra
+		 * convenience byte in TSS_IOMAP_SIZE.
+		 */
+		bitmap_set_range(&iomap, ALIGN_UP(TASK->arch.iomap.bits, 8), 8);
+	}
+	spinlock_unlock(&TASK->lock);
+
+	/*
+	 * Second, adjust TSS segment limit.
+	 * Take the extra ending byte with all bits set into account.
+	 */
+	gdtr_store(&cpugdtr);
+	gdt_p = (descriptor_t *) cpugdtr.base;
+	gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + BITS2BYTES(bits));
+	gdtr_load(&cpugdtr);
+
+	/*
+	 * Before we load new TSS limit, the current TSS descriptor
+	 * type must be changed to describe inactive TSS.
+	 */
+	gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL;
+	tr_load(selector(TSS_DES));
+	
+	/*
+	 * Update the generation count so that faults caused by
+	 * early accesses can be serviced.
+	 */
+	CPU->arch.iomapver_copy = ver;
+}
+
+/** @}
+ */
Index: kernel/arch/ia32/src/debug/panic.s
===================================================================
--- kernel/arch/ia32/src/debug/panic.s	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/debug/panic.s	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,34 @@
+#
+# 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.
+#
+
+.text
+.global panic_printf
+
+panic_printf:
+	movl $halt,(%esp)	# fake stack to make printf return to halt
+	jmp printf
Index: kernel/arch/ia32/src/debugger.c
===================================================================
--- kernel/arch/ia32/src/debugger.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/debugger.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,1 @@
+../../amd64/src/debugger.c
Index: kernel/arch/ia32/src/delay.s
===================================================================
--- kernel/arch/ia32/src/delay.s	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/delay.s	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,50 @@
+#
+# 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:
+	movl 4(%esp),%ecx	# move argument to %ecx
+0:	lahf
+	dec %ecx
+	jnz 0b
+	ret
+
+asm_fake_loop:
+	movl 4(%esp),%ecx	# move argument to %ecx
+0:	lahf
+	dec %ecx
+	jz 0b
+	ret
Index: kernel/arch/ia32/src/drivers/ega.c
===================================================================
--- kernel/arch/ia32/src/drivers/ega.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/drivers/ega.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,150 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup ia32	
+ * @{
+ */
+/**
+ * @file
+ * @brief EGA driver.
+ */
+
+#include <arch/drivers/ega.h>
+#include <putchar.h>
+#include <mm/page.h>
+#include <mm/as.h>
+#include <arch/mm/page.h>
+#include <synch/spinlock.h>
+#include <arch/types.h>
+#include <arch/asm.h>
+#include <memstr.h>
+#include <console/chardev.h>
+#include <console/console.h>
+#include <sysinfo/sysinfo.h>
+
+/*
+ * The EGA driver.
+ * Simple and short. Function for displaying characters and "scrolling".
+ */
+
+SPINLOCK_INITIALIZE(egalock);
+static uint32_t ega_cursor;
+static uint8_t *videoram;
+
+static void ega_putchar(chardev_t *d, const char ch);
+
+chardev_t ega_console;
+static chardev_operations_t ega_ops = {
+	.write = ega_putchar
+};
+
+void ega_move_cursor(void);
+
+void ega_init(void)
+{
+	uint8_t hi, lo;
+	
+	videoram = (uint8_t *) hw_map(VIDEORAM, SCREEN * 2);
+	outb(0x3d4, 0xe);
+	hi = inb(0x3d5);
+	outb(0x3d4, 0xf);
+	lo = inb(0x3d5);
+	ega_cursor = (hi << 8) | lo;
+
+	chardev_initialize("ega_out", &ega_console, &ega_ops);
+	stdout = &ega_console;
+	
+	sysinfo_set_item_val("fb", NULL, true);
+	sysinfo_set_item_val("fb.kind", NULL, 2);
+	sysinfo_set_item_val("fb.width", NULL, ROW);
+	sysinfo_set_item_val("fb.height", NULL, ROWS);
+	sysinfo_set_item_val("fb.address.physical", NULL, VIDEORAM);
+	
+#ifndef CONFIG_FB
+	putchar('\n');
+#endif	
+}
+
+static void ega_display_char(char ch)
+{
+	videoram[ega_cursor * 2] = ch;
+}
+
+/*
+ * This function takes care of scrolling.
+ */
+static void ega_check_cursor(void)
+{
+	if (ega_cursor < SCREEN)
+		return;
+
+	memcpy((void *) videoram, (void *) (videoram + ROW * 2), (SCREEN - ROW) * 2);
+	memsetw((uintptr_t) (videoram + (SCREEN - ROW) * 2), ROW, 0x0720);
+	ega_cursor = ega_cursor - ROW;
+}
+
+void ega_putchar(chardev_t *d, const char ch)
+{
+	ipl_t ipl;
+
+	ipl = interrupts_disable();
+	spinlock_lock(&egalock);
+
+	switch (ch) {
+		case '\n':
+			ega_cursor = (ega_cursor + ROW) - ega_cursor % ROW;
+			break;
+		case '\t':
+			ega_cursor = (ega_cursor + 8) - ega_cursor % 8;
+			break; 
+		case '\b':
+			if (ega_cursor % ROW)
+				ega_cursor--;
+			break;
+		default:
+			ega_display_char(ch);
+			ega_cursor++;
+			break;
+	}
+	ega_check_cursor();
+	ega_move_cursor();
+
+	spinlock_unlock(&egalock);
+	interrupts_restore(ipl);
+}
+
+void ega_move_cursor(void)
+{
+	outb(0x3d4, 0xe);
+	outb(0x3d5, (ega_cursor >> 8) & 0xff);
+	outb(0x3d4, 0xf);
+	outb(0x3d5, ega_cursor & 0xff);	
+}
+
+/** @}
+ */
Index: kernel/arch/ia32/src/drivers/i8254.c
===================================================================
--- kernel/arch/ia32/src/drivers/i8254.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/drivers/i8254.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup ia32	
+ * @{
+ */
+/**
+ * @file
+ * @brief	i8254 chip driver.
+ *
+ * Low level time functions.
+ */
+
+#include <arch/types.h>
+#include <time/clock.h>
+#include <time/delay.h>
+#include <arch/interrupt.h>
+#include <arch/drivers/i8259.h>
+#include <arch/drivers/i8254.h>
+#include <cpu.h>
+#include <config.h>
+#include <arch/pm.h>
+#include <arch/asm.h>
+#include <arch/cpuid.h>
+#include <arch.h>
+#include <time/delay.h>
+#include <interrupt.h>
+
+#define CLK_PORT1	0x40
+#define CLK_PORT4	0x43
+
+#define CLK_CONST	1193180
+#define MAGIC_NUMBER	1194
+
+static void i8254_interrupt(int n, istate_t *istate);
+
+void i8254_init(void)
+{
+	i8254_normal_operation();
+}
+
+void i8254_normal_operation(void)
+{
+	outb(CLK_PORT4, 0x36);
+	pic_disable_irqs(1<<IRQ_CLK);
+	outb(CLK_PORT1, (CLK_CONST/HZ) & 0xf);
+	outb(CLK_PORT1, (CLK_CONST/HZ) >> 8);
+	pic_enable_irqs(1<<IRQ_CLK);
+	exc_register(VECTOR_CLK, "i8254_clock", (iroutine) i8254_interrupt);
+}
+
+#define LOOPS 150000
+#define SHIFT 11
+void i8254_calibrate_delay_loop(void)
+{
+	uint64_t clk1, clk2;
+	uint32_t t1, t2, o1, o2;
+	uint8_t not_ok;
+
+
+	/*
+	 * One-shot timer. Count-down from 0xffff at 1193180Hz
+	 * MAGIC_NUMBER is the magic value for 1ms.
+	 */
+	outb(CLK_PORT4, 0x30);
+	outb(CLK_PORT1, 0xff);
+	outb(CLK_PORT1, 0xff);
+
+	do {
+		/* will read both status and count */
+		outb(CLK_PORT4, 0xc2);
+		not_ok = (inb(CLK_PORT1)>>6)&1;
+		t1 = inb(CLK_PORT1);
+		t1 |= inb(CLK_PORT1) << 8;
+	} while (not_ok);
+
+	asm_delay_loop(LOOPS);
+
+	outb(CLK_PORT4, 0xd2);
+	t2 = inb(CLK_PORT1);
+	t2 |= inb(CLK_PORT1) << 8;
+
+	/*
+	 * We want to determine the overhead of the calibrating mechanism.
+	 */
+	outb(CLK_PORT4, 0xd2);
+	o1 = inb(CLK_PORT1);
+	o1 |= inb(CLK_PORT1) << 8;
+
+	asm_fake_loop(LOOPS);
+
+	outb(CLK_PORT4, 0xd2);
+	o2 = inb(CLK_PORT1);
+	o2 |= inb(CLK_PORT1) << 8;
+
+	CPU->delay_loop_const = ((MAGIC_NUMBER*LOOPS)/1000) / ((t1-t2)-(o1-o2)) + (((MAGIC_NUMBER*LOOPS)/1000) % ((t1-t2)-(o1-o2)) ? 1 : 0);
+
+	clk1 = rdtsc();
+	delay(1<<SHIFT);
+	clk2 = rdtsc();
+	
+	CPU->frequency_mhz = (clk2-clk1)>>SHIFT;
+
+	return;
+}
+
+void i8254_interrupt(int n, istate_t *istate)
+{
+	trap_virtual_eoi();
+	clock();
+}
+
+/** @}
+ */
Index: kernel/arch/ia32/src/drivers/i8259.c
===================================================================
--- kernel/arch/ia32/src/drivers/i8259.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/drivers/i8259.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,134 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup ia32	
+ * @{
+ */
+/**
+ * @file
+ * @brief PIC driver.
+ *
+ * Programmable Interrupt Controller for UP systems based on i8259 chip.
+ */
+
+#include <arch/drivers/i8259.h>
+#include <cpu.h>
+#include <arch/types.h>
+#include <arch/asm.h>
+#include <arch.h>
+#include <print.h>
+#include <interrupt.h>
+
+static void pic_spurious(int n, istate_t *istate);
+
+void i8259_init(void)
+{
+	/* ICW1: this is ICW1, ICW4 to follow */
+	outb(PIC_PIC0PORT1, PIC_ICW1 | PIC_NEEDICW4);
+
+	/* ICW2: IRQ 0 maps to INT IRQBASE */
+	outb(PIC_PIC0PORT2, IVT_IRQBASE);
+
+	/* ICW3: pic1 using IRQ IRQ_PIC1 */
+	outb(PIC_PIC0PORT2, 1 << IRQ_PIC1);
+
+	/* ICW4: i8086 mode */
+	outb(PIC_PIC0PORT2, 1);
+
+	/* ICW1: ICW1, ICW4 to follow */
+	outb(PIC_PIC1PORT1, PIC_ICW1 | PIC_NEEDICW4);
+
+	/* ICW2: IRQ 8 maps to INT (IVT_IRQBASE + 8) */
+	outb(PIC_PIC1PORT2, IVT_IRQBASE + 8);
+
+	/* ICW3: pic1 is known as IRQ_PIC1 */
+	outb(PIC_PIC1PORT2, IRQ_PIC1);
+
+	/* ICW4: i8086 mode */
+	outb(PIC_PIC1PORT2, 1);
+
+	/*
+	 * Register interrupt handler for the PIC spurious interrupt.
+	 */
+	exc_register(VECTOR_PIC_SPUR, "pic_spurious", (iroutine) pic_spurious);	
+
+	/*
+	 * Set the enable/disable IRQs handlers.
+	 * Set the End-of-Interrupt handler.
+	 */
+	enable_irqs_function = pic_enable_irqs;
+	disable_irqs_function = pic_disable_irqs;
+	eoi_function = pic_eoi;
+
+	pic_disable_irqs(0xffff);		/* disable all irq's */
+	pic_enable_irqs(1<<IRQ_PIC1);		/* but enable pic1 */
+}
+
+void pic_enable_irqs(uint16_t irqmask)
+{
+	uint8_t x;
+
+	if (irqmask & 0xff) {
+		x = inb(PIC_PIC0PORT2);
+		outb(PIC_PIC0PORT2, x & (~(irqmask & 0xff)));
+	}
+	if (irqmask >> 8) {
+		x = inb(PIC_PIC1PORT2);
+		outb(PIC_PIC1PORT2, x & (~(irqmask >> 8)));
+	}
+}
+
+void pic_disable_irqs(uint16_t irqmask)
+{
+	uint8_t x;
+
+	if (irqmask & 0xff) {
+		x = inb(PIC_PIC0PORT2);
+		outb(PIC_PIC0PORT2, x | (irqmask & 0xff));
+	}
+	if (irqmask >> 8) {
+		x = inb(PIC_PIC1PORT2);
+		outb(PIC_PIC1PORT2, x | (irqmask >> 8));
+	}
+}
+
+void pic_eoi(void)
+{
+	outb(0x20,0x20);
+	outb(0xa0,0x20);
+}
+
+void pic_spurious(int n, istate_t *istate)
+{
+#ifdef CONFIG_DEBUG
+	printf("cpu%d: PIC spurious interrupt\n", CPU->id);
+#endif
+}
+
+/** @}
+ */
Index: kernel/arch/ia32/src/drivers/vesa.c
===================================================================
--- kernel/arch/ia32/src/drivers/vesa.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/drivers/vesa.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2006 Jakub Vana
+ * 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.
+ */
+
+/** @addtogroup ia32	
+ * @{
+ */
+/**
+ * @file
+ * @brief VESA frame buffer driver.
+ */
+
+#ifdef CONFIG_FB
+
+#include <genarch/fb/fb.h>
+#include <arch/drivers/vesa.h>
+#include <putchar.h>
+#include <mm/page.h>
+#include <mm/frame.h>
+#include <mm/as.h>
+#include <arch/mm/page.h>
+#include <synch/spinlock.h>
+#include <arch/asm.h>
+#include <arch/types.h>
+#include <typedefs.h>
+#include <memstr.h>
+#include <bitops.h>
+
+uint32_t vesa_ph_addr;
+uint16_t vesa_width;
+uint16_t vesa_height;
+uint16_t vesa_bpp;
+uint16_t vesa_scanline;
+
+int vesa_present(void)
+{
+	if (vesa_width != 0xffff)
+		return true;
+	if (vesa_height != 0xffff)
+		return true;
+	return false;
+}
+
+void vesa_init(void)
+{
+	fb_init(vesa_ph_addr, vesa_width, vesa_height, vesa_bpp, vesa_scanline);
+}
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/ia32/src/fpu_context.c
===================================================================
--- kernel/arch/ia32/src/fpu_context.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/fpu_context.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2005 Jakub Vana
+ * 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ *
+ */
+
+#include <fpu_context.h>
+#include <arch.h>
+#include <cpu.h>
+
+typedef void (*fpu_context_function)(fpu_context_t *fctx);
+
+static fpu_context_function fpu_save,fpu_restore;
+
+
+
+static void fpu_context_f_save(fpu_context_t *fctx)
+{
+	__asm__ volatile (
+		"fnsave %0"
+		: "=m"(*fctx)
+		);
+}
+
+static void fpu_context_f_restore(fpu_context_t *fctx)
+{
+	__asm__ volatile (
+		"frstor %0"
+		: "=m"(*fctx)
+		);
+}
+
+static void fpu_context_fx_save(fpu_context_t *fctx)
+{
+	__asm__ volatile (
+		"fxsave %0"
+		: "=m"(*fctx)
+		);
+}
+
+static void fpu_context_fx_restore(fpu_context_t *fctx)
+{
+	__asm__ volatile (
+		"fxrstor %0"
+		: "=m"(*fctx)
+		);
+}
+
+/*
+	Setup using fxsr instruction
+*/
+void fpu_fxsr(void)
+{
+	fpu_save=fpu_context_fx_save;
+	fpu_restore=fpu_context_fx_restore;
+}
+/*
+	Setup using not fxsr instruction
+*/
+void fpu_fsr(void)
+{
+	fpu_save=fpu_context_f_save;
+	fpu_restore=fpu_context_f_restore;
+}
+
+
+
+void fpu_context_save(fpu_context_t *fctx)
+{
+	fpu_save(fctx);
+}
+
+void fpu_context_restore(fpu_context_t *fctx)
+{
+	fpu_restore(fctx);
+}
+
+
+
+void fpu_init()
+{
+	uint32_t help0=0,help1=0;
+	__asm__ volatile (
+		"fninit;\n"
+		"stmxcsr %0\n"
+		"mov %0,%1;\n"
+		"or %2,%1;\n"
+		"mov %1,%0;\n"
+		"ldmxcsr %0;\n"
+		:"+m"(help0),"+r"(help1)
+		:"i"(0x1f80)
+	);
+}
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/src/ia32.c
===================================================================
--- kernel/arch/ia32/src/ia32.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/ia32.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ */
+
+ /** @addtogroup ia32
+ * @{
+ */
+/** @file
+ */
+
+#include <arch.h>
+
+#include <arch/types.h>
+#include <typedefs.h>
+
+#include <arch/pm.h>
+
+#include <arch/drivers/ega.h>
+#include <arch/drivers/vesa.h>
+#include <genarch/i8042/i8042.h>
+#include <arch/drivers/i8254.h>
+#include <arch/drivers/i8259.h>
+
+#include <arch/context.h>
+
+#include <config.h>
+
+#include <arch/interrupt.h>
+#include <arch/asm.h>
+#include <genarch/acpi/acpi.h>
+
+#include <arch/bios/bios.h>
+
+#include <arch/mm/memory_init.h>
+#include <interrupt.h>
+#include <arch/debugger.h>
+#include <proc/thread.h>
+#include <syscall/syscall.h>
+#include <console/console.h>
+
+void arch_pre_mm_init(void)
+{
+	pm_init();
+
+	if (config.cpu_active == 1) {
+		bios_init();
+		i8259_init();	/* PIC */
+		i8254_init();	/* hard clock */
+		
+		exc_register(VECTOR_SYSCALL, "syscall", (iroutine) syscall);
+		
+		#ifdef CONFIG_SMP
+		exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown",
+			     (iroutine) tlb_shootdown_ipi);
+		#endif /* CONFIG_SMP */
+	}
+}
+
+void arch_post_mm_init(void)
+{
+	if (config.cpu_active == 1) {
+
+#ifdef CONFIG_FB
+		if (vesa_present()) 
+			vesa_init();
+		else
+#endif
+			ega_init();	/* video */
+		
+		
+		/* Enable debugger */
+		debugger_init();
+		/* Merge all memory zones to 1 big zone */
+		zone_merge_all();
+	}
+}
+
+void arch_pre_smp_init(void)
+{
+	if (config.cpu_active == 1) {
+		memory_print_map();
+		
+		#ifdef CONFIG_SMP
+		acpi_init();
+		#endif /* CONFIG_SMP */
+	}
+}
+
+void arch_post_smp_init(void)
+{
+	i8042_init();	/* keyboard controller */
+}
+
+void calibrate_delay_loop(void)
+{
+	i8254_calibrate_delay_loop();
+	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();
+	}
+}
+
+/** Set thread-local-storage pointer
+ *
+ * TLS pointer is set in GS register. That means, the GS contains
+ * selector, and the descriptor->base is the correct address.
+ */
+unative_t sys_tls_set(unative_t addr)
+{
+	THREAD->arch.tls = addr;
+	set_tls_desc(addr);
+
+	return 0;
+}
+
+/** Acquire console back for kernel
+ *
+ */
+void arch_grab_console(void)
+{
+	i8042_grab();
+}
+/** Return console to userspace
+ *
+ */
+void arch_release_console(void)
+{
+	i8042_release();
+}
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/src/interrupt.c
===================================================================
--- kernel/arch/ia32/src/interrupt.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/interrupt.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,210 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup ia32interrupt
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/interrupt.h>
+#include <syscall/syscall.h>
+#include <print.h>
+#include <debug.h>
+#include <panic.h>
+#include <arch/drivers/i8259.h>
+#include <func.h>
+#include <cpu.h>
+#include <arch/asm.h>
+#include <mm/tlb.h>
+#include <mm/as.h>
+#include <arch.h>
+#include <symtab.h>
+#include <proc/thread.h>
+#include <proc/task.h>
+#include <synch/spinlock.h>
+#include <arch/ddi/ddi.h>
+#include <ipc/sysipc.h>
+#include <interrupt.h>
+
+/*
+ * Interrupt and exception dispatching.
+ */
+
+void (* disable_irqs_function)(uint16_t irqmask) = NULL;
+void (* enable_irqs_function)(uint16_t irqmask) = NULL;
+void (* eoi_function)(void) = NULL;
+
+void PRINT_INFO_ERRCODE(istate_t *istate)
+{
+	char *symbol = get_symtab_entry(istate->eip);
+
+	if (!symbol)
+		symbol = "";
+
+	if (CPU)
+		printf("----------------EXCEPTION OCCURED (cpu%d)----------------\n", CPU->id);
+	else
+		printf("----------------EXCEPTION OCCURED----------------\n");
+		
+	printf("%%eip: %#x (%s)\n",istate->eip,symbol);
+	printf("ERROR_WORD=%#x\n", istate->error_word);
+	printf("%%cs=%#x,flags=%#x\n", istate->cs, istate->eflags);
+	printf("%%eax=%#x, %%ecx=%#x, %%edx=%#x, %%esp=%#x\n",  istate->eax,istate->ecx,istate->edx,&istate->stack[0]);
+#ifdef CONFIG_DEBUG_ALLREGS
+	printf("%%esi=%#x, %%edi=%#x, %%ebp=%#x, %%ebx=%#x\n",  istate->esi,istate->edi,istate->ebp,istate->ebx);
+#endif
+	printf("stack: %#x, %#x, %#x, %#x\n", istate->stack[0], istate->stack[1], istate->stack[2], istate->stack[3]);
+	printf("       %#x, %#x, %#x, %#x\n", istate->stack[4], istate->stack[5], istate->stack[6], istate->stack[7]);
+}
+
+void null_interrupt(int n, istate_t *istate)
+{
+	fault_if_from_uspace(istate, "unserviced interrupt: %d", n);
+
+	PRINT_INFO_ERRCODE(istate);
+	panic("unserviced interrupt: %d\n", n);
+}
+
+/** General Protection Fault. */
+void gp_fault(int n, istate_t *istate)
+{
+	if (TASK) {
+		count_t ver;
+		
+		spinlock_lock(&TASK->lock);
+		ver = TASK->arch.iomapver;
+		spinlock_unlock(&TASK->lock);
+	
+		if (CPU->arch.iomapver_copy != ver) {
+			/*
+			 * This fault can be caused by an early access
+			 * to I/O port because of an out-dated
+			 * I/O Permission bitmap installed on CPU.
+			 * Install the fresh copy and restart
+			 * the instruction.
+			 */
+			io_perm_bitmap_install();
+			return;
+		}
+		fault_if_from_uspace(istate, "general protection fault");
+	}
+
+	PRINT_INFO_ERRCODE(istate);
+	panic("general protection fault\n");
+}
+
+void ss_fault(int n, istate_t *istate)
+{
+	fault_if_from_uspace(istate, "stack fault");
+
+	PRINT_INFO_ERRCODE(istate);
+	panic("stack fault\n");
+}
+
+void simd_fp_exception(int n, istate_t *istate)
+{
+	uint32_t mxcsr;
+	asm
+	(
+		"stmxcsr %0;\n"
+		:"=m"(mxcsr)
+	);
+	fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR: %#zx",
+			     (unative_t)mxcsr);
+
+	PRINT_INFO_ERRCODE(istate);
+	printf("MXCSR: %#zx\n",(unative_t)(mxcsr));
+	panic("SIMD FP exception(19)\n");
+}
+
+void nm_fault(int n, istate_t *istate)
+{
+#ifdef CONFIG_FPU_LAZY     
+	scheduler_fpu_lazy_request();
+#else
+	fault_if_from_uspace(istate, "fpu fault");
+	panic("fpu fault");
+#endif
+}
+
+void syscall(int n, istate_t *istate)
+{
+	panic("Obsolete syscall handler.");
+}
+
+void tlb_shootdown_ipi(int n, istate_t *istate)
+{
+	trap_virtual_eoi();
+	tlb_shootdown_ipi_recv();
+}
+
+void trap_virtual_enable_irqs(uint16_t irqmask)
+{
+	if (enable_irqs_function)
+		enable_irqs_function(irqmask);
+	else
+		panic("no enable_irqs_function\n");
+}
+
+void trap_virtual_disable_irqs(uint16_t irqmask)
+{
+	if (disable_irqs_function)
+		disable_irqs_function(irqmask);
+	else
+		panic("no disable_irqs_function\n");
+}
+
+void trap_virtual_eoi(void)
+{
+	if (eoi_function)
+		eoi_function();
+	else
+		panic("no eoi_function\n");
+
+}
+
+static void ipc_int(int n, istate_t *istate)
+{
+	ipc_irq_send_notif(n-IVT_IRQBASE);
+	trap_virtual_eoi();
+}
+
+
+/* Reregister irq to be IPC-ready */
+void irq_ipc_bind_arch(unative_t irq)
+{
+	if (irq == IRQ_CLK)
+		return;
+	exc_register(IVT_IRQBASE+irq, "ipc_int", ipc_int);
+	trap_virtual_enable_irqs(1 << irq);
+}
+
+/** @}
+ */
+
Index: kernel/arch/ia32/src/mm/as.c
===================================================================
--- kernel/arch/ia32/src/mm/as.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/mm/as.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2006 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.
+ */
+
+ /** @addtogroup ia32mm	
+ * @{
+ */
+/** @file
+ * @ingroup ia32mm, amd64mm
+ */
+
+#include <arch/mm/as.h>
+#include <genarch/mm/as_pt.h>
+
+/** Architecture dependent address space init. */
+void as_arch_init(void)
+{
+	as_operations = &as_pt_operations;
+}
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/src/mm/frame.c
===================================================================
--- kernel/arch/ia32/src/mm/frame.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/mm/frame.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,148 @@
+/*
+ * 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.
+ */
+
+ /** @addtogroup ia32mm	
+ * @{
+ */
+/** @file
+ * @ingroup ia32mm, amd64mm
+ */
+
+#include <mm/frame.h>
+#include <arch/mm/frame.h>
+#include <mm/as.h>
+#include <config.h>
+#include <arch/boot/boot.h>
+#include <arch/boot/memmap.h>
+#include <panic.h>
+#include <debug.h>
+#include <align.h>
+#include <macros.h>
+
+#include <print.h>
+#include <console/cmd.h>
+#include <console/kconsole.h>
+
+size_t hardcoded_unmapped_ktext_size = 0;
+size_t hardcoded_unmapped_kdata_size = 0;
+
+uintptr_t last_frame = 0;
+
+static void init_e820_memory(pfn_t minconf)
+{
+	int i;
+	pfn_t start, conf;
+	size_t size;
+
+	for (i = 0; i < e820counter; i++) {
+		if (e820table[i].type == MEMMAP_MEMORY_AVAILABLE) {
+			start = ADDR2PFN(ALIGN_UP(e820table[i].base_address,
+						  FRAME_SIZE));
+			size = SIZE2FRAMES(ALIGN_DOWN(e820table[i].size,
+						   FRAME_SIZE));
+			if (minconf < start || minconf >= start+size)
+				conf = start;
+			else
+				conf = minconf;
+			zone_create(start, size, conf, 0);
+			if (last_frame < ALIGN_UP(e820table[i].base_address + e820table[i].size, FRAME_SIZE))
+				last_frame = ALIGN_UP(e820table[i].base_address + e820table[i].size, FRAME_SIZE);
+		}			
+	}
+}
+
+static int cmd_e820mem(cmd_arg_t *argv);
+static cmd_info_t e820_info = {
+	.name = "e820list",
+	.description = "List e820 memory.",
+	.func = cmd_e820mem,
+	.argc = 0
+};
+
+static char *e820names[] = { "invalid", "available", "reserved",
+			     "acpi", "nvs", "unusable" };
+
+
+static int cmd_e820mem(cmd_arg_t *argv)
+{
+	int i;
+	char *name;
+
+	for (i = 0; i < e820counter; i++) {
+		if (e820table[i].type <= MEMMAP_MEMORY_UNUSABLE)
+			name = e820names[e820table[i].type];
+		else
+			name = "invalid";
+		printf("%.*p %#.16llXB %s\n", 
+			sizeof(unative_t) * 2,
+		       (unative_t) e820table[i].base_address, 
+		       (uint64_t) e820table[i].size,
+		       name);
+	}			
+	return 0;
+}
+
+
+void frame_arch_init(void)
+{
+	static pfn_t minconf;
+
+	if (config.cpu_active == 1) {
+		cmd_initialize(&e820_info);
+		cmd_register(&e820_info);
+
+
+		minconf = 1;
+#ifdef CONFIG_SMP
+		minconf = max(minconf,
+			      ADDR2PFN(AP_BOOT_OFFSET+hardcoded_unmapped_ktext_size + hardcoded_unmapped_kdata_size));
+#endif
+#ifdef CONFIG_SIMICS_FIX
+		minconf = max(minconf, ADDR2PFN(0x10000));
+#endif
+		init_e820_memory(minconf);
+
+		/* Reserve frame 0 (BIOS data) */
+		frame_mark_unavailable(0, 1);
+		
+#ifdef CONFIG_SMP
+		/* Reserve AP real mode bootstrap memory */
+		frame_mark_unavailable(AP_BOOT_OFFSET >> FRAME_WIDTH, 
+				       (hardcoded_unmapped_ktext_size + hardcoded_unmapped_kdata_size) >> FRAME_WIDTH);
+		
+#ifdef CONFIG_SIMICS_FIX
+		/* Don't know why, but this addresses help */
+		frame_mark_unavailable(0xd000 >> FRAME_WIDTH,3);
+#endif
+#endif
+	}
+}
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/src/mm/memory_init.c
===================================================================
--- kernel/arch/ia32/src/mm/memory_init.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/mm/memory_init.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2005 Josef Cejka
+ * 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.
+ */
+
+ /** @addtogroup ia32mm	
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/boot/memmap.h>
+#include <arch/mm/memory_init.h>
+#include <arch/mm/page.h>
+#include <print.h>
+
+uint8_t e820counter = 0xff;
+struct e820memmap_ e820table[MEMMAP_E820_MAX_RECORDS];
+uint32_t e801memorysize;
+
+size_t get_memory_size(void) 
+{
+	return e801memorysize*1024;
+}
+
+void memory_print_map(void)
+{
+	uint8_t i;
+	
+	for (i=0;i<e820counter;i++) {
+		printf("E820 base: %#.16llx size: %#.16llx type: ", e820table[i].base_address, e820table[i].size);
+		switch (e820table[i].type) {
+			case MEMMAP_MEMORY_AVAILABLE: 
+				printf("available memory\n");
+				break;
+			case MEMMAP_MEMORY_RESERVED: 
+				printf("reserved memory\n");
+				break;
+			case MEMMAP_MEMORY_ACPI: 
+				printf("ACPI table\n");
+				break;
+			case MEMMAP_MEMORY_NVS: 
+				printf("NVS\n");
+				break;
+			case MEMMAP_MEMORY_UNUSABLE: 
+				printf("unusable memory\n");
+				break;
+			default:
+				printf("undefined memory type\n");
+		}
+	}
+
+}
+
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/src/mm/page.c
===================================================================
--- kernel/arch/ia32/src/mm/page.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/mm/page.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+ /** @addtogroup ia32mm
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/mm/page.h>
+#include <genarch/mm/page_pt.h>
+#include <arch/mm/frame.h>
+#include <mm/frame.h>
+#include <mm/page.h>
+#include <mm/as.h>
+#include <arch/types.h>
+#include <align.h>
+#include <config.h>
+#include <func.h>
+#include <arch/interrupt.h>
+#include <arch/asm.h>
+#include <debug.h>
+#include <memstr.h>
+#include <print.h>
+#include <interrupt.h>
+
+void page_arch_init(void)
+{
+	uintptr_t cur;
+	int flags;
+
+	if (config.cpu_active == 1) {
+		page_mapping_operations = &pt_mapping_operations;
+	
+		/*
+		 * PA2KA(identity) mapping for all frames until last_frame.
+		 */
+		for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
+			flags = PAGE_CACHEABLE;
+			if ((PA2KA(cur) >= config.base) && (PA2KA(cur) < config.base + config.kernel_size))
+				flags |= PAGE_GLOBAL;
+			page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
+		}
+
+		exc_register(14, "page_fault", (iroutine) page_fault);
+		write_cr3((uintptr_t) AS_KERNEL->page_table);
+	}
+	else {
+		write_cr3((uintptr_t) AS_KERNEL->page_table);
+	}
+
+	paging_on();
+}
+
+
+uintptr_t hw_map(uintptr_t physaddr, size_t size)
+{
+	if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
+		panic("Unable to map physical memory %p (%d bytes)", physaddr, size)
+	
+	uintptr_t virtaddr = PA2KA(last_frame);
+	pfn_t i;
+	for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++)
+		page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE);
+	
+	last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
+	
+	return virtaddr;
+}
+
+void page_fault(int n, istate_t *istate)
+{
+        uintptr_t page;
+	pf_access_t access;
+	
+        page = read_cr2();
+		
+        if (istate->error_word & PFERR_CODE_RSVD)
+		panic("Reserved bit set in page directory.\n");
+
+	if (istate->error_word & PFERR_CODE_RW)
+		access = PF_ACCESS_WRITE;
+	else
+		access = PF_ACCESS_READ;
+
+        if (as_page_fault(page, access, istate) == AS_PF_FAULT) {
+		fault_if_from_uspace(istate, "Page fault: %#x", page);
+
+                PRINT_INFO_ERRCODE(istate);
+                printf("page fault address: %#x\n", page);
+                panic("page fault\n");
+        }
+}
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/src/mm/tlb.c
===================================================================
--- kernel/arch/ia32/src/mm/tlb.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/mm/tlb.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+ /** @addtogroup ia32mm	
+ * @{
+ */
+/** @file
+ * @ingroup ia32mm, amd64mm
+ */
+
+#include <mm/tlb.h>
+#include <arch/mm/asid.h>
+#include <arch/asm.h>
+#include <arch/types.h>
+
+/** Invalidate all entries in TLB. */
+void tlb_invalidate_all(void)
+{
+	write_cr3(read_cr3());
+}
+
+/** Invalidate all entries in TLB that belong to specified address space.
+ *
+ * @param asid This parameter is ignored as the architecture doesn't support it.
+ */
+void tlb_invalidate_asid(asid_t asid)
+{
+	tlb_invalidate_all();
+}
+
+/** Invalidate TLB entries for specified page range belonging to specified address space.
+ *
+ * @param asid This parameter is ignored as the architecture doesn't support it.
+ * @param page Address of the first page whose entry is to be invalidated.
+ * @param cnt Number of entries to invalidate.
+ */
+void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
+{
+	int i;
+
+	for (i = 0; i < cnt; i++)
+		invlpg(page + i * PAGE_SIZE);
+}
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/src/pm.c
===================================================================
--- kernel/arch/ia32/src/pm.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/pm.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,241 @@
+/*
+ * 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/pm.h>
+#include <config.h>
+#include <arch/types.h>
+#include <typedefs.h>
+#include <arch/interrupt.h>
+#include <arch/asm.h>
+#include <arch/context.h>
+#include <panic.h>
+#include <arch/mm/page.h>
+#include <mm/slab.h>
+#include <memstr.h>
+#include <arch/boot/boot.h>
+#include <interrupt.h>
+
+/*
+ * Early ia32 configuration functions and data structures.
+ */
+
+/*
+ * We have no use for segmentation so we set up flat mode. In this
+ * mode, we use, for each privilege level, two segments spanning the
+ * whole memory. One is for code and one is for data.
+ *
+ * One is for GS register which holds pointer to the TLS thread
+ * structure in it's base.
+ */
+descriptor_t gdt[GDT_ITEMS] = {
+	/* NULL descriptor */
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+	/* KTEXT descriptor */
+	{ 0xffff, 0, 0, AR_PRESENT | AR_CODE | DPL_KERNEL, 0xf, 0, 0, 1, 1, 0 },
+	/* KDATA descriptor */
+	{ 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_KERNEL, 0xf, 0, 0, 1, 1, 0 },
+	/* UTEXT descriptor */
+	{ 0xffff, 0, 0, AR_PRESENT | AR_CODE | DPL_USER, 0xf, 0, 0, 1, 1, 0 },
+	/* UDATA descriptor */
+	{ 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, 0xf, 0, 0, 1, 1, 0 },
+	/* TSS descriptor - set up will be completed later */
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+	/* TLS descriptor */
+	{ 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, 0xf, 0, 0, 1, 1, 0 },
+	/* VESA Init descriptor */
+#ifdef CONFIG_FB
+	{ 0xffff, 0, VESA_INIT_SEGMENT>>12, AR_PRESENT | AR_CODE | DPL_KERNEL, 0xf, 0, 0, 0, 0, 0 }
+#endif	
+};
+
+static idescriptor_t idt[IDT_ITEMS];
+
+static tss_t tss;
+
+tss_t *tss_p = NULL;
+
+/* gdtr is changed by kmp before next CPU is initialized */
+ptr_16_32_t bootstrap_gdtr = { .limit = sizeof(gdt), .base = KA2PA((uintptr_t) gdt) };
+ptr_16_32_t gdtr = { .limit = sizeof(gdt), .base = (uintptr_t) gdt };
+
+void gdt_setbase(descriptor_t *d, uintptr_t base)
+{
+	d->base_0_15 = base & 0xffff;
+	d->base_16_23 = ((base) >> 16) & 0xff;
+	d->base_24_31 = ((base) >> 24) & 0xff;
+}
+
+void gdt_setlimit(descriptor_t *d, uint32_t limit)
+{
+	d->limit_0_15 = limit & 0xffff;
+	d->limit_16_19 = (limit >> 16) & 0xf;
+}
+
+void idt_setoffset(idescriptor_t *d, uintptr_t offset)
+{
+	/*
+	 * Offset is a linear address.
+	 */
+	d->offset_0_15 = offset & 0xffff;
+	d->offset_16_31 = offset >> 16;
+}
+
+void tss_initialize(tss_t *t)
+{
+	memsetb((uintptr_t) t, sizeof(struct tss), 0);
+}
+
+/*
+ * This function takes care of proper setup of IDT and IDTR.
+ */
+void idt_init(void)
+{
+	idescriptor_t *d;
+	int i;
+
+	for (i = 0; i < IDT_ITEMS; i++) {
+		d = &idt[i];
+
+		d->unused = 0;
+		d->selector = selector(KTEXT_DES);
+
+		d->access = AR_PRESENT | AR_INTERRUPT;	/* masking interrupt */
+
+		if (i == VECTOR_SYSCALL) {
+			/*
+			 * The syscall interrupt gate must be calleable from userland.
+			 */
+			d->access |= DPL_USER;
+		}
+		
+		idt_setoffset(d, ((uintptr_t) interrupt_handlers) + i*interrupt_handler_size);
+		exc_register(i, "undef", (iroutine) null_interrupt);
+	}
+	exc_register(13, "gp_fault", (iroutine) gp_fault);
+	exc_register( 7, "nm_fault", (iroutine) nm_fault);
+	exc_register(12, "ss_fault", (iroutine) ss_fault);
+	exc_register(19, "simd_fp", (iroutine) simd_fp_exception);
+}
+
+
+/* Clean IOPL(12,13) and NT(14) flags in EFLAGS register */
+static void clean_IOPL_NT_flags(void)
+{
+	__asm__ volatile (
+		"pushfl\n"
+		"pop %%eax\n"
+		"and $0xffff8fff, %%eax\n"
+		"push %%eax\n"
+		"popfl\n"
+		: : : "eax"
+	);
+}
+
+/* Clean AM(18) flag in CR0 register */
+static void clean_AM_flag(void)
+{
+	__asm__ volatile (
+		"mov %%cr0, %%eax\n"
+		"and $0xfffbffff, %%eax\n"
+		"mov %%eax, %%cr0\n"
+		: : : "eax"
+	);
+}
+
+void pm_init(void)
+{
+	descriptor_t *gdt_p = (descriptor_t *) gdtr.base;
+	ptr_16_32_t idtr;
+
+	/*
+	 * Update addresses in GDT and IDT to their virtual counterparts.
+	 */
+	idtr.limit = sizeof(idt);
+	idtr.base = (uintptr_t) idt;
+	gdtr_load(&gdtr);
+	idtr_load(&idtr);
+	
+	/*
+	 * 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 = (tss_t *) malloc(sizeof(tss_t), FRAME_ATOMIC);
+		if (!tss_p)
+			panic("could not allocate TSS\n");
+	}
+
+	tss_initialize(tss_p);
+	
+	gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL;
+	gdt_p[TSS_DES].special = 1;
+	gdt_p[TSS_DES].granularity = 0;
+	
+	gdt_setbase(&gdt_p[TSS_DES], (uintptr_t) tss_p);
+	gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE - 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.
+	 */
+	tr_load(selector(TSS_DES));
+	
+	clean_IOPL_NT_flags();    /* Disable I/O on nonprivileged levels and clear NT flag. */
+	clean_AM_flag();          /* Disable alignment check */
+}
+
+void set_tls_desc(uintptr_t tls)
+{
+	ptr_16_32_t cpugdtr;
+	descriptor_t *gdt_p;
+
+	gdtr_store(&cpugdtr);
+	gdt_p = (descriptor_t *) cpugdtr.base;
+	gdt_setbase(&gdt_p[TLS_DES], tls);
+	/* Reload gdt register to update GS in CPU */
+	gdtr_load(&cpugdtr);
+}
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/src/proc/scheduler.c
===================================================================
--- kernel/arch/ia32/src/proc/scheduler.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/proc/scheduler.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+ /** @addtogroup ia32proc
+ * @{
+ */
+/** @file
+ */
+
+#include <proc/scheduler.h>
+#include <cpu.h>
+#include <proc/task.h>
+#include <proc/thread.h>
+#include <arch.h>
+#include <arch/context.h>	/* SP_DELTA */
+#include <arch/debugger.h>
+#include <arch/pm.h>
+#include <arch/asm.h>
+#include <arch/ddi/ddi.h>
+
+/** Perform ia32 specific tasks needed before the new task is run.
+ *
+ * Interrupts are disabled.
+ */
+void before_task_runs_arch(void)
+{
+	io_perm_bitmap_install();
+}
+
+/** Perform ia32 specific tasks needed before the new thread is scheduled.
+ *
+ * THREAD is locked and interrupts are disabled.
+ */
+void before_thread_runs_arch(void)
+{
+	CPU->arch.tss->esp0 = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE-SP_DELTA];
+	CPU->arch.tss->ss0 = selector(KDATA_DES);
+
+	/* Set up TLS in GS register */
+	set_tls_desc(THREAD->arch.tls);
+
+#ifdef CONFIG_DEBUG_AS_WATCHPOINT
+	/* Set watchpoint on AS to ensure that nobody sets it to zero */
+	if (CPU->id < BKPOINTS_MAX)
+		breakpoint_add(&((the_t *) THREAD->kstack)->as, 
+			       BKPOINT_WRITE | BKPOINT_CHECK_ZERO,
+			       CPU->id);
+#endif
+}
+
+void after_thread_ran_arch(void)
+{
+}
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/src/proc/task.c
===================================================================
--- kernel/arch/ia32/src/proc/task.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/proc/task.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2006 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.
+ */
+
+ /** @addtogroup ia32proc
+ * @{
+ */
+/** @file
+ */
+
+#include <proc/task.h>
+#include <arch/types.h>
+#include <adt/bitmap.h>
+#include <mm/slab.h>
+
+/** Perform ia32 specific task initialization.
+ *
+ * @param t Task to be initialized.
+ */
+void task_create_arch(task_t *t)
+{
+	t->arch.iomapver = 0;
+	bitmap_initialize(&t->arch.iomap, NULL, 0);
+}
+
+/** Perform ia32 specific task destruction.
+ *
+ * @param t Task to be initialized.
+ */
+void task_destroy_arch(task_t *t)
+{
+	if (t->arch.iomap.map)
+		free(t->arch.iomap.map);
+}
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/src/proc/thread.c
===================================================================
--- kernel/arch/ia32/src/proc/thread.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/proc/thread.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2006 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.
+ */
+
+ /** @addtogroup ia32proc
+ * @{
+ */
+/** @file
+ */
+
+#include <proc/thread.h>
+
+/** Perform ia32 specific thread initialization.
+ *
+ * @param t Thread to be initialized.
+ */
+void thread_create_arch(thread_t *t)
+{
+	t->arch.tls = 0;
+}
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/src/smp/ap.S
===================================================================
--- kernel/arch/ia32/src/smp/ap.S	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/smp/ap.S	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,95 @@
+#
+# Copyright (C) 2001-2004 Jakub Jermar
+# Copyright (C) 2005-2006 Martin Decky
+# 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.
+#
+
+#
+# Init code for application processors.
+#
+
+#include <arch/boot/boot.h>
+#include <arch/boot/memmap.h>
+#include <arch/mm/page.h>
+#include <arch/pm.h>
+
+.section K_TEXT_START, "ax"
+
+#ifdef CONFIG_SMP
+
+.global unmapped_ap_boot
+
+KTEXT=8
+KDATA=16
+
+# This piece of code is real-mode and is meant to be alligned at 4K boundary.
+# The requirement for such an alignment comes from MP Specification's STARTUP IPI
+# requirements.
+
+.align 4096
+unmapped_ap_boot:
+.code16
+	cli
+	xorw %ax, %ax
+	movw %ax, %ds
+
+	lgdtl ap_gdtr		# initialize Global Descriptor Table register
+	
+	movl %cr0, %eax
+	orl $1, %eax
+	movl %eax, %cr0				# switch to protected mode
+	jmpl $KTEXT, $jump_to_kernel - BOOT_OFFSET + AP_BOOT_OFFSET
+	
+jump_to_kernel:
+.code32
+	movw $KDATA, %ax
+	movw %ax, %ds
+	movw %ax, %es
+	movw %ax, %ss
+	movl $KA2PA(ctx), %eax			# KA2PA((uintptr_t) &ctx)
+	movl (%eax), %esp
+	subl $0x80000000, %esp			# KA2PA(ctx.sp)
+
+	call map_kernel					# map kernel and turn paging on
+	
+	addl $0x80000000, %esp			# PA2KA(ctx.sp)
+	
+	jmpl $KTEXT, $main_ap
+
+#endif /* CONFIG_SMP */
+
+
+.section K_DATA_START, "aw", @progbits
+
+#ifdef CONFIG_SMP
+
+.global unmapped_ap_gdtr
+
+unmapped_ap_gdtr:
+	.word 0
+	.long 0
+
+#endif /* CONFIG_SMP */
Index: kernel/arch/ia32/src/smp/apic.c
===================================================================
--- kernel/arch/ia32/src/smp/apic.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/smp/apic.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,582 @@
+/*
+ * 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/types.h>
+#include <arch/smp/apic.h>
+#include <arch/smp/ap.h>
+#include <arch/smp/mps.h>
+#include <arch/boot/boot.h>
+#include <mm/page.h>
+#include <time/delay.h>
+#include <interrupt.h>
+#include <arch/interrupt.h>
+#include <print.h>
+#include <arch/asm.h>
+#include <arch.h>
+
+#ifdef CONFIG_SMP
+
+/*
+ * Advanced Programmable Interrupt Controller for SMP systems.
+ * Tested on:
+ *	Bochs 2.0.2 - Bochs 2.2.6 with 2-8 CPUs
+ *	Simics 2.0.28 - Simics 2.2.19 2-15 CPUs
+ *	VMware Workstation 5.5 with 2 CPUs
+ *	QEMU 0.8.0 with 2-15 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
+ *	MSI K7D Master-L with 2x 2100MHz Athlon MP CPUs
+ */
+
+/*
+ * These variables either stay configured as initilalized, or are changed by
+ * the MP configuration code.
+ *
+ * Pay special attention to the volatile keyword. Without it, gcc -O2 would
+ * optimize the code too much and accesses to l_apic and io_apic, that must
+ * always be 32-bit, would use byte oriented instructions.
+ */
+volatile uint32_t *l_apic = (uint32_t *) 0xfee00000;
+volatile uint32_t *io_apic = (uint32_t *) 0xfec00000;
+
+uint32_t apic_id_mask = 0;
+
+static int apic_poll_errors(void);
+
+#ifdef LAPIC_VERBOSE
+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"
+};
+#endif /* LAPIC_VERBOSE */
+
+
+static void apic_spurious(int n, istate_t *istate);
+static void l_apic_timer_interrupt(int n, istate_t *istate);
+
+/** Initialize APIC on BSP. */
+void apic_init(void)
+{
+	io_apic_id_t idreg;
+	int i;
+
+	exc_register(VECTOR_APIC_SPUR, "apic_spurious", (iroutine) apic_spurious);
+
+	enable_irqs_function = io_apic_enable_irqs;
+	disable_irqs_function = io_apic_disable_irqs;
+	eoi_function = l_apic_eoi;
+	
+	/*
+	 * Configure interrupt routing.
+	 * IRQ 0 remains masked as the time signal is generated by l_apic's themselves.
+	 * Other interrupts will be forwarded to the lowest priority CPU.
+	 */
+	io_apic_disable_irqs(0xffff);
+	exc_register(VECTOR_CLK, "l_apic_timer", (iroutine) l_apic_timer_interrupt);
+	for (i = 0; i < IRQ_COUNT; i++) {
+		int pin;
+	
+		if ((pin = smp_irq_to_pin(i)) != -1) {
+			io_apic_change_ioredtbl(pin, DEST_ALL, IVT_IRQBASE+i, LOPRI);
+		}
+	}
+	
+	/*
+	 * Ensure that io_apic has unique ID.
+	 */
+	idreg.value = io_apic_read(IOAPICID);
+	if ((1<<idreg.apic_id) & apic_id_mask) {	/* see if IO APIC ID is used already */
+		for (i = 0; i < APIC_ID_COUNT; i++) {
+			if (!((1<<i) & apic_id_mask)) {
+				idreg.apic_id = i;
+				io_apic_write(IOAPICID, idreg.value);
+				break;
+			}
+		}
+	}
+
+	/*
+	 * Configure the BSP's lapic.
+	 */
+	l_apic_init();
+
+	l_apic_debug();	
+}
+
+/** APIC spurious interrupt handler.
+ *
+ * @param n Interrupt vector.
+ * @param istate Interrupted state.
+ */
+void apic_spurious(int n, istate_t *istate)
+{
+#ifdef CONFIG_DEBUG
+	printf("cpu%d: APIC spurious interrupt\n", CPU->id);
+#endif
+}
+
+/** 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)
+{
+	esr_t esr;
+	
+	esr.value = l_apic[ESR];
+	
+	if (esr.send_checksum_error)
+		printf("Send Checksum Error\n");
+	if (esr.receive_checksum_error)
+		printf("Receive Checksum Error\n");
+	if (esr.send_accept_error)
+		printf("Send Accept Error\n");
+	if (esr.receive_accept_error)
+		printf("Receive Accept Error\n");
+	if (esr.send_illegal_vector)
+		printf("Send Illegal Vector\n");
+	if (esr.received_illegal_vector)
+		printf("Received Illegal Vector\n");
+	if (esr.illegal_register_address)
+		printf("Illegal Register Address\n");
+
+	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(uint8_t vector)
+{
+	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.delivs == DELIVS_PENDING) {
+#ifdef CONFIG_DEBUG
+		printf("IPI is pending.\n");
+#endif
+	}
+
+	return apic_poll_errors();
+}
+
+/** 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(uint8_t apicid)
+{
+	icr_t icr;
+	int i;
+
+	/*
+	 * Read the ICR register in and zero all non-reserved fields.
+	 */
+	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;
+
+	/*
+	 * According to MP Specification, 20us should be enough to
+	 * deliver the IPI.
+	 */
+	delay(20);
+
+	if (!apic_poll_errors())
+		return 0;
+
+	icr.lo = l_apic[ICRlo];
+	if (icr.delivs == DELIVS_PENDING) {
+#ifdef CONFIG_DEBUG
+		printf("IPI is pending.\n");
+#endif
+	}
+
+	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;
+
+	/*
+	 * Wait 10ms as MP Specification specifies.
+	 */
+	delay(10000);
+
+	if (!is_82489DX_apic(l_apic[LAVR])) {
+		/*
+		 * If this is not 82489DX-based l_apic we must send two STARTUP IPI's.
+		 */
+		for (i = 0; i<2; i++) {
+			icr.lo = l_apic[ICRlo];
+			icr.vector = ((uintptr_t) 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);
+		}
+	}
+	
+	return apic_poll_errors();
+}
+
+/** Initialize Local APIC. */
+void l_apic_init(void)
+{
+	lvt_error_t error;
+	lvt_lint_t lint;
+	tpr_t tpr;
+	svr_t svr;
+	icr_t icr;
+	tdcr_t tdcr;
+	lvt_tm_t tm;
+	ldr_t ldr;
+	dfr_t dfr;
+	uint32_t 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;
+
+	/* Task Priority Register initialization. */
+	tpr.value = l_apic[TPR];
+	tpr.pri_sc = 0;
+	tpr.pri = 0;
+	l_apic[TPR] = tpr.value;
+	
+	/* Spurious-Interrupt Vector Register initialization. */
+	svr.value = l_apic[SVR];
+	svr.vector = VECTOR_APIC_SPUR;
+	svr.lapic_enabled = true;
+	svr.focus_checking = true;
+	l_apic[SVR] = svr.value;
+
+	if (CPU->arch.family >= 6)
+		enable_l_apic_in_msr();
+	
+	/* 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;
+	
+	/* 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;
+	tm.mode = TIMER_PERIODIC;
+	tm.masked = false;
+	l_apic[LVT_Tm] = tm.value;
+
+	/*
+	 * Measure and configure the timer to generate timer
+	 * interrupt with period 1s/HZ seconds.
+	 */
+	t1 = l_apic[CCRT];
+	l_apic[ICRT] = 0xffffffff;
+
+	while (l_apic[CCRT] == t1)
+		;
+		
+	t1 = l_apic[CCRT];
+	delay(1000000/HZ);
+	t2 = l_apic[CCRT];
+	
+	l_apic[ICRT] = t1-t2;
+	
+	/* Program Logical Destination Register. */
+	ldr.value = l_apic[LDR];
+	if (CPU->id < sizeof(CPU->id)*8)	/* size in bits */
+		ldr.id = (1<<CPU->id);
+	l_apic[LDR] = ldr.value;
+	
+	/* Program Destination Format Register for Flat mode. */
+	dfr.value = l_apic[DFR];
+	dfr.model = MODEL_FLAT;
+	l_apic[DFR] = dfr.value;
+}
+
+/** Local APIC End of Interrupt. */
+void l_apic_eoi(void)
+{
+	l_apic[EOI] = 0;
+}
+
+/** Dump content of Local APIC registers. */
+void l_apic_debug(void)
+{
+#ifdef LAPIC_VERBOSE
+	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());
+
+	tm.value = l_apic[LVT_Tm];
+	printf("LVT Tm: vector=%hhd, %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=%hhd, %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=%hhd, %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=%hhd, %s, %s\n", error.vector, delivs_str[error.delivs], mask_str[error.masked]);
+#endif
+}
+
+/** Local APIC Timer Interrupt.
+ *
+ * @param n Interrupt vector number.
+ * @param istate Interrupted state.
+ */
+void l_apic_timer_interrupt(int n, istate_t *istate)
+{
+	l_apic_eoi();
+	clock();
+}
+
+/** Get Local APIC ID.
+ *
+ * @return Local APIC ID.
+ */
+uint8_t l_apic_id(void)
+{
+	l_apic_id_t idreg;
+	
+	idreg.value = l_apic[L_APIC_ID];
+	return idreg.apic_id;
+}
+
+/** Read from IO APIC register.
+ *
+ * @param address IO APIC register address.
+ *
+ * @return Content of the addressed IO APIC register.
+ */
+uint32_t io_apic_read(uint8_t 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 x Content to be written to the addressed IO APIC register.
+ */
+void io_apic_write(uint8_t address, uint32_t x)
+{
+	io_regsel_t regsel;
+	
+	regsel.value = io_apic[IOREGSEL];
+	regsel.reg_addr = address;
+	io_apic[IOREGSEL] = regsel.value;
+	io_apic[IOWIN] = x;
+}
+
+/** 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, uint8_t v, int flags)
+{
+	io_redirection_reg_t reg;
+	int dlvr = DELMOD_FIXED;
+	
+	if (flags & LOPRI)
+		dlvr = DELMOD_LOWPRI;
+
+	reg.lo = io_apic_read(IOREDTBL + pin*2);
+	reg.hi = io_apic_read(IOREDTBL + pin*2 + 1);
+	
+	reg.dest = dest;
+	reg.destmod = DESTMOD_LOGIC;
+	reg.trigger_mode = TRIGMOD_EDGE;
+	reg.intpol = POLARITY_HIGH;
+	reg.delmod = dlvr;
+	reg.intvec = v;
+
+	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(uint16_t irqmask)
+{
+	io_redirection_reg_t reg;
+	int i, pin;
+	
+	for (i=0;i<16;i++) {
+		if (irqmask & (1<<i)) {
+			/*
+			 * Mask the signal input in IO APIC if there is a
+			 * mapping for the respective IRQ number.
+			 */
+			pin = smp_irq_to_pin(i);
+			if (pin != -1) {
+				reg.lo = io_apic_read(IOREDTBL + pin*2);
+				reg.masked = true;
+				io_apic_write(IOREDTBL + pin*2, reg.lo);
+			}
+			
+		}
+	}
+}
+
+/** Unmask IRQs in IO APIC.
+ *
+ * @param irqmask Bitmask of IRQs to be unmasked (0 = do not unmask, 1 = unmask).
+ */
+void io_apic_enable_irqs(uint16_t irqmask)
+{
+	int i, pin;
+	io_redirection_reg_t reg;	
+	
+	for (i=0;i<16;i++) {
+		if (irqmask & (1<<i)) {
+			/*
+			 * Unmask the signal input in IO APIC if there is a
+			 * mapping for the respective IRQ number.
+			 */
+			pin = smp_irq_to_pin(i);
+			if (pin != -1) {
+				reg.lo = io_apic_read(IOREDTBL + pin*2);
+				reg.masked = false;
+				io_apic_write(IOREDTBL + pin*2, reg.lo);
+			}
+			
+		}
+	}
+}
+
+#endif /* CONFIG_SMP */
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/src/smp/ipi.c
===================================================================
--- kernel/arch/ia32/src/smp/ipi.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/smp/ipi.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifdef CONFIG_SMP
+
+#include <smp/ipi.h>
+#include <arch/smp/apic.h>
+
+void ipi_broadcast_arch(int ipi)
+{
+	(void) l_apic_broadcast_custom_ipi((uint8_t) ipi);
+}
+
+#endif /* CONFIG_SMP */
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/src/smp/mps.c
===================================================================
--- kernel/arch/ia32/src/smp/mps.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/smp/mps.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,435 @@
+/*
+ * Copyright (C) 2001-2005 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#ifdef CONFIG_SMP
+
+#include <config.h>
+#include <print.h>
+#include <debug.h>
+#include <arch/smp/mps.h>
+#include <arch/smp/apic.h>
+#include <arch/smp/smp.h>
+#include <func.h>
+#include <arch/types.h>
+#include <typedefs.h>
+#include <cpu.h>
+#include <arch/asm.h>
+#include <arch/bios/bios.h>
+#include <mm/frame.h>
+
+/*
+ * MultiProcessor Specification detection code.
+ */
+
+#define	FS_SIGNATURE	0x5f504d5f
+#define CT_SIGNATURE 	0x504d4350
+
+int mps_fs_check(uint8_t *base);
+int mps_ct_check(void);
+
+int configure_via_ct(void);
+int configure_via_default(uint8_t n);
+
+int ct_processor_entry(struct __processor_entry *pr);
+void ct_bus_entry(struct __bus_entry *bus);
+void ct_io_apic_entry(struct __io_apic_entry *ioa);
+void ct_io_intr_entry(struct __io_intr_entry *iointr);
+void ct_l_intr_entry(struct __l_intr_entry *lintr);
+
+void ct_extended_entries(void);
+
+static struct mps_fs *fs;
+static struct mps_ct *ct;
+
+struct __processor_entry *processor_entries = NULL;
+struct __bus_entry *bus_entries = NULL;
+struct __io_apic_entry *io_apic_entries = NULL;
+struct __io_intr_entry *io_intr_entries = NULL;
+struct __l_intr_entry *l_intr_entries = NULL;
+
+int processor_entry_cnt = 0;
+int bus_entry_cnt = 0;
+int io_apic_entry_cnt = 0;
+int io_intr_entry_cnt = 0;
+int l_intr_entry_cnt = 0;
+
+waitq_t ap_completion_wq;
+
+/*
+ * Implementation of IA-32 SMP configuration interface.
+ */
+static count_t get_cpu_count(void);
+static bool is_cpu_enabled(index_t i);
+static bool is_bsp(index_t i);
+static uint8_t get_cpu_apic_id(index_t i);
+static int mps_irq_to_pin(int irq);
+
+struct smp_config_operations mps_config_operations = {
+	.cpu_count = get_cpu_count,
+	.cpu_enabled = is_cpu_enabled,
+	.cpu_bootstrap = is_bsp,
+	.cpu_apic_id = get_cpu_apic_id,
+	.irq_to_pin = mps_irq_to_pin
+};
+
+count_t get_cpu_count(void)
+{
+	return processor_entry_cnt;
+}
+
+bool is_cpu_enabled(index_t i)
+{
+	ASSERT(i < processor_entry_cnt);
+	return processor_entries[i].cpu_flags & 0x1;
+}
+
+bool is_bsp(index_t i)
+{
+	ASSERT(i < processor_entry_cnt);
+	return processor_entries[i].cpu_flags & 0x2;
+}
+
+uint8_t get_cpu_apic_id(index_t i)
+{
+	ASSERT(i < processor_entry_cnt);
+	return processor_entries[i].l_apic_id;
+}
+
+
+/*
+ * Used to check the integrity of the MP Floating Structure.
+ */
+int mps_fs_check(uint8_t *base)
+{
+	int i;
+	uint8_t sum;
+	
+	for (i = 0, sum = 0; i < 16; i++)
+		sum += base[i];
+	
+	return !sum;
+}
+
+/*
+ * Used to check the integrity of the MP Configuration Table.
+ */
+int mps_ct_check(void)
+{
+	uint8_t *base = (uint8_t *) ct;
+	uint8_t *ext = base + ct->base_table_length;
+	uint8_t sum;
+	int i;	
+	
+	/* count the checksum for the base table */
+	for (i=0,sum=0; i < ct->base_table_length; i++)
+		sum += base[i];
+		
+	if (sum)
+		return 0;
+		
+	/* count the checksum for the extended table */
+	for (i=0,sum=0; i < ct->ext_table_length; i++)
+		sum += ext[i];
+		
+	return sum == ct->ext_table_checksum;
+}
+
+void mps_init(void)
+{
+	uint8_t *addr[2] = { NULL, (uint8_t *) PA2KA(0xf0000) };
+	int i, j, length[2] = { 1024, 64*1024 };
+	
+
+	/*
+	 * Find MP Floating Pointer Structure
+	 * 1a. search first 1K of EBDA
+	 * 1b. if EBDA is undefined, search last 1K of base memory
+	 *  2. search 64K starting at 0xf0000
+	 */
+
+	addr[0] = (uint8_t *) PA2KA(ebda ? ebda : 639 * 1024);
+	for (i = 0; i < 2; i++) {
+		for (j = 0; j < length[i]; j += 16) {
+			if (*((uint32_t *) &addr[i][j]) == FS_SIGNATURE && mps_fs_check(&addr[i][j])) {
+				fs = (struct mps_fs *) &addr[i][j];
+				goto fs_found;
+			}
+		}
+	}
+
+	return;
+	
+fs_found:
+	printf("%p: MPS Floating Pointer Structure\n", fs);
+
+	if (fs->config_type == 0 && fs->configuration_table) {
+		if (fs->mpfib2 >> 7) {
+			printf("%s: PIC mode not supported\n", __FUNCTION__);
+			return;
+		}
+
+		ct = (struct mps_ct *)PA2KA((uintptr_t)fs->configuration_table);
+		config.cpu_count = configure_via_ct();
+	} 
+	else
+		config.cpu_count = configure_via_default(fs->config_type);
+
+	return;
+}
+
+int configure_via_ct(void)
+{
+	uint8_t *cur;
+	int i, cnt;
+		
+	if (ct->signature != CT_SIGNATURE) {
+		printf("%s: bad ct->signature\n", __FUNCTION__);
+		return 1;
+	}
+	if (!mps_ct_check()) {
+		printf("%s: bad ct checksum\n", __FUNCTION__);
+		return 1;
+	}
+	if (ct->oem_table) {
+		printf("%s: ct->oem_table not supported\n", __FUNCTION__);
+		return 1;
+	}
+	
+	l_apic = (uint32_t *)(uintptr_t)ct->l_apic;
+
+	cnt = 0;
+	cur = &ct->base_table[0];
+	for (i=0; i < ct->entry_count; i++) {
+		switch (*cur) {
+			/* Processor entry */
+			case 0:	
+				processor_entries = processor_entries ? processor_entries : (struct __processor_entry *) cur;
+				processor_entry_cnt++;
+				cnt += ct_processor_entry((struct __processor_entry *) cur);
+				cur += 20;
+				break;
+
+			/* Bus entry */
+			case 1:
+				bus_entries = bus_entries ? bus_entries : (struct __bus_entry *) cur;
+				bus_entry_cnt++;
+				ct_bus_entry((struct __bus_entry *) cur);
+				cur += 8;
+				break;
+				
+			/* I/O Apic */
+			case 2:
+				io_apic_entries = io_apic_entries ? io_apic_entries : (struct __io_apic_entry *) cur;
+				io_apic_entry_cnt++;
+				ct_io_apic_entry((struct __io_apic_entry *) cur);
+				cur += 8;
+				break;
+				
+			/* I/O Interrupt Assignment */
+			case 3:
+				io_intr_entries = io_intr_entries ? io_intr_entries : (struct __io_intr_entry *) cur;
+				io_intr_entry_cnt++;
+				ct_io_intr_entry((struct __io_intr_entry *) cur);
+				cur += 8;
+				break;
+
+			/* Local Interrupt Assignment */
+			case 4:
+				l_intr_entries = l_intr_entries ? l_intr_entries : (struct __l_intr_entry *) cur;
+				l_intr_entry_cnt++;
+				ct_l_intr_entry((struct __l_intr_entry *) cur);
+				cur += 8;
+				break;
+
+			default:
+				/*
+				 * Something is wrong. Fallback to UP mode.
+				 */
+				 
+				printf("%s: ct badness\n", __FUNCTION__);
+				return 1;
+		}
+	}
+	
+	/*
+	 * Process extended entries.
+	 */
+	ct_extended_entries();
+	return cnt;
+}
+
+int configure_via_default(uint8_t n)
+{
+	/*
+	 * Not yet implemented.
+	 */
+	printf("%s: not supported\n", __FUNCTION__);
+	return 1;
+}
+
+
+int ct_processor_entry(struct __processor_entry *pr)
+{
+	/*
+	 * Ignore processors which are not marked enabled.
+	 */
+	if ((pr->cpu_flags & (1<<0)) == 0)
+		return 0;
+	
+	apic_id_mask |= (1<<pr->l_apic_id); 
+	return 1;
+}
+
+void ct_bus_entry(struct __bus_entry *bus)
+{
+#ifdef MPSCT_VERBOSE
+	char buf[7];
+	memcpy((void *) buf, (void *) bus->bus_type, 6);
+	buf[6] = 0;
+	printf("bus%d: %s\n", bus->bus_id, buf);
+#endif
+}
+
+void ct_io_apic_entry(struct __io_apic_entry *ioa)
+{
+	static int io_apic_count = 0;
+
+	/* this ioapic is marked unusable */
+	if ((ioa->io_apic_flags & 1) == 0)
+		return;
+	
+	if (io_apic_count++ > 0) {
+		/*
+		 * Multiple IO APIC's are currently not supported.
+		 */
+		return;
+	}
+	
+	io_apic = (uint32_t *)(uintptr_t)ioa->io_apic;
+}
+
+//#define MPSCT_VERBOSE
+void ct_io_intr_entry(struct __io_intr_entry *iointr)
+{
+#ifdef MPSCT_VERBOSE
+	switch (iointr->intr_type) {
+	    case 0: printf("INT"); break;
+	    case 1: printf("NMI"); break;
+	    case 2: printf("SMI"); break;
+	    case 3: printf("ExtINT"); break;
+	}
+	putchar(',');
+	switch (iointr->poel&3) {
+	    case 0: printf("bus-like"); break;
+	    case 1: printf("active high"); break;
+	    case 2: printf("reserved"); break;
+	    case 3: printf("active low"); break;
+	}
+	putchar(',');
+	switch ((iointr->poel>>2)&3) {
+	    case 0: printf("bus-like"); break;
+	    case 1: printf("edge-triggered"); break;
+	    case 2: printf("reserved"); break;
+	    case 3: printf("level-triggered"); break;
+	}
+	putchar(',');
+	printf("bus%d,irq%d", iointr->src_bus_id, iointr->src_bus_irq);
+	putchar(',');
+	printf("io_apic%d,pin%d", iointr->dst_io_apic_id, iointr->dst_io_apic_pin);
+	putchar('\n');	
+#endif
+}
+
+void ct_l_intr_entry(struct __l_intr_entry *lintr)
+{
+#ifdef MPSCT_VERBOSE
+	switch (lintr->intr_type) {
+	    case 0: printf("INT"); break;
+	    case 1: printf("NMI"); break;
+	    case 2: printf("SMI"); break;
+	    case 3: printf("ExtINT"); break;
+	}
+	putchar(',');
+	switch (lintr->poel&3) {
+	    case 0: printf("bus-like"); break;
+	    case 1: printf("active high"); break;
+	    case 2: printf("reserved"); break;
+	    case 3: printf("active low"); break;
+	}
+	putchar(',');
+	switch ((lintr->poel>>2)&3) {
+	    case 0: printf("bus-like"); break;
+	    case 1: printf("edge-triggered"); break;
+	    case 2: printf("reserved"); break;
+	    case 3: printf("level-triggered"); break;
+	}
+	putchar(',');
+	printf("bus%d,irq%d", lintr->src_bus_id, lintr->src_bus_irq);
+	putchar(',');
+	printf("l_apic%d,pin%d", lintr->dst_l_apic_id, lintr->dst_l_apic_pin);
+	putchar('\n');
+#endif
+}
+
+void ct_extended_entries(void)
+{
+	uint8_t *ext = (uint8_t *) ct + ct->base_table_length;
+	uint8_t *cur;
+
+	for (cur = ext; cur < ext + ct->ext_table_length; cur += cur[CT_EXT_ENTRY_LEN]) {
+		switch (cur[CT_EXT_ENTRY_TYPE]) {
+			default:
+				printf("%p: skipping MP Configuration Table extended entry type %d\n", cur, cur[CT_EXT_ENTRY_TYPE]);
+				break;
+		}
+	}
+}
+
+int mps_irq_to_pin(int irq)
+{
+	int i;
+	
+	for(i=0;i<io_intr_entry_cnt;i++) {
+		if (io_intr_entries[i].src_bus_irq == irq && io_intr_entries[i].intr_type == 0)
+			return io_intr_entries[i].dst_io_apic_pin;
+	}
+	
+	return -1;
+}
+
+#endif /* CONFIG_SMP */
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/src/smp/smp.c
===================================================================
--- kernel/arch/ia32/src/smp/smp.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/smp/smp.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#include <smp/smp.h>
+#include <arch/smp/smp.h>
+#include <arch/smp/mps.h>
+#include <arch/smp/ap.h>
+#include <arch/boot/boot.h>
+#include <genarch/acpi/acpi.h>
+#include <genarch/acpi/madt.h>
+#include <config.h>
+#include <synch/waitq.h>
+#include <synch/synch.h>
+#include <arch/pm.h>
+#include <func.h>
+#include <panic.h>
+#include <debug.h>
+#include <arch/asm.h>
+#include <mm/frame.h>
+#include <mm/page.h>
+#include <mm/slab.h>
+#include <mm/as.h>
+#include <print.h>
+#include <memstr.h>
+#include <arch/drivers/i8259.h>
+
+#ifdef CONFIG_SMP
+
+static struct smp_config_operations *ops = NULL;
+
+void smp_init(void)
+{
+	uintptr_t l_apic_address, io_apic_address;
+
+	if (acpi_madt) {
+		acpi_madt_parse();
+		ops = &madt_config_operations;
+	}
+	if (config.cpu_count == 1) {
+		mps_init();
+		ops = &mps_config_operations;
+	}
+
+	l_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_ATOMIC | FRAME_KA);
+	if (!l_apic_address)
+		panic("cannot allocate address for l_apic\n");
+
+	io_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_ATOMIC | FRAME_KA);
+	if (!io_apic_address)
+		panic("cannot allocate address for io_apic\n");
+
+	if (config.cpu_count > 1) {		
+		page_mapping_insert(AS_KERNEL, l_apic_address, (uintptr_t) l_apic, 
+				  PAGE_NOT_CACHEABLE);
+		page_mapping_insert(AS_KERNEL, io_apic_address, (uintptr_t) io_apic,
+				  PAGE_NOT_CACHEABLE);
+				  
+		l_apic = (uint32_t *) l_apic_address;
+		io_apic = (uint32_t *) io_apic_address;
+        }
+}
+
+/*
+ * Kernel thread for bringing up application processors. It becomes clear
+ * that we need an arrangement like this (AP's being initialized by a kernel
+ * thread), for a thread has its dedicated stack. (The stack used during the
+ * BSP initialization (prior the very first call to scheduler()) will be used
+ * as an initialization stack for each AP.)
+ */
+void kmp(void *arg)
+{
+	int i;
+	
+	ASSERT(ops != NULL);
+
+	waitq_initialize(&ap_completion_wq);
+
+	/*
+	 * We need to access data in frame 0.
+	 * We boldly make use of kernel address space mapping.
+	 */
+
+	/*
+	 * Set the warm-reset vector to the real-mode address of 4K-aligned ap_boot()
+	 */
+	*((uint16_t *) (PA2KA(0x467+0))) =  ((uintptr_t) ap_boot) >> 4;	/* segment */
+	*((uint16_t *) (PA2KA(0x467+2))) =  0;				/* offset */
+	
+	/*
+	 * Save 0xa to address 0xf of the CMOS RAM.
+	 * BIOS will not do the POST after the INIT signal.
+	 */
+	outb(0x70,0xf);
+	outb(0x71,0xa);
+
+	pic_disable_irqs(0xffff);
+	apic_init();
+
+	for (i = 0; i < ops->cpu_count(); i++) {
+		struct descriptor *gdt_new;
+	
+		/*
+		 * Skip processors marked unusable.
+		 */
+		if (!ops->cpu_enabled(i))
+			continue;
+
+		/*
+		 * The bootstrap processor is already up.
+		 */
+		if (ops->cpu_bootstrap(i))
+			continue;
+
+		if (ops->cpu_apic_id(i) == l_apic_id()) {
+			printf("%s: bad processor entry #%d, will not send IPI to myself\n", __FUNCTION__, i);
+			continue;
+		}
+		
+		/*
+		 * Prepare new GDT for CPU in question.
+		 */
+		if (!(gdt_new = (struct descriptor *) malloc(GDT_ITEMS*sizeof(struct descriptor), FRAME_ATOMIC)))
+			panic("couldn't allocate memory for GDT\n");
+
+		memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(struct descriptor));
+		memsetb((uintptr_t)(&gdt_new[TSS_DES]), sizeof(struct descriptor), 0);
+		protected_ap_gdtr.limit = GDT_ITEMS * sizeof(struct descriptor);
+		protected_ap_gdtr.base = KA2PA((uintptr_t) gdt_new);
+		gdtr.base = (uintptr_t) gdt_new;
+
+		if (l_apic_send_init_ipi(ops->cpu_apic_id(i))) {
+			/*
+			 * There may be just one AP being initialized at
+			 * the time. After it comes completely up, it is
+			 * supposed to wake us up.
+			 */
+			if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT)
+				printf("%s: waiting for cpu%d (APIC ID = %d) timed out\n", __FUNCTION__, config.cpu_active > i ? config.cpu_active : i, ops->cpu_apic_id(i));
+		} else
+			printf("INIT IPI for l_apic%d failed\n", ops->cpu_apic_id(i));
+	}
+}
+
+int smp_irq_to_pin(int irq)
+{
+	ASSERT(ops != NULL);
+	return ops->irq_to_pin(irq);
+}
+
+#endif /* CONFIG_SMP */
+
+ /** @}
+ */
+
Index: kernel/arch/ia32/src/userspace.c
===================================================================
--- kernel/arch/ia32/src/userspace.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/ia32/src/userspace.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+ /** @addtogroup ia32	
+ * @{
+ */
+/** @file
+ */
+
+#include <userspace.h>
+#include <arch/pm.h>
+#include <arch/types.h>
+#include <arch.h>
+#include <proc/uarg.h>
+#include <mm/as.h>
+
+
+/** Enter userspace
+ *
+ * Change CPU protection level to 3, enter userspace.
+ *
+ */
+void userspace(uspace_arg_t *kernel_uarg)
+{
+	ipl_t ipl;
+
+	ipl = interrupts_disable();
+
+	__asm__ volatile (
+		/*
+		 * Clear nested task flag.
+		 */
+		"pushfl\n"
+		"pop %%eax\n"
+		"and $0xffffbfff, %%eax\n"
+		"push %%eax\n"
+		"popfl\n"
+
+		/* Set up GS register (TLS) */
+		"movl %6, %%gs\n"
+
+		"pushl %0\n"
+		"pushl %1\n"
+		"pushl %2\n"
+		"pushl %3\n"
+		"pushl %4\n"
+		"movl %5, %%eax\n"
+		"iret\n"
+		: 
+		: "i" (selector(UDATA_DES) | PL_USER), "r" (kernel_uarg->uspace_stack+THREAD_STACK_SIZE),
+		  "r" (ipl), "i" (selector(UTEXT_DES) | PL_USER), "r" (kernel_uarg->uspace_entry),
+		"r" (kernel_uarg->uspace_uarg),
+		"r" (selector(TLS_DES))
+		: "eax");
+	
+	/* Unreachable */
+	for(;;)
+		;
+}
+
+ /** @}
+ */
+
