]>
Commit | Line | Data |
---|---|---|
76d2a049 PD |
1 | /* |
2 | * Copyright (C) 2012 Regents of the University of California | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or | |
5 | * modify it under the terms of the GNU General Public License | |
6 | * as published by the Free Software Foundation, version 2. | |
7 | * | |
8 | * This program is distributed in the hope that it will be useful, | |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | * GNU General Public License for more details. | |
12 | */ | |
13 | ||
14 | #include <asm/thread_info.h> | |
15 | #include <asm/asm-offsets.h> | |
16 | #include <asm/asm.h> | |
17 | #include <linux/init.h> | |
18 | #include <linux/linkage.h> | |
19 | #include <asm/thread_info.h> | |
20 | #include <asm/page.h> | |
21 | #include <asm/csr.h> | |
22 | ||
23 | __INIT | |
24 | ENTRY(_start) | |
25 | /* Mask all interrupts */ | |
26 | csrw sie, zero | |
27 | ||
28 | /* Load the global pointer */ | |
29 | .option push | |
30 | .option norelax | |
31 | la gp, __global_pointer$ | |
32 | .option pop | |
33 | ||
34 | /* | |
35 | * Disable FPU to detect illegal usage of | |
36 | * floating point in kernel space | |
37 | */ | |
38 | li t0, SR_FS | |
39 | csrc sstatus, t0 | |
40 | ||
41 | /* Pick one hart to run the main boot sequence */ | |
42 | la a3, hart_lottery | |
43 | li a2, 1 | |
44 | amoadd.w a3, a2, (a3) | |
45 | bnez a3, .Lsecondary_start | |
46 | ||
c0fbcd99 AP |
47 | /* Clear BSS for flat non-ELF images */ |
48 | la a3, __bss_start | |
49 | la a4, __bss_stop | |
50 | ble a4, a3, clear_bss_done | |
51 | clear_bss: | |
52 | REG_S zero, (a3) | |
53 | add a3, a3, RISCV_SZPTR | |
54 | blt a3, a4, clear_bss | |
55 | clear_bss_done: | |
56 | ||
76d2a049 PD |
57 | /* Save hart ID and DTB physical address */ |
58 | mv s0, a0 | |
59 | mv s1, a1 | |
f99fb607 AP |
60 | la a2, boot_cpu_hartid |
61 | REG_S a0, (a2) | |
76d2a049 PD |
62 | |
63 | /* Initialize page tables and relocate to virtual addresses */ | |
64 | la sp, init_thread_union + THREAD_SIZE | |
65 | call setup_vm | |
66 | call relocate | |
67 | ||
68 | /* Restore C environment */ | |
69 | la tp, init_task | |
f99fb607 | 70 | sw zero, TASK_TI_CPU(tp) |
76d2a049 PD |
71 | |
72 | la sp, init_thread_union | |
73 | li a0, ASM_THREAD_SIZE | |
74 | add sp, sp, a0 | |
75 | ||
76 | /* Start the kernel */ | |
77 | mv a0, s0 | |
78 | mv a1, s1 | |
8b08f501 | 79 | call parse_dtb |
76d2a049 PD |
80 | tail start_kernel |
81 | ||
82 | relocate: | |
83 | /* Relocate return address */ | |
84 | li a1, PAGE_OFFSET | |
85 | la a0, _start | |
86 | sub a1, a1, a0 | |
87 | add ra, ra, a1 | |
88 | ||
7549cdf5 | 89 | /* Point stvec to virtual address of intruction after satp write */ |
76d2a049 PD |
90 | la a0, 1f |
91 | add a0, a0, a1 | |
92 | csrw stvec, a0 | |
93 | ||
7549cdf5 | 94 | /* Compute satp for kernel page tables, but don't load it yet */ |
76d2a049 PD |
95 | la a2, swapper_pg_dir |
96 | srl a2, a2, PAGE_SHIFT | |
7549cdf5 | 97 | li a1, SATP_MODE |
76d2a049 PD |
98 | or a2, a2, a1 |
99 | ||
100 | /* | |
101 | * Load trampoline page directory, which will cause us to trap to | |
102 | * stvec if VA != PA, or simply fall through if VA == PA | |
103 | */ | |
104 | la a0, trampoline_pg_dir | |
105 | srl a0, a0, PAGE_SHIFT | |
106 | or a0, a0, a1 | |
107 | sfence.vma | |
108 | csrw sptbr, a0 | |
94f592f0 | 109 | .align 2 |
76d2a049 PD |
110 | 1: |
111 | /* Set trap vector to spin forever to help debug */ | |
112 | la a0, .Lsecondary_park | |
113 | csrw stvec, a0 | |
114 | ||
115 | /* Reload the global pointer */ | |
116 | .option push | |
117 | .option norelax | |
118 | la gp, __global_pointer$ | |
119 | .option pop | |
120 | ||
121 | /* Switch to kernel page tables */ | |
122 | csrw sptbr, a2 | |
123 | ||
124 | ret | |
125 | ||
126 | .Lsecondary_start: | |
127 | #ifdef CONFIG_SMP | |
128 | li a1, CONFIG_NR_CPUS | |
129 | bgeu a0, a1, .Lsecondary_park | |
130 | ||
131 | /* Set trap vector to spin forever to help debug */ | |
132 | la a3, .Lsecondary_park | |
133 | csrw stvec, a3 | |
134 | ||
135 | slli a3, a0, LGREG | |
136 | la a1, __cpu_up_stack_pointer | |
137 | la a2, __cpu_up_task_pointer | |
138 | add a1, a3, a1 | |
139 | add a2, a3, a2 | |
140 | ||
141 | /* | |
142 | * This hart didn't win the lottery, so we wait for the winning hart to | |
143 | * get far enough along the boot process that it should continue. | |
144 | */ | |
145 | .Lwait_for_cpu_up: | |
146 | /* FIXME: We should WFI to save some energy here. */ | |
147 | REG_L sp, (a1) | |
148 | REG_L tp, (a2) | |
149 | beqz sp, .Lwait_for_cpu_up | |
150 | beqz tp, .Lwait_for_cpu_up | |
151 | fence | |
152 | ||
153 | /* Enable virtual memory and relocate to virtual address */ | |
154 | call relocate | |
155 | ||
156 | tail smp_callin | |
157 | #endif | |
158 | ||
94f592f0 | 159 | .align 2 |
76d2a049 PD |
160 | .Lsecondary_park: |
161 | /* We lack SMP support or have too many harts, so park this hart */ | |
162 | wfi | |
163 | j .Lsecondary_park | |
164 | END(_start) | |
165 | ||
166 | __PAGE_ALIGNED_BSS | |
167 | /* Empty zero page */ | |
168 | .balign PAGE_SIZE |