瀏覽代碼

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>
Sam Ravnborg 13 年之前
父節點
當前提交
1ddb22e13d
共有 1 個文件被更改,包括 41 次插入32 次删除
  1. 41 32
      arch/sparc/kernel/head_32.S

+ 41 - 32
arch/sparc/kernel/head_32.S

@@ -372,36 +372,9 @@ execute_in_high_mem:
 		sethi	%hi(linux_dbvec), %g1
 		st	%o1, [%g1 + %lo(linux_dbvec)]
 
-		/* Check if this is a LEON CPU.
-		 * Skip getprops call if it is
+		/* Get the machine type via the romvec
+		 * getprops node operation
 		 */
-		srl	%g3, PSR_IMPL_SHIFT, %g3
-		and	%g3, PSR_IMPL_SHIFTED_MASK, %g3
-		cmp	%g3, PSR_IMPL_LEON
-		 bne	get_cputype
-
-
-		/* LEON CPU - set boot_cpu_id */
-		sethi	%hi(boot_cpu_id), %g2	! boot-cpu index
-
-#ifdef CONFIG_SMP
-		ldub	[%g2 + %lo(boot_cpu_id)], %g1
-		cmp	%g1, 0xff		! unset means first CPU
-		bne	leon_smp_cpu_startup	! continue only with master
-		 nop
-#endif
-		/* Get CPU-ID from most significant 4-bit of ASR17 */
-		rd     %asr17, %g1
-		srl    %g1, 28, %g1
-
-		/* Update boot_cpu_id only on boot cpu */
-		stub	%g1, [%g2 + %lo(boot_cpu_id)]
-
-		ba continue_boot
-		 nop
-
-/* Get the machine type via the mysterious romvec node operations. */
-get_cputype:
 		add	%g7, 0x1c, %l1
 		ld	[%l1], %l0
 		ld	[%l0], %l0
@@ -420,10 +393,26 @@ get_cputype:
 						! to a buf where above string
 						! will get stored by the prom.
 
-/* Check to cputype. We may be booted on a sun4u (64 bit box),
- * and sun4d needs special treatment.
- */
+
+		/* Check value of "compatible" property.
+		 * "value" => "model"
+		 * leon => sparc_leon
+		 * sun4m => sun4m
+		 * sun4s => sun4m
+		 * sun4d => sun4d
+		 * sun4e => "no_sun4e_here"
+		 * '*'   => "no_sun4u_here"
+		 * Check single letters only
+		 */
+
 		set	cputypval, %o2
+		/* If cputypval[0] == 'l' (lower case letter L) this is leon */
+		ldub	[%o2], %l1
+		cmp	%l1, 'l'
+		be	leon_init
+		 nop
+
+		/* Check cputypval[4] to find the sun model */
 		ldub	[%o2 + 0x4], %l1
 
 		cmp	%l1, 'm'
@@ -438,6 +427,26 @@ get_cputype:
 		b	no_sun4u_here		! AIEEE, a V9 sun4u... Get our BIG BROTHER kernel :))
 		 nop
 
+leon_init:
+		/* LEON CPU - set boot_cpu_id */
+		sethi	%hi(boot_cpu_id), %g2	! boot-cpu index
+
+#ifdef CONFIG_SMP
+		ldub	[%g2 + %lo(boot_cpu_id)], %g1
+		cmp	%g1, 0xff		! unset means first CPU
+		bne	leon_smp_cpu_startup	! continue only with master
+		 nop
+#endif
+		/* Get CPU-ID from most significant 4-bit of ASR17 */
+		rd     %asr17, %g1
+		srl    %g1, 28, %g1
+
+		/* Update boot_cpu_id only on boot cpu */
+		stub	%g1, [%g2 + %lo(boot_cpu_id)]
+
+		ba continue_boot
+		 nop
+
 /* CPUID in bootbus can be found at PA 0xff0140000 */
 #define SUN4D_BOOTBUS_CPUID     0xf0140000