Initial x86 port
diff --git a/arch/x86/arch.c b/arch/x86/arch.c
new file mode 100644
index 0000000..99ca572
--- /dev/null
+++ b/arch/x86/arch.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2009 Corey Tabaka
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include <debug.h>
+#include <arch.h>
+#include <arch/ops.h>
+#include <arch/x86.h>
+#include <arch/x86/mmu.h>
+#include <arch/x86/descriptor.h>
+#include <platform.h>
+#include <sys/types.h>
+#include <string.h>
+
+static tss_t system_tss;
+
+void arch_early_init(void)
+{
+	x86_mmu_init();
+
+	platform_init_mmu_mappings();
+	
+	/* enable caches here for now */
+	clear_in_cr0(X86_CR0_NW | X86_CR0_CD);
+	
+	memset(&system_tss, 0, sizeof(tss_t));
+	
+	system_tss.esp0 = 0;
+	system_tss.ss0 = DATA_SELECTOR;
+	system_tss.ss1 = 0;
+	system_tss.ss2 = 0;
+	system_tss.eflags = 0x00003002;
+	system_tss.bitmap = offsetof(tss_t, tss_bitmap);
+	system_tss.trace = 1; // trap on hardware task switch
+	
+	set_global_desc(TSS_SELECTOR, &system_tss, sizeof(tss_t), 1, 0, 0, SEG_TYPE_TSS, 0, 0);
+
+	x86_ltr(TSS_SELECTOR);
+}
+
+void arch_init(void)
+{
+}
+
diff --git a/arch/x86/asm.S b/arch/x86/asm.S
new file mode 100644
index 0000000..4d7763c
--- /dev/null
+++ b/arch/x86/asm.S
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2009 Corey Tabaka
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include <asm.h>
+
+
+	/* context switch frame is as follows:
+	 * ulr
+	 * usp
+	 * lr
+	 * r11
+	 * r10
+	 * r9
+	 * r8
+	 * r7
+	 * r6
+	 * r5
+	 * r4
+	 */
+/* x86_context_switch(addr_t *old_sp, addr_t new_sp) */
+FUNCTION(x86_context_switch)
+	/* TODO */
+	ret
diff --git a/arch/x86/cache-ops.S b/arch/x86/cache-ops.S
new file mode 100644
index 0000000..9ad7c71
--- /dev/null
+++ b/arch/x86/cache-ops.S
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2009 Corey Tabaka
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include <asm.h>
+#include <arch/ops.h>
+#include <arch/defines.h>
+
+.text
+
+/* stubs */
+
+FUNCTION(arch_disable_cache)
+	ret
+
+FUNCTION(arch_enable_cache)
+	ret
+
+FUNCTION(arch_clean_cache_range)
+	ret
+
+FUNCTION(arch_clean_invalidate_cache_range)
+	ret
+
diff --git a/arch/x86/cache.c b/arch/x86/cache.c
new file mode 100644
index 0000000..b00d6cc
--- /dev/null
+++ b/arch/x86/cache.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2009 Corey Tabaka
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
diff --git a/arch/x86/compile.mk b/arch/x86/compile.mk
new file mode 100644
index 0000000..271db17
--- /dev/null
+++ b/arch/x86/compile.mk
@@ -0,0 +1,16 @@
+
+$(BUILDDIR)/%.o: %.c $(SRCDEPS)
+	@$(MKDIR)
+	@echo compiling $<
+	$(NOECHO)$(CC) $(CFLAGS) --std=c99 $(INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@
+
+$(BUILDDIR)/%.o: %.cpp $(SRCDEPS)
+	@$(MKDIR)
+	@echo compiling $<
+	$(NOECHO)$(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@
+
+$(BUILDDIR)/%.o: %.S $(SRCDEPS)
+	@$(MKDIR)
+	@echo compiling $<
+	$(NOECHO)$(CC) $(CFLAGS) $(ASMFLAGS) $(INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@
+
diff --git a/arch/x86/crt0.S b/arch/x86/crt0.S
new file mode 100644
index 0000000..9cc9ab0
--- /dev/null
+++ b/arch/x86/crt0.S
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2009 Corey Tabaka
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* The magic number for the Multiboot header. */
+#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
+
+/* The flags for the Multiboot header. */
+#if defined(__ELF__) && 0
+#define MULTIBOOT_HEADER_FLAGS 0x00000002
+#else
+#define MULTIBOOT_HEADER_FLAGS 0x00010002
+#endif
+
+/* The magic number passed by a Multiboot-compliant boot loader. */
+#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
+
+#define NUM_INT 0x31
+#define NUM_EXC 0x14
+
+.text
+.global _start
+_start:
+	jmp real_start
+
+.align 4
+
+multiboot_header:
+	/* magic */
+	.int MULTIBOOT_HEADER_MAGIC
+	/* flags */
+	.int MULTIBOOT_HEADER_FLAGS
+	/* checksum */
+	.int -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
+
+#if !defined(__ELF__) || 1
+	/* header_addr */
+	.int multiboot_header
+	/* load_addr */
+	.int _start
+	/* load_end_addr */
+	.int __bss_start
+	/* bss_end_addr */
+	.int __bss_end
+	/* entry_addr */
+	.int real_start
+#endif
+
+real_start:
+	cmpl $MULTIBOOT_BOOTLOADER_MAGIC, %eax
+	jne 0f
+	movl %ebx, (_multiboot_info)
+0:
+	/* setup isr stub descriptors in the idt */
+	movl $_isr, %esi
+	movl $_idt, %edi
+	movl $NUM_INT, %ecx
+	
+.Lloop:
+	movl %esi, %ebx
+	movw %bx, (%edi)		/* low word in IDT(n).low */
+	shrl $16, %ebx
+	movw %bx, 6(%edi)		/* high word in IDT(n).high */
+	
+	addl $isr_stub_len, %esi/* index the next ISR stub */
+	addl $8, %edi			/* index the next IDT entry */
+	
+	loop .Lloop
+	
+	lidt _idtr
+	xorl %eax, %eax
+	movl %eax, %cr3
+
+	lgdt _gdtr
+		
+	movw $datasel, %ax
+	movw %ax, %ds
+	movw %ax, %es
+	movw %ax, %fs
+	movw %ax, %ss
+	movw %ax, %gs
+	movw %ax, %ss
+	
+	movl $_kstack, %esp
+	
+	/* zero the bss section */
+	movl $__bss_start, %edi	/* starting address of the bss */
+	movl $__bss_end, %ecx	/* find the length of the bss in bytes */
+	subl %edi, %ecx
+	shrl $2, %ecx			/* convert to 32 bit words, since the bss is aligned anyway */
+2:
+	movl $0, (%edi)
+	addl $4, %edi
+	loop 2b
+	
+	/* call the main module */
+	call kmain
+	
+0:							/* just sit around waiting for interrupts */
+	hlt						/* interrupts will unhalt the processor */
+	pause
+	jmp 0b					/* so jump back to halt to conserve power */
+
+/* interrupt service routine stubs */
+_isr:
+
+.set i, 0
+.rept NUM_INT
+
+.set isr_stub_start, .
+
+.if i == 8 || (i >= 10 && i <= 14) || i == 17
+	nop						/* error code pushed by exception */
+	nop						/* 2 nops are the same length as push byte */
+	pushl $i				/* interrupt number */
+	jmp interrupt_common
+.else
+	pushl $0				/* fill in error code in iframe */
+	pushl $i				/* interrupt number */
+	jmp interrupt_common
+.endif
+
+/* figure out the length of a single isr stub (usually 6 or 9 bytes) */
+.set isr_stub_len, . - isr_stub_start
+
+.set i, i + 1
+.endr
+
+/* annoying, but force AS to use the same (longer) encoding of jmp for all of the stubs */
+.fill 256
+
+interrupt_common:
+	pushl %gs				/* save segment registers */
+	pushl %fs
+	pushl %es
+	pushl %ds
+	pusha					/* save general purpose registers */
+	movl $datasel, %eax		/* put known good value in segment registers */
+	movl %eax, %gs
+	movl %eax, %fs
+	movl %eax, %es
+	movl %eax, %ds
+	movl %esp, %eax			/* store stack switch pivot. push esp has errata on some cpus, so use mov/push */
+	pushl %eax
+	movl %esp, %eax			/* store pointer to iframe, using same method */
+	pushl %eax
+	
+	incl critical_section_count
+
+	call platform_irq
+	
+	cmpl $0,%eax
+	je 0f
+	call thread_preempt
+
+0:
+	decl critical_section_count
+
+	popl %eax				/* drop pointer to iframe */
+	popl %eax				/* restore task_esp, stack switch can occur here if task_esp is modified */
+	movl %eax, %esp
+	popa					/* restore general purpose registers */
+	popl %ds				/* restore segment registers */
+	popl %es
+	popl %fs
+	popl %gs
+	addl $8, %esp			/* drop exception number and error code */
+	iret
+
+.data
+.align 4
+
+/* define the heap end as read-write data containing the default end of the
+ * heap. dynamic memory length discovery can update this value during init.
+ * other archs can define this statically based on the memory layout of the
+ * platform.
+ */
+.global _heap_end
+_heap_end:
+	.int 4096*1024	/* default to 4MB total */
+
+.global _multiboot_info
+_multiboot_info:
+	.int 0
+
+.global _gdtr
+_gdtr:
+	.short _gdt_end - _gdt - 1
+	.int _gdt
+
+.global _gdt
+_gdt:
+	.int 0
+	.int 0
+
+/* ring 0 descriptors */
+.set codesel, . - _gdt
+_code_gde:
+	.short 0xffff			/* limit 15:00 */
+	.short 0x0000			/* base 15:00 */
+	.byte  0x00				/* base 23:16 */
+	.byte  0b10011010		/* P(1) DPL(00) S(1) 1 C(0) R(1) A(0) */
+	.byte  0b11001111		/* G(1) D(1) 0 0 limit 19:16 */
+	.byte  0x0				/* base 31:24 */
+	
+.set datasel, . - _gdt
+_data_gde:
+	.short 0xffff			/* limit 15:00 */
+	.short 0x0000			/* base 15:00 */
+	.byte  0x00				/* base 23:16 */
+	.byte  0b10010010		/* P(1) DPL(00) S(1) 0 E(0) W(1) A(0) */
+	.byte  0b11001111		/* G(1) B(1) 0 0 limit 19:16 */
+	.byte  0x0				/* base 31:24 */
+	
+.set videosel, . - _gdt
+_video_gde:
+	.short 0xffff			/* limit 15:00 */
+	.short 0x8000			/* base 15:00 */
+	.byte  0x0b				/* base 23:16 */
+	.byte  0b10010010		/* P(1) DPL(00) S(1) 0 E(0) W(1) A(0) */
+	.byte  0b11001111		/* G(1) B(1) 0 0 limit 19:16 */
+	.byte  0x0				/* base 31:24 */
+	
+.if 1
+/* ring 3 descriptors */
+.set user_codesel, . - _gdt
+_user_code_gde:
+	.short 0xffff			/* limit 15:00 */
+	.short 0x0000			/* base 15:00 */
+	.byte  0x00				/* base 23:16 */
+	.byte  0b11111010		/* P(1) DPL(11) S(1) 1 C(0) R(1) A(0) */
+	.byte  0b11001111		/* G(1) D(1) 0 0 limit 19:16 */
+	.byte  0x0				/* base 31:24 */
+	
+.set user_datasel, . - _gdt
+_user_data_gde:
+	.short 0xffff			/* limit 15:00 */
+	.short 0x0000			/* base 15:00 */
+	.byte  0x00				/* base 23:16 */
+	.byte  0b11110010		/* P(1) DPL(11) S(1) 0 E(0) W(1) A(0) */
+	.byte  0b11001111		/* G(1) B(1) 0 0 limit 19:16 */
+	.byte  0x0				/* base 31:24 */
+.endif
+
+/* TSS descriptor */
+.if 1
+.set tsssel, . - _gdt
+_tss_gde:
+	.short 0				/* limit 15:00 */
+	.short 0				/* base 15:00 */
+	.byte  0				/* base 23:16 */
+	.byte  0xe9				/* P(1) DPL(11) 0 10 B(0) 1 */
+	.byte  0x00				/* G(0) 0 0 AVL(0) limit 19:16 */
+	.short 0				/* base 31:24 */
+.endif
+
+.global _gdt_end
+_gdt_end:
+
+.global _idtr
+_idtr:
+	.short _idt_end - _idt - 1	/* IDT limit */
+	.int _idt
+
+/* interrupt descriptor table (IDT) */
+.global _idt
+_idt:
+
+.set i, 0
+.rept NUM_INT-1
+	.short 0				/* low 16 bits of ISR offset (_isr#i & 0FFFFh) */
+	.short codesel			/* selector */
+	.byte  0
+	.byte  0x8e				/* present, ring 0, 32-bit interrupt gate */
+	.short 0				/* high 16 bits of ISR offset (_isr#i / 65536) */
+	
+.set i, i + 1
+.endr
+
+/* syscall int (ring 3) */
+_idt30:
+	.short 0				/* low 16 bits of ISR offset (_isr#i & 0FFFFh) */
+	.short codesel			/* selector */
+	.byte  0
+	.byte  0xee				/* present, ring 3, 32-bit interrupt gate */
+	.short 0				/* high 16 bits of ISR offset (_isr#i / 65536) */
+
+.global _idt_end
+_idt_end:
+
+.bss
+.align 4096
+
+.global _kstack
+.fill 4096
+_kstack:
diff --git a/arch/x86/descriptor.c b/arch/x86/descriptor.c
new file mode 100644
index 0000000..27ee37e
--- /dev/null
+++ b/arch/x86/descriptor.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2009 Corey Tabaka
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <compiler.h>
+#include <arch/x86/descriptor.h>
+
+/* not the best way to do this, but easy for now */
+typedef struct {
+	uint16_t limit_15_0;
+	uint16_t base_15_0;
+	uint8_t base_23_16;
+	
+	uint8_t type : 4;
+	uint8_t s : 1;
+	uint8_t dpl : 2;
+	uint8_t p : 1;
+	
+	uint8_t limit_19_16 : 4;
+	uint8_t avl : 1;
+	uint8_t reserved_0 : 1;
+	uint8_t d_b : 1;
+	uint8_t g : 1;
+	
+	uint8_t base_31_24;
+} __PACKED seg_desc_t;
+
+extern seg_desc_t _gdt[];
+
+void set_global_desc(seg_sel_t sel, void *base, uint32_t limit,
+	uint8_t present, uint8_t ring, uint8_t sys, uint8_t type, uint8_t gran, uint8_t bits)
+{
+	// convert selector into index
+	uint16_t index = sel >> 3;
+
+	_gdt[index].limit_15_0 = limit & 0x0000ffff;
+	_gdt[index].limit_19_16 = (limit & 0x000f0000) >> 16;
+
+	_gdt[index].base_15_0 = ((uint32_t) base) & 0x0000ffff;
+	_gdt[index].base_23_16 = (((uint32_t) base) & 0x00ff0000) >> 16;
+	_gdt[index].base_31_24 = ((uint32_t) base) >> 24;
+
+	_gdt[index].type = type & 0x0f;	// segment type
+	_gdt[index].p = present != 0;	// present
+	_gdt[index].dpl = ring & 0x03;	// descriptor privilege level
+	_gdt[index].g = gran != 0;		// granularity
+	_gdt[index].s = sys != 0;		// system / non-system
+	_gdt[index].d_b = bits != 0;	// 16 / 32 bit
+}
diff --git a/arch/x86/faults.c b/arch/x86/faults.c
new file mode 100644
index 0000000..3d4c8d2
--- /dev/null
+++ b/arch/x86/faults.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2009 Corey Tabaka
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include <debug.h>
+#include <arch/x86.h>
+#include <kernel/thread.h>
+
+static void dump_fault_frame(struct x86_iframe *frame)
+{
+	dprintf(CRITICAL, " CS:     %04x EIP: %08x EFL: %08x CR2: %08x\n",
+		frame->cs, frame->eip, frame->eflags, x86_get_cr2());
+	dprintf(CRITICAL, "EAX: %08x ECX: %08x EDX: %08x EBX: %08x\n",
+		frame->eax, frame->ecx, frame->edx, frame->ebx);
+	dprintf(CRITICAL, "ESP: %08x EBP: %08x ESI: %08x EDI: %08x\n",
+		frame->esp, frame->ebp, frame->esi, frame->edi);
+	dprintf(CRITICAL, " DS:     %04x  ES:     %04x  FS:     %04x  GS:     %04x\n",
+		frame->ds, frame->es, frame->fs, frame->gs);
+
+	// dump the bottom of the current stack
+	addr_t stack = (addr_t) frame; //(addr_t) (((uint32_t *) frame) + (sizeof(struct x86_iframe) / sizeof(uint32_t) - 1));
+
+	if (stack != 0) {
+		dprintf(CRITICAL, "bottom of stack at 0x%08x:\n", (unsigned int)stack);
+		hexdump((void *)stack, 192);
+	}
+}
+
+static void exception_die(struct x86_iframe *frame, const char *msg)
+{
+	inc_critical_section();
+	dprintf(CRITICAL, msg);
+	dump_fault_frame(frame);
+	
+	for (;;) {
+		x86_cli();
+		x86_hlt();
+	}
+}
+
+void x86_syscall_handler(struct x86_iframe *frame)
+{
+	exception_die(frame, "unhandled syscall, halting\n");
+}
+
+void x86_gpf_handler(struct x86_iframe *frame)
+{
+	exception_die(frame, "unhandled gpf, halting\n");	
+}
+
+void x86_invop_handler(struct x86_iframe *frame)
+{
+	exception_die(frame, "unhandled invalid op, halting\n");	
+}
+
+void x86_unhandled_exception(struct x86_iframe *frame)
+{
+	exception_die(frame, "unhandled exception, halting\n");	
+}
diff --git a/arch/x86/include/arch/arch_thread.h b/arch/x86/include/arch/arch_thread.h
new file mode 100644
index 0000000..9347bcd
--- /dev/null
+++ b/arch/x86/include/arch/arch_thread.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2009 Corey Tabaka
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __X86_ARCH_THREAD_H
+#define __X86_ARCH_THREAD_H
+
+struct arch_thread {
+	vaddr_t esp;
+	
+	// TODO: fpu context
+};
+
+#endif
+
diff --git a/arch/x86/include/arch/defines.h b/arch/x86/include/arch/defines.h
new file mode 100644
index 0000000..814fcc9
--- /dev/null
+++ b/arch/x86/include/arch/defines.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2009 Corey Tabaka
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __ARCH_CPU_H
+#define __ARCH_CPU_H
+
+#define PAGE_SIZE 4096
+
+// TODO: define to resolve to platform setup discovered value
+#define CACHE_LINE 32
+
+#endif
+
diff --git a/arch/x86/include/arch/x86.h b/arch/x86/include/arch/x86.h
new file mode 100644
index 0000000..4cf65d9
--- /dev/null
+++ b/arch/x86/include/arch/x86.h
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2009 Corey Tabaka
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __ARCH_X86_H
+#define __ARCH_X86_H
+
+#include <compiler.h>
+#include <sys/types.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+void x86_mmu_init(void);
+
+struct x86_iframe {
+	uint32_t pivot;										// stack switch pivot
+	uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;	// pushed by common handler using pusha
+	uint32_t ds, es, fs, gs;							// pushed by common handler
+	uint32_t vector;									// pushed by stub
+	uint32_t err_code;									// pushed by interrupt or stub
+	uint32_t eip, cs, eflags;							// pushed by interrupt
+	uint32_t user_esp, user_ss;							// pushed by interrupt if priv change occurs
+};
+
+/*
+ * x86 TSS structure
+ */
+typedef struct {
+	uint16_t	backlink, __blh;
+	uint32_t	esp0;
+	uint16_t	ss0, __ss0h;
+	uint32_t	esp1;
+	uint16_t	ss1, __ss1h;
+	uint32_t	esp2;
+	uint16_t	ss2, __ss2h;
+	uint32_t	cr3;
+	uint32_t	eip;
+	uint32_t	eflags;
+	uint32_t	eax, ecx, edx, ebx;
+	uint32_t	esp, ebp, esi, edi;
+	uint16_t	es, __esh;
+	uint16_t	cs, __csh;
+	uint16_t	ss, __ssh;
+	uint16_t	ds, __dsh;
+	uint16_t	fs, __fsh;
+	uint16_t	gs, __gsh;
+	uint16_t	ldt, __ldth;
+	uint16_t	trace, bitmap;
+	
+	uint8_t tss_bitmap[8192];
+} __PACKED tss_t;
+
+#define X86_CR0_PE		0x00000001 /* protected mode enable */
+#define X86_CR0_MP		0x00000002 /* monitor coprocessor */
+#define X86_CR0_EM		0x00000004 /* emulation */
+#define X86_CR0_TS		0x00000008 /* task switched */
+#define X86_CR0_WP		0x00010000 /* supervisor write protect */
+#define X86_CR0_NW		0x20000000 /* not write-through */
+#define X86_CR0_CD		0x40000000 /* cache disable */
+#define X86_CR0_PG		0x80000000 /* enable paging */
+
+static inline void set_in_cr0(uint32_t mask) {
+	__asm__ __volatile__ (
+		"movl %%cr0,%%eax	\n\t"
+		"orl %0,%%eax		\n\t"
+		"movl %%eax,%%cr0	\n\t"
+		: : "irg" (mask)
+		:"ax");
+}
+
+static inline void clear_in_cr0(uint32_t mask) {
+	__asm__ __volatile__ (
+		"movl %%cr0, %%eax	\n\t"
+		"andl %0, %%eax		\n\t"
+		"movl %%eax, %%cr0	\n\t"
+		: : "irg" (~mask)
+		: "ax");
+}
+
+static inline void x86_clts(void) {__asm__ __volatile__ ("clts"); }
+static inline void x86_hlt(void) {__asm__ __volatile__ ("hlt"); }
+static inline void x86_sti(void) {__asm__ __volatile__ ("sti"); }
+static inline void x86_cli(void) {__asm__ __volatile__ ("cli"); }
+static inline void x86_ltr(uint16_t sel) {
+	__asm__ __volatile__ ("ltr %%ax" :: "a" (sel));
+}
+
+static inline uint32_t x86_get_cr2(void) {
+	uint32_t rv;
+	
+	__asm__ __volatile__ (
+		"movl %%cr2, %0"
+		: "=r" (rv)
+	);
+	
+	return rv;
+}
+
+#define rdtsc(low,high) \
+     __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
+
+#define rdtscl(low) \
+     __asm__ __volatile__("rdtsc" : "=a" (low) : : "edx")
+
+#define rdtscll(val) \
+     __asm__ __volatile__("rdtsc" : "=A" (val))
+
+static inline uint8_t inp(uint16_t _port) {
+    uint8_t rv;
+    __asm__ __volatile__ ("inb %1, %0"
+	  : "=a" (rv)
+	  : "d" (_port));
+    return(rv);
+}
+
+static inline uint16_t inpw (uint16_t _port) {
+    uint16_t rv;
+    __asm__ __volatile__ ("inw %1, %0"
+	  : "=a" (rv)
+	  : "d" (_port));
+    return(rv);
+}
+
+static inline uint32_t inpd(uint16_t _port) {
+    uint32_t rv;
+    __asm__ __volatile__ ("inl %1, %0"
+	  : "=a" (rv)
+	  : "d" (_port));
+    return(rv);
+}
+
+static inline void outp(uint16_t _port, uint8_t _data) {
+    __asm__ __volatile__ ("outb %1, %0"
+	  :
+	  : "d" (_port),
+	    "a" (_data));
+}
+
+static inline void outpw(uint16_t _port, uint16_t _data) {
+    __asm__ __volatile__ ("outw %1, %0"
+	  :
+	  : "d" (_port),
+	    "a" (_data));
+}
+
+static inline void outpd(uint16_t _port, uint32_t _data) {
+    __asm__ __volatile__ ("outl %1, %0"
+	  :
+	  : "d" (_port),
+	    "a" (_data));
+}
+
+static inline void inprep(uint16_t _port, uint8_t *_buffer, uint32_t _reads) {
+	__asm__ __volatile__ ("pushal \n\t"	
+		"pushfl \n\t"	
+		"cli \n\t"	
+		"cld \n\t"	
+		"rep insb \n\t"	
+		"popfl \n\t"	
+		"popal"	
+		:
+		: "d" (_port),
+		  "D" (_buffer),
+		  "c" (_reads));
+}
+
+static inline void outprep(uint16_t _port, uint8_t *_buffer, uint32_t _writes) {
+	__asm__ __volatile__ ("pushal \n\t"
+		"pushfl \n\t"
+		"cli \n\t"
+		"cld \n\t"
+		"rep outsb \n\t"
+		"popfl \n\t"
+		"popal"
+		:
+		: "d" (_port),
+		  "S" (_buffer),
+		  "c" (_writes));
+}
+
+static inline void inpwrep(uint16_t _port, uint16_t *_buffer, uint32_t _reads) {
+	__asm__ __volatile__ ("pushal \n\t"	
+		"pushfl \n\t"	
+		"cli \n\t"	
+		"cld \n\t"	
+		"rep insw \n\t"	
+		"popfl \n\t"	
+		"popal"	
+		:
+		: "d" (_port),
+		  "D" (_buffer),
+		  "c" (_reads));
+}
+
+static inline void outpwrep(uint16_t _port, uint16_t *_buffer,
+	uint32_t _writes) {
+	__asm__ __volatile__ ("pushal \n\t"
+		"pushfl \n\t"
+		"cli \n\t"
+		"cld \n\t"
+		"rep outsw \n\t"
+		"popfl \n\t"
+		"popal"
+		:
+		: "d" (_port),
+		  "S" (_buffer),
+		  "c" (_writes));
+}
+
+static inline void inpdrep(uint16_t _port, uint32_t *_buffer,
+	uint32_t _reads) {
+	__asm__ __volatile__ ("pushal \n\t"	
+		"pushfl \n\t"	
+		"cli \n\t"	
+		"cld \n\t"	
+		"rep insl \n\t"	
+		"popfl \n\t"	
+		"popal"	
+		:
+		: "d" (_port),
+		  "D" (_buffer),
+		  "c" (_reads));
+}
+
+static inline void outpdrep(uint16_t _port, uint32_t *_buffer,
+	uint32_t _writes) {
+	__asm__ __volatile__ ("pushal \n\t"
+		"pushfl \n\t"
+		"cli \n\t"
+		"cld \n\t"
+		"rep outsl \n\t"
+		"popfl \n\t"
+		"popal"
+		:
+		: "d" (_port),
+		  "S" (_buffer),
+		  "c" (_writes));
+}
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/arch/x86/include/arch/x86/descriptor.h b/arch/x86/include/arch/x86/descriptor.h
new file mode 100644
index 0000000..1b2580d
--- /dev/null
+++ b/arch/x86/include/arch/x86/descriptor.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2009 Corey Tabaka
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __ARCH_DESCRIPTOR_H
+#define __ARCH_DESCRIPTOR_H
+
+#include <sys/types.h>
+
+/*
+ * System Selectors
+ */
+#define CODE_SELECTOR	0x08
+#define DATA_SELECTOR	0x10
+#define VIDEO_SELECTOR	0x18
+#define TSS_SELECTOR	0x30
+
+#define USER_CODE_SELECTOR 0x23
+#define USER_DATA_SELECTOR 0x2b
+
+/*
+ * Descriptor Types
+ */
+#define SEG_TYPE_TSS		0x9
+#define SEG_TYPE_TSS_BUSY	0xb
+#define SEG_TYPE_TASK_GATE	0x5
+#define SEG_TYPE_INT_GATE	0xe		// 32 bit
+#define SEG_TYPE_DATA_RW	0x2
+#define SEG_TYPE_CODE_RW	0xa
+
+typedef uint16_t seg_sel_t;
+
+void set_global_desc(seg_sel_t sel, void *base, uint32_t limit,
+	uint8_t present, uint8_t ring, uint8_t sys, uint8_t type, uint8_t gran, uint8_t bits);
+
+#endif
diff --git a/arch/x86/include/arch/x86/mmu.h b/arch/x86/include/arch/x86/mmu.h
new file mode 100644
index 0000000..719710c
--- /dev/null
+++ b/arch/x86/include/arch/x86/mmu.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2008 Travis Geiselbrecht
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __ARCH_ARM_MMU_H
+#define __ARCH_ARM_MMU_H
+
+#include <sys/types.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+void arm_mmu_init(void);
+
+#define MMU_FLAG_CACHED 0x1
+#define MMU_FLAG_BUFFERED 0x2
+#define MMU_FLAG_READWRITE 0x4
+void arm_mmu_map_section(addr_t paddr, addr_t vaddr, uint flags);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/arch/x86/include/arch/x86/ops.h b/arch/x86/include/arch/x86/ops.h
new file mode 100644
index 0000000..d2bbc24
--- /dev/null
+++ b/arch/x86/include/arch/x86/ops.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2009 Corey Tabaka
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __ARCH_X86_OPS_H
+#define __ARHC_X86_OPS_H
+
+#if 0
+#include <compiler.h>
+
+#ifndef ASSEMBLY
+
+// override of some routines
+__GNU_INLINE __ALWAYS_INLINE extern inline void arch_enable_ints(void)
+{
+	__asm__ __volatile__ ("sti");
+}
+
+__GNU_INLINE __ALWAYS_INLINE extern inline void arch_disable_ints(void)
+{
+	__asm__ __volatile__ ("cli");
+}
+
+#endif
+#endif
+
+#endif
+
diff --git a/arch/x86/kernel.ld b/arch/x86/kernel.ld
new file mode 100644
index 0000000..1e3abba
--- /dev/null
+++ b/arch/x86/kernel.ld
@@ -0,0 +1,83 @@
+/*

+ * Copyright (c) 2009 Corey Tabaka

+ *

+ * Permission is hereby granted, free of charge, to any person obtaining

+ * a copy of this software and associated documentation files

+ * (the "Software"), to deal in the Software without restriction,

+ * including without limitation the rights to use, copy, modify, merge,

+ * publish, distribute, sublicense, and/or sell copies of the Software,

+ * and to permit persons to whom the Software is furnished to do so,

+ * subject to the following conditions:

+ *

+ * The above copyright notice and this permission notice shall be

+ * included in all copies or substantial portions of the Software.

+ *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,

+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF

+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.

+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY

+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,

+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE

+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ */

+

+ENTRY(_start)

+SECTIONS

+{

+	.text 0x0200000 : {

+		*(.text)

+		*(SORT(.text$*))

+		*(.gnu.linkonce.t.*)

+		

+		__ctor_list = .;

+		*(SORT(.ctor*))

+		__ctor_end = .;

+		__dtor_list = .;

+		*(SORT(.dtor*))

+		__dtor_end = .;

+		

+		. = ALIGN(4096);

+	}

+	

+	__data_start = .;

+	.data		: { *(.data .data.* .gnu.linkonce.d.*) }

+	.stab		: { *(.stab) }

+	.stabst		: { *(.stabstr) }

+	

+	. = ALIGN(4096);

+	__data_end = .;

+	

+	.rdata		: {

+		*(.rdata)

+		*(SORT(.rdata$*))

+		*(.rodata*)

+		*(.gnu.linkonce.r.*)

+		__commands_start = .;

+		KEEP (*(.commands))

+		__commands_end = .;

+		. = ALIGN(4);

+		__apps_start = .;

+		KEEP (*(.apps))

+		__apps_end = .;

+		

+		. = ALIGN(4096);

+	}

+	

+	__bss_start = .;

+	.bss		: {

+		*(.bss*)

+		*(.gnu.linkonce.b.*)

+		*(COMMON)

+		

+		. = ALIGN(4096);

+	}

+	__bss_end = .;

+	

+	/*. += 0x2000;

+	_kstack = .;

+	. += 0x1000;*/

+	

+	_end = .;

+	

+	/DISCARD/ : { *(.comment .note .eh_frame) }

+}

diff --git a/arch/x86/mmu.c b/arch/x86/mmu.c
new file mode 100644
index 0000000..6cefe67
--- /dev/null
+++ b/arch/x86/mmu.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2009 Corey Tabaka
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include <debug.h>
+#include <sys/types.h>
+#include <compiler.h>
+#include <arch.h>
+#include <arch/x86.h>
+#include <arch/x86/mmu.h>
+
+void x86_mmu_map_section(addr_t paddr, addr_t vaddr, uint flags)
+{
+	// TODO: stuff
+	//x86_invalidate_tlb();
+}
+
+void x86_mmu_init(void)
+{
+	// TODO: stuff
+}
+
+void arch_disable_mmu(void)
+{
+	// TODO: stuff
+}
diff --git a/arch/x86/ops.S b/arch/x86/ops.S
new file mode 100644
index 0000000..17c08ae
--- /dev/null
+++ b/arch/x86/ops.S
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2009 Corey Tabaka
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include <asm.h>
+
+.text
+
+/* void arch_enable_ints(void); */
+FUNCTION(arch_enable_ints)
+	sti
+	ret
+
+/* void arch_disable_ints(void); */
+FUNCTION(arch_disable_ints)
+	cli
+	ret
+
+/* int atomic_swap(int *ptr, int val); */
+FUNCTION(atomic_swap)
+	movl 4(%esp), %edx
+	movl 8(%esp), %eax
+	xchgl %eax, (%edx)
+	ret
+
+/* int atomic_add(int *ptr, int val); */
+FUNCTION(atomic_add)
+	movl 4(%esp), %edx
+	movl 8(%esp), %eax
+	lock
+	xadd %eax, (%edx)
+	ret
+	
+/* int atomic_and(int *ptr, int val); */
+FUNCTION(atomic_and)
+	movl 4(%esp), %edx
+	movl (%edx), %eax
+0:
+	movl %eax, %ecx
+	andl 8(%esp), %ecx
+	lock
+	cmpxchgl %ecx, (%edx)
+	jnz 1f					/* static prediction: branch forward not taken */
+	ret
+1:
+	jmp 0b
+	
+	
+/* int atomic_or(int *ptr, int val); */
+FUNCTION(atomic_or)
+movl 4(%esp), %edx
+	movl (%edx), %eax
+0:
+	movl %eax, %ecx
+	orl 8(%esp), %ecx
+	lock
+	cmpxchgl %ecx, (%edx)
+	jnz 1f					/* static prediction: branch forward not taken */
+	ret
+1:
+	jmp 0b
+
+/* void arch_idle(); */
+FUNCTION(arch_idle)
+	hlt
+	ret
+
+/* void arch_switch_stacks_and_call(addr_t call, addr_t stack) */
+FUNCTION(arch_switch_stacks_and_call)
+	movl 4(%esp), %eax
+	movl 8(%esp), %edx
+	movl %edx, %esp
+	call *%eax			/* perhaps this should be a jmp? it's not used anywhere so I don't know. */
diff --git a/arch/x86/rules.mk b/arch/x86/rules.mk
new file mode 100644
index 0000000..943ccd8
--- /dev/null
+++ b/arch/x86/rules.mk
@@ -0,0 +1,35 @@
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+INCLUDES += \
+	-I$(LOCAL_DIR)/include
+
+BOOTOBJS += \
+	$(LOCAL_DIR)/crt0.o
+
+OBJS += \
+	$(LOCAL_DIR)/arch.o \
+	$(LOCAL_DIR)/asm.o \
+	$(LOCAL_DIR)/cache.o \
+	$(LOCAL_DIR)/cache-ops.o \
+	$(LOCAL_DIR)/ops.o \
+	$(LOCAL_DIR)/thread.o \
+	$(LOCAL_DIR)/mmu.o \
+	$(LOCAL_DIR)/faults.o \
+	$(LOCAL_DIR)/descriptor.o
+
+# set the default toolchain to x86 elf and set a #define
+TOOLCHAIN_PREFIX ?= #x86-elf-
+
+LIBGCC := $(shell $(TOOLCHAIN_PREFIX)gcc $(CFLAGS) -print-libgcc-file-name)
+#$(info LIBGCC = $(LIBGCC))
+
+# potentially generated files that should be cleaned out with clean make rule
+GENERATED += \
+	$(BUILDDIR)/kernel.ld
+
+# rules for generating the linker scripts
+
+$(BUILDDIR)/kernel.ld: $(LOCAL_DIR)/kernel.ld
+	@echo generating $@
+	@$(MKDIR)
+	$(NOECHO)cp $< $@
diff --git a/arch/x86/thread.c b/arch/x86/thread.c
new file mode 100644
index 0000000..f2c2f84
--- /dev/null
+++ b/arch/x86/thread.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2009 Corey Tabaka
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include <debug.h>
+#include <kernel/thread.h>
+#include <arch/x86.h>
+#include <arch/x86/descriptor.h>
+
+/*struct context_switch_frame {
+	uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
+	uint32_t ds, es, fs, gs;
+	uint32_t eip, cs, eflags;
+};*/
+struct context_switch_frame {
+	uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
+	uint32_t eflags;
+	uint32_t eip;
+};
+
+extern void x86_context_switch(addr_t *old_sp, addr_t new_sp);
+
+static void initial_thread_func(void) __NO_RETURN;
+static void initial_thread_func(void)
+{
+	int ret;
+
+//	dprintf("initial_thread_func: thread %p calling %p with arg %p\n", current_thread, current_thread->entry, current_thread->arg);
+//	dump_thread(current_thread);
+
+	/* exit the implicit critical section we're within */
+	exit_critical_section();
+
+	ret = current_thread->entry(current_thread->arg);
+
+//	dprintf("initial_thread_func: thread %p exiting with %d\n", current_thread, ret);
+
+	thread_exit(ret);
+}
+
+void arch_thread_initialize(thread_t *t)
+{
+	// create a default stack frame on the stack
+	vaddr_t stack_top = (vaddr_t)t->stack + t->stack_size;
+
+	// make sure the top of the stack is 8 byte aligned for EABI compliance
+	stack_top = ROUNDDOWN(stack_top, 8);
+
+	struct context_switch_frame *frame = (struct context_switch_frame *)(stack_top);
+	frame--;
+
+	// fill it in
+	memset(frame, 0, sizeof(*frame));
+	
+	frame->eip = (vaddr_t) &initial_thread_func;
+	frame->eflags = 0x3002; // IF = 0, NT = 0, IOPL = 3
+	//frame->cs = CODE_SELECTOR;
+	//frame->fs = DATA_SELECTOR;
+	//frame->gs = DATA_SELECTOR;
+	//frame->es = DATA_SELECTOR;
+	//frame->ds = DATA_SELECTOR;
+	
+	// set the stack pointer
+	t->arch.esp = (vaddr_t)frame;
+}
+
+void arch_context_switch(thread_t *oldthread, thread_t *newthread)
+{
+	//dprintf(DEBUG, "arch_context_switch: old %p (%s), new %p (%s)\n", oldthread, oldthread->name, newthread, newthread->name);
+	
+	__asm__ __volatile__ (
+		"pushl $1f			\n\t"
+		"pushf				\n\t"
+		"pusha				\n\t"
+		"movl %%esp,(%%edx)	\n\t"
+		"movl %%eax,%%esp	\n\t"
+		"popa				\n\t"
+		"popf				\n\t"
+		"ret				\n\t"
+		"1:					\n\t"
+		
+		:
+		: "d" (&oldthread->arch.esp), "a" (newthread->arch.esp)
+	);
+	
+	/*__asm__ __volatile__ (
+		"pushf				\n\t"
+		"pushl %%cs			\n\t"
+		"pushl $1f			\n\t"
+		"pushl %%gs			\n\t"
+		"pushl %%fs			\n\t"
+		"pushl %%es			\n\t"
+		"pushl %%ds			\n\t"
+		"pusha				\n\t"
+		"movl %%esp,(%%edx)	\n\t"
+		"movl %%eax,%%esp	\n\t"
+		"popa				\n\t"
+		"popl %%ds			\n\t"
+		"popl %%es			\n\t"
+		"popl %%fs			\n\t"
+		"popl %%gs			\n\t"
+		"iret				\n\t"
+		"1:	"
+		:
+		: "d" (&oldthread->arch.esp), "a" (newthread->arch.esp)
+	);*/
+}
+