aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/head_32.S
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-06-25 13:06:12 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-06-25 13:10:36 -0400
commit7b0cfee1a24efdfe0235bac62e53f686fe8a8e24 (patch)
treeeeeb8cc3bf7be5ec0e54b7c4f3808ef88ecca012 /arch/sparc/kernel/head_32.S
parent9756fe38d10b2bf90c81dc4d2f17d5632e135364 (diff)
parent6b16351acbd415e66ba16bf7d473ece1574cf0bc (diff)
Merge tag 'v3.5-rc4' into drm-intel-next-queued
I want to merge the "no more fake agp on gen6+" patches into drm-intel-next (well, the last pieces). But a patch in 3.5-rc4 also adds a new use of dev->agp. Hence the backmarge to sort this out, for otherwise drm-intel-next merged into Linus' tree would conflict in the relevant code, things would compile but nicely OOPS at driver load :( Conflicts in this merge are just simple cases of "both branches changed/added lines at the same place". The only tricky part is to keep the order correct wrt the unwind code in case of errors in intel_ringbuffer.c (and the MI_DISPLAY_FLIP #defines in i915_reg.h together, obviously). Conflicts: drivers/gpu/drm/i915/i915_reg.h drivers/gpu/drm/i915/intel_ringbuffer.c Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'arch/sparc/kernel/head_32.S')
-rw-r--r--arch/sparc/kernel/head_32.S168
1 files changed, 102 insertions, 66 deletions
diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S
index a0f5c20e4b9c..afeb1d770303 100644
--- a/arch/sparc/kernel/head_32.S
+++ b/arch/sparc/kernel/head_32.S
@@ -30,10 +30,6 @@
30 * the cpu-type 30 * the cpu-type
31 */ 31 */
32 .align 4 32 .align 4
33cputyp:
34 .word 1
35
36 .align 4
37 .globl cputypval 33 .globl cputypval
38cputypval: 34cputypval:
39 .asciz "sun4m" 35 .asciz "sun4m"
@@ -46,8 +42,8 @@ cputypvar:
46 42
47 .align 4 43 .align 4
48 44
49sun4c_notsup: 45notsup:
50 .asciz "Sparc-Linux sun4/sun4c support does no longer exist.\n\n" 46 .asciz "Sparc-Linux sun4/sun4c or MMU-less not supported\n\n"
51 .align 4 47 .align 4
52 48
53sun4e_notsup: 49sun4e_notsup:
@@ -123,7 +119,7 @@ current_pc:
123 tst %o0 119 tst %o0
124 be no_sun4u_here 120 be no_sun4u_here
125 mov %g4, %o7 /* Previous %o7. */ 121 mov %g4, %o7 /* Previous %o7. */
126 122
127 mov %o0, %l0 ! stash away romvec 123 mov %o0, %l0 ! stash away romvec
128 mov %o0, %g7 ! put it here too 124 mov %o0, %g7 ! put it here too
129 mov %o1, %l1 ! stash away debug_vec too 125 mov %o1, %l1 ! stash away debug_vec too
@@ -132,7 +128,7 @@ current_pc:
132 set current_pc, %g5 128 set current_pc, %g5
133 cmp %g3, %g5 129 cmp %g3, %g5
134 be already_mapped 130 be already_mapped
135 nop 131 nop
136 132
137 /* %l6 will hold the offset we have to subtract 133 /* %l6 will hold the offset we have to subtract
138 * from absolute symbols in order to access areas 134 * from absolute symbols in order to access areas
@@ -192,9 +188,9 @@ copy_prom_done:
192 bne not_a_sun4 188 bne not_a_sun4
193 nop 189 nop
194 190
195halt_sun4_or_sun4c: 191halt_notsup:
196 ld [%g7 + 0x68], %o1 192 ld [%g7 + 0x68], %o1
197 set sun4c_notsup, %o0 193 set notsup, %o0
198 sub %o0, %l6, %o0 194 sub %o0, %l6, %o0
199 call %o1 195 call %o1
200 nop 196 nop
@@ -202,18 +198,31 @@ halt_sun4_or_sun4c:
202 nop 198 nop
203 199
204not_a_sun4: 200not_a_sun4:
201 /* It looks like this is a machine we support.
202 * Now find out what MMU we are dealing with
203 * LEON - identified by the psr.impl field
204 * Viking - identified by the psr.impl field
205 * In all other cases a sun4m srmmu.
206 * We check that the MMU is enabled in all cases.
207 */
208
209 /* Check if this is a LEON CPU */
210 rd %psr, %g3
211 srl %g3, PSR_IMPL_SHIFT, %g3
212 and %g3, PSR_IMPL_SHIFTED_MASK, %g3
213 cmp %g3, PSR_IMPL_LEON
214 be leon_remap /* It is a LEON - jump */
215 nop
216
217 /* Sanity-check, is MMU enabled */
205 lda [%g0] ASI_M_MMUREGS, %g1 218 lda [%g0] ASI_M_MMUREGS, %g1
206 andcc %g1, 1, %g0 219 andcc %g1, 1, %g0
207 be halt_sun4_or_sun4c 220 be halt_notsup
208 nop 221 nop
209 222
210srmmu_remap: 223 /* Check for a viking (TI) module. */
211 /* First, check for a viking (TI) module. */ 224 cmp %g3, PSR_IMPL_TI
212 set 0x40000000, %g2 225 bne srmmu_not_viking
213 rd %psr, %g3
214 and %g2, %g3, %g3
215 subcc %g3, 0x0, %g0
216 bz srmmu_nviking
217 nop 226 nop
218 227
219 /* Figure out what kind of viking we are on. 228 /* Figure out what kind of viking we are on.
@@ -228,14 +237,14 @@ srmmu_remap:
228 lda [%g0] ASI_M_MMUREGS, %g3 ! peek in the control reg 237 lda [%g0] ASI_M_MMUREGS, %g3 ! peek in the control reg
229 and %g2, %g3, %g3 238 and %g2, %g3, %g3
230 subcc %g3, 0x0, %g0 239 subcc %g3, 0x0, %g0
231 bnz srmmu_nviking ! is in mbus mode 240 bnz srmmu_not_viking ! is in mbus mode
232 nop 241 nop
233 242
234 rd %psr, %g3 ! DO NOT TOUCH %g3 243 rd %psr, %g3 ! DO NOT TOUCH %g3
235 andn %g3, PSR_ET, %g2 244 andn %g3, PSR_ET, %g2
236 wr %g2, 0x0, %psr 245 wr %g2, 0x0, %psr
237 WRITE_PAUSE 246 WRITE_PAUSE
238 247
239 /* Get context table pointer, then convert to 248 /* Get context table pointer, then convert to
240 * a physical address, which is 36 bits. 249 * a physical address, which is 36 bits.
241 */ 250 */
@@ -258,12 +267,12 @@ srmmu_remap:
258 lda [%g4] ASI_M_BYPASS, %o1 ! This is a level 1 ptr 267 lda [%g4] ASI_M_BYPASS, %o1 ! This is a level 1 ptr
259 srl %o1, 0x4, %o1 ! Clear low 4 bits 268 srl %o1, 0x4, %o1 ! Clear low 4 bits
260 sll %o1, 0x8, %o1 ! Make physical 269 sll %o1, 0x8, %o1 ! Make physical
261 270
262 /* Ok, pull in the PTD. */ 271 /* Ok, pull in the PTD. */
263 lda [%o1] ASI_M_BYPASS, %o2 ! This is the 0x0 16MB pgd 272 lda [%o1] ASI_M_BYPASS, %o2 ! This is the 0x0 16MB pgd
264 273
265 /* Calculate to KERNBASE entry. */ 274 /* Calculate to KERNBASE entry. */
266 add %o1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %o3 275 add %o1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %o3
267 276
268 /* Poke the entry into the calculated address. */ 277 /* Poke the entry into the calculated address. */
269 sta %o2, [%o3] ASI_M_BYPASS 278 sta %o2, [%o3] ASI_M_BYPASS
@@ -293,12 +302,12 @@ srmmu_remap:
293 b go_to_highmem 302 b go_to_highmem
294 nop 303 nop
295 304
305srmmu_not_viking:
296 /* This works on viking's in Mbus mode and all 306 /* This works on viking's in Mbus mode and all
297 * other MBUS modules. It is virtually the same as 307 * other MBUS modules. It is virtually the same as
298 * the above madness sans turning traps off and flipping 308 * the above madness sans turning traps off and flipping
299 * the AC bit. 309 * the AC bit.
300 */ 310 */
301srmmu_nviking:
302 set AC_M_CTPR, %g1 311 set AC_M_CTPR, %g1
303 lda [%g1] ASI_M_MMUREGS, %g1 ! get ctx table ptr 312 lda [%g1] ASI_M_MMUREGS, %g1 ! get ctx table ptr
304 sll %g1, 0x4, %g1 ! make physical addr 313 sll %g1, 0x4, %g1 ! make physical addr
@@ -313,6 +322,29 @@ srmmu_nviking:
313 nop ! wheee.... 322 nop ! wheee....
314 323
315 324
325leon_remap:
326 /* Sanity-check, is MMU enabled */
327 lda [%g0] ASI_LEON_MMUREGS, %g1
328 andcc %g1, 1, %g0
329 be halt_notsup
330 nop
331
332 /* Same code as in the srmmu_not_viking case,
333 * with the LEON ASI for mmuregs
334 */
335 set AC_M_CTPR, %g1
336 lda [%g1] ASI_LEON_MMUREGS, %g1 ! get ctx table ptr
337 sll %g1, 0x4, %g1 ! make physical addr
338 lda [%g1] ASI_M_BYPASS, %g1 ! ptr to level 1 pg_table
339 srl %g1, 0x4, %g1
340 sll %g1, 0x8, %g1 ! make phys addr for l1 tbl
341
342 lda [%g1] ASI_M_BYPASS, %g2 ! get level1 entry for 0x0
343 add %g1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %g3
344 sta %g2, [%g3] ASI_M_BYPASS ! place at KERNBASE entry
345 b go_to_highmem
346 nop ! wheee....
347
316/* Now do a non-relative jump so that PC is in high-memory */ 348/* Now do a non-relative jump so that PC is in high-memory */
317go_to_highmem: 349go_to_highmem:
318 set execute_in_high_mem, %g1 350 set execute_in_high_mem, %g1
@@ -336,8 +368,9 @@ execute_in_high_mem:
336 sethi %hi(linux_dbvec), %g1 368 sethi %hi(linux_dbvec), %g1
337 st %o1, [%g1 + %lo(linux_dbvec)] 369 st %o1, [%g1 + %lo(linux_dbvec)]
338 370
339/* Get the machine type via the mysterious romvec node operations. */ 371 /* Get the machine type via the romvec
340 372 * getprops node operation
373 */
341 add %g7, 0x1c, %l1 374 add %g7, 0x1c, %l1
342 ld [%l1], %l0 375 ld [%l1], %l0
343 ld [%l0], %l0 376 ld [%l0], %l0
@@ -356,9 +389,42 @@ execute_in_high_mem:
356 ! to a buf where above string 389 ! to a buf where above string
357 ! will get stored by the prom. 390 ! will get stored by the prom.
358 391
359#ifdef CONFIG_SPARC_LEON
360 /* no cpu-type check is needed, it is a SPARC-LEON */
361 392
393 /* Check value of "compatible" property.
394 * "value" => "model"
395 * leon => sparc_leon
396 * sun4m => sun4m
397 * sun4s => sun4m
398 * sun4d => sun4d
399 * sun4e => "no_sun4e_here"
400 * '*' => "no_sun4u_here"
401 * Check single letters only
402 */
403
404 set cputypval, %o2
405 /* If cputypval[0] == 'l' (lower case letter L) this is leon */
406 ldub [%o2], %l1
407 cmp %l1, 'l'
408 be leon_init
409 nop
410
411 /* Check cputypval[4] to find the sun model */
412 ldub [%o2 + 0x4], %l1
413
414 cmp %l1, 'm'
415 be sun4m_init
416 cmp %l1, 's'
417 be sun4m_init
418 cmp %l1, 'd'
419 be sun4d_init
420 cmp %l1, 'e'
421 be no_sun4e_here ! Could be a sun4e.
422 nop
423 b no_sun4u_here ! AIEEE, a V9 sun4u... Get our BIG BROTHER kernel :))
424 nop
425
426leon_init:
427 /* LEON CPU - set boot_cpu_id */
362 sethi %hi(boot_cpu_id), %g2 ! boot-cpu index 428 sethi %hi(boot_cpu_id), %g2 ! boot-cpu index
363 429
364#ifdef CONFIG_SMP 430#ifdef CONFIG_SMP
@@ -376,26 +442,6 @@ execute_in_high_mem:
376 442
377 ba continue_boot 443 ba continue_boot
378 nop 444 nop
379#endif
380
381/* Check to cputype. We may be booted on a sun4u (64 bit box),
382 * and sun4d needs special treatment.
383 */
384
385 set cputypval, %o2
386 ldub [%o2 + 0x4], %l1
387
388 cmp %l1, 'm'
389 be sun4m_init
390 cmp %l1, 's'
391 be sun4m_init
392 cmp %l1, 'd'
393 be sun4d_init
394 cmp %l1, 'e'
395 be no_sun4e_here ! Could be a sun4e.
396 nop
397 b no_sun4u_here ! AIEEE, a V9 sun4u... Get our BIG BROTHER kernel :))
398 nop
399 445
400/* CPUID in bootbus can be found at PA 0xff0140000 */ 446/* CPUID in bootbus can be found at PA 0xff0140000 */
401#define SUN4D_BOOTBUS_CPUID 0xf0140000 447#define SUN4D_BOOTBUS_CPUID 0xf0140000
@@ -431,9 +477,9 @@ sun4m_init:
431/* This sucks, apparently this makes Vikings call prom panic, will fix later */ 477/* This sucks, apparently this makes Vikings call prom panic, will fix later */
4322: 4782:
433 rd %psr, %o1 479 rd %psr, %o1
434 srl %o1, 28, %o1 ! Get a type of the CPU 480 srl %o1, PSR_IMPL_SHIFT, %o1 ! Get a type of the CPU
435 481
436 subcc %o1, 4, %g0 ! TI: Viking or MicroSPARC 482 subcc %o1, PSR_IMPL_TI, %g0 ! TI: Viking or MicroSPARC
437 be continue_boot 483 be continue_boot
438 nop 484 nop
439 485
@@ -459,10 +505,6 @@ continue_boot:
459/* Aieee, now set PC and nPC, enable traps, give ourselves a stack and it's 505/* Aieee, now set PC and nPC, enable traps, give ourselves a stack and it's
460 * show-time! 506 * show-time!
461 */ 507 */
462
463 sethi %hi(cputyp), %o0
464 st %g4, [%o0 + %lo(cputyp)]
465
466 /* Turn on Supervisor, EnableFloating, and all the PIL bits. 508 /* Turn on Supervisor, EnableFloating, and all the PIL bits.
467 * Also puts us in register window zero with traps off. 509 * Also puts us in register window zero with traps off.
468 */ 510 */
@@ -480,7 +522,7 @@ continue_boot:
480 set __bss_start , %o0 ! First address of BSS 522 set __bss_start , %o0 ! First address of BSS
481 set _end , %o1 ! Last address of BSS 523 set _end , %o1 ! Last address of BSS
482 add %o0, 0x1, %o0 524 add %o0, 0x1, %o0
4831: 5251:
484 stb %g0, [%o0] 526 stb %g0, [%o0]
485 subcc %o0, %o1, %g0 527 subcc %o0, %o1, %g0
486 bl 1b 528 bl 1b
@@ -546,7 +588,7 @@ continue_boot:
546 set dest, %g2; \ 588 set dest, %g2; \
547 ld [%g5], %g4; \ 589 ld [%g5], %g4; \
548 st %g4, [%g2]; 590 st %g4, [%g2];
549 591
550 /* Patch for window spills... */ 592 /* Patch for window spills... */
551 PATCH_INSN(spnwin_patch1_7win, spnwin_patch1) 593 PATCH_INSN(spnwin_patch1_7win, spnwin_patch1)
552 PATCH_INSN(spnwin_patch2_7win, spnwin_patch2) 594 PATCH_INSN(spnwin_patch2_7win, spnwin_patch2)
@@ -597,7 +639,7 @@ continue_boot:
597 st %g4, [%g5 + 0x18] 639 st %g4, [%g5 + 0x18]
598 st %g4, [%g5 + 0x1c] 640 st %g4, [%g5 + 0x1c]
599 641
6002: 6422:
601 sethi %hi(nwindows), %g4 643 sethi %hi(nwindows), %g4
602 st %g3, [%g4 + %lo(nwindows)] ! store final value 644 st %g3, [%g4 + %lo(nwindows)] ! store final value
603 sub %g3, 0x1, %g3 645 sub %g3, 0x1, %g3
@@ -617,18 +659,12 @@ continue_boot:
617 wr %g3, PSR_ET, %psr 659 wr %g3, PSR_ET, %psr
618 WRITE_PAUSE 660 WRITE_PAUSE
619 661
620 /* First we call prom_init() to set up PROMLIB, then 662 /* Call sparc32_start_kernel(struct linux_romvec *rp) */
621 * off to start_kernel().
622 */
623
624 sethi %hi(prom_vector_p), %g5 663 sethi %hi(prom_vector_p), %g5
625 ld [%g5 + %lo(prom_vector_p)], %o0 664 ld [%g5 + %lo(prom_vector_p)], %o0
626 call prom_init 665 call sparc32_start_kernel
627 nop 666 nop
628 667
629 call start_kernel
630 nop
631
632 /* We should not get here. */ 668 /* We should not get here. */
633 call halt_me 669 call halt_me
634 nop 670 nop
@@ -659,7 +695,7 @@ sun4u_5:
659 .asciz "write" 695 .asciz "write"
660 .align 4 696 .align 4
661sun4u_6: 697sun4u_6:
662 .asciz "\n\rOn sun4u you have to use UltraLinux (64bit) kernel\n\rand not a 32bit sun4[cdem] version\n\r\n\r" 698 .asciz "\n\rOn sun4u you have to use sparc64 kernel\n\rand not a sparc32 version\n\r\n\r"
663sun4u_6e: 699sun4u_6e:
664 .align 4 700 .align 4
665sun4u_7: 701sun4u_7: