404
|
1
|
|
2 ; This file contains the low level assembly code required for interrupt
|
|
3 ; handling and virtual memory.
|
340
|
4
|
408
|
5
|
385
|
6 section reset
|
408
|
7 ; The reset vector:
|
375
|
8
|
|
9 interrupt_vector_table:
|
389
|
10 ivt_reset: B start ; 0x0 reset
|
|
11 ivt_undef: B undef_handler ; 0x4 undefined instruction
|
|
12 ivt_svc: B undef_handler ; 0x08 Supervisor call
|
375
|
13 ivt_prefetch: B undef_handler ; 0x0C prefetch abort
|
389
|
14 ivt_data: B undef_handler ; 0x10 data abort
|
|
15 ivt_hyptrap: B undef_handler ; 0x14 not used
|
|
16 ivt_irq: B undef_handler ; 0x18 IRQ
|
|
17 ivt_fiq: B undef_handler ; 0x18 FIQ
|
375
|
18
|
|
19
|
|
20 start:
|
|
21
|
404
|
22 ; Setup the memory manager and the stack before entering kernel
|
|
23
|
406
|
24 ; Output an 'A' to indicate aliveness:
|
|
25 ldr r0, txtA
|
|
26 ldr r1, DRreg
|
|
27 str r0, [r1, 0]
|
|
28
|
375
|
29 ; Setup TTBR1 (translation table base register)
|
|
30
|
408
|
31 ldr r0, =kernel_table0 ; Load address of table
|
406
|
32 mcr p15, 0, r0, c2, c0, 0 ; TTBR0
|
375
|
33 mcr p15, 0, r0, c2, c0, 1 ; TTBR1
|
|
34
|
|
35 ; Prepare the TTBCR (translation table base control register)
|
|
36 mov r0, 0x1 ; TBD: why set this to 1?
|
|
37 mcr p15, 0, r0, c2, c0, 2
|
|
38
|
386
|
39
|
|
40 ; Set domain 0 to manager:
|
|
41 mov r0, 3
|
|
42 mcr p15, 0, r0, c3, c0, 0
|
|
43
|
406
|
44 ldr r0, txtB
|
|
45 ldr r1, DRreg
|
|
46 str r0, [r1, 0]
|
386
|
47
|
375
|
48 ; Enable the VMSA (Virtual memory system architecture):
|
|
49 mrc p15, 0, r0, c1, c0, 0
|
388
|
50 mov r1, 0x1
|
406
|
51 orr r0, r0, r1
|
375
|
52 mcr p15, 0, r0, c1, c0, 0
|
|
53
|
406
|
54 ldr r0, txtA
|
|
55 ldr r1, DRregmapped
|
|
56 str r0, [r1, 0]
|
|
57
|
375
|
58 ; Setup stack:
|
408
|
59 ldr r0, =stack_top
|
|
60 mov sp, r0
|
404
|
61 BL kernel_start ; Branch to main (this is actually in the interrupt vector)
|
352
|
62 local_loop:
|
|
63 B local_loop
|
362
|
64
|
|
65
|
375
|
66 ; Interrupt handlers:
|
|
67
|
|
68 undef_handler:
|
|
69 B undef_handler
|
|
70
|
381
|
71
|
|
72 ; Assembly language helpers:
|
362
|
73 ; Called to identify the proc:
|
381
|
74 arch_pfr0:
|
362
|
75 mrc p15, 0, r0, c0, c1, 0
|
|
76 mov pc, lr
|
|
77
|
381
|
78 arch_pfr1:
|
362
|
79 mrc p15, 0, r0, c0, c1, 1
|
|
80 mov pc, lr
|
|
81
|
381
|
82 arch_mmfr0:
|
362
|
83 mrc p15, 0, r0, c0, c1, 4
|
|
84 mov pc, lr
|
|
85
|
381
|
86 arch_mpuir:
|
362
|
87 mrc p15, 0, r0, c0, c0, 4
|
|
88 mov pc, lr
|
381
|
89
|
408
|
90 arch_get_image_address:
|
|
91 ldr r0, =ramdisk_start
|
|
92 mov pc, lr
|
|
93
|
406
|
94 ; data:
|
|
95 txtA:
|
|
96 dcd 65
|
|
97 txtB:
|
|
98 dcd 66
|
|
99 DRreg:
|
|
100 dcd 0x10009000
|
|
101 DRregmapped:
|
|
102 dcd 0x109000
|
381
|
103
|
|
104 ; Memory map tables:
|
|
105
|
406
|
106 ; Possibly, we are loaded into highmem at address 0x6000 0000,
|
|
107 ; or it may as well be 0x0000 0000 as an alias.
|
|
108 ; In any case, we must put an alias at 0x6000 0000 virtual.
|
|
109
|
381
|
110 section mem_tables
|
|
111
|
|
112 kernel_table0:
|
408
|
113 dcd 0
|
388
|
114 dcd 0x10000402 ; Map to peripheral space 1 MB
|
|
115 repeat 0x5FE
|
386
|
116 dcd 0
|
|
117 endrepeat
|
381
|
118
|
408
|
119 dcd 0x60000402 ; Identity map this!
|
388
|
120
|
|
121 repeat 0x9FF
|
|
122 dcd 0
|
|
123 endrepeat
|
|
124
|
408
|
125 ; Create a label to indicate the ramdisk:
|
|
126 section ramdisk
|
|
127 ramdisk_start:
|
|
128
|
|
129 ; Create stack space:
|
|
130 section stack
|
|
131
|
|
132 stack_bot:
|
|
133 ds 0x1000
|
|
134 stack_top:
|
|
135
|