diff options
author | Sam Ravnborg <sam@ravnborg.org> | 2012-05-29 04:14:12 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-05-29 15:47:36 -0400 |
commit | 1ddb22e13dea3f9511c8e934331e1e44b666bc79 (patch) | |
tree | e0e14e4b9a92a830c3733b0b9573ead9b995b4ac /arch/sparc | |
parent | d4511e694ed9b903d8d3d3957180cabf23d2ee7f (diff) |
sparc32,leon: fix leon bootup
head_32.S failed to set cputypval for leon, causing boot to fail.
The boot failed because we failed to recognize this was a LEON
cpu so we did not preoperly run-time patch the the kernel.
This resulted in an early crash.
Reported-by: Daniel Hellstrom <daniel@gaisler.com>
Tested-by: Daniel Hellstrom <daniel@gaisler.com>
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Cc: Konrad Eisele <konrad@gaisler.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc')
-rw-r--r-- | arch/sparc/kernel/head_32.S | 73 |
1 files changed, 41 insertions, 32 deletions
diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S index cdc7f29ba17b..5364a05177c2 100644 --- a/arch/sparc/kernel/head_32.S +++ b/arch/sparc/kernel/head_32.S | |||
@@ -372,36 +372,9 @@ execute_in_high_mem: | |||
372 | sethi %hi(linux_dbvec), %g1 | 372 | sethi %hi(linux_dbvec), %g1 |
373 | st %o1, [%g1 + %lo(linux_dbvec)] | 373 | st %o1, [%g1 + %lo(linux_dbvec)] |
374 | 374 | ||
375 | /* Check if this is a LEON CPU. | 375 | /* Get the machine type via the romvec |
376 | * Skip getprops call if it is | 376 | * getprops node operation |
377 | */ | 377 | */ |
378 | srl %g3, PSR_IMPL_SHIFT, %g3 | ||
379 | and %g3, PSR_IMPL_SHIFTED_MASK, %g3 | ||
380 | cmp %g3, PSR_IMPL_LEON | ||
381 | bne get_cputype | ||
382 | |||
383 | |||
384 | /* LEON CPU - set boot_cpu_id */ | ||
385 | sethi %hi(boot_cpu_id), %g2 ! boot-cpu index | ||
386 | |||
387 | #ifdef CONFIG_SMP | ||
388 | ldub [%g2 + %lo(boot_cpu_id)], %g1 | ||
389 | cmp %g1, 0xff ! unset means first CPU | ||
390 | bne leon_smp_cpu_startup ! continue only with master | ||
391 | nop | ||
392 | #endif | ||
393 | /* Get CPU-ID from most significant 4-bit of ASR17 */ | ||
394 | rd %asr17, %g1 | ||
395 | srl %g1, 28, %g1 | ||
396 | |||
397 | /* Update boot_cpu_id only on boot cpu */ | ||
398 | stub %g1, [%g2 + %lo(boot_cpu_id)] | ||
399 | |||
400 | ba continue_boot | ||
401 | nop | ||
402 | |||
403 | /* Get the machine type via the mysterious romvec node operations. */ | ||
404 | get_cputype: | ||
405 | add %g7, 0x1c, %l1 | 378 | add %g7, 0x1c, %l1 |
406 | ld [%l1], %l0 | 379 | ld [%l1], %l0 |
407 | ld [%l0], %l0 | 380 | ld [%l0], %l0 |
@@ -420,10 +393,26 @@ get_cputype: | |||
420 | ! to a buf where above string | 393 | ! to a buf where above string |
421 | ! will get stored by the prom. | 394 | ! will get stored by the prom. |
422 | 395 | ||
423 | /* Check to cputype. We may be booted on a sun4u (64 bit box), | 396 | |
424 | * and sun4d needs special treatment. | 397 | /* Check value of "compatible" property. |
425 | */ | 398 | * "value" => "model" |
399 | * leon => sparc_leon | ||
400 | * sun4m => sun4m | ||
401 | * sun4s => sun4m | ||
402 | * sun4d => sun4d | ||
403 | * sun4e => "no_sun4e_here" | ||
404 | * '*' => "no_sun4u_here" | ||
405 | * Check single letters only | ||
406 | */ | ||
407 | |||
426 | set cputypval, %o2 | 408 | set cputypval, %o2 |
409 | /* If cputypval[0] == 'l' (lower case letter L) this is leon */ | ||
410 | ldub [%o2], %l1 | ||
411 | cmp %l1, 'l' | ||
412 | be leon_init | ||
413 | nop | ||
414 | |||
415 | /* Check cputypval[4] to find the sun model */ | ||
427 | ldub [%o2 + 0x4], %l1 | 416 | ldub [%o2 + 0x4], %l1 |
428 | 417 | ||
429 | cmp %l1, 'm' | 418 | cmp %l1, 'm' |
@@ -438,6 +427,26 @@ get_cputype: | |||
438 | b no_sun4u_here ! AIEEE, a V9 sun4u... Get our BIG BROTHER kernel :)) | 427 | b no_sun4u_here ! AIEEE, a V9 sun4u... Get our BIG BROTHER kernel :)) |
439 | nop | 428 | nop |
440 | 429 | ||
430 | leon_init: | ||
431 | /* LEON CPU - set boot_cpu_id */ | ||
432 | sethi %hi(boot_cpu_id), %g2 ! boot-cpu index | ||
433 | |||
434 | #ifdef CONFIG_SMP | ||
435 | ldub [%g2 + %lo(boot_cpu_id)], %g1 | ||
436 | cmp %g1, 0xff ! unset means first CPU | ||
437 | bne leon_smp_cpu_startup ! continue only with master | ||
438 | nop | ||
439 | #endif | ||
440 | /* Get CPU-ID from most significant 4-bit of ASR17 */ | ||
441 | rd %asr17, %g1 | ||
442 | srl %g1, 28, %g1 | ||
443 | |||
444 | /* Update boot_cpu_id only on boot cpu */ | ||
445 | stub %g1, [%g2 + %lo(boot_cpu_id)] | ||
446 | |||
447 | ba continue_boot | ||
448 | nop | ||
449 | |||
441 | /* CPUID in bootbus can be found at PA 0xff0140000 */ | 450 | /* CPUID in bootbus can be found at PA 0xff0140000 */ |
442 | #define SUN4D_BOOTBUS_CPUID 0xf0140000 | 451 | #define SUN4D_BOOTBUS_CPUID 0xf0140000 |
443 | 452 | ||