patch-2.4.4 linux/arch/mips/kernel/setup.c

Next file: linux/arch/mips/kernel/signal.c
Previous file: linux/arch/mips/kernel/semaphore.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.3/linux/arch/mips/kernel/setup.c linux/arch/mips/kernel/setup.c
@@ -4,8 +4,9 @@
  * for more details.
  *
  * Copyright (C) 1995  Linus Torvalds
- * Copyright (C) 1995, 1996, 1997, 1998  Ralf Baechle
+ * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000  Ralf Baechle
  * Copyright (C) 1996  Stoned Elipot
+ * Copyright (C) 2000  Maciej W. Rozycki
  */
 #include <linux/config.h>
 #include <linux/errno.h>
@@ -36,10 +37,10 @@
 #include <asm/asm.h>
 #include <asm/bootinfo.h>
 #include <asm/cachectl.h>
+#include <asm/cpu.h>
 #include <asm/io.h>
 #include <asm/stackframe.h>
 #include <asm/system.h>
-#include <asm/cpu.h>
 #ifdef CONFIG_SGI_IP22
 #include <asm/sgialib.h>
 #endif
@@ -152,64 +153,171 @@
 #endif
 }
 
+/* declaration of the global struct */
+struct mips_cpu mips_cpu = {PRID_IMP_UNKNOWN, CPU_UNKNOWN, 0, 0, 0,
+			    {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}};
+
+/* Shortcut for assembler access to mips_cpu.options */
+int *cpuoptions = &mips_cpu.options;
+
+#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \
+		| MIPS_CPU_COUNTER | MIPS_CPU_CACHE_CDEX)
+
 static inline void cpu_probe(void)
 {
-	unsigned int prid = read_32bit_cp0_register(CP0_PRID);
-	switch(prid & 0xff00) {
+	unsigned long config1;
+
+	mips_cpu.processor_id = read_32bit_cp0_register(CP0_PRID);
+	switch (mips_cpu.processor_id & 0xff00) {
 	case PRID_IMP_R2000:
-		mips_cputype = CPU_R2000;
+		mips_cpu.cputype = CPU_R2000;
+		mips_cpu.isa_level = MIPS_CPU_ISA_I;
+		mips_cpu.options = MIPS_CPU_TLB;
+		mips_cpu.tlbsize = 64;
 		break;
 	case PRID_IMP_R3000:
-		if((prid & 0xff) == PRID_REV_R3000A)
-			if(cpu_has_confreg())
-				mips_cputype = CPU_R3081E;
+		if ((mips_cpu.processor_id & 0xff) == PRID_REV_R3000A)
+			if (cpu_has_confreg())
+				mips_cpu.cputype = CPU_R3081E;
 			else
-				mips_cputype = CPU_R3000A;
+				mips_cpu.cputype = CPU_R3000A;
 		else
-			 mips_cputype = CPU_R3000;
+			 mips_cpu.cputype = CPU_R3000;
+		mips_cpu.isa_level = MIPS_CPU_ISA_I;
+		mips_cpu.options = MIPS_CPU_TLB;
+		mips_cpu.tlbsize = 64;
 		break;
 	case PRID_IMP_R4000:
-		if((prid & 0xff) == PRID_REV_R4400)
-			mips_cputype = CPU_R4400SC;
+		if ((mips_cpu.processor_id & 0xff) == PRID_REV_R4400)
+			mips_cpu.cputype = CPU_R4400SC;
 		else
-			mips_cputype = CPU_R4000SC;
+			mips_cpu.cputype = CPU_R4000SC;
+		mips_cpu.isa_level = MIPS_CPU_ISA_III;
+		mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+		                   MIPS_CPU_WATCH | MIPS_CPU_VCE;
+		mips_cpu.tlbsize = 48;
 		break;
 	case PRID_IMP_R4600:
-		mips_cputype = CPU_R4600;
+		mips_cpu.cputype = CPU_R4600;
+		mips_cpu.isa_level = MIPS_CPU_ISA_III;
+		mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU;
+		mips_cpu.tlbsize = 48;
 		break;
+/*
+ * This processor doesn't have an MMU, so it's not "real easy" to
+ * run Linux on it. It is left purely for documentation.
+ *
 	case PRID_IMP_R4650:
-		mips_cputype = CPU_R4650;
+		mips_cpu.cputype = CPU_R4650;
+		mips_cpu.isa_level = MIPS_CPU_ISA_III;
+		mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU;
+		mips_cpu.tlbsize = 48;
+		break;
+ */
+	case PRID_IMP_R3912:
+		mips_cpu.cputype = CPU_R3912;
+		mips_cpu.isa_level = MIPS_CPU_ISA_I;
+		mips_cpu.options = MIPS_CPU_TLB;
+		mips_cpu.tlbsize = 32;
 		break;
 	case PRID_IMP_R4700:
-		mips_cputype = CPU_R4700;
+		mips_cpu.cputype = CPU_R4700;
+		mips_cpu.isa_level = MIPS_CPU_ISA_III;
+		mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR;
+		mips_cpu.tlbsize = 48;
 		break;
 	case PRID_IMP_R5000:
-		mips_cputype = CPU_R5000;
+		mips_cpu.cputype = CPU_R5000;
+		mips_cpu.isa_level = MIPS_CPU_ISA_IV; 
+		mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR;
+		mips_cpu.tlbsize = 48;
+		break;
+	case PRID_IMP_R5432:
+	        mips_cpu.cputype = CPU_R5432;
+		mips_cpu.isa_level = MIPS_CPU_ISA_IV; 
+		mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR;
+		mips_cpu.tlbsize = 48;
 		break;
 	case PRID_IMP_NEVADA:
-		mips_cputype = CPU_NEVADA;
+		mips_cpu.cputype = CPU_NEVADA;
+		mips_cpu.isa_level = MIPS_CPU_ISA_IV; 
+		mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | 
+		                   MIPS_CPU_DIVEC;
+		mips_cpu.tlbsize = 48;
+		mips_cpu.icache.ways = 2;
+		mips_cpu.dcache.ways = 2;
 		break;
 	case PRID_IMP_R6000:
-		mips_cputype = CPU_R6000;
+		mips_cpu.cputype = CPU_R6000;
+		mips_cpu.isa_level = MIPS_CPU_ISA_II;
+		mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU;
+		mips_cpu.tlbsize = 32;
 		break;
 	case PRID_IMP_R6000A:
-		mips_cputype = CPU_R6000A;
+		mips_cpu.cputype = CPU_R6000A;
+		mips_cpu.isa_level = MIPS_CPU_ISA_II;
+		mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU;
+		mips_cpu.tlbsize = 32;
+		break;
+	case PRID_IMP_RM7000:
+		mips_cpu.cputype = CPU_RM7000;
+	        mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+		mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR;
 		break;
 	case PRID_IMP_R8000:
-		mips_cputype = CPU_R8000;
+		mips_cpu.cputype = CPU_R8000;
+	        mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+		mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+		                   MIPS_CPU_FPU | MIPS_CPU_32FPR;
+		mips_cpu.tlbsize = 384;      /* has wierd TLB: 3-way x 128 */
 		break;
 	case PRID_IMP_R10000:
-		mips_cputype = CPU_R10000;
-		break;
-	case PRID_IMP_RM7000:
-		mips_cputype = CPU_R5000;
+		mips_cpu.cputype = CPU_R10000;
+		mips_cpu.isa_level = MIPS_CPU_ISA_IV;
+		mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
+		                   MIPS_CPU_FPU | MIPS_CPU_32FPR | 
+		                   MIPS_CPU_COUNTER | MIPS_CPU_WATCH;
+		mips_cpu.tlbsize = 64;
+		break;
+#ifdef CONFIG_CPU_MIPS32
+	case PRID_IMP_4KC:
+		mips_cpu.cputype = CPU_4KC;
+		mips_cpu.isa_level = MIPS_CPU_ISA_M32;
+		mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
+		                   MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | 
+		                   MIPS_CPU_DIVEC | MIPS_CPU_WATCH;
+		config1 = read_mips32_cp0_config1();
+		if (config1 & (1 << 3))
+		        mips_cpu.options |= MIPS_CPU_WATCH;
+		if (config1 & (1 << 2))
+		        mips_cpu.options |= MIPS_CPU_MIPS16;
+		if (config1 & 1)
+		        mips_cpu.options |= MIPS_CPU_FPU;
+		mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT;
+		break;
+	case PRID_IMP_5KC:
+		mips_cpu.cputype = CPU_5KC;
+		mips_cpu.isa_level = MIPS_CPU_ISA_M64;
+		mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 
+		                   MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | 
+		                   MIPS_CPU_DIVEC | MIPS_CPU_WATCH;
+		config1 = read_mips32_cp0_config1();
+		if (config1 & (1 << 3))
+		        mips_cpu.options |= MIPS_CPU_WATCH;
+		if (config1 & (1 << 2))
+		        mips_cpu.options |= MIPS_CPU_MIPS16;
+		if (config1 & 1)
+		        mips_cpu.options |= MIPS_CPU_FPU;
+		mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT;
 		break;
+#endif
 	default:
-		mips_cputype = CPU_UNKNOWN;
+		mips_cpu.cputype = CPU_UNKNOWN;
 	}
 }
 
-asmlinkage void __init init_arch(int argc, char **argv, char **envp, int *prom_vec)
+asmlinkage void __init
+init_arch(int argc, char **argv, char **envp, int *prom_vec)
 {
 	unsigned int s;
 
@@ -232,18 +340,13 @@
 	 */
 	loadmmu();
 
-	/* Disable coprocessors */
+	/* Disable coprocessors and set FPU for 16 FPRs */
 	s = read_32bit_cp0_register(CP0_STATUS);
-	s &= ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX);
+	s &= ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_FR);
 	s |= ST0_CU0;
 	write_32bit_cp0_register(CP0_STATUS, s);
 
-	/*
-	 * Main should never return here, but
-	 * just in case, we know what happens.
-	 */
-	for(;;)
-		start_kernel();
+	start_kernel();
 }
 
 static void __init default_irq_setup(void)

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)