diff options
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/imx31/crt0.S | 236 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/avic-imx31.c | 26 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/avic-imx31.h | 4 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c | 32 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/system-imx31.c | 14 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/system-target.h | 14 |
6 files changed, 186 insertions, 140 deletions
diff --git a/firmware/target/arm/imx31/crt0.S b/firmware/target/arm/imx31/crt0.S index 9d50888536..4e79cd1352 100644 --- a/firmware/target/arm/imx31/crt0.S +++ b/firmware/target/arm/imx31/crt0.S | |||
@@ -23,9 +23,16 @@ | |||
23 | 23 | ||
24 | .global start | 24 | .global start |
25 | start: | 25 | start: |
26 | b newstart | 26 | /* Exception vectors */ |
27 | .space 4*12 /* Space for low vectors */ | 27 | b newstart |
28 | 28 | b undef_instr_handler | |
29 | b software_int_handler | ||
30 | b prefetch_abort_handler | ||
31 | b data_abort_handler | ||
32 | b reserved_handler | ||
33 | b irq_handler | ||
34 | b fiq_handler | ||
35 | .balign 0x40, 0x6B | ||
29 | 36 | ||
30 | /* Arm bootloader and startup code based on startup.s from the iPodLinux loader | 37 | /* Arm bootloader and startup code based on startup.s from the iPodLinux loader |
31 | * | 38 | * |
@@ -34,28 +41,41 @@ start: | |||
34 | * | 41 | * |
35 | */ | 42 | */ |
36 | 43 | ||
44 | /* Initially this code is running at VA 0x8a000000 (PA 0x82000000). | ||
45 | * The mapping stub is copied to IRAM (0x1fffc000) and jumps to the final | ||
46 | * VA remapping starting at 0x01f00000 because the 1MB section containing | ||
47 | * the framebuffer at PA 0x81000000 is skipped in the remapping giving 63MB | ||
48 | * of contiguous RAM for the firmware. The TTB is placed at the end of said | ||
49 | * section. | ||
50 | * | ||
51 | * For now this will be done in bootloader, especially if usb will be needed | ||
52 | * within the bootloader to load the main firmware file. Interrupts will be | ||
53 | * needed for this (whether they be swi or irq). | ||
54 | */ | ||
37 | newstart: | 55 | newstart: |
38 | msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */ | 56 | msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */ |
39 | 57 | ||
40 | #ifdef BOOTLOADER | 58 | #ifdef BOOTLOADER |
41 | ldr r2, =remap_start | 59 | adr r2, remap_start /* Load PC-relative labels */ |
42 | ldr r3, =remap_end | 60 | adr r3, remap_end |
43 | ldr r5, =TTB_BASE_ADDR /* TTB pointer */ | 61 | ldr r5, =TTB_BASE_ADDR /* TTB pointer */ |
44 | ldr r6, =IRAM_BASE_ADDR | 62 | ldr r6, =IRAM_BASE_ADDR |
45 | mov r1, r6 | 63 | mov r1, r6 |
46 | 64 | ||
47 | 1: | 65 | 1: /* Copy remapping stub to IRAM */ |
48 | cmp r3, r2 | 66 | cmp r3, r2 |
49 | ldrhi r4, [r2], #4 | 67 | ldrhi r4, [r2], #4 |
50 | strhi r4, [r1], #4 | 68 | strhi r4, [r1], #4 |
51 | bhi 1b | 69 | bhi 1b |
52 | 70 | ||
53 | mov pc, r6 | 71 | mov pc, r6 |
54 | 72 | ||
73 | /* Remapping stub. No absolute addresses may be used until after the | ||
74 | * remapping is complete. */ | ||
55 | remap_start: | 75 | remap_start: |
56 | mrc p15, 0, r3, c1, c0, 0 /* perform writeback if D cache is enabled */ | 76 | mrc p15, 0, r3, c1, c0, 0 /* perform writeback if D cache is enabled */ |
57 | tst r3, #(1 << 2) | 77 | tst r3, #(1 << 2) /* dcache? */ |
58 | tsteq r3, #(1 << 12) | 78 | tsteq r3, #(1 << 12) /* or icache? */ |
59 | mcrne p15, 0, r0, c7, c10, 0 /* clean dcache */ | 79 | mcrne p15, 0, r0, c7, c10, 0 /* clean dcache */ |
60 | mov r0, #0 | 80 | mov r0, #0 |
61 | mcrne p15, 0, r0, c7, c7, 0 /* invalidate I cache and D cache */ | 81 | mcrne p15, 0, r0, c7, c7, 0 /* invalidate I cache and D cache */ |
@@ -77,9 +97,9 @@ remap_start: | |||
77 | str r1, [r0, #L2_CACHE_CTL_REG] | 97 | str r1, [r0, #L2_CACHE_CTL_REG] |
78 | 98 | ||
79 | /* Disble L1 caches and memory manager */ | 99 | /* Disble L1 caches and memory manager */ |
80 | bic r3, r3, #(1 << 1) | 100 | bic r3, r3, #(1 << 12) /* L1 I-cache disabled */ |
81 | bic r3, r3, #(1 << 2) | 101 | bic r3, r3, #((1 << 2) | /* L1 D-cache disabled */ \ |
82 | bic r3, r3, #(1 << 12) | 102 | (1 << 0)) /* MMU disabled */ |
83 | mcr p15, 0, r3, c1, c0, 0 | 103 | mcr p15, 0, r3, c1, c0, 0 |
84 | 104 | ||
85 | /* | 105 | /* |
@@ -96,92 +116,97 @@ remap_start: | |||
96 | /* Invalidate L2 */ | 116 | /* Invalidate L2 */ |
97 | mov r1, #0x000000FF | 117 | mov r1, #0x000000FF |
98 | str r1, [r0, #L2_CACHE_INV_WAY_REG] | 118 | str r1, [r0, #L2_CACHE_INV_WAY_REG] |
99 | L2_loop: | 119 | 1: |
100 | /* Poll Invalidate By Way register */ | 120 | /* Poll Invalidate By Way register */ |
101 | ldr r2, [r0, #L2_CACHE_INV_WAY_REG] | 121 | ldr r1, [r0, #L2_CACHE_INV_WAY_REG] |
102 | cmp r2, #0 | 122 | cmp r1, #0 |
103 | bne L2_loop | 123 | bne 1b |
104 | 124 | ||
105 | /*** End of L2 operations ***/ | 125 | /*** End of L2 operations ***/ |
106 | 126 | ||
107 | /*remap memory as well as exception vectors*/ | ||
108 | /*for now this will be done in bootloader, especially | ||
109 | if usb will be needed within the bootloader to load the | ||
110 | main firmware file. Interrupts will be needed for this | ||
111 | (whether they be swi or irq)*/ | ||
112 | |||
113 | /* TTB Initialisation */ | 127 | /* TTB Initialisation */ |
114 | mov r3, r5 | 128 | mov r2, r5 |
115 | add r2, r3, #TTB_SIZE | 129 | add r3, r5, #TTB_SIZE |
116 | mov r1, #0 | 130 | mov r1, #0 |
117 | ttbloop: | 131 | 1: |
118 | str r1, [r3], #4 | 132 | str r1, [r2], #4 |
119 | cmp r3, r2 | 133 | cmp r2, r3 |
120 | bne ttbloop | 134 | blo 1b |
121 | 135 | ||
122 | /* Set TTB base address */ | 136 | /* Set TTB base address */ |
123 | mov r3, r5 | 137 | mcr p15, 0, r5, c2, c0, 0 |
124 | mcr p15, 0, r3, c2, c0, 0 | 138 | |
125 | /* Set all domains to manager status */ | 139 | /* Set all domains to manager status */ |
126 | mvn r3, #0 | 140 | mvn r0, #0 |
127 | mcr p15, 0, r3, c3, c0, 0 | 141 | mcr p15, 0, r0, c3, c0, 0 |
128 | 142 | ||
129 | /* Set page tables */ | 143 | /* Set page tables */ |
130 | 144 | ||
131 | /* Map each memory loc to itself, no cache */ | 145 | /* Map each memory loc to itself, no cache */ |
132 | mov r1, #0 /* Physical address */ | 146 | /* Physical address = 0x0 */ |
133 | mov r3, r5 | 147 | mov r1, #(1 << 10) /* superuser - r/w, user - no access */ |
134 | add r4, r3, #TTB_SIZE /* End position */ | 148 | orr r1, r1, #((0 << 5) | /* domain 0th */ \ |
135 | maploop1: | 149 | (1 << 4) | /* should be "1" */ \ |
136 | mov r2, r1 | 150 | (1 << 1)) /* Section signature */ |
137 | orr r2, r2, #(1<<10) /* superuser - r/w, user - no access */ | 151 | mov r2, r5 |
138 | //orr r2, r2, #(0<<5) /* domain 0th */ | 152 | add r3, r5, #TTB_SIZE /* End position */ |
139 | orr r2, r2, #(1<<4) /* should be "1" */ | 153 | 1: |
140 | orr r2, r2, #(1<<1) /* Section signature */ | 154 | str r1, [r2], #4 |
141 | str r2, [r3], #4 | 155 | add r1, r1, #(1 << 20) /* Next MB */ |
142 | add r1, r1, #(1<<20) | 156 | cmp r2, r3 |
143 | cmp r3, r4 | 157 | blo 1b |
144 | bne maploop1 | 158 | sub r1, r1, #TTB_SIZE/4*(1 << 20) /* Back up */ |
145 | 159 | ||
146 | /* Map 0x80000000 -> 0x0, cached */ | 160 | /* Map 0x80000000 -> 0x0, cached */ |
147 | mov r1, #0x80000000 /* Physical address */ | 161 | mov r2, r5 /* TTB pointer */ |
148 | mov r3, r5 /* TTB pointer */ | 162 | add r3, r5, #63*4 /* End position */ |
149 | add r4, r3, #64*4 /* End position */ | 163 | orr r1, r1, #0x80000000 /* Physical address */ |
150 | maploop2: | 164 | orr r1, r1, #((1 << 3) | /* cache flag */ \ |
151 | mov r2, r1 | 165 | (1 << 2)) /* buffer flag */ |
152 | orr r2, r2, #(1<<10) /* superuser - r/w, user - no access */ | 166 | 1: |
153 | //orr r2, r2, #(0<<5) /* domain 0th */ | 167 | str r1, [r2], #4 |
154 | orr r2, r2, #(1<<4) /* should be "1" */ | 168 | add r1, r1, #(1 << 20) |
155 | orr r2, r2, #(1<<3) /* cache flags */ | 169 | and r4, r1, #0x0ff00000 |
156 | orr r2, r2, #(1<<2) /* more cache stuff */ | 170 | cmp r4, #0x00100000 /* Skip framebuffer */ |
157 | orr r2, r2, #(1<<1) /* Section signature */ | 171 | addeq r1, r1, #(1 << 20) |
158 | str r2, [r3], #4 | 172 | cmp r2, r3 |
159 | add r1, r1, #(1<<20) | 173 | blo 1b |
160 | bic r6, r1, #0xf0000000 | ||
161 | cmp r6, #0x00100000 /* Skip framebuffer */ | ||
162 | addeq r1, r1, #(1<<20) | ||
163 | cmp r3, r4 | ||
164 | bne maploop2 | ||
165 | 174 | ||
166 | /* Enable MMU */ | 175 | /* Enable MMU */ |
167 | 176 | ||
168 | mov r0, #0 | 177 | mov r0, #0 |
169 | mcr p15, 0, r0, c8, c7, 0 /* Invalidate TLB */ | 178 | mcr p15, 0, r0, c8, c7, 0 /* Invalidate TLB */ |
170 | mcr p15, 0, r0, c7, c7, 0 /* Invalidate icache and dcache */ | 179 | mcr p15, 0, r0, c7, c7, 0 /* Invalidate icache and dcache */ |
171 | #if 1 | 180 | |
181 | /* Auxilliary control register */ | ||
172 | mrc p15, 0, r0, c1, c0, 1 | 182 | mrc p15, 0, r0, c1, c0, 1 |
173 | bic r0, r0, #0x70 | 183 | bic r0, r0, #((1 << 6) | /* Restrict cache size OFF */ \ |
174 | bic r0, r0, #0x07 | 184 | (1 << 5) | /* Enable block tranfer cache operations */ \ |
185 | (1 << 4) | /* Clean+Invalidate cache operation ON */ \ | ||
186 | (1 << 3)) /* Round-robin micro TLB replacement */ | ||
187 | orr r0, r0, #((1 << 2) | /* Static branch prediction ON */ \ | ||
188 | (1 << 1) | /* Dynamic branch prediction ON */ \ | ||
189 | (1 << 0)) /* Return stack enabled */ | ||
175 | mcr p15, 0, r0, c1, c0, 1 | 190 | mcr p15, 0, r0, c1, c0, 1 |
176 | #endif | 191 | |
192 | /* Control register */ | ||
177 | mrc p15, 0, r0, c1, c0, 0 | 193 | mrc p15, 0, r0, c1, c0, 0 |
178 | orr r0, r0, #(1 << 0) /* enable mmu bit */ | 194 | bic r0, r0, #((1 << 29) | /* AF by AP disabled */ \ |
179 | orr r0, r0, #(1 << 2) /* enable dcache */ | 195 | (1 << 28) | /* TEX remap disabled */ \ |
180 | bic r0, r0, #(1 << 11) /* no program flow prediction */ | 196 | (1 << 24) | /* Vectored interrupt OFF */ \ |
181 | orr r0, r0, #(1 << 12) /* enable icache */ | 197 | (1 << 23) | /* Sub AP bits enabled (compatible) */ \ |
182 | bic r0, r0, #(1 << 13) /* low vectors */ | 198 | (1 << 22)) /* Unaligned access support disabled */ |
183 | orr r0, r0, #(1 << 14) /* Round-robin */ | 199 | bic r0, r0, #((1 << 21) | /* All performance features enabled */ \ |
184 | bic r0, r0, #(1 << 21) /* No low latency interrupt */ | 200 | (1 << 15)) /* Loads to PC set T bit */ |
201 | bic r0, r0, #((1 << 13) | /* Low vectors */ \ | ||
202 | (1 << 11)) /* Program flow prediction disabled (for now) */ | ||
203 | orr r0, r0, #((1 << 14) | /* Round-robin replacement for I/D caches */ \ | ||
204 | (1 << 12) | /* L1 I-cache enabled */ \ | ||
205 | (1 << 9) | /* ROM protection enabled */ \ | ||
206 | (1 << 8)) /* MMU protection enabled */ | ||
207 | orr r0, r0, #((1 << 2) | /* L1 D-cache enabled */ \ | ||
208 | (1 << 1) | /* Strict alignment enabled */ \ | ||
209 | (1 << 0)) /* MMU enabled */ | ||
185 | mcr p15, 0, r0, c1, c0, 0 | 210 | mcr p15, 0, r0, c1, c0, 0 |
186 | nop | 211 | nop |
187 | nop | 212 | nop |
@@ -194,8 +219,8 @@ remap_end: | |||
194 | 219 | ||
195 | #endif /* BOOTLOADER */ | 220 | #endif /* BOOTLOADER */ |
196 | 221 | ||
197 | #ifndef BOOTLOADER | 222 | #ifdef BOOTLOADER |
198 | /* Copy exception handler code to address 0 */ | 223 | /* Copy bootloader exception handler code to address 0 */ |
199 | ldr r2, =_vectorsstart | 224 | ldr r2, =_vectorsstart |
200 | ldr r3, =_vectorsend | 225 | ldr r3, =_vectorsend |
201 | ldr r4, =_vectorscopy | 226 | ldr r4, =_vectorscopy |
@@ -204,7 +229,7 @@ remap_end: | |||
204 | ldrhi r5, [r4], #4 | 229 | ldrhi r5, [r4], #4 |
205 | strhi r5, [r2], #4 | 230 | strhi r5, [r2], #4 |
206 | bhi 1b | 231 | bhi 1b |
207 | 232 | #else | |
208 | /* Zero out IBSS */ | 233 | /* Zero out IBSS */ |
209 | ldr r2, =_iedata | 234 | ldr r2, =_iedata |
210 | ldr r3, =_iend | 235 | ldr r3, =_iend |
@@ -261,47 +286,41 @@ remap_end: | |||
261 | msr cpsr_c, #0xd3 | 286 | msr cpsr_c, #0xd3 |
262 | bl main | 287 | bl main |
263 | 288 | ||
264 | /* Exception handlers. Will be copied to address 0 after memory remapping */ | 289 | #ifdef BOOTLOADER |
265 | _vectorstart: | 290 | /* Exception vectors with absolute jumps for bootloader */ |
266 | .section .vectors,"aw" | 291 | .section .vectors,"aw" |
267 | ldr pc, [pc, #24] | 292 | ldr pc, [pc, #24] |
268 | ldr pc, [pc, #24] | 293 | ldr pc, [pc, #24] |
269 | ldr pc, [pc, #24] | 294 | ldr pc, [pc, #24] |
270 | ldr pc, [pc, #24] | 295 | ldr pc, [pc, #24] |
271 | ldr pc, [pc, #24] | 296 | ldr pc, [pc, #24] |
272 | ldr pc, [pc, #24] | 297 | ldr pc, [pc, #24] |
273 | ldr pc, [pc, #24] | 298 | ldr pc, [pc, #24] |
274 | ldr pc, [pc, #24] | 299 | ldr pc, [pc, #24] |
275 | 300 | .word newstart | |
276 | /* Exception vectors */ | 301 | .word undef_instr_handler |
277 | .global vectors | 302 | .word software_int_handler |
278 | vectors: | 303 | .word prefetch_abort_handler |
279 | .word start | 304 | .word data_abort_handler |
280 | .word undef_instr_handler | 305 | .word reserved_handler |
281 | .word software_int_handler | 306 | .word irq_handler |
282 | .word prefetch_abort_handler | 307 | .word fiq_handler |
283 | .word data_abort_handler | 308 | #endif /* BOOTLOADER */ |
284 | .word reserved_handler | ||
285 | .word irq_handler | ||
286 | .word fiq_handler | ||
287 | 309 | ||
288 | .text | 310 | .text |
289 | |||
290 | .global UIE | 311 | .global UIE |
291 | 312 | ||
292 | /* All illegal exceptions call into UIE with exception address as first | 313 | /* All illegal exceptions call into UIE with exception address as first |
293 | parameter. This is calculated differently depending on which exception | 314 | * parameter. This is calculated differently depending on which exception |
294 | we're in. Second parameter is exception number, used for a string lookup | 315 | * we're in. Second parameter is exception number, used for a string lookup |
295 | in UIE. | 316 | * in UIE. */ |
296 | */ | ||
297 | undef_instr_handler: | 317 | undef_instr_handler: |
298 | mov r0, lr | 318 | mov r0, lr |
299 | mov r1, #0 | 319 | mov r1, #0 |
300 | b UIE | 320 | b UIE |
301 | 321 | ||
302 | /* We run supervisor mode most of the time, and should never see a software | 322 | /* We run supervisor mode most of the time, and should never see a software |
303 | exception being thrown. Perhaps make it illegal and call UIE? | 323 | * exception being thrown. Perhaps make it illegal and call UIE? */ |
304 | */ | ||
305 | software_int_handler: | 324 | software_int_handler: |
306 | reserved_handler: | 325 | reserved_handler: |
307 | movs pc, lr | 326 | movs pc, lr |
@@ -316,11 +335,6 @@ data_abort_handler: | |||
316 | mov r1, #2 | 335 | mov r1, #2 |
317 | b UIE | 336 | b UIE |
318 | 337 | ||
319 | #ifdef BOOTLOADER | ||
320 | UIE: | ||
321 | b UIE | ||
322 | #endif | ||
323 | |||
324 | /* 256 words of IRQ stack */ | 338 | /* 256 words of IRQ stack */ |
325 | .space 256*4 | 339 | .space 256*4 |
326 | irq_stack: | 340 | irq_stack: |
diff --git a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c index fa74d3bb9f..b04b22911a 100644 --- a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c | |||
@@ -84,18 +84,24 @@ void __attribute__((naked)) fiq_handler(void) | |||
84 | 84 | ||
85 | void avic_init(void) | 85 | void avic_init(void) |
86 | { | 86 | { |
87 | int i; | ||
88 | |||
87 | /* Disable all interrupts and set to unhandled */ | 89 | /* Disable all interrupts and set to unhandled */ |
88 | avic_disable_int(ALL); | 90 | avic_disable_int(ALL); |
89 | 91 | ||
92 | /* Reset AVIC control */ | ||
93 | INTCNTL = 0; | ||
94 | |||
90 | /* Init all interrupts to type IRQ */ | 95 | /* Init all interrupts to type IRQ */ |
91 | avic_set_int_type(ALL, IRQ); | 96 | avic_set_int_type(ALL, IRQ); |
92 | 97 | ||
98 | /* Set all normal to lowest priority */ | ||
99 | for (i = 0; i < 8; i++) | ||
100 | NIPRIORITY(i) = 0; | ||
101 | |||
93 | /* Set NM bit to enable VIC */ | 102 | /* Set NM bit to enable VIC */ |
94 | INTCNTL |= INTCNTL_NM; | 103 | INTCNTL |= INTCNTL_NM; |
95 | 104 | ||
96 | /* Enable IRQ/FIQ in imx31 INTCNTL reg */ | ||
97 | INTCNTL &= ~(INTCNTL_ABFEN | INTCNTL_NIDIS | INTCNTL_FIDIS); | ||
98 | |||
99 | /* Enable VE bit in CP15 Control reg to enable VIC */ | 105 | /* Enable VE bit in CP15 Control reg to enable VIC */ |
100 | asm volatile ( | 106 | asm volatile ( |
101 | "mrc p15, 0, r0, c1, c0, 0 \n" | 107 | "mrc p15, 0, r0, c1, c0, 0 \n" |
@@ -104,11 +110,20 @@ void avic_init(void) | |||
104 | : : : "r0"); | 110 | : : : "r0"); |
105 | 111 | ||
106 | /* Enable normal interrupts at all priorities */ | 112 | /* Enable normal interrupts at all priorities */ |
107 | NIMASK = 16; | 113 | NIMASK = 0x1f; |
114 | } | ||
115 | |||
116 | void avic_set_int_priority(enum IMX31_INT_LIST ints, | ||
117 | unsigned long ni_priority) | ||
118 | { | ||
119 | volatile unsigned long *reg = &NIPRIORITY((63 - ints) / 8); | ||
120 | unsigned int shift = 4*(ints % 8); | ||
121 | unsigned long mask = 0xful << shift; | ||
122 | *reg = (*reg & ~mask) | ((ni_priority << shift) & mask); | ||
108 | } | 123 | } |
109 | 124 | ||
110 | void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, | 125 | void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, |
111 | void (*handler)(void)) | 126 | unsigned long ni_priority, void (*handler)(void)) |
112 | { | 127 | { |
113 | int oldstatus = set_interrupt_status(IRQ_FIQ_DISABLED, | 128 | int oldstatus = set_interrupt_status(IRQ_FIQ_DISABLED, |
114 | IRQ_FIQ_STATUS); | 129 | IRQ_FIQ_STATUS); |
@@ -118,6 +133,7 @@ void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, | |||
118 | avic_set_int_type(ints, intstype); | 133 | avic_set_int_type(ints, intstype); |
119 | VECTOR(ints) = (long)handler; | 134 | VECTOR(ints) = (long)handler; |
120 | INTENNUM = ints; | 135 | INTENNUM = ints; |
136 | avic_set_int_priority(ints, ni_priority); | ||
121 | } | 137 | } |
122 | 138 | ||
123 | set_interrupt_status(oldstatus, IRQ_FIQ_STATUS); | 139 | set_interrupt_status(oldstatus, IRQ_FIQ_STATUS); |
diff --git a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h index 29a3ec8dd0..7bb7c09da7 100644 --- a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h +++ b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h | |||
@@ -49,7 +49,9 @@ enum IMX31_INT_LIST | |||
49 | 49 | ||
50 | void avic_init(void); | 50 | void avic_init(void); |
51 | void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, | 51 | void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, |
52 | void (*handler)(void)); | 52 | unsigned long ni_priority, void (*handler)(void)); |
53 | void avic_set_int_priority(enum IMX31_INT_LIST ints, | ||
54 | unsigned long ni_priority); | ||
53 | void avic_disable_int(enum IMX31_INT_LIST ints); | 55 | void avic_disable_int(enum IMX31_INT_LIST ints); |
54 | void avic_set_int_type(enum IMX31_INT_LIST ints, enum INT_TYPE intstype); | 56 | void avic_set_int_type(enum IMX31_INT_LIST ints, enum INT_TYPE intstype); |
55 | #endif | 57 | #endif |
diff --git a/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c b/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c index 3c44a156b0..c2fddc40a7 100644 --- a/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c | |||
@@ -7,7 +7,6 @@ | |||
7 | 7 | ||
8 | extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); | 8 | extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); |
9 | 9 | ||
10 | #ifndef BOOTLOADER | ||
11 | static __attribute__((interrupt("IRQ"))) void EPIT1_HANDLER(void) | 10 | static __attribute__((interrupt("IRQ"))) void EPIT1_HANDLER(void) |
12 | { | 11 | { |
13 | int i; | 12 | int i; |
@@ -23,14 +22,11 @@ static __attribute__((interrupt("IRQ"))) void EPIT1_HANDLER(void) | |||
23 | 22 | ||
24 | current_tick++; | 23 | current_tick++; |
25 | } | 24 | } |
26 | #endif | ||
27 | 25 | ||
28 | void tick_start(unsigned int interval_in_ms) | 26 | void tick_start(unsigned int interval_in_ms) |
29 | { | 27 | { |
30 | EPITCR1 &= ~(1 << 0); /* Disable the counter */ | 28 | CLKCTL_CGR0 |= (3 << 6); /* EPIT1 module clock ON - before writing regs! */ |
31 | EPITCR1 |= (1 << 16); /* Reset */ | 29 | EPITCR1 &= ~((1 << 2) | (1 << 0)); /* Disable the counter */ |
32 | |||
33 | CLKCTL_CGR0 |= (0x3 << 6); /* Clock ON */ | ||
34 | CLKCTL_WIMR0 &= ~(1 << 23); /* Clear wakeup mask */ | 30 | CLKCTL_WIMR0 &= ~(1 << 23); /* Clear wakeup mask */ |
35 | 31 | ||
36 | /* NOTE: This isn't really accurate yet but it's close enough to work | 32 | /* NOTE: This isn't really accurate yet but it's close enough to work |
@@ -39,17 +35,21 @@ void tick_start(unsigned int interval_in_ms) | |||
39 | /* CLKSRC=32KHz, EPIT Output Disconnected, Enabled | 35 | /* CLKSRC=32KHz, EPIT Output Disconnected, Enabled |
40 | * prescale 1/32, Reload from modulus register, Compare interrupt enabled, | 36 | * prescale 1/32, Reload from modulus register, Compare interrupt enabled, |
41 | * Count from load value */ | 37 | * Count from load value */ |
42 | EPITCR1 = (0x3 << 24) | (1 << 19) | (32 << 4) | | 38 | EPITCR1 = (3 << 24) | (1 << 19) | (32 << 4) | |
43 | (1 << 3) | (1 << 2) | (1 << 1); | 39 | (1 << 3) | (1 << 2) | (1 << 1); |
44 | #ifndef BOOTLOADER | ||
45 | EPITLR1 = interval_in_ms; | ||
46 | EPITCMPR1 = 0; /* Event when counter reaches 0 */ | ||
47 | avic_enable_int(EPIT1, IRQ, EPIT1_HANDLER); | ||
48 | #else | ||
49 | (void)interval_in_ms; | ||
50 | #endif | ||
51 | EPITSR1 = 1; /* Clear any pending interrupt after | ||
52 | enabling the vector */ | ||
53 | 40 | ||
41 | EPITLR1 = interval_in_ms; /* Count down from interval */ | ||
42 | EPITCMPR1 = 0; /* Event when counter reaches 0 */ | ||
43 | EPITSR1 = 1; /* Clear any pending interrupt */ | ||
44 | avic_enable_int(EPIT1, IRQ, 7, EPIT1_HANDLER); | ||
54 | EPITCR1 |= (1 << 0); /* Enable the counter */ | 45 | EPITCR1 |= (1 << 0); /* Enable the counter */ |
55 | } | 46 | } |
47 | |||
48 | #ifdef BOOTLOADER | ||
49 | void tick_stop(void) | ||
50 | { | ||
51 | avic_disable_int(EPIT1); /* Disable insterrupt */ | ||
52 | EPITCR1 &= ~((1 << 2) | (1 << 0)); /* Disable counter */ | ||
53 | CLKCTL_CGR0 &= ~(3 << 6); /* EPIT1 module clock OFF */ | ||
54 | } | ||
55 | #endif | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c index ed5a26cd6e..c77c923d60 100644 --- a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c | |||
@@ -1,6 +1,7 @@ | |||
1 | #include "kernel.h" | 1 | #include "kernel.h" |
2 | #include "system.h" | 2 | #include "system.h" |
3 | #include "panic.h" | 3 | #include "panic.h" |
4 | #include "avic-imx31.h" | ||
4 | #include "mmu-imx31.h" | 5 | #include "mmu-imx31.h" |
5 | #include "system-target.h" | 6 | #include "system-target.h" |
6 | #include "lcd.h" | 7 | #include "lcd.h" |
@@ -19,11 +20,20 @@ void system_reboot(void) | |||
19 | 20 | ||
20 | void system_init(void) | 21 | void system_init(void) |
21 | { | 22 | { |
22 | #ifndef BOOTLOADER | 23 | /* MCR WFI enables wait mode */ |
24 | CLKCTL_CCMR &= ~(3 << 14); | ||
23 | avic_init(); | 25 | avic_init(); |
24 | #endif | ||
25 | } | 26 | } |
26 | 27 | ||
28 | #ifdef BOOTLOADER | ||
29 | void system_prepare_fw_start(void) | ||
30 | { | ||
31 | set_interrupt_status(IRQ_FIQ_DISABLED, IRQ_FIQ_STATUS); | ||
32 | avic_disable_int(ALL); | ||
33 | tick_stop(); | ||
34 | } | ||
35 | #endif | ||
36 | |||
27 | inline void dumpregs(void) | 37 | inline void dumpregs(void) |
28 | { | 38 | { |
29 | asm volatile ("mov %0,r0\n\t" | 39 | asm volatile ("mov %0,r0\n\t" |
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-target.h b/firmware/target/arm/imx31/gigabeat-s/system-target.h index 1f7a2475af..327d72b7bc 100644 --- a/firmware/target/arm/imx31/gigabeat-s/system-target.h +++ b/firmware/target/arm/imx31/gigabeat-s/system-target.h | |||
@@ -33,24 +33,28 @@ static inline void udelay(unsigned int usecs) | |||
33 | #define __dbg_hw_info(...) 0 | 33 | #define __dbg_hw_info(...) 0 |
34 | #define __dbg_ports(...) 0 | 34 | #define __dbg_ports(...) 0 |
35 | 35 | ||
36 | void system_prepare_fw_start(void); | ||
37 | void tick_stop(void); | ||
38 | |||
36 | #define HAVE_INVALIDATE_ICACHE | 39 | #define HAVE_INVALIDATE_ICACHE |
37 | static inline void invalidate_icache(void) | 40 | static inline void invalidate_icache(void) |
38 | { | 41 | { |
39 | long rd = 0; | ||
40 | asm volatile( | 42 | asm volatile( |
41 | "mcr p15, 0, %0, c7, c10, 0 \n" | 43 | /* Clean and invalidate entire data cache */ |
44 | "mcr p15, 0, %0, c7, c14, 0 \n" | ||
45 | /* Invalidate entire instruction cache */ | ||
42 | "mcr p15, 0, %0, c7, c5, 0 \n" | 46 | "mcr p15, 0, %0, c7, c5, 0 \n" |
43 | : : "r"(rd) | 47 | : : "r"(0) |
44 | ); | 48 | ); |
45 | } | 49 | } |
46 | 50 | ||
47 | #define HAVE_FLUSH_ICACHE | 51 | #define HAVE_FLUSH_ICACHE |
48 | static inline void flush_icache(void) | 52 | static inline void flush_icache(void) |
49 | { | 53 | { |
50 | long rd = 0; | ||
51 | asm volatile ( | 54 | asm volatile ( |
55 | /* Clean entire data cache */ | ||
52 | "mcr p15, 0, %0, c7, c10, 0 \n" | 56 | "mcr p15, 0, %0, c7, c10, 0 \n" |
53 | : : "r"(rd) | 57 | : : "r"(0) |
54 | ); | 58 | ); |
55 | } | 59 | } |
56 | 60 | ||