Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: reset.s | |
5 | * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
6 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. | |
7 | * | |
8 | * The above named program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public | |
10 | * License version 2 as published by the Free Software Foundation. | |
11 | * | |
12 | * The above named program is distributed in the hope that it will be | |
13 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public | |
18 | * License along with this work; if not, write to the Free Software | |
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. | |
20 | * | |
21 | * ========== Copyright Header End ============================================ | |
22 | */ | |
23 | /* | |
24 | * Copyright 2007 Sun Microsystems, Inc. All rights reserved. | |
25 | * Use is subject to license terms. | |
26 | */ | |
27 | ||
28 | /* | |
29 | * OpenSPARC T1 reset sequence | |
30 | */ | |
31 | ||
32 | #include <sys/asm_linkage.h> | |
33 | ||
34 | #include "xilinx_t1_system_config.h" | |
35 | #include "asi.h" | |
36 | #include "hprivregs.h" | |
37 | #include "traps.h" | |
38 | ||
39 | ||
40 | /* | |
41 | * Interrupt Management | |
42 | */ | |
43 | #define IOBBASE 0x9800000000 | |
44 | #define INT_MAN 0x000 | |
45 | #define INT_CTL 0x400 | |
46 | #define INT_VEC_DIS 0x800 | |
47 | ||
48 | #define ASI_ERROR_STATUS 0x4c | |
49 | ||
50 | #define ICACHE_MAX_WAYS 4 | |
51 | #define PIL_15 0xf | |
52 | ||
53 | ||
54 | #define BIST_CTL_BISI_MODE (1 << 6) | |
55 | #define BIST_DONE (1 << 10) | |
56 | #define BIST_START 1 | |
57 | ||
58 | #define BISI_START (BIST_CTL_BISI_MODE + BIST_START) | |
59 | ||
60 | ||
61 | ||
62 | #define STR_STATUS_REG %asr26 | |
63 | ||
64 | #define STR_STATUS_STRAND_ACTIVE 1 | |
65 | #define STR_STATUS_STRAND_ID_SHIFT 8 | |
66 | #define STR_STATUS_STRAND_ID_MASK 0x3 | |
67 | #define STR_STATUS_CORE_ID_SHIFT 10 | |
68 | #define STR_STATUS_CORE_ID_MASK 0x7 | |
69 | ||
70 | #define CPU_ID_STRAND_MASK 0x3 | |
71 | #define CPU_ID_STRAND_SHIFT 0x0 | |
72 | #define CPU_ID_CORE_MASK 0x7 | |
73 | #define CPU_ID_CORE_SHIFT 0x2 | |
74 | #define CPU_ID_MASK 0x1f | |
75 | ||
76 | #define N_THREADS_PER_CORE 0x4 | |
77 | #define N_THREADS 0x20 | |
78 | ||
79 | ||
80 | #define STR_STATUS_CPU_ID_SHIFT STR_STATUS_STRAND_ID_SHIFT | |
81 | #define STR_STATUS_CPU_ID_MASK 0x1f | |
82 | ||
83 | ||
84 | ||
85 | ||
86 | /* | |
87 | * Niagara reset trap tables | |
88 | */ | |
89 | ||
90 | #define TRAP_ALIGN_SIZE 32 | |
91 | #define TRAP_ALIGN .align TRAP_ALIGN_SIZE | |
92 | #define TRAP_ALIGN_BIG .align (TRAP_ALIGN_SIZE * 4) | |
93 | ||
94 | #define TT_TRACE(label) | |
95 | #define TT_TRACE_L(label) | |
96 | ||
97 | #define TRAP(ttnum, action) \ | |
98 | .global r/**/ttnum ;\ | |
99 | r/**/ttnum: ;\ | |
100 | action ;\ | |
101 | TRAP_ALIGN | |
102 | ||
103 | #define BIGTRAP(ttnum, action) \ | |
104 | .global r/**/ttnum ;\ | |
105 | r/**/ttnum: ;\ | |
106 | action ;\ | |
107 | TRAP_ALIGN_BIG | |
108 | ||
109 | #define GOTO(label) \ | |
110 | TT_TRACE(trace_gen) ;\ | |
111 | .global label ;\ | |
112 | ba,a label ;\ | |
113 | .empty | |
114 | ||
115 | /* revector to hypervisor */ | |
116 | #define HREVEC(ttnum) \ | |
117 | TT_TRACE(trace_gen) ;\ | |
118 | mov ttnum, %g1 ;\ | |
119 | ba,a revec ;\ | |
120 | .empty | |
121 | ||
122 | ||
123 | #define NOT GOTO(rtrap) | |
124 | #define NOT_BIG NOT NOT NOT NOT | |
125 | #define RED NOT | |
126 | ||
127 | ||
128 | /* | |
129 | * The basic hypervisor trap table | |
130 | */ | |
131 | ||
132 | .section ".text" | |
133 | .align 0x8000 | |
134 | .global rtraptable | |
135 | .type rtraptable, #function | |
136 | rtraptable: | |
137 | /* hardware traps */ | |
138 | TRAP(tt0_000, NOT) /* reserved */ | |
139 | TRAP(tt0_001, GOTO(start_reset)) /* power-on reset */ | |
140 | TRAP(tt0_002, HREVEC(0x2)) /* watchdog reset */ | |
141 | TRAP(tt0_003, HREVEC(0x3)) /* externally initiated reset */ | |
142 | TRAP(tt0_004, NOT) /* software initiated reset */ | |
143 | TRAP(tt0_005, NOT) /* red mode exception */ | |
144 | TRAP(tt0_006, NOT) /* reserved */ | |
145 | TRAP(tt0_007, NOT) /* reserved */ | |
146 | ertraptable: | |
147 | .size rtraptable, (.-rtraptable) | |
148 | .global rtraptable | |
149 | .type rtraptable, #function | |
150 | ||
151 | ENTRY_NP(start_reset) | |
152 | #ifdef CONFIG_SAS | |
153 | ! tick needs to be initialized, this is a hack for SAS | |
154 | wrpr %g0, 0, %tick | |
155 | #endif | |
156 | ||
157 | wrpr %g0, 1, %gl | |
158 | wrpr %g0, 1, %tl | |
159 | wrpr %g0, 7, %cleanwin | |
160 | wrpr %g0, 0, %otherwin | |
161 | wrpr %g0, 0, %wstate | |
162 | wrpr %g0, 0, %cwp | |
163 | wrpr %g0, 0, %canrestore | |
164 | wrpr %g0, 5, %cansave | |
165 | wrpr %g0, PSTATE_PRIV, %pstate | |
166 | ||
167 | clr %g1 | |
168 | mov NWINDOWS - 1, %g1 | |
169 | 1: wrpr %g1, %cwp | |
170 | clr %i0 | |
171 | clr %i1 | |
172 | clr %i2 | |
173 | clr %i3 | |
174 | clr %i4 | |
175 | clr %i5 | |
176 | clr %i6 | |
177 | clr %i7 | |
178 | clr %l0 | |
179 | clr %l1 | |
180 | clr %l2 | |
181 | clr %l3 | |
182 | clr %l4 | |
183 | clr %l5 | |
184 | clr %l6 | |
185 | deccc %g1 | |
186 | bge,pn %xcc, 1b | |
187 | clr %l7 | |
188 | ||
189 | ! %cwp == 0 | |
190 | ||
191 | mov MAXGL, %l0 | |
192 | 1: wrpr %l0, %gl | |
193 | clr %g1 | |
194 | clr %g2 | |
195 | clr %g3 | |
196 | clr %g4 | |
197 | clr %g5 | |
198 | clr %g6 | |
199 | deccc %l0 | |
200 | bge,pn %xcc, 1b | |
201 | clr %g7 | |
202 | ||
203 | wrpr %g0, 1, %gl | |
204 | ||
205 | ! set ENB bit | |
206 | set HPSTATE_ENB, %g1 | |
207 | rdhpr %hpstate, %g2 | |
208 | or %g1, %g2, %g1 | |
209 | wrhpr %g1, %hpstate | |
210 | ||
211 | ||
212 | wrpr %g0, 1, %tl | |
213 | set ((PSTATE_PRIV | PSTATE_MM_TSO) << TSTATE_PSTATE_SHIFT), %g2 | |
214 | wrpr %g2, %tstate ! gl=0 ccr=0 asi=0 | |
215 | set (HPSTATE_HPRIV), %g2 | |
216 | wrhpr %g2, %htstate | |
217 | ||
218 | call init_regfile | |
219 | nop | |
220 | ||
221 | set STRAND_STARTSET, %o0 | |
222 | call is_core_master | |
223 | nop | |
224 | ||
225 | brz,pt %o0, slave_thread | |
226 | nop | |
227 | ||
228 | call l1_bisi | |
229 | nop | |
230 | ||
231 | call init_icache | |
232 | nop | |
233 | ||
234 | call init_dcache | |
235 | nop | |
236 | ||
237 | call init_tlbs | |
238 | nop | |
239 | ||
240 | wrpr %g0, 1, %gl | |
241 | wrpr %g0, 1, %tl | |
242 | ||
243 | #ifdef T1_FPGA_DISABLE_DCACHE | |
244 | set (LSUCR_IC), %g1 | |
245 | stxa %g1, [%g0]ASI_LSUCR ! enable Icache | |
246 | #else | |
247 | set (LSUCR_DC | LSUCR_IC), %g1 | |
248 | stxa %g1, [%g0]ASI_LSUCR ! enable Icache and Dcache | |
249 | #endif | |
250 | ||
251 | ||
252 | set STRAND_STARTSET, %o0 | |
253 | call is_master_cpu | |
254 | nop | |
255 | ||
256 | brnz,pt %o0, master_cpu | |
257 | nop | |
258 | ||
259 | set STRAND_STARTSET, %o0 | |
260 | call wakeup_slave_threads | |
261 | nop | |
262 | ||
263 | brz,pt %g0, slave_thread | |
264 | nop | |
265 | ||
266 | master_cpu: | |
267 | setx T1_FPGA_HV_MEMBASE, %o5, %g1 | |
268 | setx T1_FPGA_HV_MEMSIZE, %o5, %g2 | |
269 | setx T1_FPGA_HV_MD_ADDR, %o5, %g3 | |
270 | set STRAND_STARTSET, %g4 | |
271 | set T1_FPGA_TOTAL_MEMSIZE, %g5 | |
272 | ||
273 | rd %pc, %o3 ! master | |
274 | srlx %o3, 20, %o3 | |
275 | sllx %o3, 20, %o3 | |
276 | set T1_FPGA_PROM_HV_START_OFFSET, %o4 ! next stage start point. | |
277 | ||
278 | jmp %o3 + %o4 | |
279 | nop | |
280 | ||
281 | slave_thread: | |
282 | ||
283 | wrpr %g0, 1, %gl | |
284 | wrpr %g0, 1, %tl | |
285 | ||
286 | #ifdef T1_FPGA_DISABLE_DCACHE | |
287 | set (LSUCR_IC), %g1 | |
288 | stxa %g1, [%g0]ASI_LSUCR ! enable Icache | |
289 | #else | |
290 | set (LSUCR_DC | LSUCR_IC), %g1 | |
291 | stxa %g1, [%g0]ASI_LSUCR ! enable Icache and Dcache | |
292 | #endif | |
293 | ||
294 | setx T1_FPGA_HV_MEMBASE, %o5, %g1 | |
295 | setx T1_FPGA_HV_MEMSIZE, %o5, %g2 | |
296 | setx T1_FPGA_HV_MD_ADDR, %o5, %g3 | |
297 | set STRAND_STARTSET, %g4 | |
298 | set T1_FPGA_TOTAL_MEMSIZE, %g5 | |
299 | ||
300 | rd %pc, %o3 ! master | |
301 | srlx %o3, 20, %o3 | |
302 | sllx %o3, 20, %o3 | |
303 | set T1_FPGA_PROM_HV_START_OFFSET, %o4 ! next stage start point. | |
304 | add %o4, 0x10, %o4 | |
305 | ||
306 | jmp %o3 + %o4 | |
307 | nop | |
308 | SET_SIZE(start_reset) | |
309 | ||
310 | ||
311 | ENTRY_NP(rtrap) | |
312 | ta 0x1 | |
313 | SET_SIZE(rtrap) | |
314 | ||
315 | ||
316 | ! %g1 contains trap# to revector to | |
317 | ENTRY_NP(revec) | |
318 | rdhpr %htba, %g2 | |
319 | sllx %g1, 5, %g1 | |
320 | add %g2, %g1, %g2 | |
321 | jmp %g2 | |
322 | wrhpr %g0, (HPSTATE_HPRIV | HPSTATE_ENB), %hpstate | |
323 | SET_SIZE(revec) | |
324 | ||
325 | ||
326 | ||
327 | ENTRY_NP(init_regfile) | |
328 | save %sp, -(MINFRAME64), %sp | |
329 | ||
330 | wrpr %g0, %tba | |
331 | wrpr %g0, PIL_15, %pil | |
332 | ||
333 | mov MAXGL, %l0 | |
334 | 1: wrpr %l0, %gl | |
335 | clr %g1 | |
336 | clr %g2 | |
337 | clr %g3 | |
338 | clr %g4 | |
339 | clr %g5 | |
340 | clr %g6 | |
341 | deccc %l0 | |
342 | bge,pn %xcc, 1b | |
343 | clr %g7 | |
344 | ||
345 | wr %g0, %ccr | |
346 | wr %g0, %y | |
347 | wr %g0, %fprs | |
348 | wrpr %g0, 0, %tick | |
349 | ||
350 | wrpr %g0, 6, %tl | |
351 | wrpr %g0, -1, %tpc | |
352 | wrpr %g0, -1, %tnpc | |
353 | wrpr %g0, -1, %tt | |
354 | ||
355 | wrpr %g0, 5, %tl | |
356 | wrpr %g0, -1, %tpc | |
357 | wrpr %g0, -1, %tnpc | |
358 | wrpr %g0, -1, %tt | |
359 | ||
360 | wrpr %g0, 4, %tl | |
361 | wrpr %g0, -1, %tpc | |
362 | wrpr %g0, -1, %tnpc | |
363 | wrpr %g0, -1, %tt | |
364 | ||
365 | wrpr %g0, 3, %tl | |
366 | wrpr %g0, -1, %tpc | |
367 | wrpr %g0, -1, %tnpc | |
368 | wrpr %g0, -1, %tt | |
369 | ||
370 | wrpr %g0, 2, %tl | |
371 | wrpr %g0, -1, %tpc | |
372 | wrpr %g0, -1, %tnpc | |
373 | wrpr %g0, -1, %tt | |
374 | ||
375 | wrpr %g0, 1, %tl | |
376 | wrpr %g0, -1, %tpc | |
377 | wrpr %g0, -1, %tnpc | |
378 | wrpr %g0, -1, %tt | |
379 | ||
380 | ! tl == 1 | |
381 | ||
382 | mov -1, %g1 | |
383 | stxa %g1, [%g0]ASI_ERROR_STATUS ! Clear SPARC Error Status | |
384 | ||
385 | mov 0x18, %g1 | |
386 | stxa %g0, [%g1] ASI_IMMU ! Clear IMMU_SFSR | |
387 | stxa %g0, [%g1] ASI_DMMU ! Clear DMMU_SFSR | |
388 | ||
389 | rd %asr26, %g1 | |
390 | or %g1, 0x4, %g1 ! Enable speculative load | |
391 | wr %g1, %g0, %asr26 | |
392 | ||
393 | ret | |
394 | restore | |
395 | ||
396 | SET_SIZE(init_regfile) | |
397 | ||
398 | ||
399 | ENTRY_NP(is_core_master) | |
400 | ||
401 | save %sp, -(MINFRAME64), %sp | |
402 | ||
403 | rd STR_STATUS_REG, %l0 | |
404 | srlx %l0, STR_STATUS_CPU_ID_SHIFT, %l0 | |
405 | and %l0, STR_STATUS_CPU_ID_MASK, %l0 ! cpu_id | |
406 | ||
407 | mov CPU_ID_STRAND_MASK, %l7 | |
408 | andn %l0, %l7, %l1 ! id of the first cpu in the core | |
409 | ||
410 | srlx %i0, %l1, %l2 | |
411 | and %l2, CPU_ID_MASK, %l2 | |
412 | ||
413 | add %l1, N_THREADS_PER_CORE, %l3 | |
414 | ||
415 | 1: | |
416 | andcc %l2, 1, %g0 | |
417 | bne,pt %xcc, 2f | |
418 | nop | |
419 | inc %l1 | |
420 | srlx %l2, 1, %l2 | |
421 | cmp %l1, %l3 | |
422 | bne,pt %xcc, 1b | |
423 | nop | |
424 | 2: | |
425 | mov 0, %i0 | |
426 | cmp %l1, %l0 | |
427 | movz %xcc, 1, %i0 | |
428 | ||
429 | ret | |
430 | restore | |
431 | ||
432 | SET_SIZE(is_core_master) | |
433 | ||
434 | ||
435 | ENTRY_NP(is_master_cpu) | |
436 | ||
437 | save %sp, -(MINFRAME64), %sp | |
438 | ||
439 | rd STR_STATUS_REG, %l0 | |
440 | srlx %l0, STR_STATUS_CPU_ID_SHIFT, %l0 | |
441 | and %l0, STR_STATUS_CPU_ID_MASK, %l0 ! cpu_id | |
442 | ||
443 | mov 0, %l1 | |
444 | mov %i0, %l2 | |
445 | ||
446 | mov N_THREADS, %l3 | |
447 | ||
448 | 1: | |
449 | andcc %l2, 1, %g0 | |
450 | bne,pt %xcc, 2f | |
451 | nop | |
452 | inc %l1 | |
453 | srlx %l2, 1, %l2 | |
454 | cmp %l1, %l3 | |
455 | bne,pt %xcc, 1b | |
456 | nop | |
457 | 2: | |
458 | mov 0, %i0 | |
459 | cmp %l1, %l0 | |
460 | movz %xcc, 1, %i0 | |
461 | ||
462 | ret | |
463 | restore | |
464 | ||
465 | SET_SIZE(is_master_cpu) | |
466 | ||
467 | ||
468 | ||
469 | ENTRY_NP(wakeup_slave_threads) | |
470 | ||
471 | save %sp, -(MINFRAME64), %sp | |
472 | ||
473 | rd STR_STATUS_REG, %l0 | |
474 | srlx %l0, STR_STATUS_CPU_ID_SHIFT, %l0 | |
475 | and %l0, STR_STATUS_CPU_ID_MASK, %l0 ! cpu_id | |
476 | ||
477 | mov CPU_ID_STRAND_MASK, %l7 | |
478 | andn %l0, %l7, %l1 ! id of the first cpu in the core | |
479 | ||
480 | srlx %i0, %l0, %l2 | |
481 | and %l2, CPU_ID_MASK, %l2 | |
482 | ||
483 | add %l1, N_THREADS_PER_CORE, %l3 | |
484 | ||
485 | 1: | |
486 | inc %l0 | |
487 | srlx %l2, 1, %l2 | |
488 | cmp %l0, %l3 | |
489 | beq,pt %xcc, 2f | |
490 | nop | |
491 | ||
492 | andcc %l2, 1, %g0 | |
493 | beq,pt %xcc, 1b | |
494 | nop | |
495 | ||
496 | setx IOBBASE + INT_VEC_DIS, %g4, %g5 | |
497 | mov INT_VEC_DIS_TYPE_RESET, %g4 | |
498 | sllx %g4, INT_VEC_DIS_TYPE_SHIFT, %g4 | |
499 | or %g4, INT_VEC_DIS_VECTOR_RESET, %g4 | |
500 | ||
501 | sllx %l0, INT_VEC_DIS_VCID_SHIFT, %g3 | |
502 | or %g4, %g3, %g3 | |
503 | stx %g3, [%g5] | |
504 | ||
505 | brz,pt %g0, 1b | |
506 | nop | |
507 | ||
508 | 2: | |
509 | ret | |
510 | restore | |
511 | ||
512 | SET_SIZE(wakeup_slave_threads) | |
513 | ||
514 | ||
515 | ||
516 | ENTRY_NP(init_tlbs) | |
517 | ||
518 | save %sp, -(MINFRAME64), %sp | |
519 | ||
520 | stxa %g0, [%g0]ASI_TLB_INVALIDATE ! ITLB | |
521 | mov 0x8, %o1 | |
522 | stxa %g0, [%o1]ASI_TLB_INVALIDATE ! DTLB | |
523 | membar #Sync | |
524 | ||
525 | ret | |
526 | restore | |
527 | ||
528 | SET_SIZE(init_tlbs) | |
529 | ||
530 | ||
531 | ||
532 | ||
533 | ENTRY_NP(l1_bisi) | |
534 | ||
535 | save %sp, -(MINFRAME64), %sp | |
536 | ||
537 | set BIST_START, %l1 | |
538 | stxa %l1, [%g0]ASI_NIAGARA | |
539 | ||
540 | 1: ldxa [%g0]ASI_NIAGARA, %l0 | |
541 | andcc %l0, BIST_DONE, %l0 | |
542 | be,pt %xcc, 1b | |
543 | nop | |
544 | ||
545 | ret | |
546 | restore | |
547 | ||
548 | SET_SIZE(l1_bisi) | |
549 | ||
550 | ||
551 | ||
552 | ENTRY_NP(init_icache) | |
553 | save %sp, -(MINFRAME64), %sp | |
554 | ||
555 | set (ICACHE_MAX_WAYS - 1), %l0 /* way */ | |
556 | sllx %l0, 16, %l2 | |
557 | set (1 << 13), %l1 /* index */ | |
558 | ||
559 | ||
560 | 1: subcc %l1, (1 << 3), %l1 | |
561 | stxa %g0, [%l1+%l2] ASI_ICACHE_INSTR | |
562 | bne,pt %xcc, 1b | |
563 | nop | |
564 | ||
565 | set (1 << 13), %l1 /* index */ | |
566 | subcc %l0, 1, %l0 | |
567 | bge,pt %xcc, 1b | |
568 | sllx %l0, 16, %l2 | |
569 | ||
570 | set (ICACHE_MAX_WAYS - 1), %l0 /* way */ | |
571 | set (1 << 13), %l1 /* index */ | |
572 | sllx %l0, 16, %l2 | |
573 | ||
574 | 2: subcc %l1, (1 << 6), %l1 | |
575 | stxa %g0, [%l1+%l2] ASI_ICACHE_TAG | |
576 | bne,pt %xcc, 2b | |
577 | nop | |
578 | ||
579 | set (1 << 13), %l1 /* index */ | |
580 | subcc %l0, 1, %l0 | |
581 | bge,pt %xcc, 2b | |
582 | sllx %l0, 16, %l2 | |
583 | ||
584 | ret | |
585 | restore | |
586 | SET_SIZE(init_icache) | |
587 | ||
588 | ||
589 | ||
590 | /* | |
591 | * init_dcache - init D$ tag, data | |
592 | */ | |
593 | ||
594 | ENTRY_NP(init_dcache) | |
595 | save %sp, -(MINFRAME64), %sp | |
596 | ||
597 | set (1 << 13), %l0 /* index */ | |
598 | 1: subcc %l0, (1 << 3), %l0 | |
599 | stxa %g0, [%l0]ASI_DC_DATA | |
600 | bne,pt %xcc, 1b | |
601 | nop | |
602 | ||
603 | set (1 << 13), %l0 /* index */ | |
604 | 2: subcc %l0, (1 << 4), %l0 | |
605 | stxa %g0, [%l0]ASI_DC_TAG | |
606 | bne,pt %xcc, 2b | |
607 | nop | |
608 | ||
609 | ret | |
610 | restore | |
611 | SET_SIZE(init_dcache) | |
612 | ||
613 | ||
614 | ||
615 | !! KEEP THIS AT THE END | |
616 | .align 0x100 |