summaryrefslogtreecommitdiffstats
path: root/firmware/target/arm/mmu-arm.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/mmu-arm.c')
-rw-r--r--firmware/target/arm/mmu-arm.c253
1 files changed, 137 insertions, 116 deletions
diff --git a/firmware/target/arm/mmu-arm.c b/firmware/target/arm/mmu-arm.c
index ffca7a43ee..c4b63cf805 100644
--- a/firmware/target/arm/mmu-arm.c
+++ b/firmware/target/arm/mmu-arm.c
@@ -20,70 +20,111 @@
#include "mmu-arm.h"
#include "panic.h"
-#define SECTION_ADDRESS_MASK (-1 << 20)
-#define MB (1 << 20)
+void __attribute__((naked)) ttb_init(void) {
+ asm volatile
+ (
+ "mcr p15, 0, %[ttbB], c2, c0, 0 \n" /* Set the TTB base address */
+ "mcr p15, 0, %[ffff], c3, c0, 0 \n" /* Set all domains to manager status */
+ "bx lr \n"
+ :
+ : [ttbB] "r" (TTB_BASE),
+ [ffff] "r" (0xFFFFFFFF)
+ );
+}
-void ttb_init(void) {
- unsigned int* ttbPtr;
+void __attribute__((naked)) map_section(unsigned int pa, unsigned int va, int mb, int flags) {
+#if 0 /* This code needs to be fixed and the C needs to be replaced to ensure that stack is not used */
+ asm volatile
+ (
+ /* pa &= (-1 << 20); // align to 1MB */
+ "mov r0, r0, lsr #20 \n"
+ "mov r0, r0, lsl #20 \n"
- /* must be 16Kb (0x4000) aligned - clear out the TTB */
- for (ttbPtr=TTB_BASE; ttbPtr<(TTB_SIZE+TTB_BASE); ttbPtr++)
- {
- *ttbPtr = 0;
- }
+ /* pa |= (flags | 0x412);
+ * bit breakdown:
+ * 10: superuser - r/w, user - no access
+ * 4: should be "1"
+ * 3,2: Cache flags (flags (r3))
+ * 1: Section signature
+ */
- /* Set the TTB base address */
- asm volatile("mcr p15, 0, %0, c2, c0, 0" : : "r" (TTB_BASE));
+ "orr r0, r0, r3 \n"
+ "orr r0, r0, #0x410 \n"
+ "orr r0, r0, #0x2 \n"
+ :
+ :
+ );
- /* Set all domains to manager status */
- asm volatile("mcr p15, 0, %0, c3, c0, 0" : : "r" (0xFFFFFFFF));
-}
+ register int *ttb_base asm ("r3") = TTB_BASE; /* force in r3 */
-void map_section(unsigned int pa, unsigned int va, int mb, int cache_flags) {
- unsigned int* ttbPtr;
- int i;
- int section_no;
+ asm volatile
+ (
+ /* unsigned int* ttbPtr = TTB_BASE + (va >> 20);
+ * sections are 1MB size
+ */
- section_no = va >> 20; /* sections are 1Mb size */
- ttbPtr = TTB_BASE + section_no;
- pa &= SECTION_ADDRESS_MASK; /* align to 1Mb */
- for(i=0; i<mb; i++, pa += MB) {
- *(ttbPtr + i) =
- pa |
- 1 << 10 | /* superuser - r/w, user - no access */
- 0 << 5 | /* domain 0th */
- 1 << 4 | /* should be "1" */
- cache_flags |
- 1 << 1; /* Section signature */
- }
-}
+ "mov r1, r1, lsr #20 \n"
+ "add r1, %[ttbB], r1, lsl #0x2 \n"
-void enable_mmu(void) {
- int regread;
+ /* Add MB to pa, flags are already present in pa, but addition
+ * should not effect them
+ *
+ * #define MB (1 << 20)
+ * for( ; mb>0; mb--, pa += MB)
+ * {
+ * *(ttbPtr++) = pa;
+ * }
+ * #undef MB
+ */
- asm volatile(
- "MRC p15, 0, %r0, c1, c0, 0\n" /* Read reg1, control register */
- : /* outputs */
- "=r"(regread)
- : /* inputs */
- : /* clobbers */
- "r0"
+ "cmp r2, #0 \n"
+ "bxle lr \n"
+ "loop: \n"
+ "str r0, [r1], #4 \n"
+ "add r0, r0, #0x100000 \n"
+ "sub r2, r2, #0x01 \n"
+ "bne loop \n"
+ "bx lr \n"
+ :
+ : [ttbB] "r" (ttb_base) /* This /HAS/ to be in r3 */
);
+ (void) pa;
+ (void) va;
+ (void) mb;
+ (void) flags;
+#else
+ pa &= (-1 << 20);
+ pa |= (flags | 0x412);
+ unsigned int* ttbPtr = TTB_BASE + (va >> 20);
- if ( !(regread & 0x04) || !(regread & 0x00001000) ) /* Was the ICache or DCache Enabled? */
- clean_dcache(); /* If so we need to clean the DCache before invalidating below */
-
- asm volatile("mov r0, #0\n"
- "mcr p15, 0, r0, c8, c7, 0\n" /* invalidate TLB */
-
- "mcr p15, 0, r0, c7, c7,0\n" /* invalidate both icache and dcache */
+#define MB (1 << 20)
+ for( ; mb>0; mb--, pa += MB)
+ {
+ *(ttbPtr++) = pa;
+ }
+#undef MB
+#endif
+}
- "mrc p15, 0, r0, c1, c0, 0\n"
- "orr r0, r0, #1<<0\n" /* enable mmu bit, icache and dcache */
- "orr r0, r0, #1<<2\n" /* enable dcache */
- "orr r0, r0, #1<<12\n" /* enable icache */
- "mcr p15, 0, r0, c1, c0, 0" : : : "r0");
- asm volatile("nop \n nop \n nop \n nop");
+void __attribute__((naked)) enable_mmu(void) {
+ asm volatile(
+ "mov r0, #0 \n"
+ "mcr p15, 0, r0, c8, c7, 0 \n" /* invalidate TLB */
+ "mcr p15, 0, r0, c7, c7,0 \n" /* invalidate both icache and dcache */
+ "mrc p15, 0, r0, c1, c0, 0 \n"
+ "orr r0, r0, #1 \n" /* enable mmu bit, icache and dcache */
+ "orr r0, r0, #1<<2 \n" /* enable dcache */
+ "orr r0, r0, #1<<12 \n" /* enable icache */
+ "mcr p15, 0, r0, c1, c0, 0 \n"
+ "nop \n"
+ "nop \n"
+ "nop \n"
+ "nop \n"
+ "bx lr \n"
+ :
+ :
+ : "r0"
+ );
}
#if CONFIG_CPU == IMX31L
@@ -105,35 +146,36 @@ void invalidate_dcache_range(const void *base, unsigned int size) {
unsigned int addr = (((int) base) & ~31); /* Align start to cache line*/
unsigned int end = ((addr+size) & ~31)+64; /* Align end to cache line, pad */
asm volatile(
-"inv_start: \n"
- "mcr p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
- "add %0, %0, #32 \n"
- "cmp %0, %1 \n"
- "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
- "addne %0, %0, #32 \n"
- "cmpne %0, %1 \n"
- "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
- "addne %0, %0, #32 \n"
- "cmpne %0, %1 \n"
- "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
- "addne %0, %0, #32 \n"
- "cmpne %0, %1 \n"
- "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
- "addne %0, %0, #32 \n"
- "cmpne %0, %1 \n"
- "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
- "addne %0, %0, #32 \n"
- "cmpne %0, %1 \n"
- "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
- "addne %0, %0, #32 \n"
- "cmpne %0, %1 \n"
- "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
- "addne %0, %0, #32 \n"
- "cmpne %0, %1 \n"
- "bne inv_start \n"
- "mov %0, #0\n"
- "mcr p15,0,%0,c7,c10,4\n" /* Drain write buffer */
- : : "r" (addr), "r" (end));
+ "inv_start: \n"
+ "mcr p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
+ "add %0, %0, #32 \n"
+ "cmp %0, %1 \n"
+ "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
+ "addne %0, %0, #32 \n"
+ "cmpne %0, %1 \n"
+ "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
+ "addne %0, %0, #32 \n"
+ "cmpne %0, %1 \n"
+ "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
+ "addne %0, %0, #32 \n"
+ "cmpne %0, %1 \n"
+ "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
+ "addne %0, %0, #32 \n"
+ "cmpne %0, %1 \n"
+ "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
+ "addne %0, %0, #32 \n"
+ "cmpne %0, %1 \n"
+ "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
+ "addne %0, %0, #32 \n"
+ "cmpne %0, %1 \n"
+ "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
+ "addne %0, %0, #32 \n"
+ "cmpne %0, %1 \n"
+ "bne inv_start \n"
+ "mov %0, #0\n"
+ "mcr p15,0,%0,c7,c10,4\n" /* Drain write buffer */
+ : : "r" (addr), "r" (end)
+ );
}
#endif
@@ -239,41 +281,20 @@ void __attribute__((naked)) clean_dcache(void)
/* Cleans entire DCache */
void clean_dcache(void)
{
- unsigned int index, addr;
+ unsigned int index, addr, low;
- for(index = 0; index <= 63; index++) {
- addr = (0 << 5) | (index << 26);
- asm volatile(
- "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
- : : "r" (addr));
- addr = (1 << 5) | (index << 26);
- asm volatile(
- "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
- : : "r" (addr));
- addr = (2 << 5) | (index << 26);
- asm volatile(
- "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
- : : "r" (addr));
- addr = (3 << 5) | (index << 26);
- asm volatile(
- "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
- : : "r" (addr));
- addr = (4 << 5) | (index << 26);
- asm volatile(
- "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
- : : "r" (addr));
- addr = (5 << 5) | (index << 26);
- asm volatile(
- "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
- : : "r" (addr));
- addr = (6 << 5) | (index << 26);
- asm volatile(
- "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
- : : "r" (addr));
- addr = (7 << 5) | (index << 26);
- asm volatile(
- "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
- : : "r" (addr));
+ for(index = 0; index <= 63; index++)
+ {
+ for(low = 0;low <= 7; low++)
+ {
+ addr = (index << 26) | (low << 5);
+ asm volatile
+ (
+ "mcr p15, 0, %[addr], c7, c10, 2 \n" /* Clean this entry by index */
+ :
+ : [addr] "r" (addr)
+ );
+ }
}
}
#endif