1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <linux/linkage.h>
18#include <linux/init.h>
19#include <asm/page.h>
20#include <asm/pgtable.h>
21#include <asm/thread_info.h>
22#include <asm/processor.h>
23#include <asm/asm-offsets.h>
24#include <hv/hypervisor.h>
25#include <arch/chip.h>
26#include <arch/spr_def.h>
27
28
29#ifdef __BIG_ENDIAN__
30#define GET_FIRST_INT(rd, rs) shrsi rd, rs, 32
31#define GET_SECOND_INT(rd, rs) addxi rd, rs, 0
32#else
33#define GET_FIRST_INT(rd, rs) addxi rd, rs, 0
34#define GET_SECOND_INT(rd, rs) shrsi rd, rs, 32
35#endif
36
37
38
39
40
41
42 __HEAD
43ENTRY(_start)
44
45 {
46
47
48 movei r0, _HV_VERSION_OLD_HV_INIT
49#else
50 movei r0, _HV_VERSION
51#endif
52 movei r1, TILE_CHIP
53 }
54 {
55 movei r2, TILE_CHIP_REV
56 movei r3, KERNEL_PL
57 }
58 jal _hv_init
59
60 {
61 move r0, zero
62 jal _hv_inquire_asid
63 }
64
65
66
67
68
69
70
71
72 {
73 GET_FIRST_INT(r2, r0)
74 moveli r4, hw1_last(swapper_pgprot - PAGE_OFFSET)
75 }
76 {
77 shl16insli r4, r4, hw0(swapper_pgprot - PAGE_OFFSET)
78 }
79 {
80 ld r1, r4
81 }
82 {
83 moveli r0, hw1_last(.Lsv_data_pmd - PAGE_OFFSET)
84 moveli r6, hw1_last(temp_data_pmd - PAGE_OFFSET)
85 }
86 {
87
88 bfextu r7, r1, HV_PTE_INDEX_GLOBAL, HV_PTE_INDEX_GLOBAL
89 finv r4
90 }
91 bnez r7, .Lno_write
92 {
93 shl16insli r0, r0, hw0(.Lsv_data_pmd - PAGE_OFFSET)
94 shl16insli r6, r6, hw0(temp_data_pmd - PAGE_OFFSET)
95 }
96 {
97
98 shrui r6, r6, HV_LOG2_PAGE_TABLE_ALIGN
99
100 move r5, r1
101 }
102 {
103
104 bfins r5, r6, HV_PTE_INDEX_PTFN, \
105 HV_PTE_INDEX_PTFN + HV_PTE_PTFN_BITS - 1
106 }
107 {
108
109 st r0, r5
110 addli r6, r6, (temp_code_pmd - temp_data_pmd) >> \
111 HV_LOG2_PAGE_TABLE_ALIGN
112 }
113 {
114 addli r0, r0, .Lsv_code_pmd - .Lsv_data_pmd
115 bfins r5, r6, HV_PTE_INDEX_PTFN, \
116 HV_PTE_INDEX_PTFN + HV_PTE_PTFN_BITS - 1
117 }
118
119 st r0, r5
120
121.Lno_write:
122 moveli lr, hw2_last(1f)
123 {
124 shl16insli lr, lr, hw1(1f)
125 moveli r0, hw1_last(swapper_pg_dir - PAGE_OFFSET)
126 }
127 {
128 shl16insli lr, lr, hw0(1f)
129 shl16insli r0, r0, hw0(swapper_pg_dir - PAGE_OFFSET)
130 }
131 {
132 moveli r3, CTX_PAGE_FLAG
133 j _hv_install_context
134 }
1351:
136
137
138 moveli r0, hw2_last(intrpt_start)
139 shl16insli r0, r0, hw1(intrpt_start)
140 shl16insli r0, r0, hw0(intrpt_start)
141 mtspr SPR_INTERRUPT_VECTOR_BASE_K, r0
142
143
144 jal _hv_inquire_topology
145 {
146 GET_FIRST_INT(r5, r1)
147 GET_SECOND_INT(r4, r0)
148 }
149 {
150 GET_FIRST_INT(r6, r0)
151 mul_lu_lu r4, r4, r5
152 }
153 {
154 add r4, r4, r6
155 }
156
157#ifdef CONFIG_SMP
158
159
160
161
162
163
164
165
166 moveli r5, hw2_last(__per_cpu_offset)
167 shl16insli r5, r5, hw1(__per_cpu_offset)
168 shl16insli r5, r5, hw0(__per_cpu_offset)
169 shl3add r5, r4, r5
170 ld r5, r5
171 bnez r5, 1f
172
173
174
175
176
177 moveli r0, hw2_last(smp_topology + HV_TOPOLOGY_WIDTH_OFFSET)
178 shl16insli r0, r0, hw1(smp_topology + HV_TOPOLOGY_WIDTH_OFFSET)
179 shl16insli r0, r0, hw0(smp_topology + HV_TOPOLOGY_WIDTH_OFFSET)
180 st r0, r1
1811:
182#else
183 move r5, zero
184#endif
185
186
187 {
188 moveli r1, hw2_last(boot_sp)
189 moveli r0, hw2_last(boot_pc)
190 }
191 {
192 shl16insli r1, r1, hw1(boot_sp)
193 shl16insli r0, r0, hw1(boot_pc)
194 }
195 {
196 shl16insli r1, r1, hw0(boot_sp)
197 shl16insli r0, r0, hw0(boot_pc)
198 }
199 {
200 add r1, r1, r5
201 add r0, r0, r5
202 }
203 ld r0, r0
204 ld sp, r1
205 shli r4, r4, CPU_SHIFT
206 bfins r4, sp, 0, CPU_SHIFT-1
207 mtspr SPR_SYSTEM_SAVE_K_0, r4
208 {
209 move lr, zero
210 jr r0
211 }
212 ENDPROC(_start)
213
214__PAGE_ALIGNED_BSS
215 .align PAGE_SIZE
216ENTRY(empty_zero_page)
217 .fill PAGE_SIZE,1,0
218 END(empty_zero_page)
219
220 .macro PTE cpa, bits1
221 .quad HV_PTE_PAGE | HV_PTE_DIRTY | HV_PTE_PRESENT | HV_PTE_ACCESSED |\
222 HV_PTE_GLOBAL | (HV_PTE_MODE_CACHE_NO_L3 << HV_PTE_INDEX_MODE) |\
223 (\bits1) | (HV_CPA_TO_PTFN(\cpa) << HV_PTE_INDEX_PTFN)
224 .endm
225
226__PAGE_ALIGNED_DATA
227 .align PAGE_SIZE
228ENTRY(swapper_pg_dir)
229 .org swapper_pg_dir + PGD_INDEX(PAGE_OFFSET) * HV_PTE_SIZE
230.Lsv_data_pmd:
231 .quad 0
232 .org swapper_pg_dir + PGD_INDEX(MEM_SV_START) * HV_PTE_SIZE
233.Lsv_code_pmd:
234 .quad 0
235 .org swapper_pg_dir + SIZEOF_PGD
236 END(swapper_pg_dir)
237
238 .align HV_PAGE_TABLE_ALIGN
239ENTRY(temp_data_pmd)
240
241
242
243
244
245 .set addr, 0
246 .rept PTRS_PER_PMD
247 PTE addr, HV_PTE_READABLE | HV_PTE_WRITABLE
248 .set addr, addr + HPAGE_SIZE
249 .endr
250 .org temp_data_pmd + SIZEOF_PMD
251 END(temp_data_pmd)
252
253 .align HV_PAGE_TABLE_ALIGN
254ENTRY(temp_code_pmd)
255
256
257
258
259
260 .set addr, 0
261 .rept PTRS_PER_PMD
262 PTE addr, HV_PTE_READABLE | HV_PTE_EXECUTABLE
263 .set addr, addr + HPAGE_SIZE
264 .endr
265 .org temp_code_pmd + SIZEOF_PMD
266 END(temp_code_pmd)
267
268
269
270
271
272
273
274 __INITDATA
275 .align CHIP_L2_LINE_SIZE()
276ENTRY(swapper_pgprot)
277 .quad HV_PTE_PRESENT | (HV_PTE_MODE_CACHE_NO_L3 << HV_PTE_INDEX_MODE)
278 .align CHIP_L2_LINE_SIZE()
279 END(swapper_pgprot)
280