patch-2.3.99-pre9 linux/arch/mips/kernel/setup.c
Next file: linux/arch/mips/kernel/signal.c
Previous file: linux/arch/mips/kernel/scall_o32.S
Back to the patch index
Back to the overall index
- Lines: 187
- Date:
Sat May 13 08:29:14 2000
- Orig file:
v2.3.99-pre8/linux/arch/mips/kernel/setup.c
- Orig date:
Sat Feb 26 22:31:40 2000
diff -u --recursive --new-file v2.3.99-pre8/linux/arch/mips/kernel/setup.c linux/arch/mips/kernel/setup.c
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.22 2000/01/27 01:05:23 ralf Exp $
+/* $Id: setup.c,v 1.28 2000/03/13 22:21:44 harald Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -39,6 +39,7 @@
#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
@@ -46,11 +47,13 @@
struct mips_cpuinfo boot_cpu_data = { NULL, NULL, 0 };
/*
- * Not all of the MIPS CPUs have the "wait" instruction available. This
- * is set to true if it is available. The wait instruction stops the
- * pipeline and reduces the power consumption of the CPU very much.
+ * Not all of the MIPS CPUs have the "wait" instruction available. Moreover,
+ * the implementation of the "wait" feature differs between CPU families. This
+ * points to the function that implements CPU specific wait.
+ * The wait instruction stops the pipeline and reduces the power consumption of
+ * the CPU very much.
*/
-char wait_available;
+void (*cpu_wait)(void) = NULL;
/*
* Do we have a cyclecounter available?
@@ -119,6 +122,125 @@
*/
unsigned long isa_slot_offset;
+extern void sgi_sysinit(void);
+extern void SetUpBootInfo(void);
+extern void loadmmu(void);
+extern asmlinkage void start_kernel(void);
+extern int prom_init(int, char **, char **, int *);
+
+/*
+ * Probe whether cpu has config register by trying to play with
+ * alternate cache bit and see whether it matters.
+ * It's used by cpu_probe to distinguish between R3000A and R3081.
+ */
+static inline int cpu_has_confreg(void)
+{
+#ifdef CONFIG_CPU_R3000
+ extern unsigned long r3k_cache_size(unsigned long);
+ unsigned long size1, size2;
+ unsigned long cfg = read_32bit_cp0_register(CP0_CONF);
+
+ size1 = r3k_cache_size(ST0_DE);
+ write_32bit_cp0_register(CP0_CONF, cfg^CONF_AC);
+ size2 = r3k_cache_size(ST0_DE);
+ write_32bit_cp0_register(CP0_CONF, cfg);
+ return size1 != size2;
+#else
+ return 0;
+#endif
+}
+
+static inline void cpu_probe(void)
+{
+ unsigned int prid = read_32bit_cp0_register(CP0_PRID);
+ switch(prid & 0xff00) {
+ case PRID_IMP_R2000:
+ mips_cputype = CPU_R2000;
+ break;
+ case PRID_IMP_R3000:
+ if((prid & 0xff) == PRID_REV_R3000A)
+ if(cpu_has_confreg())
+ mips_cputype = CPU_R3081E;
+ else
+ mips_cputype = CPU_R3000A;
+ else
+ mips_cputype = CPU_R3000;
+ break;
+ case PRID_IMP_R4000:
+ if((prid & 0xff) == PRID_REV_R4400)
+ mips_cputype = CPU_R4400SC;
+ else
+ mips_cputype = CPU_R4000SC;
+ break;
+ case PRID_IMP_R4600:
+ mips_cputype = CPU_R4600;
+ break;
+ case PRID_IMP_R4650:
+ mips_cputype = CPU_R4650;
+ break;
+ case PRID_IMP_R4700:
+ mips_cputype = CPU_R4700;
+ break;
+ case PRID_IMP_R5000:
+ mips_cputype = CPU_R5000;
+ break;
+ case PRID_IMP_NEVADA:
+ mips_cputype = CPU_NEVADA;
+ break;
+ case PRID_IMP_R6000:
+ mips_cputype = CPU_R6000;
+ break;
+ case PRID_IMP_R6000A:
+ mips_cputype = CPU_R6000A;
+ break;
+ case PRID_IMP_R8000:
+ mips_cputype = CPU_R8000;
+ break;
+ case PRID_IMP_R10000:
+ mips_cputype = CPU_R10000;
+ break;
+ default:
+ mips_cputype = CPU_UNKNOWN;
+ }
+}
+
+asmlinkage void __init init_arch(int argc, char **argv, char **envp, int *prom_vec)
+{
+ unsigned int s;
+
+ /* Determine which MIPS variant we are running on. */
+ cpu_probe();
+
+ prom_init(argc, argv, envp, prom_vec);
+
+#ifdef CONFIG_SGI_IP22
+ sgi_sysinit();
+#endif
+#ifdef CONFIG_COBALT_MICRO_SERVER
+ SetUpBootInfo();
+#endif
+
+ /*
+ * Determine the mmu/cache attached to this machine,
+ * then flush the tlb and caches. On the r4xx0
+ * variants this also sets CP0_WIRED to zero.
+ */
+ loadmmu();
+
+ /* Disable coprocessors */
+ s = read_32bit_cp0_register(CP0_STATUS);
+ s &= ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX);
+ 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();
+}
+
static void __init default_irq_setup(void)
{
panic("Unknown machtype in init_IRQ");
@@ -156,7 +278,7 @@
switch(mips_machgroup)
{
#ifdef CONFIG_BAGET_MIPS
- case MACH_GROUP_UNKNOWN:
+ case MACH_GROUP_BAGET:
baget_setup();
break;
#endif
@@ -220,4 +342,19 @@
*memory_start_p = initrd_end;
}
#endif
+
+ paging_init();
+}
+
+void r3081_wait(void)
+{
+ unsigned long cfg = read_32bit_cp0_register(CP0_CONF);
+ write_32bit_cp0_register(CP0_CONF, cfg|CONF_HALT);
+}
+
+void r4k_wait(void)
+{
+ __asm__(".set\tmips3\n\t"
+ "wait\n\t"
+ ".set\tmips0");
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)