initial commit of lk (little kernel) project
diff --git a/arch/arm/arch.c b/arch/arm/arch.c
new file mode 100644
index 0000000..37b557c
--- /dev/null
+++ b/arch/arm/arch.c
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+#include <debug.h>
+#include <arch.h>
+#include <arch/ops.h>
+#include <arch/arm.h>
+#include <arch/arm/mmu.h>
+#include <platform.h>
+
+#if ARM_CPU_CORTEX_A8
+static void set_vector_base(addr_t addr)
+{
+ __asm__ volatile("mcr p15, 0, %0, c12, c0, 0" :: "r" (addr));
+}
+#endif
+
+void arch_early_init(void)
+{
+ /* turn off the cache */
+ arch_disable_cache(UCACHE);
+
+ /* set the vector base to our exception vectors so we dont need to double map at 0 */
+#if ARM_CPU_CORTEX_A8
+ set_vector_base(MEMBASE);
+#endif
+
+#if ARM_WITH_MMU
+ arm_mmu_init();
+
+ platform_init_mmu_mappings();
+#endif
+
+ /* turn the cache back on */
+ arch_enable_cache(UCACHE);
+
+#if ARM_WITH_NEON
+ /* enable cp10 and cp11 */
+ uint32_t val;
+ __asm__ volatile("mrc p15, 0, %0, c1, c0, 2" : "=r" (val));
+ val |= (3<<22)|(3<<20);
+ __asm__ volatile("mcr p15, 0, %0, c1, c0, 2" :: "r" (val));
+
+ /* set enable bit in fpexc */
+ val = (1<<30);
+ __asm__ volatile("mcr p10, 7, %0, c8, c0, 0" :: "r" (val));
+#endif
+}
+
+void arch_init(void)
+{
+}
+
diff --git a/arch/arm/asm.S b/arch/arm/asm.S
new file mode 100644
index 0000000..2953bd6
--- /dev/null
+++ b/arch/arm/asm.S
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+#include <asm.h>
+
+
+ /* context switch frame is as follows:
+ * ulr
+ * usp
+ * lr
+ * r11
+ * r10
+ * r9
+ * r8
+ * r7
+ * r6
+ * r5
+ * r4
+ */
+/* arm_context_switch(addr_t *old_sp, addr_t new_sp) */
+FUNCTION(arm_context_switch)
+ /* save all the usual registers + user regs */
+ /* the spsr is saved and restored in the iframe by exceptions.S */
+ sub r3, sp, #(11*4) /* can't use sp in user mode stm */
+ mov r12, lr
+ stmia r3, { r4-r11, r12, r13, r14 }^
+
+ /* save old sp */
+ str r3, [r0]
+
+ /* load new regs */
+ ldmia r1, { r4-r11, r12, r13, r14 }^
+ mov lr, r12 /* restore lr */
+ add sp, r1, #(11*4) /* restore sp */
+ bx lr
+
+FUNCTION(arm_save_mode_regs)
+ mrs r1, cpsr
+
+#if ARM_ISA_ARMv6
+ cps #0x11 /* fiq */
+ str r13, [r0], #4
+ str r14, [r0], #4
+ cps #0x12 /* irq */
+ str r13, [r0], #4
+ str r14, [r0], #4
+ cps #0x13 /* svc */
+ str r13, [r0], #4
+ str r14, [r0], #4
+ cps #0x17 /* abt */
+ str r13, [r0], #4
+ str r14, [r0], #4
+ cps #0x1b /* und */
+ str r13, [r0], #4
+ str r14, [r0], #4
+ cps #0x1f /* sys */
+ str r13, [r0], #4
+ str r14, [r0], #4
+#else
+ // XXX implement
+ b .
+#endif
+
+ msr cpsr, r1
+
+ bx lr
+
+
+
diff --git a/arch/arm/cache-ops.S b/arch/arm/cache-ops.S
new file mode 100644
index 0000000..8a545dc
--- /dev/null
+++ b/arch/arm/cache-ops.S
@@ -0,0 +1,366 @@
+/*
+ * 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.
+ */
+#include <asm.h>
+#include <arch/ops.h>
+#include <arch/defines.h>
+
+.text
+
+#if ARM_WITH_CACHE
+
+/* low level cache routines for various cpu families */
+
+#if ARM_CPU_ARM1136 || ARM_CPU_ARM926
+
+/* void arch_disable_cache(uint flags) */
+FUNCTION(arch_disable_cache)
+ mov r12, #0 // zero register
+ mrs r3, cpsr // save the old interrupt state
+#if ARM_ISA_ARMv6
+ .word 0xf10c01c0 /* cpsid iaf */ // interrupts disabled
+#else
+ orr r3, r3, #(1<<7)
+ msr cpsr, r3
+#endif
+
+.Ldcache_disable:
+ tst r0, #DCACHE
+ beq .Licache_disable
+ mrc p15, 0, r1, c1, c0, 0 // cr1
+ tst r1, #(1<<2) // is the dcache already disabled?
+ beq .Licache_disable
+
+ bic r1, #(1<<2)
+ mcr p15, 0, r1, c1, c0, 0 // disable dcache
+
+#if ARM_CPU_ARM1136
+ mcr p15, 0, r12, c7, c14, 0 // clean & invalidate dcache
+#elif ARM_CPU_ARM926
+0:
+ mrc p15, 0, r15, c7, c14, 3 // clean & invalidate dcache
+ bne 0b
+#else
+#error whut?
+#endif
+ mcr p15, 0, r0, c7, c10, 4 // data sync barrier (formerly drain write buffer)
+
+.Licache_disable:
+ tst r0, #ICACHE
+ beq .Ldone_disable
+
+ mrc p15, 0, r1, c1, c0, 0 // cr1
+ bic r1, #(1<<12)
+ mcr p15, 0, r1, c1, c0, 0 // disable icache
+
+ mcr p15, 0, r12, c7, c5, 0 // invalidate icache
+
+.Ldone_disable:
+ msr cpsr, r3
+ bx lr
+
+/* void arch_enable_cache(uint flags) */
+FUNCTION(arch_enable_cache)
+ mov r12, #0 // zero register
+ mrs r3, cpsr // save the old interrupt state
+#if ARM_ISA_ARMv6
+ .word 0xf10c01c0 /* cpsid iaf */ // interrupts disabled
+#else
+ orr r3, r3, #(1<<7)
+ msr cpsr, r3
+#endif
+
+.Ldcache_enable:
+ tst r0, #DCACHE
+ beq .Licache_enable
+ mrc p15, 0, r1, c1, c0, 0 // cr1
+ tst r1, #(1<<2) // is the dcache already enabled?
+ bne .Licache_enable
+
+ mcr p15, 0, r12, c7, c6, 0 // invalidate dcache
+
+ orr r1, #(1<<2)
+ mcr p15, 0, r1, c1, c0, 0 // enable dcache
+
+.Licache_enable:
+ tst r0, #ICACHE
+ beq .Ldone_enable
+
+ mcr p15, 0, r12, c7, c5, 0 // invalidate icache
+
+ mrc p15, 0, r1, c1, c0, 0 // cr1
+ orr r1, #(1<<12)
+ mcr p15, 0, r1, c1, c0, 0 // enable icache
+
+.Ldone_enable:
+ msr cpsr, r3
+ bx lr
+
+#elif ARM_CPU_CORTEX_A8
+
+/* void arch_disable_cache(uint flags) */
+FUNCTION(arch_disable_cache)
+ stmfd sp!, {r4-r11, lr}
+
+ mov r7, r0 // save flags
+
+ mrs r12, cpsr // save the old interrupt state
+ .word 0xf10c01c0 /* cpsid iaf */ // interrupts disabled
+
+.Ldcache_disable:
+ tst r7, #DCACHE
+ beq .Licache_disable
+ mrc p15, 0, r0, c1, c0, 0 // cr1
+ tst r0, #(1<<2) // is the dcache already disabled?
+ beq .Ldcache_already_disabled
+
+ bic r0, #(1<<2)
+ mcr p15, 0, r0, c1, c0, 0 // disable dcache
+
+ // flush and invalidate the dcache
+ // NOTE: trashes a bunch of registers, can't be spilling stuff to the stack
+ bl flush_invalidate_cache_v7
+
+ b .Ldcache_disable_L2
+
+.Ldcache_already_disabled:
+ // make sure all of the caches are invalidated
+ // NOTE: trashes a bunch of registers, can't be spilling stuff to the stack
+ bl invalidate_cache_v7
+
+.Ldcache_disable_L2:
+
+#if ARM_WITH_L2
+ // disable the L2, if present
+ mrc p15, 0, r0, c1, c0, 1 // aux cr1
+ bic r0, #(1<<1)
+ mcr p15, 0, r0, c1, c0, 1 // disable L2 dcache
+#endif
+
+.Licache_disable:
+ tst r7, #ICACHE
+ beq .Ldone_disable
+
+ mrc p15, 0, r0, c1, c0, 0 // cr1
+ bic r0, #(1<<12)
+ mcr p15, 0, r0, c1, c0, 0 // disable icache
+
+.Ldone_disable:
+ // make sure the icache is always invalidated
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 // invalidate icache to PoU
+
+ msr cpsr, r12
+ ldmfd sp!, {r4-r11, pc}
+
+/* void arch_enable_cache(uint flags) */
+FUNCTION(arch_enable_cache)
+ stmfd sp!, {r4-r11, lr}
+
+ mov r7, r0 // save flags
+
+ mrs r12, cpsr // save the old interrupt state
+ .word 0xf10c01c0 /* cpsid iaf */ // interrupts disabled
+
+.Ldcache_enable:
+ tst r7, #DCACHE
+ beq .Licache_enable
+ mrc p15, 0, r0, c1, c0, 0 // cr1
+ tst r0, #(1<<2) // is the dcache already enabled?
+ bne .Licache_enable
+
+ // invalidate L1 and L2
+ // NOTE: trashes a bunch of registers, can't be spilling stuff to the stack
+ bl invalidate_cache_v7
+
+#if ARM_WITH_L2
+ // enable the L2, if present
+ mrc p15, 0, r0, c1, c0, 1 // aux cr1
+ orr r0, #(1<<1)
+ mcr p15, 0, r0, c1, c0, 1 // enable L2 dcache
+#endif
+
+ mrc p15, 0, r0, c1, c0, 0 // cr1
+ orr r0, #(1<<2)
+ mcr p15, 0, r0, c1, c0, 0 // enable dcache
+
+.Licache_enable:
+ tst r7, #ICACHE
+ beq .Ldone_enable
+
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 // invalidate icache to PoU
+
+ mrc p15, 0, r0, c1, c0, 0 // cr1
+ orr r0, #(1<<12)
+ mcr p15, 0, r0, c1, c0, 0 // enable icache
+
+.Ldone_enable:
+ msr cpsr, r12
+ ldmfd sp!, {r4-r11, pc}
+
+// flush & invalidate cache routine, trashes r0-r6, r9-r11
+flush_invalidate_cache_v7:
+ /* from ARMv7 manual, B2-17 */
+ MRC p15, 1, R0, c0, c0, 1 // Read CLIDR
+ ANDS R3, R0, #0x7000000
+ MOV R3, R3, LSR #23 // Cache level value (naturally aligned)
+ BEQ .Lfinished
+ MOV R10, #0
+.Loop1:
+ ADD R2, R10, R10, LSR #1 // Work out 3xcachelevel
+ MOV R1, R0, LSR R2 // bottom 3 bits are the Cache type for this level
+ AND R1, R1, #7 // get those 3 bits alone
+ CMP R1, #2
+ BLT .Lskip // no cache or only instruction cache at this level
+ MCR p15, 2, R10, c0, c0, 0 // write the Cache Size selection register
+ .word 0xf57ff06f // ISB // ISB to sync the change to the CacheSizeID reg
+ MRC p15, 1, R1, c0, c0, 0 // reads current Cache Size ID register
+ AND R2, R1, #0x7 // extract the line length field
+ ADD R2, R2, #4 // add 4 for the line length offset (log2 16 bytes)
+ LDR R4, =0x3FF
+ ANDS R4, R4, R1, LSR #3 // R4 is the max number on the way size (right aligned)
+ CLZ R5, R4 // R5 is the bit position of the way size increment
+ LDR R6, =0x00007FFF
+ ANDS R6, R6, R1, LSR #13 // R6 is the max number of the index size (right aligned)
+.Loop2:
+ MOV R9, R4 // R9 working copy of the max way size (right aligned)
+.Loop3:
+ ORR R11, R10, R9, LSL R5 // factor in the way number and cache number into R11
+ ORR R11, R11, R6, LSL R2 // factor in the index number
+ MCR p15, 0, R11, c7, c14, 2 // clean & invalidate by set/way
+ SUBS R9, R9, #1 // decrement the way number
+ BGE .Loop3
+ SUBS R6, R6, #1 // decrement the index
+ BGE .Loop2
+.Lskip:
+ ADD R10, R10, #2 // increment the cache number
+ CMP R3, R10
+ BGT .Loop1
+
+.Lfinished:
+ mov r10, #0
+ mcr p15, 2, r10, c0, c0, 0 // select cache level 0
+ .word 0xf57ff06f // isb
+
+ bx lr
+
+// invalidate cache routine, trashes r0-r6, r9-r11
+invalidate_cache_v7:
+ /* from ARMv7 manual, B2-17 */
+ MRC p15, 1, R0, c0, c0, 1 // Read CLIDR
+ ANDS R3, R0, #0x7000000
+ MOV R3, R3, LSR #23 // Cache level value (naturally aligned)
+ BEQ .Lfinished_invalidate
+ MOV R10, #0
+.Loop1_invalidate:
+ ADD R2, R10, R10, LSR #1 // Work out 3xcachelevel
+ MOV R1, R0, LSR R2 // bottom 3 bits are the Cache type for this level
+ AND R1, R1, #7 // get those 3 bits alone
+ CMP R1, #2
+ BLT .Lskip_invalidate // no cache or only instruction cache at this level
+ MCR p15, 2, R10, c0, c0, 0 // write the Cache Size selection register
+ .word 0xf57ff06f // ISB // ISB to sync the change to the CacheSizeID reg
+ MRC p15, 1, R1, c0, c0, 0 // reads current Cache Size ID register
+ AND R2, R1, #0x7 // extract the line length field
+ ADD R2, R2, #4 // add 4 for the line length offset (log2 16 bytes)
+ LDR R4, =0x3FF
+ ANDS R4, R4, R1, LSR #3 // R4 is the max number on the way size (right aligned)
+ CLZ R5, R4 // R5 is the bit position of the way size increment
+ LDR R6, =0x00007FFF
+ ANDS R6, R6, R1, LSR #13 // R6 is the max number of the index size (right aligned)
+.Loop2_invalidate:
+ MOV R9, R4 // R9 working copy of the max way size (right aligned)
+.Loop3_invalidate:
+ ORR R11, R10, R9, LSL R5 // factor in the way number and cache number into R11
+ ORR R11, R11, R6, LSL R2 // factor in the index number
+ MCR p15, 0, R11, c7, c6, 2 // invalidate by set/way
+ SUBS R9, R9, #1 // decrement the way number
+ BGE .Loop3_invalidate
+ SUBS R6, R6, #1 // decrement the index
+ BGE .Loop2_invalidate
+.Lskip_invalidate:
+ ADD R10, R10, #2 // increment the cache number
+ CMP R3, R10
+ BGT .Loop1_invalidate
+
+.Lfinished_invalidate:
+ mov r10, #0
+ mcr p15, 2, r10, c0, c0, 0 // select cache level 0
+ .word 0xf57ff06f // isb
+
+ bx lr
+
+#else
+#error unhandled cpu
+#endif
+
+#if ARM_CPU_ARM926 || ARM_CPU_ARM1136 || ARM_CPU_CORTEX_A8
+/* shared cache flush routines */
+
+ /* void arch_flush_cache_range(addr_t start, size_t len); */
+FUNCTION(arch_clean_cache_range)
+0:
+ mcr p15, 0, r0, c7, c10, 1 // clean cache to PoC by MVA
+ add r0, r0, #CACHE_LINE
+ subs r1, r1, #CACHE_LINE
+ bhs 0b
+
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 // data sync barrier (formerly drain write buffer)
+
+ bx lr
+
+ /* void arch_flush_invalidate_cache_range(addr_t start, size_t len); */
+FUNCTION(arch_clean_invalidate_cache_range)
+0:
+ mcr p15, 0, r0, c7, c14, 1 // clean & invalidate cache to PoC by MVA
+ add r0, r0, #CACHE_LINE
+ subs r1, r1, #CACHE_LINE
+ bhs 0b
+
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 // data sync barrier (formerly drain write buffer)
+
+ bx lr
+#else
+#error unhandled cpu
+#endif
+
+#else
+
+/* no cache */
+
+FUNCTION(arch_disable_cache)
+ bx lr
+
+FUNCTION(arch_enable_cache)
+ bx lr
+
+FUNCTION(arch_clean_cache_range)
+ bx lr
+
+FUNCTION(arch_clean_invalidate_cache_range)
+ bx lr
+
+#endif // ARM_WITH_CACHE
+
diff --git a/arch/arm/cache.c b/arch/arm/cache.c
new file mode 100644
index 0000000..0a403b5
--- /dev/null
+++ b/arch/arm/cache.c
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
diff --git a/arch/arm/compile.mk b/arch/arm/compile.mk
new file mode 100644
index 0000000..b509e16
--- /dev/null
+++ b/arch/arm/compile.mk
@@ -0,0 +1,33 @@
+
+$(BUILDDIR)/%.o: %.c $(SRCDEPS)
+ @$(MKDIR)
+ @echo compiling $<
+ $(NOECHO)$(CC) $(CFLAGS) $(THUMBCFLAGS) --std=c99 $(INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@
+
+$(BUILDDIR)/%.o: %.cpp $(SRCDEPS)
+ @$(MKDIR)
+ @echo compiling $<
+ $(NOECHO)$(CC) $(CFLAGS) $(CPPFLAGS) $(THUMBCFLAGS) $(INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@
+
+# to override thumb setting, mark the .o file as .Ao
+$(BUILDDIR)/%.Ao: %.c $(SRCDEPS)
+ @$(MKDIR)
+ @echo compiling $<
+ $(NOECHO)$(CC) $(CFLAGS) --std=c99 $(INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@
+
+$(BUILDDIR)/%.Ao: %.cpp $(SRCDEPS)
+ @$(MKDIR)
+ @echo compiling $<
+ $(NOECHO)$(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@
+
+# assembly is always compiled in ARM mode at the moment
+$(BUILDDIR)/%.Ao: %.S $(SRCDEPS)
+ @$(MKDIR)
+ @echo compiling $<
+ $(NOECHO)$(CC) $(CFLAGS) $(ASMFLAGS) $(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/arm/crt0.S b/arch/arm/crt0.S
new file mode 100644
index 0000000..40cbf27
--- /dev/null
+++ b/arch/arm/crt0.S
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+.text
+.globl _start
+_start:
+ b reset
+ b arm_undefined
+ b arm_syscall
+ b arm_prefetch_abort
+ b arm_data_abort
+ b arm_reserved
+ b arm_irq
+ b arm_fiq
+
+reset:
+ /* do some cpu setup */
+#if ARM_WITH_CP15
+ mrc p15, 0, r0, c1, c0, 0
+ /* XXX this is currently for arm926, revist with armv6 cores */
+ /* new thumb behavior, low exception vectors, i/d cache disable, mmu disabled */
+ bic r0, r0, #(1<<15| 1<<13 | 1<<12)
+ bic r0, r0, #(1<<2 | 1<<0)
+ /* enable alignment faults */
+ orr r0, r0, #(1<<1)
+ mcr p15, 0, r0, c1, c0, 0
+#endif
+
+ /* set up the stack for irq, fiq, abort, undefined, system/user, and lastly supervisor mode */
+ mrs r0, cpsr
+ bic r0, r0, #0x1f
+
+ ldr r2, =abort_stack_top
+ orr r1, r0, #0x12 // irq
+ msr cpsr_c, r1
+ ldr r13, =irq_save_spot /* save a pointer to a temporary dumping spot used during irq delivery */
+
+ orr r1, r0, #0x11 // fiq
+ msr cpsr_c, r1
+ mov sp, r2
+
+ orr r1, r0, #0x17 // abort
+ msr cpsr_c, r1
+ mov sp, r2
+
+ orr r1, r0, #0x1b // undefined
+ msr cpsr_c, r1
+ mov sp, r2
+
+ orr r1, r0, #0x1f // system
+ msr cpsr_c, r1
+ mov sp, r2
+
+ orr r1, r0, #0x13 // supervisor
+ msr cpsr_c, r1
+ mov sp, r2
+
+ /* copy the initialized data segment out of rom if necessary */
+ ldr r0, =__data_start_rom
+ ldr r1, =__data_start
+ ldr r2, =__data_end
+
+ cmp r0, r1
+ beq __do_bss
+
+__copy_loop:
+ cmp r1, r2
+ ldrlt r3, [r0], #4
+ strlt r3, [r1], #4
+ blt __copy_loop
+
+__do_bss:
+ /* clear out the bss */
+ ldr r0, =__bss_start
+ ldr r1, =_end
+ mov r2, #0
+__bss_loop:
+ cmp r0, r1
+ strlt r2, [r0], #4
+ blt __bss_loop
+
+ bl kmain
+ b .
+
+.ltorg
+
+.bss
+.align 2
+ /* the abort stack is for unrecoverable errors.
+ * also note the initial working stack is set to here.
+ * when the threading system starts up it'll switch to a new
+ * dynamically allocated stack, so we don't need it for very long
+ */
+abort_stack:
+ .skip 1024
+abort_stack_top:
diff --git a/arch/arm/exceptions.S b/arch/arm/exceptions.S
new file mode 100644
index 0000000..fa0ea9e
--- /dev/null
+++ b/arch/arm/exceptions.S
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ */
+#include <asm.h>
+
+FUNCTION(arm_undefined)
+ stmfd sp!, { r0-r12, r14 }
+ sub sp, sp, #12
+ mov r0, sp
+ mrs r1, spsr
+ stmia r0, { r1, r13-r14 }^
+ b arm_undefined_handler
+ b .
+
+FUNCTION(arm_syscall)
+ stmfd sp!, { r0-r12, r14 }
+ sub sp, sp, #12
+ mov r0, sp
+ mrs r1, spsr
+ stmia r0, { r1, r13-r14 }^
+ b arm_syscall_handler
+ b .
+
+FUNCTION(arm_prefetch_abort)
+ stmfd sp!, { r0-r12, r14 }
+ sub sp, sp, #12
+ mov r0, sp
+ mrs r1, spsr
+ stmia r0, { r1, r13-r14 }^
+ b arm_prefetch_abort_handler
+ b .
+
+FUNCTION(arm_data_abort)
+ stmfd sp!, { r0-r12, r14 }
+ sub sp, sp, #12
+ mov r0, sp
+ mrs r1, spsr
+ stmia r0, { r1, r13-r14 }^
+ b arm_data_abort_handler
+ b .
+
+FUNCTION(arm_reserved)
+ b .
+
+FUNCTION(arm_irq)
+ /* XXX only deals with interrupting supervisor mode */
+
+ /* save r4-r6 and use as a temporary place to save while we switch into supervisor mode */
+ stmia r13, { r4-r6 }
+ mov r4, r13
+ sub r5, lr, #4
+ mrs r6, spsr
+
+ /* move into supervisor mode. irq/fiq disabled */
+ msr cpsr_c, #(3<<6 | 0x13)
+
+ /* save the return address */
+ stmfd sp!, { r5 }
+
+ /* save C trashed regs, supervisor lr */
+ stmfd sp!, { r0-r3, r12, lr }
+
+ /* save spsr */
+ stmfd sp!, { r6 }
+
+ /* restore r4-r6 */
+ ldmia r4, { r4-r6 }
+
+ /* increment the global critical section count */
+ ldr r1, =critical_section_count
+ ldr r0, [r1]
+ add r0, r0, #1
+ str r0, [r1]
+
+ /* call into higher level code */
+ mov r0, sp /* iframe */
+ bl platform_irq
+
+ /* reschedule if the handler returns nonzero */
+ cmp r0, #0
+ blne thread_preempt
+
+ /* decrement the global critical section count */
+ ldr r1, =critical_section_count
+ ldr r0, [r1]
+ sub r0, r0, #1
+ str r0, [r1]
+
+ /* restore spsr */
+ ldmfd sp!, { r0 }
+ msr spsr, r0
+
+ /* restore back to where we came from */
+ ldmfd sp!, { r0-r3, r12, lr, pc }^
+
+.bss
+.align 2
+ .global irq_save_spot
+irq_save_spot:
+ .word 0 /* r4 */
+ .word 0 /* r5 */
+ .word 0 /* r6 */
+
+.text
+FUNCTION(arm_fiq)
+ sub lr, lr, #4
+ stmfd sp!, { r0-r3, r12, lr }
+
+ bl platform_fiq
+
+ ldmfd sp!, { r0-r3, r12, pc }^
+
+.ltorg
diff --git a/arch/arm/faults.c b/arch/arm/faults.c
new file mode 100644
index 0000000..c16aff0
--- /dev/null
+++ b/arch/arm/faults.c
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+#include <debug.h>
+#include <arch/arm.h>
+#include <kernel/thread.h>
+
+static void dump_fault_frame(struct arm_fault_frame *frame)
+{
+ dprintf("r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n", frame->r[0], frame->r[1], frame->r[2], frame->r[3]);
+ dprintf("r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n", frame->r[4], frame->r[5], frame->r[6], frame->r[7]);
+ dprintf("r8 0x%08x r9 0x%08x r10 0x%08x r11 0x%08x\n", frame->r[8], frame->r[9], frame->r[10], frame->r[11]);
+ dprintf("r12 0x%08x usp 0x%08x ulr 0x%08x pc 0x%08x\n", frame->r[12], frame->usp, frame->ulr, frame->pc);
+ dprintf("spsr 0x%08x\n", frame->spsr);
+
+ struct arm_mode_regs regs;
+ arm_save_mode_regs(®s);
+
+ dprintf("%c%s r13 0x%08x r14 0x%08x\n", ((frame->spsr & MODE_MASK) == MODE_FIQ) ? '*' : ' ', "fiq", regs.fiq_r13, regs.fiq_r14);
+ dprintf("%c%s r13 0x%08x r14 0x%08x\n", ((frame->spsr & MODE_MASK) == MODE_IRQ) ? '*' : ' ', "irq", regs.irq_r13, regs.irq_r14);
+ dprintf("%c%s r13 0x%08x r14 0x%08x\n", ((frame->spsr & MODE_MASK) == MODE_SVC) ? '*' : ' ', "svc", regs.svc_r13, regs.svc_r14);
+ dprintf("%c%s r13 0x%08x r14 0x%08x\n", ((frame->spsr & MODE_MASK) == MODE_UND) ? '*' : ' ', "und", regs.und_r13, regs.und_r14);
+ dprintf("%c%s r13 0x%08x r14 0x%08x\n", ((frame->spsr & MODE_MASK) == MODE_SYS) ? '*' : ' ', "sys", regs.sys_r13, regs.sys_r14);
+}
+
+static void exception_die(struct arm_fault_frame *frame, int pc_off, const char *msg)
+{
+ inc_critical_section();
+ frame->pc += pc_off;
+ dump_fault_frame(frame);
+ dprintf(msg);
+ debug_halt();
+ for(;;);
+}
+
+void arm_syscall_handler(struct arm_fault_frame *frame)
+{
+ exception_die(frame, -4, "unhandled syscall, halting\n");
+}
+
+void arm_undefined_handler(struct arm_fault_frame *frame)
+{
+ exception_die(frame, -4, "undefined abort, halting\n");
+}
+
+void arm_data_abort_handler(struct arm_fault_frame *frame)
+{
+ exception_die(frame, -8, "data abort, halting\n");
+}
+
+void arm_prefetch_abort_handler(struct arm_fault_frame *frame)
+{
+ exception_die(frame, -4, "prefetch abort, halting\n");
+}
diff --git a/arch/arm/include/arch/arch_thread.h b/arch/arm/include/arch/arch_thread.h
new file mode 100644
index 0000000..2f4facf
--- /dev/null
+++ b/arch/arm/include/arch/arch_thread.h
@@ -0,0 +1,31 @@
+/*
+ * 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 __ARM_ARCH_THREAD_H
+#define __ARM_ARCH_THREAD_H
+
+struct arch_thread {
+ vaddr_t sp;
+};
+
+#endif
+
diff --git a/arch/arm/include/arch/arm.h b/arch/arm/include/arch/arm.h
new file mode 100644
index 0000000..a14bf9c
--- /dev/null
+++ b/arch/arm/include/arch/arm.h
@@ -0,0 +1,94 @@
+/*
+ * 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_H
+#define __ARCH_ARM_H
+
+#include <sys/types.h>
+#include <arch/arm/cores.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+void arm_context_switch(vaddr_t *old_sp, vaddr_t new_sp);
+
+static inline uint32_t read_cpsr() {
+ uint32_t cpsr;
+
+ __asm__ volatile("mrs %0, cpsr" : "=r" (cpsr));
+ return cpsr;
+}
+
+struct arm_iframe {
+ uint32_t spsr;
+ uint32_t r0;
+ uint32_t r1;
+ uint32_t r2;
+ uint32_t r3;
+ uint32_t r12;
+ uint32_t lr;
+ uint32_t pc;
+};
+
+struct arm_fault_frame {
+ uint32_t spsr;
+ uint32_t usp;
+ uint32_t ulr;
+ uint32_t r[13];
+ uint32_t pc;
+};
+
+#define MODE_MASK 0x1f
+#define MODE_USR 0x10
+#define MODE_FIQ 0x11
+#define MODE_IRQ 0x12
+#define MODE_SVC 0x13
+#define MODE_MON 0x16
+#define MODE_ABT 0x17
+#define MODE_UND 0x1b
+#define MODE_SYS 0x1f
+
+struct arm_mode_regs {
+ uint32_t fiq_r13, fiq_r14;
+ uint32_t irq_r13, irq_r14;
+ uint32_t svc_r13, svc_r14;
+ uint32_t abt_r13, abt_r14;
+ uint32_t und_r13, und_r14;
+ uint32_t sys_r13, sys_r14;
+};
+
+void arm_save_mode_regs(struct arm_mode_regs *regs);
+
+uint32_t arm_read_cr1(void);
+void arm_write_cr1(uint32_t val);
+uint32_t arm_read_cr1_aux(void);
+void arm_write_cr1_aux(uint32_t val);
+void arm_write_ttbr(uint32_t val);
+void arm_write_dacr(uint32_t val);
+void arm_invalidate_tlb(void);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/arch/arm/include/arch/arm/cores.h b/arch/arm/include/arch/arm/cores.h
new file mode 100644
index 0000000..e5ddd66
--- /dev/null
+++ b/arch/arm/include/arch/arm/cores.h
@@ -0,0 +1,122 @@
+/*
+ * 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 __ARM_CORES_H
+#define __ARM_CORES_H
+
+/*
+ * make the gcc built in define a little easier to deal with
+ * to decide what core it is generating code for
+ *
+ * ARM_ARCH_LEVEL gets assigned a numeric value of the general family
+ *
+ * ARM_ARCH_* gets defined for each feature recursively
+ */
+
+#if defined(__ARM_ARCH_7M__)
+#define ARM_ARCH_7M 1
+#endif
+#if defined(__ARM_ARCH_7R__)
+#define ARM_ARCH_7R 1
+#endif
+#if defined(__ARM_ARCH_7A__) || defined(ARM_ARCH_7R)
+#define ARM_ARCH_7A 1
+#endif
+#if defined(__ARM_ARCH_7__) || defined(ARM_ARCH_7A) || defined(ARM_ARCH_7M)
+#define ARM_ARCH_7 1
+#ifndef ARM_ARCH_LEVEL
+#define ARM_ARCH_LEVEL 7
+#endif
+#endif
+
+#if defined(__ARM_ARCH_6M__)
+#define ARM_ARCH_6M 1
+#endif
+#if defined(__ARM_ARCH_6T2__) || defined(ARM_ARCH_7)
+#define ARM_ARCH_6T2 1
+#endif
+#if defined(__ARM_ARCH_6ZK__)
+#define ARM_ARCH_6ZK 1
+#endif
+#if defined(__ARM_ARCH_6Z__) || defined(ARM_ARCH_6ZK)
+#define ARM_ARCH_6Z 1
+#endif
+#if defined(__ARM_ARCH_6K__) || defined(ARM_ARCH_6ZK) || defined(ARM_ARCH_7)
+#define ARM_ARCH_6K 1
+#endif
+#if defined(__ARM_ARCH_6J__)
+#define ARM_ARCH_6J 1
+#endif
+#if defined(__ARM_ARCH_6__) || defined(ARM_ARCH_6J) || defined(ARM_ARCH_6K) || defined(ARM_ARCH_6Z) || defined(ARM_ARCH_6T2) || defined(ARM_ARCH_6M)
+#define ARM_ARCH_6 1
+#ifndef ARM_ARCH_LEVEL
+#define ARM_ARCH_LEVEL 6
+#endif
+#endif
+
+#if defined(__ARM_ARCH_5TEJ__)
+#define ARM_ARCH_5TEJ 1
+#endif
+#if defined(__ARM_ARCH_5TE__) || defined(ARM_ARCH_5TEJ) || defined(ARM_ARCH_6)
+#define ARM_ARCH_5TE 1
+#endif
+#if defined(__ARM_ARCH_5E__) || defined(ARM_ARCH_5TE)
+#define ARM_ARCH_5E 1
+#endif
+#if defined(__ARM_ARCH_5T__) || defined(ARM_ARCH_5TE)
+#define ARM_ARCH_5T 1
+#endif
+#if defined(__ARM_ARCH_5__) || defined(ARM_ARCH_5E) || defined(ARM_ARCH_5T)
+#define ARM_ARCH_5 1
+#ifndef ARM_ARCH_LEVEL
+#define ARM_ARCH_LEVEL 5
+#endif
+#endif
+
+#if defined(__ARM_ARCH_4T__) || defined(ARM_ARCH_5T)
+#define ARM_ARCH_4T 1
+#endif
+#if defined(__ARM_ARCH_4__) || defined(ARM_ARCH_4T) || defined(ARM_ARCH_5)
+#define ARM_ARCH_4 1
+#ifndef ARM_ARCH_LEVEL
+#define ARM_ARCH_LEVEL 4
+#endif
+#endif
+
+#if 0
+/* test */
+#if ARM_ARCH_LEVEL >= 7
+#warning ARM_ARCH_LEVEL >= 7
+#endif
+#if ARM_ARCH_LEVEL >= 6
+#warning ARM_ARCH_LEVEL >= 6
+#endif
+#if ARM_ARCH_LEVEL >= 5
+#warning ARM_ARCH_LEVEL >= 5
+#endif
+#if ARM_ARCH_LEVEL >= 4
+#warning ARM_ARCH_LEVEL >= 4
+#endif
+#endif
+
+#endif
+
diff --git a/arch/arm/include/arch/arm/mmu.h b/arch/arm/include/arch/arm/mmu.h
new file mode 100644
index 0000000..719710c
--- /dev/null
+++ b/arch/arm/include/arch/arm/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/arm/include/arch/arm/ops.h b/arch/arm/include/arch/arm/ops.h
new file mode 100644
index 0000000..6e763c9
--- /dev/null
+++ b/arch/arm/include/arch/arm/ops.h
@@ -0,0 +1,48 @@
+/*
+ * 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_OPS_H
+#define __ARHC_ARM_OPS_H
+
+#if 0
+#include <compiler.h>
+
+#ifndef ASSEMBLY
+
+#if ARM_ISA_ARMV7 || ARM_ISA_ARMV6
+// override of some routines
+__GNU_INLINE __ALWAYS_INLINE extern inline void arch_enable_ints(void)
+{
+ __asm__("cpsie i");
+}
+
+__GNU_INLINE __ALWAYS_INLINE extern inline void arch_disable_ints(void)
+{
+ __asm__("cpsid i");
+}
+#endif
+
+#endif
+#endif
+
+#endif
+
diff --git a/arch/arm/include/arch/defines.h b/arch/arm/include/arch/defines.h
new file mode 100644
index 0000000..1d62a68
--- /dev/null
+++ b/arch/arm/include/arch/defines.h
@@ -0,0 +1,43 @@
+/*
+ * 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_CPU_H
+#define __ARCH_CPU_H
+
+/* arm specific stuff */
+#define PAGE_SIZE 4096
+
+#if ARM_CPU_ARM7
+/* irrelevant, no consistent cache */
+#define CACHE_LINE 32
+#elif ARM_CPU_ARM926
+#define CACHE_LINE 32
+#elif ARM_CPU_ARM1136
+#define CACHE_LINE 32
+#elif ARM_CPU_CORTEX_A8
+#define CACHE_LINE 64
+#else
+#error unknown cpu
+#endif
+
+#endif
+
diff --git a/arch/arm/mmu.c b/arch/arm/mmu.c
new file mode 100644
index 0000000..8109e39
--- /dev/null
+++ b/arch/arm/mmu.c
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+#include <debug.h>
+#include <sys/types.h>
+#include <compiler.h>
+#include <arch.h>
+#include <arch/arm.h>
+#include <arch/arm/mmu.h>
+
+#if ARM_WITH_MMU
+
+#define MB (1024*1024)
+
+/* the location of the table may be brought in from outside */
+#if WITH_EXTERNAL_TRANSLATION_TABLE
+#if !defined(MMU_TRANSLATION_TABLE_ADDR)
+#error must set MMU_TRANSLATION_TABLE_ADDR in the make configuration
+#endif
+static uint32_t *tt = (void *)MMU_TRANSLATION_TABLE_ADDR;
+#else
+/* the main translation table */
+static uint32_t tt[4096] __ALIGNED(16384);
+#endif
+
+#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)
+{
+ int index;
+ uint AP;
+ uint CB;
+
+ AP = (flags & MMU_FLAG_READWRITE) ? 0x3 : 0x2;
+ CB = ((flags & MMU_FLAG_CACHED) ? 0x2 : 0) | ((flags & MMU_FLAG_BUFFERED) ? 0x1 : 0);
+
+ index = vaddr / MB;
+ tt[index] = (paddr & ~(MB-1)) | (AP << 10) | (0<<5) | (CB << 2) | (2<<0); // section mapping
+
+ arm_invalidate_tlb();
+}
+
+void arm_mmu_init(void)
+{
+ int i;
+
+ /* set some mmu specific control bits */
+ arm_write_cr1(arm_read_cr1() & ~((1<<29)|(1<<28)|(1<<0))); // access flag disabled, TEX remap disabled, mmu disabled
+
+ /* set up an identity-mapped translation table with cache disabled */
+ for (i=0; i < 4096; i++) {
+ arm_mmu_map_section(i * MB, i * MB, MMU_FLAG_READWRITE); // map everything uncached
+ }
+
+ /* set up the translation table base */
+ arm_write_ttbr((uint32_t)tt);
+
+ /* set up the domain access register */
+ arm_write_dacr(0x00000001);
+
+ /* turn on the mmu */
+ arm_write_cr1(arm_read_cr1() | 0x1);
+}
+
+void arch_disable_mmu(void)
+{
+ arm_write_cr1(arm_read_cr1() & ~(1<<0)); // access flag disabled, TEX remap disabled, mmu disabled
+}
+
+#endif // ARM_WITH_MMU
+
diff --git a/arch/arm/ops.S b/arch/arm/ops.S
new file mode 100644
index 0000000..c1d612c
--- /dev/null
+++ b/arch/arm/ops.S
@@ -0,0 +1,159 @@
+/*
+ * 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.
+ */
+#include <asm.h>
+
+.text
+
+/* void arch_enable_ints(void); */
+FUNCTION(arch_enable_ints)
+ mrs r0, cpsr
+ bic r0, r0, #(1<<7) /* clear the I bit */
+ msr cpsr_c, r0
+ bx lr
+
+/* void arch_disable_ints(void); */
+FUNCTION(arch_disable_ints)
+ mrs r0, cpsr
+ orr r0, r0, #(1<<7)
+ msr cpsr_c, r0
+ bx lr
+
+/* int atomic_swap(int *ptr, int val); */
+FUNCTION(atomic_swap)
+ swp r0, r2, [r1]
+ bx lr
+
+/* int atomic_add(int *ptr, int val); */
+FUNCTION(atomic_add)
+ /* disable interrupts, do the add, and reenable */
+ mrs r2, cpsr
+ mov r12, r2
+ orr r2, r2, #(3<<6)
+ msr cpsr_c, r2
+
+ /* ints disabled, old cpsr state in r12 */
+
+ /* do the add, leave the previous value in r0 */
+ mov r3, r0
+ ldr r0, [r3]
+ add r2, r0, r1
+ str r2, [r3]
+
+ /* restore interrupts and exit */
+ msr cpsr_c, r12
+ bx lr
+
+/* int atomic_and(int *ptr, int val); */
+FUNCTION(atomic_and)
+ /* disable interrupts, do the and, and reenable */
+ mrs r2, cpsr
+ mov r12, r2
+ orr r2, r2, #(3<<6)
+ msr cpsr_c, r2
+
+ /* ints disabled, old cpsr state in r12 */
+
+ /* do the and, leave the previous value in r0 */
+ mov r3, r0
+ ldr r0, [r3]
+ and r2, r0, r1
+ str r2, [r3]
+
+ /* restore interrupts and exit */
+ msr cpsr_c, r12
+ bx lr
+
+/* int atomic_or(int *ptr, int val); */
+FUNCTION(atomic_or)
+ /* disable interrupts, do the or, and reenable */
+ mrs r2, cpsr
+ mov r12, r2
+ orr r2, r2, #(3<<6)
+ msr cpsr_c, r2
+
+ /* ints disabled, old cpsr state in r12 */
+
+ /* do the or, leave the previous value in r0 */
+ mov r3, r0
+ ldr r0, [r3]
+ orr r2, r0, r1
+ str r2, [r3]
+
+ /* restore interrupts and exit */
+ msr cpsr_c, r12
+ bx lr
+
+/* void arch_idle(); */
+FUNCTION(arch_idle)
+#if ARM_CPU_CORTEX_A8
+ .word 0xe320f003 /* wfi */
+#elif ARM_CPU_ARM1136 || ARM_CPU_ARM926
+ mov r0, #0
+ mcr p15, 0, r0, c7, c0, #4
+#elif ARM_CPU_ARM7
+ /* nothing to do here */
+#else
+#error unknown cpu
+#endif
+ bx lr
+
+/* uint32_t arm_read_cr1(void) */
+FUNCTION(arm_read_cr1)
+ mrc p15, 0, r0, c1, c0, 0
+ bx lr
+
+/* void arm_write_cr1(uint32_t val) */
+FUNCTION(arm_write_cr1)
+ mcr p15, 0, r0, c1, c0, 0
+ bx lr
+
+/* uint32_t arm_read_cr1_aux(void) */
+FUNCTION(arm_read_cr1_aux)
+ mrc p15, 0, r0, c1, c0, 1
+ bx lr
+
+/* void arm_write_cr1_aux(uint32_t val) */
+FUNCTION(arm_write_cr1_aux)
+ mcr p15, 0, r0, c1, c0, 1
+ bx lr
+
+/* void arm_write_ttbr(uint32_t val) */
+FUNCTION(arm_write_ttbr)
+ mcr p15, 0, r0, c2, c0, 0
+ bx lr
+
+/* void arm_write_dacr(uint32_t val) */
+FUNCTION(arm_write_dacr)
+ mcr p15, 0, r0, c3, c0, 0
+ bx lr
+
+/* void arm_invalidate_tlb(void) */
+FUNCTION(arm_invalidate_tlb)
+ mov r0, #0
+ mcr p15, 0, r0, c8, c7, 0
+ bx lr
+
+/* void arch_switch_stacks_and_call(addr_t call, addr_t stack) */
+FUNCTION(arch_switch_stacks_and_call)
+ mov sp, r1
+ bx r0
diff --git a/arch/arm/rules.mk b/arch/arm/rules.mk
new file mode 100644
index 0000000..c8e3d5d
--- /dev/null
+++ b/arch/arm/rules.mk
@@ -0,0 +1,125 @@
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+TOOLCHAIN_PREFIX ?= arm-elf-
+
+ENABLE_THUMB ?= true
+
+CFLAGS += -finline
+
+DEFINES += \
+ ARM_CPU_$(ARM_CPU)=1
+
+# do set some options based on the cpu core
+HANDLED_CORE := false
+ifeq ($(ARM_CPU),cortex-a8)
+DEFINES += \
+ ARM_WITH_CP15=1 \
+ ARM_WITH_MMU=1 \
+ ARM_ISA_ARMv7=1 \
+ ARM_WITH_VFP=1 \
+ ARM_WITH_NEON=1 \
+ ARM_WITH_THUMB=1 \
+ ARM_WITH_THUMB2=1 \
+ ARM_WITH_CACHE=1 \
+ ARM_WITH_L2=1
+#CFLAGS += -mcpu=$(ARM_CPU)
+CFLAGS += -mcpu=arm1136jf-s # compiler doesn't understand cortex yet
+HANDLED_CORE := true
+#CFLAGS += -mfpu=vfp -mfloat-abi=softfp
+endif
+ifeq ($(ARM_CPU),arm1176jzf-s)
+DEFINES += \
+ ARM_WITH_CP15=1 \
+ ARM_WITH_MMU=1 \
+ ARM_ISA_ARMv6=1 \
+ ARM_WITH_VFP=1 \
+ ARM_WITH_THUMB=1 \
+ ARM_WITH_CACHE=1 \
+ ARM_CPU_ARM1136=1
+CFLAGS += -mcpu=$(ARM_CPU)
+HANDLED_CORE := true
+endif
+ifeq ($(ARM_CPU),arm926ej-s)
+DEFINES += \
+ ARM_WITH_CP15=1 \
+ ARM_WITH_MMU=1 \
+ ARM_ISA_ARMv5E=1 \
+ ARM_WITH_THUMB=1 \
+ ARM_WITH_CACHE=1 \
+ ARM_CPU_ARM9=1 \
+ ARM_CPU_ARM926=1
+CFLAGS += -mcpu=$(ARM_CPU)
+HANDLED_CORE := true
+endif
+ifeq ($(ARM_CPU),arm7tdmi)
+DEFINES += \
+ ARM_ISA_ARMv4=1 \
+ ARM_WITH_THUMB=1 \
+ ARM_CPU_ARM7=1
+CFLAGS += -mcpu=$(ARM_CPU)
+HANDLED_CORE := true
+endif
+
+ifneq ($(HANDLED_CORE),true)
+$(warning $(LOCAL_DIR)/rules.mk doesnt have logic for arm core $(ARM_CPU))
+$(warning this is likely to be broken)
+endif
+
+THUMBCFLAGS :=
+THUMBINTERWORK :=
+ifeq ($(ENABLE_THUMB),true)
+THUMBCFLAGS := -mthumb -D__thumb__
+THUMBINTERWORK := -mthumb-interwork
+endif
+
+CFLAGS += $(THUMBINTERWORK)
+
+INCLUDES += \
+ -I$(LOCAL_DIR)/include
+
+BOOTOBJS += \
+ $(LOCAL_DIR)/crt0.o
+
+OBJS += \
+ $(LOCAL_DIR)/arch.Ao \
+ $(LOCAL_DIR)/asm.o \
+ $(LOCAL_DIR)/cache.o \
+ $(LOCAL_DIR)/cache-ops.o \
+ $(LOCAL_DIR)/ops.o \
+ $(LOCAL_DIR)/exceptions.o \
+ $(LOCAL_DIR)/faults.o \
+ $(LOCAL_DIR)/mmu.o \
+ $(LOCAL_DIR)/thread.o
+
+# make sure some bits were set up
+MEMVARS_SET := 0
+ifneq ($(MEMBASE),)
+MEMVARS_SET := 1
+endif
+ifneq ($(MEMSIZE),)
+MEMVARS_SET := 1
+endif
+ifeq ($(MEMVARS_SET),0)
+$(error missing MEMBASE or MEMSIZE variable, please set in target rules.mk)
+endif
+
+LIBGCC := $(shell $(TOOLCHAIN_PREFIX)gcc $(CFLAGS) $(THUMBCFLAGS) -print-libgcc-file-name)
+#$(info LIBGCC = $(LIBGCC))
+
+# potentially generated files that should be cleaned out with clean make rule
+GENERATED += \
+ $(BUILDDIR)/system-onesegment.ld \
+ $(BUILDDIR)/system-twosegment.ld
+
+# rules for generating the linker scripts
+
+$(BUILDDIR)/system-onesegment.ld: $(LOCAL_DIR)/system-onesegment.ld
+ @echo generating $@
+ @$(MKDIR)
+ $(NOECHO)sed "s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/" < $< > $@
+
+$(BUILDDIR)/system-twosegment.ld: $(LOCAL_DIR)/system-twosegment.ld
+ @echo generating $@
+ @$(MKDIR)
+ $(NOECHO)sed "s/%ROMBASE%/$(ROMBASE)/;s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/" < $< > $@
+
diff --git a/arch/arm/system-onesegment.ld b/arch/arm/system-onesegment.ld
new file mode 100644
index 0000000..fe3a83c
--- /dev/null
+++ b/arch/arm/system-onesegment.ld
@@ -0,0 +1,78 @@
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+
+ENTRY(_start)
+SECTIONS
+{
+ . = %MEMBASE%;
+
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) *(.rel.gnu.linkonce.t*) }
+ .rela.text : { *(.rela.text) *(.rela.gnu.linkonce.t*) }
+ .rel.data : { *(.rel.data) *(.rel.gnu.linkonce.d*) }
+ .rela.data : { *(.rela.data) *(.rela.gnu.linkonce.d*) }
+ .rel.rodata : { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
+ .rela.rodata : { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.init : { *(.rel.init) }
+ .rela.init : { *(.rela.init) }
+ .rel.fini : { *(.rel.fini) }
+ .rela.fini : { *(.rela.fini) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) } =0x9090
+ .plt : { *(.plt) }
+
+ /* text/read-only data */
+ .text : { *(.text .text.* .glue_7* .gnu.linkonce.t.*) } =0x9090
+
+ .rodata : {
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ . = ALIGN(4);
+ __commands_start = .;
+ KEEP (*(.commands))
+ __commands_end = .;
+ . = ALIGN(4);
+ __rodata_end = . ;
+ }
+
+ /* writable data */
+ __data_start_rom = .; /* in one segment binaries, the rom data address is on top of the ram data address */
+ __data_start = .;
+ .data : { *(.data .data.* .gnu.linkonce.d.*) }
+
+ __ctor_list = .;
+ .ctors : { *(.ctors) }
+ __ctor_end = .;
+ __dtor_list = .;
+ .dtors : { *(.dtors) }
+ __dtor_end = .;
+ .got : { *(.got.plt) *(.got) }
+ .dynamic : { *(.dynamic) }
+
+ __data_end = .;
+
+ /* unintialized data (in same segment as writable data) */
+ . = ALIGN(4);
+ __bss_start = .;
+ .bss : { *(.bss .bss.*) }
+
+ . = ALIGN(4);
+ _end = .;
+
+ . = %MEMBASE% + %MEMSIZE%;
+ _end_of_ram = .;
+
+ /* Strip unnecessary stuff */
+ /DISCARD/ : { *(.comment .note .eh_frame) }
+}
diff --git a/arch/arm/system-twosegment.ld b/arch/arm/system-twosegment.ld
new file mode 100644
index 0000000..aee3913
--- /dev/null
+++ b/arch/arm/system-twosegment.ld
@@ -0,0 +1,81 @@
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+
+ENTRY(_start)
+SECTIONS
+{
+ . = %ROMBASE%;
+
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) *(.rel.gnu.linkonce.t*) }
+ .rela.text : { *(.rela.text) *(.rela.gnu.linkonce.t*) }
+ .rel.data : { *(.rel.data) *(.rel.gnu.linkonce.d*) }
+ .rela.data : { *(.rela.data) *(.rela.gnu.linkonce.d*) }
+ .rel.rodata : { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
+ .rela.rodata : { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.init : { *(.rel.init) }
+ .rela.init : { *(.rela.init) }
+ .rel.fini : { *(.rel.fini) }
+ .rela.fini : { *(.rela.fini) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) } =0x9090
+ .plt : { *(.plt) }
+
+ /* text/read-only data */
+ .text : { *(.text .text.* .glue_7* .gnu.linkonce.t.*) } =0x9090
+
+ .rodata : {
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ . = ALIGN(4);
+ __commands_start = .;
+ KEEP (*(.commands))
+ __commands_end = .;
+ . = ALIGN(4);
+ __rodata_end = . ;
+ }
+
+ /* writable data */
+ __data_start_rom = .;
+ . = %MEMBASE%;
+ __data_start = .;
+ .data :
+ AT ( ADDR (.rodata) + SIZEOF (.rodata) )
+ { *(.data .data.* .gnu.linkonce.d.*) }
+
+ __ctor_list = .;
+ .ctors : { *(.ctors) }
+ __ctor_end = .;
+ __dtor_list = .;
+ .dtors : { *(.dtors) }
+ __dtor_end = .;
+ .got : { *(.got.plt) *(.got) }
+ .dynamic : { *(.dynamic) }
+
+ __data_end = .;
+
+ /* unintialized data (in same segment as writable data) */
+ . = ALIGN(4);
+ __bss_start = .;
+ .bss : { *(.bss .bss.*) }
+
+ . = ALIGN(4);
+ _end = . ;
+
+ . = %MEMBASE% + %MEMSIZE%;
+ _end_of_ram = . ;
+
+ /* Strip unnecessary stuff */
+ /DISCARD/ : { *(.comment .note .eh_frame) }
+}
diff --git a/arch/arm/thread.c b/arch/arm/thread.c
new file mode 100644
index 0000000..a3b9a95
--- /dev/null
+++ b/arch/arm/thread.c
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include <debug.h>
+#include <kernel/thread.h>
+#include <arch/arm.h>
+
+struct context_switch_frame {
+ vaddr_t r4;
+ vaddr_t r5;
+ vaddr_t r6;
+ vaddr_t r7;
+ vaddr_t r8;
+ vaddr_t r9;
+ vaddr_t r10;
+ vaddr_t r11;
+ vaddr_t lr;
+ vaddr_t usp;
+ vaddr_t ulr;
+};
+
+extern void arm_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->lr = (vaddr_t)&initial_thread_func;
+
+ // set the stack pointer
+ t->arch.sp = (vaddr_t)frame;
+}
+
+void arch_context_switch(thread_t *oldthread, thread_t *newthread)
+{
+// dprintf("arch_context_switch: old %p (%s), new %p (%s)\n", oldthread, oldthread->name, newthread, newthread->name);
+ arm_context_switch(&oldthread->arch.sp, newthread->arch.sp);
+}
+