gitlab: Extract default build/test jobs templates
[qemu/ar7.git] / tests / tcg / aarch64 / system / boot.S
blobe190b1efa613953f97098c73ed23b3c1d89321ff
1 /*
2  * Minimal AArch64 system boot code.
3  *
4  * Copyright Linaro Ltd 2019
5  *
6  * Loosely based on the newlib/libgloss setup stubs. Using semihosting
7  * for serial output and exit functions.
8  */
11  * Semihosting interface on ARM AArch64
12  * See "Semihosting for AArch32 and AArch64 Relase 2.0" by ARM
13  * w0 - semihosting call number
14  * x1 - semihosting parameter
15  */
16 #define semihosting_call hlt 0xf000
17 #define SYS_WRITEC      0x03    /* character to debug channel */
18 #define SYS_WRITE0      0x04    /* string to debug channel */
19 #define SYS_EXIT        0x18
21         .align  12
23         .macro  ventry  label
24         .align  7
25         b       \label
26         .endm
28 vector_table:
29         /* Current EL with SP0.  */
30         ventry  curr_sp0_sync           /* Synchronous  */
31         ventry  curr_sp0_irq            /* Irq/vIRQ  */
32         ventry  curr_sp0_fiq            /* Fiq/vFIQ  */
33         ventry  curr_sp0_serror         /* SError/VSError  */
35         /* Current EL with SPx.  */
36         ventry  curr_spx_sync           /* Synchronous  */
37         ventry  curr_spx_irq            /* IRQ/vIRQ  */
38         ventry  curr_spx_fiq            /* FIQ/vFIQ  */
39         ventry  curr_spx_serror         /* SError/VSError  */
41         /* Lower EL using AArch64.  */
42         ventry  lower_a64_sync          /* Synchronous  */
43         ventry  lower_a64_irq           /* IRQ/vIRQ  */
44         ventry  lower_a64_fiq           /* FIQ/vFIQ  */
45         ventry  lower_a64_serror        /* SError/VSError  */
47         /* Lower EL using AArch32.  */
48         ventry  lower_a32_sync          /* Synchronous  */
49         ventry  lower_a32_irq           /* IRQ/vIRQ  */
50         ventry  lower_a32_fiq           /* FIQ/vFIQ  */
51         ventry  lower_a32_serror        /* SError/VSError  */
53         .text
54         .align 4
56         /* Common vector handling for now */
57 curr_sp0_sync:
58 curr_sp0_irq:
59 curr_sp0_fiq:
60 curr_sp0_serror:
61 curr_spx_sync:
62 curr_spx_irq:
63 curr_spx_fiq:
64 curr_spx_serror:
65 lower_a64_sync:
66 lower_a64_irq:
67 lower_a64_fiq:
68 lower_a64_serror:
69 lower_a32_sync:
70 lower_a32_irq:
71 lower_a32_fiq:
72 lower_a32_serror:
73         mov     x0, SYS_WRITE0
74         adr     x1, .error
75         semihosting_call
76         mov     x0, SYS_EXIT
77         mov     x1, 1
78         semihosting_call
79         /* never returns */
81         .section .rodata
82 .error:
83         .string "Terminated by exception.\n"
85         .text
86         .align 4
87         .global __start
88 __start:
89         /* Installs a table of exception vectors to catch and handle all
90            exceptions by terminating the process with a diagnostic.  */
91         adr     x0, vector_table
92         msr     vbar_el1, x0
94         /* Page table setup (identity mapping). */
95         adrp    x0, ttb
96         add     x0, x0, :lo12:ttb
97         msr     ttbr0_el1, x0
99         /*
100          * Setup a flat address mapping page-tables. Stage one simply
101          * maps RAM to the first Gb. The stage2 tables have two 2mb
102          * translation block entries covering a series of adjacent
103          * 4k pages.
104         */
106         /* Stage 1 entry: indexed by IA[38:30] */
107         adr     x1, .                           /* phys address */
108         bic     x1, x1, #(1 << 30) - 1          /* 1GB alignment*/
109         add     x2, x0, x1, lsr #(30 - 3)       /* offset in l1 page table */
111         /* point to stage 2 table [47:12] */
112         adrp    x0, ttb_stage2
113         orr     x1, x0, #3                      /* ptr to stage 2 */
114         str     x1, [x2]
116         /* Stage 2 entries: indexed by IA[29:21] */
117         ldr     x5, =(((1 << 9) - 1) << 21)
119         /* First block: .text/RO/execute enabled */
120         adr     x1, .                           /* phys address */
121         bic     x1, x1, #(1 << 21) - 1          /* 2mb block alignment  */
122         and     x4, x1, x5                      /* IA[29:21] */
123         add     x2, x0, x4, lsr #(21 - 3)       /* offset in l2 page table */
124         ldr     x3, =0x401                      /* attr(AF, block) */
125         orr     x1, x1, x3
126         str     x1, [x2]                        /* 1st 2mb (.text & rodata) */
128         /* Second block: .data/RW/no execute */
129         adrp    x1, .data
130         add     x1, x1, :lo12:.data
131         bic     x1, x1, #(1 << 21) - 1          /* 2mb block alignment */
132         and     x4, x1, x5                      /* IA[29:21] */
133         add     x2, x0, x4, lsr #(21 - 3)       /* offset in l2 page table */
134         ldr     x3, =(3 << 53) | 0x401          /* attr(AF, NX, block) */
135         orr     x1, x1, x3
136         str     x1, [x2]                        /* 2nd 2mb (.data & .bss)*/
138         /* Setup/enable the MMU.  */
140         /*
141          * TCR_EL1 - Translation Control Registers
142          *
143          * IPS[34:32] = 40-bit PA, 1TB
144          * TG0[14:15] = b00 => 4kb granuale
145          * ORGN0[11:10] = Outer: Normal, WB Read-Alloc No Write-Alloc Cacheable
146          * IRGN0[9:8] = Inner: Normal, WB Read-Alloc No Write-Alloc Cacheable
147          * T0SZ[5:0]  = 2^(64 - 25)
148          *
149          * The size of T0SZ controls what the initial lookup level. It
150          * would be nice to start at level 2 but unfortunatly for a
151          * flat-mapping on the virt machine we need to handle IA's
152          * with at least 1gb range to see RAM. So we start with a
153          * level 1 lookup.
154          */
155         ldr     x0, = (2 << 32) | 25 | (3 << 10) | (3 << 8)
156         msr     tcr_el1, x0
158         mov     x0, #0xee                       /* Inner/outer cacheable WB */
159         msr     mair_el1, x0
160         isb
162         /*
163          * SCTLR_EL1 - System Control Register
164          *
165          * WXN[19] = 0 = no effect, Write does not imply XN (execute never)
166          * I[12] = Instruction cachability control
167          * SA[3] = SP alignment check
168          * C[2] = Data cachability control
169          * M[0] = 1, enable stage 1 address translation for EL0/1
170          */
171         mrs     x0, sctlr_el1
172         ldr     x1, =0x100d                     /* bits I(12) SA(3) C(2) M(0) */
173         bic     x0, x0, #(1 << 1)               /* clear bit A(1) */
174         bic     x0, x0, #(1 << 19)              /* clear WXN */
175         orr     x0, x0, x1                      /* set bits */
177         dsb     sy
178         msr     sctlr_el1, x0
179         isb
181         /*
182          * Enable FP registers. The standard C pre-amble will be
183          * saving these and A-profile compilers will use AdvSIMD
184          * registers unless we tell it not to.
185         */
186         mrs     x0, cpacr_el1
187         orr     x0, x0, #(3 << 20)
188         msr     cpacr_el1, x0
190         /* Setup some stack space and enter the test code.
191          * Assume everthing except the return value is garbage when we
192          * return, we won't need it.
193          */
194         adrp    x0, stack_end
195         add     x0, x0, :lo12:stack_end
196         mov     sp, x0
197         bl      main
199         /* pass return value to sys exit */
200 _exit:
201         mov    x1, x0
202         ldr    x0, =0x20026 /* ADP_Stopped_ApplicationExit */
203         stp    x0, x1, [sp, #-16]!
204         mov    x1, sp
205         mov    x0, SYS_EXIT
206         semihosting_call
207         /* never returns */
209         /*
210          * Helper Functions
211         */
213         /* Output a single character to serial port */
214         .global __sys_outc
215 __sys_outc:
216         stp x0, x1, [sp, #-16]!
217         /* pass address of c on stack */
218         mov x1, sp
219         mov x0, SYS_WRITEC
220         semihosting_call
221         ldp x0, x1, [sp], #16
222         ret
224         .data
225         .align  12
227         /* Translation table
228          * @4k granuale: 9 bit lookup, 512 entries
229         */
230 ttb:
231         .space  4096, 0
233         .align  12
234 ttb_stage2:
235         .space  4096, 0
237         .align  12
238 stack:
239         .space 65536, 0
240 stack_end: