
Am 21.09.2016 um 15:59 schrieb Paul Burton:
Some systems are configured such that multiple CPUs begin running from their reset vector following a system reset. If this occurs then U-Boot will be run on multiple CPUs simultaneously, which causes all sorts of issues as the multiple instances of U-Boot clobber each other.
Prevent this from happening by simply hanging with an infinite loop if we run on a CPU whose ID, as determined by GlobalNumber or EBase.CPUNum as appropriate, is non-zero.
Signed-off-by: Paul Burton paul.burton@imgtec.com
Changes in v4:
- Presume Config5 is present for MIPSr6, as the arch says it will be
Changes in v3:
- Fix branch target for MIPSr6 case... Oops!
Changes in v2:
- Rebase atop u-boot-mips/next
- Execute a wait instruction in the loop
- Fill delay slots with NOPs
arch/mips/cpu/start.S | 21 ++++++++++++++++++++- arch/mips/include/asm/mipsregs.h | 7 +++++++ 2 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/arch/mips/cpu/start.S b/arch/mips/cpu/start.S index 8f85ede..5eca829 100644 --- a/arch/mips/cpu/start.S +++ b/arch/mips/cpu/start.S @@ -108,9 +108,28 @@ ENTRY(_start)
.align 4 reset: +#if __mips_isa_rev >= 6
- mfc0 t0, CP0_CONFIG, 5
- and t0, t0, MIPS_CONF5_VP
- beqz t0, 1f
nop
- b 2f
mfc0 t0, CP0_GLOBALNUMBER
+#endif
+1: mfc0 t0, CP0_EBASE
- and t0, t0, EBASE_CPUNUM
just nit-picking but actually you're creating dead code for MIPS r6 by the permanent branch to label 2. Maybe it's better to move these two lines to the #else branch of "#if __mips_isa_rev >= 6" and save the branch to label 2?
- /* Hang if this isn't the first CPU in the system */
+2: beqz t0, 4f
nop
+3: wait
b 3b
nop
/* Clear watch registers */
- MTC0 zero, CP0_WATCHLO
+4: MTC0 zero, CP0_WATCHLO mtc0 zero, CP0_WATCHHI
/* WP(Watch Pending), SW0/1 should be cleared */ diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index b4c2dff..9ab5063 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -39,6 +39,7 @@ #define CP0_ENTRYLO0 $2 #define CP0_ENTRYLO1 $3 #define CP0_CONF $3 +#define CP0_GLOBALNUMBER $3, 1 #define CP0_CONTEXT $4 #define CP0_PAGEMASK $5 #define CP0_WIRED $6 @@ -361,6 +362,11 @@ #define CAUSEF_BD (_ULCAST_(1) << 31)
/*
- Bits in the coprocessor 0 EBase register.
- */
+#define EBASE_CPUNUM 0x3ff
+/*
- Bits in the coprocessor 0 config register.
*/ /* Generic bits. */ @@ -553,6 +559,7 @@ #define MIPS_CONF5_MRP (_ULCAST_(1) << 3) #define MIPS_CONF5_LLB (_ULCAST_(1) << 4) #define MIPS_CONF5_MVH (_ULCAST_(1) << 5) +#define MIPS_CONF5_VP (_ULCAST_(1) << 7) #define MIPS_CONF5_FRE (_ULCAST_(1) << 8) #define MIPS_CONF5_UFE (_ULCAST_(1) << 9) #define MIPS_CONF5_L2C (_ULCAST_(1) << 10)