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