pinctrl: meson: axg: Fix GPIO pin offsets
[platform/kernel/u-boot.git] / arch / riscv / cpu / start.S
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * Startup Code for RISC-V Core
4  *
5  * Copyright (c) 2017 Microsemi Corporation.
6  * Copyright (c) 2017 Padmarao Begari <Padmarao.Begari@microsemi.com>
7  *
8  * Copyright (C) 2017 Andes Technology Corporation
9  * Rick Chen, Andes Technology Corporation <rick@andestech.com>
10  */
11
12 #include <asm-offsets.h>
13 #include <config.h>
14 #include <common.h>
15 #include <elf.h>
16 #include <asm/encoding.h>
17
18 #ifdef CONFIG_32BIT
19 #define LREG                    lw
20 #define SREG                    sw
21 #define REGBYTES                4
22 #define RELOC_TYPE              R_RISCV_32
23 #define SYM_INDEX               0x8
24 #define SYM_SIZE                0x10
25 #else
26 #define LREG                    ld
27 #define SREG                    sd
28 #define REGBYTES                8
29 #define RELOC_TYPE              R_RISCV_64
30 #define SYM_INDEX               0x20
31 #define SYM_SIZE                0x18
32 #endif
33
34 .section .text
35 .globl _start
36 _start:
37         /* save hart id and dtb pointer */
38         mv      s0, a0
39         mv      s1, a1
40
41         li      t0, CONFIG_SYS_SDRAM_BASE
42         SREG    a2, 0(t0)
43         la      t0, trap_entry
44         csrw    mtvec, t0
45
46         /* mask all interrupts */
47         csrw    mie, zero
48
49         /* Enable cache */
50         jal     icache_enable
51         jal     dcache_enable
52
53 /*
54  * Set stackpointer in internal/ex RAM to call board_init_f
55  */
56 call_board_init_f:
57         li      t0, -16
58         li      t1, CONFIG_SYS_INIT_SP_ADDR
59         and     sp, t1, t0              /* force 16 byte alignment */
60
61 #ifdef CONFIG_DEBUG_UART
62         jal     debug_uart_init
63 #endif
64
65 call_board_init_f_0:
66         mv      a0, sp
67         jal     board_init_f_alloc_reserve
68         mv      sp, a0
69
70         la      t0, prior_stage_fdt_address
71         SREG    s1, 0(t0)
72
73         jal     board_init_f_init_reserve
74
75         mv      a0, zero                /* a0 <-- boot_flags = 0 */
76         la      t5, board_init_f
77         jr      t5                      /* jump to board_init_f() */
78
79 /*
80  * void relocate_code (addr_sp, gd, addr_moni)
81  *
82  * This "function" does not return, instead it continues in RAM
83  * after relocating the monitor code.
84  *
85  */
86 .globl relocate_code
87 relocate_code:
88         mv      s2, a0                  /* save addr_sp */
89         mv      s3, a1                  /* save addr of gd */
90         mv      s4, a2                  /* save addr of destination */
91
92 /*
93  *Set up the stack
94  */
95 stack_setup:
96         mv      sp, s2
97         la      t0, _start
98         sub     t6, s4, t0              /* t6 <- relocation offset */
99         beq     t0, s4, clear_bss       /* skip relocation */
100
101         mv      t1, s4                  /* t1 <- scratch for copy_loop */
102         la      t3, __bss_start
103         sub     t3, t3, t0              /* t3 <- __bss_start_ofs */
104         add     t2, t0, t3              /* t2 <- source end address */
105
106 copy_loop:
107         LREG    t5, 0(t0)
108         addi    t0, t0, REGBYTES
109         SREG    t5, 0(t1)
110         addi    t1, t1, REGBYTES
111         blt     t0, t2, copy_loop
112
113 /*
114  * Update dynamic relocations after board_init_f
115  */
116 fix_rela_dyn:
117         la      t1, __rel_dyn_start
118         la      t2, __rel_dyn_end
119         beq     t1, t2, clear_bss
120         add     t1, t1, t6              /* t1 <- rela_dyn_start in RAM */
121         add     t2, t2, t6              /* t2 <- rela_dyn_end in RAM */
122
123 /*
124  * skip first reserved entry: address, type, addend
125  */
126         bne     t1, t2, 7f
127
128 6:
129         LREG    t5, -(REGBYTES*2)(t1)   /* t5 <-- relocation info:type */
130         li      t3, R_RISCV_RELATIVE    /* reloc type R_RISCV_RELATIVE */
131         bne     t5, t3, 8f              /* skip non-RISCV_RELOC entries */
132         LREG    t3, -(REGBYTES*3)(t1)
133         LREG    t5, -(REGBYTES)(t1)     /* t5 <-- addend */
134         add     t5, t5, t6              /* t5 <-- location to fix up in RAM */
135         add     t3, t3, t6              /* t3 <-- location to fix up in RAM */
136         SREG    t5, 0(t3)
137 7:
138         addi    t1, t1, (REGBYTES*3)
139         ble     t1, t2, 6b
140
141 8:
142         la      t4, __dyn_sym_start
143         add     t4, t4, t6
144
145 9:
146         LREG    t5, -(REGBYTES*2)(t1)   /* t5 <-- relocation info:type */
147         srli    t0, t5, SYM_INDEX       /* t0 <--- sym table index */
148         andi    t5, t5, 0xFF            /* t5 <--- relocation type */
149         li      t3, RELOC_TYPE
150         bne     t5, t3, 10f             /* skip non-addned entries */
151
152         LREG    t3, -(REGBYTES*3)(t1)
153         li      t5, SYM_SIZE
154         mul     t0, t0, t5
155         add     s5, t4, t0
156         LREG    t5, REGBYTES(s5)
157         add     t5, t5, t6              /* t5 <-- location to fix up in RAM */
158         add     t3, t3, t6              /* t3 <-- location to fix up in RAM */
159         SREG    t5, 0(t3)
160 10:
161         addi    t1, t1, (REGBYTES*3)
162         ble     t1, t2, 9b
163
164 /*
165  * trap update
166 */
167         la      t0, trap_entry
168         add     t0, t0, t6
169         csrw    mtvec, t0
170
171 clear_bss:
172         la      t0, __bss_start         /* t0 <- rel __bss_start in FLASH */
173         add     t0, t0, t6              /* t0 <- rel __bss_start in RAM */
174         la      t1, __bss_end           /* t1 <- rel __bss_end in FLASH */
175         add     t1, t1, t6              /* t1 <- rel __bss_end in RAM */
176         beq     t0, t1, call_board_init_r
177
178 clbss_l:
179         SREG    zero, 0(t0)             /* clear loop... */
180         addi    t0, t0, REGBYTES
181         bne     t0, t1, clbss_l
182
183 /*
184  * We are done. Do not return, instead branch to second part of board
185  * initialization, now running from RAM.
186  */
187 call_board_init_r:
188         jal     invalidate_icache_all
189         jal     flush_dcache_all
190         la      t0, board_init_r
191         mv      t4, t0                  /* offset of board_init_r() */
192         add     t4, t4, t6              /* real address of board_init_r() */
193 /*
194  * setup parameters for board_init_r
195  */
196         mv      a0, s3                  /* gd_t */
197         mv      a1, s4                  /* dest_addr */
198
199 /*
200  * jump to it ...
201  */
202         jr      t4                      /* jump to board_init_r() */
203
204 /*
205  * trap entry
206  */
207 .align 2
208 trap_entry:
209         addi    sp, sp, -32*REGBYTES
210         SREG    x1, 1*REGBYTES(sp)
211         SREG    x2, 2*REGBYTES(sp)
212         SREG    x3, 3*REGBYTES(sp)
213         SREG    x4, 4*REGBYTES(sp)
214         SREG    x5, 5*REGBYTES(sp)
215         SREG    x6, 6*REGBYTES(sp)
216         SREG    x7, 7*REGBYTES(sp)
217         SREG    x8, 8*REGBYTES(sp)
218         SREG    x9, 9*REGBYTES(sp)
219         SREG    x10, 10*REGBYTES(sp)
220         SREG    x11, 11*REGBYTES(sp)
221         SREG    x12, 12*REGBYTES(sp)
222         SREG    x13, 13*REGBYTES(sp)
223         SREG    x14, 14*REGBYTES(sp)
224         SREG    x15, 15*REGBYTES(sp)
225         SREG    x16, 16*REGBYTES(sp)
226         SREG    x17, 17*REGBYTES(sp)
227         SREG    x18, 18*REGBYTES(sp)
228         SREG    x19, 19*REGBYTES(sp)
229         SREG    x20, 20*REGBYTES(sp)
230         SREG    x21, 21*REGBYTES(sp)
231         SREG    x22, 22*REGBYTES(sp)
232         SREG    x23, 23*REGBYTES(sp)
233         SREG    x24, 24*REGBYTES(sp)
234         SREG    x25, 25*REGBYTES(sp)
235         SREG    x26, 26*REGBYTES(sp)
236         SREG    x27, 27*REGBYTES(sp)
237         SREG    x28, 28*REGBYTES(sp)
238         SREG    x29, 29*REGBYTES(sp)
239         SREG    x30, 30*REGBYTES(sp)
240         SREG    x31, 31*REGBYTES(sp)
241         csrr    a0, mcause
242         csrr    a1, mepc
243         mv      a2, sp
244         jal     handle_trap
245         csrw    mepc, a0
246
247 /*
248  * Remain in M-mode after mret
249  */
250         li      t0, MSTATUS_MPP
251         csrs    mstatus, t0
252         LREG    x1, 1*REGBYTES(sp)
253         LREG    x2, 2*REGBYTES(sp)
254         LREG    x3, 3*REGBYTES(sp)
255         LREG    x4, 4*REGBYTES(sp)
256         LREG    x5, 5*REGBYTES(sp)
257         LREG    x6, 6*REGBYTES(sp)
258         LREG    x7, 7*REGBYTES(sp)
259         LREG    x8, 8*REGBYTES(sp)
260         LREG    x9, 9*REGBYTES(sp)
261         LREG    x10, 10*REGBYTES(sp)
262         LREG    x11, 11*REGBYTES(sp)
263         LREG    x12, 12*REGBYTES(sp)
264         LREG    x13, 13*REGBYTES(sp)
265         LREG    x14, 14*REGBYTES(sp)
266         LREG    x15, 15*REGBYTES(sp)
267         LREG    x16, 16*REGBYTES(sp)
268         LREG    x17, 17*REGBYTES(sp)
269         LREG    x18, 18*REGBYTES(sp)
270         LREG    x19, 19*REGBYTES(sp)
271         LREG    x20, 20*REGBYTES(sp)
272         LREG    x21, 21*REGBYTES(sp)
273         LREG    x22, 22*REGBYTES(sp)
274         LREG    x23, 23*REGBYTES(sp)
275         LREG    x24, 24*REGBYTES(sp)
276         LREG    x25, 25*REGBYTES(sp)
277         LREG    x26, 26*REGBYTES(sp)
278         LREG    x27, 27*REGBYTES(sp)
279         LREG    x28, 28*REGBYTES(sp)
280         LREG    x29, 29*REGBYTES(sp)
281         LREG    x30, 30*REGBYTES(sp)
282         LREG    x31, 31*REGBYTES(sp)
283         addi    sp, sp, 32*REGBYTES
284         mret