Kernel - Slight reworks to timer code
[tpg/acess2.git] / Kernel / arch / armv7 / start.S
1
2 #include "include/assembly.h"
3 #include "include/options.h"
4
5 @
6 @ Exception defs taken from ARM DDI 0406B
7
8 .section .init
9 interrupt_vector_table:
10 ivt_reset:      b _start        @ 0x00 Reset
11 ivt_undef:      b Undef_Handler @ 0x04 #UD
12 ivt_svc:        b SVC_Handler   @ 0x08 SVC (used to be called SWI)
13 ivt_prefetch:   b PrefetchAbort @ 0x0C Prefetch abort
14 ivt_data:       b DataAbort     @ 0x10 Data abort
15 ivt_unused:     b .             @ 0x14 Not Used
16 ivt_irq:        b IRQHandler    @ 0x18 IRQ
17 ivt_fiq:        b .             @ 0x1C FIQ (Fast interrupt)
18
19 .globl _start
20 _start:
21         ldr r2, =UART0_PADDR
22         mov r1, #'A'
23         str r1, [r2]    
24
25         ldr r0, =kernel_table0-KERNEL_BASE
26         mcr p15, 0, r0, c2, c0, 1       @ Set TTBR1 to r0
27         mcr p15, 0, r0, c2, c0, 0       @ Set TTBR0 to r0 too (for identity)
28
29         mov r1, #'c'
30         str r1, [r2]    
31
32         mov r0, #1
33         mcr p15, 0, r0, c2, c0, 2       @ Set TTCR to 1 (50/50 split)
34
35         mov r1, #'e'
36         str r1, [r2]    
37         
38         mov r0, #3
39         mcr p15, 0, r0, c3, c0, 0       @ Set Domain 0 to Manager
40
41         mov r1, #'s'
42         str r1, [r2]    
43
44         @ Enable VMSA
45         mrc p15, 0, r0, c1, c0, 0
46         orr r0, r0, #1
47         orr r0, r0, #1 << 23
48         mvn r1, #1 << 2
49         and r0, r0, r1
50         mcr p15, 0, r0, c1, c0, 0
51
52         @ HACK! Disable caching
53         mrc p15, 0, r1, c1, c0, 0
54
55         ldr r2, =0xF1000000
56         mov r1, #'s'
57         str r1, [r2]    
58
59         @ Enable access faults on domains 0 & 1
60         mov r0, #0x55   @ 01010101b
61         mcr p15, 0, r0, c3, c0, 0
62
63         mov r1, #'2'
64         str r1, [r2]    
65
66         @
67         @ Check for security extensions
68         @
69         mrc p15, 0, r0, c0, c1, 1
70         and r0, #0xF0
71         @ - Present
72         ldrne r0,=KERNEL_BASE
73         mcrne p15, 0, r0, c12, c0, 0    @ Set the VBAR (brings exceptions into high memory)
74         @ - Absent
75         mrceq p15, 0, r0, c1, c0, 0     @ Set SCTLR.V
76         orreq r0, #0x2000
77         mcreq p15, 0, r0, c1, c0, 0
78
79         mov r1, #'-'
80         str r1, [r2]    
81
82         @ Prepare for interrupts
83         cps #18 @ IRQ Mode
84         ldr sp, =irqstack+0x1000        @ Set up stack
85         cps #23 @ Abort Mode
86         ldr sp, =abortstack+0x1000
87         cps #19
88
89         mov r1, #'a'
90         str r1, [r2]    
91         mov r1, #'r'
92         str r1, [r2]    
93         mov r1, #'m'
94         str r1, [r2]    
95         mov r1, #13
96         str r1, [r2]    
97         mov r1, #10
98         str r1, [r2]    
99
100 .extern bss_start
101 .extern bss_size_div_4
102 .zero_bss:
103         ldr r0, =bss_start
104         ldr r1, =bss_end
105         mov r3, #0
106 .zero_bss_loop:
107         str r3, [r0],#4
108         cmp r0, r1
109         bls .zero_bss_loop
110
111 .goto_c:
112         ldr sp, =0x80000000-8   @ Set up stack (top of user range)
113         ldr r0, =kmain
114         mov pc, r0
115 1:      b 1b    @ Infinite loop
116
117 .comm irqstack, 0x1000  @ ; 4KiB Stack
118 .comm abortstack, 0x1000        @ ; 4KiB Stack
119
120 .extern SyscallHandler
121 SVC_Handler:
122 @       sub lr, #4
123         srsdb sp!, #19  @ Save state to stack
124         cpsie ifa, #19  @ Ensure we're in supervisor with interrupts enabled (should already be there)
125         push {r0-r12}
126
127         ldr r4, [lr,#-4]
128         mvn r5, #0xFF000000
129         and r4, r5
130
131         tst r4, #0x1000 
132         bne .arm_specifics
133
134         push {r4}
135
136         mov r0, sp
137         ldr r4, =SyscallHandler
138         blx r4
139         
140 @       ldr r0, =csSyscallPrintRetAddr
141 @       ldr r1, [sp,#9*4+5*4]
142 @       ldr r4, =Log
143 @       blx r4
144         
145         pop {r2}        @ errno
146         pop {r0,r1}     @ Ret/RetHi
147         add sp, #2*4    @ Saved r2/r3
148
149         pop {r4-r12}
150         rfeia sp!       @ Pop state (actually RFEFD)
151 .arm_specifics:
152         and r4, #0xFF
153         mov r0, r4      @ Number
154         mov r1, sp      @ Arguments
155         
156         ldr r4, =ARMv7_int_HandleSyscalls
157         blx r4
158
159         add sp, #4*4
160         pop {r4-r12}
161         rfeia sp!
162
163
164 .globl gpIRQHandler
165 gpIRQHandler:   .long   0
166 IRQ_saved_sp:   .long   0
167 IRQ_saved_lr:   .long   0
168 .globl IRQHandler
169 IRQHandler:
170         sub lr, #4      @ Adjust LR to the correct value
171         srsdb sp!, #19  @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
172         cps #19
173
174         PUSH_GPRS
175
176 @       ldr r0, =csIRQ_Tag
177 @       ldr r1, =csIRQ_Fmt
178 @       ldr r4, =Log_Debug
179 @       blx r4
180         
181         @ Call the registered handler
182         ldr r0, gpIRQHandler
183         blx r0
184
185         @ Restore CPU state
186         POP_GPRS
187         cpsie i
188         rfeia sp!       @ Pop state (actually RFEFD)
189         bx lr
190
191 .globl DataAbort
192 DataAbort:
193         sub lr, #8      @ Adjust LR to the correct value
194         srsdb sp!, #23  @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
195 @       cpsid ifa, #19
196         PUSH_GPRS
197
198         mov r3, #0      @ not a prefetch abort
199         mrc p15, 0, r2, c5, c0, 0       @ Read DFSR (Data Fault Status Register) to R2
200         mrc p15, 0, r1, c6, c0, 0       @ Read DFAR (Data Fault Address Register) into R1
201         mov r0, lr      @ PC
202         ldr r4, =MM_PageFault
203         blx r4
204
205         POP_GPRS
206         rfeia sp!       @ Pop state (actually RFEFD)
207
208 .globl PrefetchAbort
209 PrefetchAbort:
210         sub lr, #4      @ Adjust LR to the correct value
211         srsdb sp!, #23  @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
212 @       cpsid ifa, #19
213         PUSH_GPRS
214
215         ldr r0, =csAbort_Tag
216         ldr r1, =csPrefetchAbort_Fmt
217 #       mov r2, lr
218         mrc p15, 0, r2, c6, c0, 2       @ Read IFAR (Instruction Fault Address Register) into R3
219         mrc p15, 0, r3, c5, c0, 1       @ Read IFSR (Instruction Fault Status Register) into R3
220         ldr r5, =Log_Error
221         blx r5
222
223 .loop:
224         wfi
225         b .loop
226 .globl Undef_Handler
227 Undef_Handler:
228         wfi
229         b Undef_Handler
230
231
232
233 .section .rodata
234 csIRQ_Tag:
235 csAbort_Tag:
236         .asciz "ARMv7"
237 csIRQ_Fmt:
238         .asciz "IRQ"
239 csDataAbort_Fmt:
240         .asciz "Data Abort - %p accessed %p, DFSR=%x Unk:%x Unk:%x"
241 csPrefetchAbort_Fmt:
242         .asciz "Prefetch Abort at %p, IFSR=%x"
243 csSyscallPrintRetAddr:
244         .asciz "Syscall ret to %p"
245
246 .section .padata
247 .globl kernel_table0
248
249 kernel_table0:
250         .long 0x00000402        @ Identity map the first 1 MiB
251         .rept 0x7FC - 1
252                 .long 0
253         .endr
254         .long user_table1_map + 0x000 - KERNEL_BASE + 1 @ 0x7FC00000
255         .long user_table1_map + 0x400 - KERNEL_BASE + 1 @ 0x7FD00000
256         .long user_table1_map + 0x800 - KERNEL_BASE + 1 @ KStacks
257         .long user_table1_map + 0xC00 - KERNEL_BASE + 1
258         @ 0x80000000 - User/Kernel split
259         .long 0x00000402        @ Map first 4 MiB to 2GiB (KRW only)
260         .long 0x00100402        @ 
261         .long 0x00200402        @ 
262         .long 0x00300402        @ 
263         .rept 0xF00 - 0x800 - 4
264                 .long 0
265         .endr
266 #if PCI_PADDR
267         .long PCI_PADDR +  0*(1 << 20) + 0x402  @ Map PCI config space
268         .long PCI_PADDR +  1*(1 << 20) + 0x402
269         .long PCI_PADDR +  2*(1 << 20) + 0x402
270         .long PCI_PADDR +  3*(1 << 20) + 0x402
271         .long PCI_PADDR +  4*(1 << 20) + 0x402
272         .long PCI_PADDR +  5*(1 << 20) + 0x402
273         .long PCI_PADDR +  6*(1 << 20) + 0x402
274         .long PCI_PADDR +  7*(1 << 20) + 0x402
275         .long PCI_PADDR +  8*(1 << 20) + 0x402
276         .long PCI_PADDR +  9*(1 << 20) + 0x402
277         .long PCI_PADDR + 10*(1 << 20) + 0x402
278         .long PCI_PADDR + 11*(1 << 20) + 0x402
279         .long PCI_PADDR + 12*(1 << 20) + 0x402
280         .long PCI_PADDR + 13*(1 << 20) + 0x402
281         .long PCI_PADDR + 14*(1 << 20) + 0x402
282         .long PCI_PADDR + 15*(1 << 20) + 0x402
283 #else
284         .rept 16
285                 .long 0
286         .endr
287 #endif
288         .long hwmap_table_0 + 0x000 - KERNEL_BASE + 1
289         .long hwmap_table_0 + 0x400 - KERNEL_BASE + 1
290         .long hwmap_table_0 + 0x800 - KERNEL_BASE + 1
291         .long hwmap_table_0 + 0xC00 - KERNEL_BASE + 1
292         .rept 0xFF8 - 0xF00 - 16 - 4
293                 .long 0
294         .endr
295         @ Page fractals
296         .long kernel_table1_map + 0x000 - KERNEL_BASE + 1
297         .long kernel_table1_map + 0x400 - KERNEL_BASE + 1
298         .long kernel_table1_map + 0x800 - KERNEL_BASE + 1
299         .long kernel_table1_map + 0xC00 - KERNEL_BASE + 1
300         .long kernel_exception_map + 0x000 - KERNEL_BASE + 1
301         .long kernel_exception_map + 0x400 - KERNEL_BASE + 1
302         .long kernel_exception_map + 0x800 - KERNEL_BASE + 1
303         .long kernel_exception_map + 0xC00 - KERNEL_BASE + 1
304
305 @ PID0 user table
306 .globl user_table1_map
307 @ User table1 data table (only the first half is needed)
308 @ - Abused to provide kernel stacks in the unused half of the table
309 user_table1_map:        @ Size = 4KiB (only 2KiB used)
310         .rept 0x800/4-1
311                 .long 0
312         .endr
313         .long user_table1_map - KERNEL_BASE + 0x13      @ ...1FF000 = 0x7FDFF000
314         @ Kernel stack zone
315         .long kernel_table0 + 0x0000 - KERNEL_BASE + 0x13       @ ...200000 = 0x7FE00000
316         .long kernel_table0 + 0x1000 - KERNEL_BASE + 0x13       @ ...201000 = 0x7FE01000
317         .rept (0x800/4)-(MM_KSTACK_SIZE/0x1000)-2
318                 .long 0
319         .endr
320         #if MM_KSTACK_SIZE != 0x2000
321         #error Kernel stack size not changed in start.S
322         #endif
323         .long stack + 0x0000 - KERNEL_BASE + 0x13       @ Kernel Stack
324         .long stack + 0x1000 - KERNEL_BASE + 0x13       @ 
325
326 .globl kernel_table1_map
327 kernel_table1_map:      @ Size = 4KiB
328         .rept (0xF00+16)/4
329                 .long 0
330         .endr
331         .long hwmap_table_0 - KERNEL_BASE + 0x13
332         .rept 0xFF8/4 - (0xF00+16)/4 - 1
333                 .long 0
334         .endr
335         .long kernel_table1_map - KERNEL_BASE + 0x13
336         .long kernel_exception_map - KERNEL_BASE + 0x13
337
338 @ Hardware mappings 
339 .globl hwmap_table_0
340 hwmap_table_0:
341         .long UART0_PADDR + 0x13        @ UART0
342         .rept 1024 - 1
343                 .long 0
344         .endr
345 .globl kernel_exception_map
346 kernel_exception_map:
347         @ Padding
348         .rept 1024-256
349                 .long 0
350         .endr
351         @ Align to nearly the end
352         .rept 256-16
353                 .long   0
354         .endr
355         .long 0x212     @ Map first page for exceptions (Kernel RO, Execute)
356         .rept 16-1-2
357                 .long 0
358         .endr
359         .long gUsertextPhysStart + 0x22 @ User .text (User RO, Kernel RW, because both is COW)
360         .long 0
361         
362 .section .padata
363 stack:
364         .space MM_KSTACK_SIZE, 0        @ Original kernel stack
365
366 // vim: ts=8 ft=armv7
367

UCC git Repository :: git.ucc.asn.au