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)
+ );*/
+}
+