1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
#include "tztest_asm.h"
/* The nonsecure image load code must be placed at the beginning of the image
* as this is the starting point for the boot code to load. The loader code
* will pass the initial starting point back to the boot code for later
* execution.
*/
nonsecure_load:
ldr r0, =_flash_nsectext_start
ldr r1, =_ram_nsectext_start
ldr r2, =_nsectext_size
copy_nsectext:
ldrb r10, [r0], #1
strb r10, [r1], #1
subs r2, r2, #1
bne copy_nsectext
ldr r0, =_flash_nsecdata_start
ldr r1, =_ram_nsecdata_start
ldr r2, =_nsecdata_size
copy_nsecdata:
ldrb r10, [r0], #1
strb r10, [r1], #1
subs r2, r2, #1
bne copy_nsecdata
ldr r0, =nonsecure_init
mov pc, lr
.align 5
/* We use the same vector table for Hyp and Monitor mode, since
* we will only use each once and they don't overlap.
*/
nonsecure_vectors:
b nonsecure_init /* reset */
b nonsecure_undef_vec /* undef */
b nonsecure_svc_vec /* svc */
b nonsecure_pabort_vec /* pabt */
b nonsecure_dabort_vec /* dabt */
.word 0 /* hmc */
.word 0 /* irq */
.word 0 /* fiq */
nonsecure_undef_vec:
srsdb sp!, #CPSR_MODE_UND
bl nonsecure_undef_handler
rfefd sp!
nonsecure_pabort_vec:
mrc p15, 0, r0, c5, c0, 1 /* IFSR */
mrc p15, 0, r1, c6, c0, 2 /* IFAR */
bl nonsecure_pabort_handler
b end
nonsecure_dabort_vec:
mrc p15, 0, r0, c5, c0, 0 /* DFSR */
mrc p15, 0, r1, c6, c0, 0 /* DFAR */
bl nonsecure_dabort_handler
b end
nonsecure_svc_vec:
srsdb sp!, #CPSR_MODE_SVC
bl nonsecure_svc_handler
rfefd sp!
nonsecure_init:
/* Disable interrupts for now */
mrs r10, cpsr
orr r10, r10, #0xc0 @ Mask IRQ and FIQ
msr cpsr_all, r10
/* Make sure vectors are based at 0 */
mrc p15, 0, r10, c1, c0, 0
bic r10, r10, #0x2000 @ SCTLR.V = 0
mcr p15, 0, r10, c1, c0, 0
/* Set up non-secure VBAR */
ldr r11, =nonsecure_vectors
mcr p15, 0, r11, c12, c0, 0
isb
nonsecure_stack_init:
/* Reset the SVC stack*/
ldr sp, =nsec_svc_stacktop
cps #CPSR_MODE_UND
ldr sp, =nsec_und_stacktop
cps #CPSR_MODE_ABT
ldr sp, =nsec_abt_stacktop
/* Have to set user (and system) stack from SYS mode so we can get back to
* SVC.
*/
cps #CPSR_MODE_SYS
ldr sp, =nsec_usr_stacktop
cps #CPSR_MODE_SVC
nonsecure_mmu_init:
/* Disable data and instruction caches */
mrc p15, 0, r10, c1, c0, 0
bic r10, r10, #0x0004
bic r10, r10, #0x1000
mcr p15, 0, r10, c1, c0, 0
/* Set domain 0 & 1 for client access */
mov r10, #0x5
mcr p15, 0, r10, c3, c0, 0
/* This function will return the initialized base address */
bl nonsecure_pagetable_init
/* Set TTBR0 to the initialized address plus enable shareable write-back
* write-allocate.
*/
ldr r10, =_nsec_l1_page_table
orr r10, r10, #0xB
mcr p15, 0, r10, c2, c0, 0
/* Set-up the table base control to split between TTBR0/1 (N = 0) */
mov r10, #0x0
mcr p15, 0, r10, c2, c0, 2
/* Enable the mmu */
mcr p15, 0, r10, c8, c7, 0
mrc p15, 0, r10, c1, c0, 0
orr r10, r10, #0x1
mcr p15, 0, r10, c1, c0, 0
isb
dsb
cps #CPSR_MODE_USR
bl tztest_nonsecure_usr_main
end:
mov r0, #SVC_EXIT
svc #0
b end
|