imx31lk_start.S revision 1.3
1/* $NetBSD: imx31lk_start.S,v 1.3 2009/11/05 16:28:09 uebayasi Exp $ */ 2 3#include <machine/asm.h> 4#include <arm/armreg.h> 5#include <arm/arm32/pmap.h> 6#include <arm/arm32/pte.h> 7 8 9/* 10 */ 11 12#define CPWAIT_BRANCH \ 13 sub pc, pc, #4 14 15#define CPWAIT(tmp) \ 16 mrc p15, 0, tmp, c2, c0, 0 /* arbitrary read of CP15 */ ;\ 17 mov tmp, tmp /* wait for it to complete */ ;\ 18 CPWAIT_BRANCH /* branch to next insn */ 19 20 21#ifndef SDRAM_START 22#define SDRAM_START 0x80000000 23#endif 24 25#define IMX31_DCACHE_SIZE 0x4000 /* 16KB L1 */ 26 27/* 28 * L1 == "Level One" == "first-level" 29 * L2 == "Level Two" == "second-level" 30 */ 31 32 .text 33 34 .global _C_LABEL(imx31lk_start) 35_C_LABEL(imx31lk_start): 36 /* Figure out where we want to jump to when the time comes */ 37 adr r8, .Lstart 38 ldr r8, [r8] 39 40 /* 41 * set up virtual address space mapping 42 * for initial bootstrap. 43 */ 44 mov r2, #(L1_S_SIZE) /* 1MB chunks */ 45 46 /* 47 * Firmware already mapped SDRAM VA == PA. at 0x800.. 48 * now map SDRAM also at VA 0x800... 49 */ 50 mrc p15, 0, r0, c2, c0, 0 /* L1 table addr into r0 */ 51 add r0, r0, #(0x800 * 4) /* offset to 0x80000000 */ 52 53 mov r3, #SDRAM_START /* map to 0x800.. */ 54 orr r3, r3, #(L1_S_AP(AP_KRW)) /* the usual perms & stuff */ 55 orr r3, r3, #(L1_TYPE_S) 56 orr r3, r3, #(L1_S_DOM(PMAP_DOMAIN_KERNEL)) 57 58 mov r1, #0x80 /* 128 1MB entries */ 591: 60 /* and looplooploop */ 61 str r3, [r0], #4 62 add r3, r3, r2 63 subs r1, r1, #1 64 bgt 1b 65 66 /* 67 * Map an L1 section for each device to make this easy. 68 */ 69 /* UART1 */ 70 mrc p15, 0, r0, c2, c0, 0 /* L1 table addr into r0 */ 71 add r0, r0, #(0xfd0 * 4) /* offset to 0xfd000000 */ 72 73 mov r3, #0x43000000 74 orr r3, r3, #0x00f00000 75 orr r3, r3, #(L1_S_AP(AP_KRW)) 76 orr r3, r3, #(L1_TYPE_S) 77 orr r3, r3, #(L1_S_DOM(PMAP_DOMAIN_KERNEL)) 78 str r3, [r0], #4 /* note autoinc */ 79 80 /* etc, TBD... */ 81 82 /* 83 * Make domain control go full art. 84 */ 85 mov r0, #0xffffffff 86 mcr p15, 0, r0, c3, c0, 0 87 88 /* 89 * Now let's clean the cache again to make sure everything 90 * is in place. 91 * 92 * XXX: should this take into account the XScale cache clean bug? 93 */ 94 mov r3, #(IMX31_DCACHE_SIZE) 95 subs r3, r3, #32 961: 97 mcr p15, 0, r3, c7, c10, 2 98 subs r3, r3, #32 99 bne 1b 100 CPWAIT(r3) 101 102 /* Drain write buffer */ 103 mcr p15, 0, r6, c7, c10, 4 104 105 /* Invalidate TLBs just to be sure */ 106 mcr p15, 0, r0, c8, c7, 0 107 108 /* 109 * You are standing at the gate to NetBSD. --More-- 110 * Unspeakable cruelty and harm lurk down there. --More-- 111 * Are you sure you want to enter? 112 */ 113 adr r8, .Lstart 114 ldr r8, [r8] 115 mov pc, r8 /* So be it */ 116 117/* symbol to use for address calculation in the right VA */ 118.Lstart: 119 .word start 120 121 122/* 123 * Calculate size of kernel to copy. Don't bother to copy bss, 124 * although I guess the CPU could use the warmup exercise ... 125 */ 126.Lcopy_size: 127 .word _edata - _C_LABEL(imx31lk_start) 128 129