M7350v1_en_gpl

This commit is contained in:
T
2024-09-09 08:52:07 +00:00
commit f9cc65cfda
65988 changed files with 26357421 additions and 0 deletions
+85
View File
@@ -0,0 +1,85 @@
/*
* 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();
#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 */
__asm__ volatile("mrc p10, 7, %0, c8, c0, 0" : "=r" (val));
val |= (1<<30);
__asm__ volatile("mcr p10, 7, %0, c8, c0, 0" :: "r" (val));
#endif
#if ARM_CPU_CORTEX_A8
/* enable the cycle count register */
uint32_t en;
__asm__ volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (en));
en &= ~(1<<3); /* cycle count every cycle */
en |= 1; /* enable all performance counters */
__asm__ volatile("mcr p15, 0, %0, c9, c12, 0" :: "r" (en));
/* enable cycle counter */
en = (1<<31);
__asm__ volatile("mcr p15, 0, %0, c9, c12, 1" :: "r" (en));
#endif
}
void arch_init(void)
{
}
+103
View File
@@ -0,0 +1,103 @@
/*
* 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]
/* clear any exlusive locks that the old thread holds */
#if ARM_ISA_ARMV7
/* can clear it directly */
.word 0xf57ff01f // clrex
#elif ARM_ISA_ARMV6
/* have to do a fake strex to clear it */
ldr r0, =strex_spot
strex r3, r2, [r0]
#endif
/* load new regs */
ldmia r1, { r4-r11, r12, r13, r14 }^
mov lr, r12 /* restore lr */
add sp, r1, #(11*4) /* restore sp */
bx lr
.ltorg
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_c, r1
bx lr
.data
strex_spot:
.word 0
+405
View File
@@ -0,0 +1,405 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
* Copyright (c) 2013, The Linux Foundation. All rights reserved.
*
* 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)
// make sure all data operations are completed
dsb
mcr p15, 0, r0, c1, c0, 0 // disable dcache
// make sure previous instruction finishes before we clean and flush
isb
// 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
// make sure previous instruction finishes
isb
.Ldone_disable:
// make sure the icache is always invalidated
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 // invalidate icache to PoU
// make sure that data is in sync
dsb
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:
DMB
/* 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
dsb
.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
dsb
.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
/* void arch_invalidate_cache_range(addr_t start, size_t len); */
FUNCTION(arch_invalidate_cache_range)
0:
/* invalidate cache line */
mcr p15, 0, r0, c7, c6, 1
add r0, r0, #CACHE_LINE
subs r1, r1, #CACHE_LINE
bhs 0b
mov r0, #0
/* data sync barrier (formerly drain write buffer*/
mcr p15, 0, r0, c7, c10, 4
bx lr
/* void arch_sync_cache_range(addr_t start, size_t len); */
FUNCTION(arch_sync_cache_range)
push { r14 }
bl arch_clean_cache_range
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 // invalidate icache to PoU
pop { pc }
#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
FUNCTION(arch_sync_cache_range)
bx lr
#endif // ARM_WITH_CACHE
+22
View File
@@ -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.
*/
@@ -0,0 +1,39 @@
$(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 $@
ifeq ($(ENABLE_TRUSTZONE), 1)
$(BUILDDIR)/%.o: %.S $(SRCDEPS)
@$(MKDIR)
@echo compiling $<
$(NOECHO)$(CC) -DENABLE_TRUSTZONE $(CFLAGS) $(ASMFLAGS) $(INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@
else
$(BUILDDIR)/%.o: %.S $(SRCDEPS)
@$(MKDIR)
@echo compiling $<
$(NOECHO)$(CC) $(CFLAGS) $(ASMFLAGS) $(INCLUDES) -c $< -MD -MT $@ -MF $(@:%o=%d) -o $@
endif
+189
View File
@@ -0,0 +1,189 @@
/*
* 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.
*/
#define DSB .byte 0x4f, 0xf0, 0x7f, 0xf5
#define ISB .byte 0x6f, 0xf0, 0x7f, 0xf5
.section ".text.boot"
.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:
#ifdef ENABLE_TRUSTZONE
/*Add reference to TZ symbol so linker includes it in final image */
ldr r7, =_binary_tzbsp_tzbsp_bin_start
#endif
/* do some cpu setup */
#if ARM_WITH_CP15
/* Read SCTLR */
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)
/* Write SCTLR */
mcr p15, 0, r0, c1, c0, 0
#ifdef ENABLE_TRUSTZONE
/*nkazi: not needed ? Setting VBAR to location of new vector table : 0x80000 */
ldr r0, =0x00080000
mcr p15, 0, r0, c12, c0, 0
#endif
#endif
#if WITH_CPU_EARLY_INIT
/* call platform/arch/etc specific init code */
#ifndef ENABLE_TRUSTZONE
/* Not needed when TrustZone is the first bootloader that runs.*/
bl __cpu_early_init
#endif
/* declare return address as global to avoid using stack */
.globl _cpu_early_init_complete
_cpu_early_init_complete:
#endif
#if (!ENABLE_NANDWRITE)
#if WITH_CPU_WARM_BOOT
ldr r0, warm_boot_tag
cmp r0, #1
/* if set, warm boot */
ldreq pc, =BASE_ADDR
mov r0, #1
str r0, warm_boot_tag
#endif
#endif
/* see if we need to relocate */
mov r0, pc
sub r0, r0, #(.Laddr - _start)
.Laddr:
ldr r1, =_start
cmp r0, r1
beq .Lstack_setup
/* we need to relocate ourselves to the proper spot */
ldr r2, =__data_end
.Lrelocate_loop:
ldr r3, [r0], #4
str r3, [r1], #4
cmp r1, r2
bne .Lrelocate_loop
/* we're relocated, jump to the right address */
ldr r0, =.Lstack_setup
bx r0
.ltorg
#if WITH_CPU_WARM_BOOT
warm_boot_tag:
.word 0
#endif
.Lstack_setup:
/* 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 .L__do_bss
.L__copy_loop:
cmp r1, r2
ldrlt r3, [r0], #4
strlt r3, [r1], #4
blt .L__copy_loop
.L__do_bss:
/* clear out the bss */
ldr r0, =__bss_start
ldr r1, =_end
mov r2, #0
.L__bss_loop:
cmp r0, r1
strlt r2, [r0], #4
blt .L__bss_loop
#ifdef ARM_CPU_CORTEX_A8
DSB
ISB
#endif
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:
+41
View File
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2008 Brian Swetland
*
* 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.
*/
.global dcc_putc
.global dcc_getc
#if defined(ARM_ISA_ARMV6) || defined(ARM_ISA_ARMV7)
dcc_getc:
mrc 14, 0, r0, c0, c1, 0
tst r0, #(1 << 30)
moveq r0, #-1
mrcne 14, 0, r0, c0, c5, 0
bx lr
dcc_putc:
mrc 14, 0, r15, c0, c1, 0
mcrcc 14, 0, r0, c0, c5, 0
movcc r0, #0
movcs r0, #-1
bx lr
#endif
@@ -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_cxsf, 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
+91
View File
@@ -0,0 +1,91 @@
/*
* 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(CRITICAL, "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(CRITICAL, "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(CRITICAL, "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(CRITICAL, "r12 0x%08x usp 0x%08x ulr 0x%08x pc 0x%08x\n", frame->r[12], frame->usp, frame->ulr, frame->pc);
dprintf(CRITICAL, "spsr 0x%08x\n", frame->spsr);
struct arm_mode_regs regs;
arm_save_mode_regs(&regs);
dprintf(CRITICAL, "%c%s r13 0x%08x r14 0x%08x\n", ((frame->spsr & MODE_MASK) == MODE_FIQ) ? '*' : ' ', "fiq", regs.fiq_r13, regs.fiq_r14);
dprintf(CRITICAL, "%c%s r13 0x%08x r14 0x%08x\n", ((frame->spsr & MODE_MASK) == MODE_IRQ) ? '*' : ' ', "irq", regs.irq_r13, regs.irq_r14);
dprintf(CRITICAL, "%c%s r13 0x%08x r14 0x%08x\n", ((frame->spsr & MODE_MASK) == MODE_SVC) ? '*' : ' ', "svc", regs.svc_r13, regs.svc_r14);
dprintf(CRITICAL, "%c%s r13 0x%08x r14 0x%08x\n", ((frame->spsr & MODE_MASK) == MODE_UND) ? '*' : ' ', "und", regs.und_r13, regs.und_r14);
dprintf(CRITICAL, "%c%s r13 0x%08x r14 0x%08x\n", ((frame->spsr & MODE_MASK) == MODE_SYS) ? '*' : ' ', "sys", regs.sys_r13, regs.sys_r14);
// dump the bottom of the current stack
addr_t stack;
switch (frame->spsr & MODE_MASK) {
case MODE_FIQ: stack = regs.fiq_r13; break;
case MODE_IRQ: stack = regs.irq_r13; break;
case MODE_SVC: stack = regs.svc_r13; break;
case MODE_UND: stack = regs.und_r13; break;
case MODE_SYS: stack = regs.sys_r13; break;
default:
stack = 0;
}
if (stack != 0) {
dprintf(CRITICAL, "bottom of stack at 0x%08x:\n", (unsigned int)stack);
hexdump((void *)stack, 128);
}
}
static void exception_die(struct arm_fault_frame *frame, int pc_off, const char *msg)
{
inc_critical_section();
frame->pc += pc_off;
dprintf(CRITICAL, msg);
dump_fault_frame(frame);
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");
}
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2008 Brian Swetland
*
* 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_DCC_H
#define __ARCH_ARM_DCC_H
/* returns < 0 if no data available */
int dcc_getc(void);
/* returns < 0 if output register was already full */
int dcc_putc(unsigned c);
#endif
@@ -0,0 +1,65 @@
/*
* 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);
#if defined(ARM_ISA_ARMV6) | defined(ARM_ISA_ARMV7)
/* C, B and TEX[2:0] encodings without TEX remap */
/* TEX | CB */
#define MMU_MEMORY_TYPE_STRONGLY_ORDERED ((0x0 << 12) | (0x0 << 2))
#define MMU_MEMORY_TYPE_DEVICE_SHARED ((0x0 << 12) | (0x1 << 2))
#define MMU_MEMORY_TYPE_DEVICE_NON_SHARED ((0x2 << 12) | (0x0 << 2))
#define MMU_MEMORY_TYPE_NORMAL ((0x1 << 12) | (0x0 << 2))
#define MMU_MEMORY_TYPE_NORMAL_WRITE_THROUGH ((0x0 << 12) | (0x2 << 2))
#define MMU_MEMORY_TYPE_NORMAL_WRITE_BACK_NO_ALLOCATE ((0x0 << 12) | (0x3 << 2))
#define MMU_MEMORY_TYPE_NORMAL_WRITE_BACK_ALLOCATE ((0x1 << 12) | (0x3 << 2))
#define MMU_MEMORY_AP_NO_ACCESS (0x0 << 10)
#define MMU_MEMORY_AP_READ_ONLY (0x7 << 10)
#define MMU_MEMORY_AP_READ_WRITE (0x3 << 10)
#define MMU_MEMORY_XN (0x1 << 4)
#else
#error "MMU implementation needs to be updated for this ARM architecture"
#endif
void arm_mmu_map_section(addr_t paddr, addr_t vaddr, uint flags);
#if defined(__cplusplus)
}
#endif
#endif
@@ -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
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
* Copyright (c) 2013, The Linux Foundation. All rights reserved.
*
* 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 defined(ARM_CPU_ARM1136)
#define CACHE_LINE 32
#elif defined(ARM_CPU_CORE_A5)
#define CACHE_LINE 32
#elif defined(ARM_CPU_CORE_SCORPION)
#define CACHE_LINE 32
#elif defined(ARM_CPU_CORE_KRAIT) || defined(ARM_CPU_CORE_A7)
#define CACHE_LINE 64
#else
#error unknown cpu
#endif
#define IS_CACHE_LINE_ALIGNED(addr) !((uint32_t) (addr) & (CACHE_LINE - 1))
#endif
+101
View File
@@ -0,0 +1,101 @@
/*
* 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
void arm_mmu_map_section(addr_t paddr, addr_t vaddr, uint flags)
{
int index;
/* Get the index into the translation table */
index = vaddr / MB;
/* Set the entry value:
* (2<<0): Section entry
* (0<<5): Domain = 0
* flags: TEX, CB and AP bit settings provided by the caller.
*/
tt[index] = (paddr & ~(MB-1)) | (0<<5) | (2<<0) | flags;
arm_invalidate_tlb();
}
void arm_mmu_init(void)
{
int i;
/* set some mmu specific control bits:
* access flag disabled, TEX remap disabled, mmu disabled
*/
arm_write_cr1(arm_read_cr1() & ~((1<<29)|(1<<28)|(1<<0)));
if (platform_use_identity_mmu_mappings())
{
/* set up an identity-mapped translation table with
* strongly ordered memory type and read/write access.
*/
for (i=0; i < 4096; i++) {
arm_mmu_map_section(i * MB,
i * MB,
MMU_MEMORY_TYPE_STRONGLY_ORDERED | MMU_MEMORY_AP_READ_WRITE);
}
}
platform_init_mmu_mappings();
/* 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));
arm_invalidate_tlb();
}
#endif // ARM_WITH_MMU
+285
View File
@@ -0,0 +1,285 @@
/*
* 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)
#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
/* use load/store exclusive */
.L_loop_add:
ldrex r12, [r0]
add r2, r12, r1
strex r3, r2, [r0]
cmp r3, #0
bne .L_loop_add
/* save old value */
mov r0, r12
bx lr
#else
/* 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
#endif
/* uint64_t atomic_dw_read(uint32_t rd_addr,
* uint32_t st_addr_lo, uint32_t st_addr_hi);
*/
/* Reads a double word from memory atomically */
FUNCTION(atomic_dw_read)
#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
stmfd sp!, {r4-r5}
/* use load/store exclusive */
ldrexd r4, [r0]
str r4, [r1]
str r5, [r2]
/* Restore registers */
ldmfd sp!, {r4-r5}
bx lr
#else
stmfd sp!, {r4-r5}
/* disable interrupts, do read, 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 memory read, return the double word read */
ldr r4, [r0]
ldr r5, [r0, #4]
str r4, [r1]
str r5, [r2]
/* restore interrupts */
msr cpsr_c, r12
/* restore registers */
ldmfd sp!, {r4-r5}
bx lr
#endif
/* int atomic_and(int *ptr, int val); */
FUNCTION(atomic_and)
#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
/* use load/store exclusive */
.L_loop_and:
ldrex r12, [r0]
and r2, r12, r1
strex r3, r2, [r0]
cmp r3, #0
bne .L_loop_and
/* save old value */
mov r0, r12
bx lr
#else
/* 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
#endif
/* int atomic_or(int *ptr, int val); */
FUNCTION(atomic_or)
#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
/* use load/store exclusive */
.L_loop_or:
ldrex r12, [r0]
orr r2, r12, r1
strex r3, r2, [r0]
cmp r3, #0
bne .L_loop_or
/* save old value */
mov r0, r12
bx lr
#else
/* 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
#endif
/* void arch_idle(); */
FUNCTION(arch_idle)
#if ARM_CPU_CORTEX_A8
.word 0xe320f003 /* wfi */
#elif PLATFORM_MSM7K
/* TODO: safely handle 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
/*void dmb(void) */
FUNCTION(dmb)
#if ARM_CPU_CORTEX_A8
dmb sy
#elif ARM_CPU_ARM1136
mov r0, #0
mcr p15, 0, r0, c7, c10, 5
#endif
bx lr
/*void isb(void) */
FUNCTION(isb)
#if ARM_CPU_CORTEX_A8
isb sy
#elif ARM_CPU_ARM1136
mov r0, #0
mcr p15, 0, r0, c7, c5, 4
#endif
bx lr
/*void dsb(void) */
FUNCTION(dsb)
#if ARM_CPU_CORTEX_A8
dsb sy
#elif ARM_CPU_ARM1136
mov r0, #0
mcr p15, 0, r0, c7, c10, 4
#endif
bx lr
/* uint32_t arm_read_cycle_count(void); */
FUNCTION(arm_read_cycle_count)
/* uint32_t arch_cycle_count(void); */
FUNCTION(arch_cycle_count)
#if ARM_CPU_CORTEX_A8
mrc p15, 0, r0, c9, c13, 0
#else
mov r0, #0
#endif
bx lr
+154
View File
@@ -0,0 +1,154 @@
LOCAL_DIR := $(GET_LOCAL_DIR)
# can override this in local.mk
ENABLE_THUMB?=true
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),arm1136j-s)
DEFINES += \
ARM_WITH_CP15=1 \
ARM_WITH_MMU=1 \
ARM_ISA_ARMv6=1 \
ARM_WITH_THUMB=1 \
ARM_WITH_CACHE=1 \
ARM_CPU_ARM1136=1
CFLAGS += -mcpu=$(ARM_CPU)
HANDLED_CORE := true
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
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 \
$(LOCAL_DIR)/dcc.o
# set the default toolchain to arm eabi and set a #define
TOOLCHAIN_PREFIX ?= arm-eabi-
ifeq ($(TOOLCHAIN_PREFIX),arm-none-linux-gnueabi-)
# XXX test for EABI better than this
# eabi compilers dont need this
THUMBINTERWORK:=
endif
CFLAGS += $(THUMBINTERWORK)
# 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)/trustzone-test-system-onesegment.ld: $(LOCAL_DIR)/trustzone-test-system-onesegment.ld
@echo generating $@
@$(MKDIR)
$(NOECHO)sed "s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/;s/%ROMLITE_PREFLASHED_DATA%/$(ROMLITE_PREFLASHED_DATA)/" < $< > $@
$(BUILDDIR)/trustzone-system-onesegment.ld: $(LOCAL_DIR)/trustzone-system-onesegment.ld
@echo generating $@
@$(MKDIR)
$(NOECHO)sed "s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/" < $< > $@
$(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)/" < $< > $@
@@ -0,0 +1,83 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = %MEMBASE%;
/* text/read-only data */
.text.boot : { *(.text.boot) }
.text : { *(.text .text.* .glue_7* .gnu.linkonce.t.*) } =0x9090
.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) }
.rodata : {
*(.rodata .rodata.* .gnu.linkonce.r.*)
. = ALIGN(4);
__commands_start = .;
KEEP (*(.commands))
__commands_end = .;
. = ALIGN(4);
__apps_start = .;
KEEP (*(.apps))
__apps_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 : SUBALIGN(4) { *(.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) }
}
@@ -0,0 +1,86 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = %ROMBASE%;
/* text/read-only data */
.text.boot : { *(.text.boot) }
.text : { *(.text .text.* .glue_7* .gnu.linkonce.t.*) } =0x9090
.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) }
.rodata : {
*(.rodata .rodata.* .gnu.linkonce.r.*)
. = ALIGN(4);
__commands_start = .;
KEEP (*(.commands))
__commands_end = .;
. = ALIGN(4);
__apps_start = .;
KEEP (*(.apps))
__apps_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) }
}
+88
View File
@@ -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);
}
@@ -0,0 +1,92 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
/*Added TRUSTZONE at 0x0. Moving rest of APPSBL to %MEMBASE% */
. = 0x0;
.tzbsp 0x0 : {*tzbsp_bin.o(.data)}
. = %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) }
/*Moving harcoded addresses by a displacement of %MEMBASE% */
.init : { *(.init) } = %MEMBASE% + 0x9090
.plt : { *(.plt) }
/* text/read-only data */
/*Moving harcoded addresses by a displacement of %MEMBASE% */
.text : { *(.text .text.* .glue_7* .gnu.linkonce.t.*) } = %MEMBASE% + 0x9090
.rodata : {
*(.rodata .rodata.* .gnu.linkonce.r.*)
. = ALIGN(4);
__commands_start = .;
KEEP (*(.commands))
__commands_end = .;
. = ALIGN(4);
__apps_start = .;
KEEP (*(.apps))
__apps_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 : SUBALIGN(4) { *(.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) }
}
@@ -0,0 +1,93 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
/*Added TRUSTZONE at 0x0. Moving rest of APPSBL to %MEMBASE% */
. = 0x0;
.tzbsp 0x0 : {*tzbsp_bin.o(.data)}
.romlite 0xBF000 : {*romlite_toc_and_data.o(.data.rom_lite_preflashed_data)}
. = %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) }
/*Moving harcoded addresses by a displacement of %MEMBASE% */
.init : { *(.init) } = %MEMBASE% + 0x9090
.plt : { *(.plt) }
/* text/read-only data */
/*Moving harcoded addresses by a displacement of %MEMBASE% */
.text : { *(.text .text.* .glue_7* .gnu.linkonce.t.*) } = %MEMBASE% + 0x9090
.rodata : {
*(.rodata .rodata.* .gnu.linkonce.r.*)
. = ALIGN(4);
__commands_start = .;
KEEP (*(.commands))
__commands_end = .;
. = ALIGN(4);
__apps_start = .;
KEEP (*(.apps))
__apps_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 : SUBALIGN(4) { *(.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) }
}