cpu-probe.c
来自「linux 内核源代码」· C语言 代码 · 共 962 行 · 第 1/2 页
C
962 行
* Undocumented RM7000: Bit 29 in the info register of * the RM7000 v2.0 indicates if the TLB has 48 or 64 * entries. * * 29 1 => 64 entry JTLB * 0 => 48 entry JTLB */ c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48; break; case PRID_IMP_RM9000: c->cputype = CPU_RM9000; c->isa_level = MIPS_CPU_ISA_IV; c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_LLSC; /* * Bit 29 in the info register of the RM9000 * indicates if the TLB has 48 or 64 entries. * * 29 1 => 64 entry JTLB * 0 => 48 entry JTLB */ c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48; break; case PRID_IMP_R8000: c->cputype = CPU_R8000; c->isa_level = MIPS_CPU_ISA_IV; c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_LLSC; c->tlbsize = 384; /* has weird TLB: 3-way x 128 */ break; case PRID_IMP_R10000: c->cputype = CPU_R10000; c->isa_level = MIPS_CPU_ISA_IV; c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX | MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_COUNTER | MIPS_CPU_WATCH | MIPS_CPU_LLSC; c->tlbsize = 64; break; case PRID_IMP_R12000: c->cputype = CPU_R12000; c->isa_level = MIPS_CPU_ISA_IV; c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX | MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_COUNTER | MIPS_CPU_WATCH | MIPS_CPU_LLSC; c->tlbsize = 64; break; case PRID_IMP_R14000: c->cputype = CPU_R14000; c->isa_level = MIPS_CPU_ISA_IV; c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX | MIPS_CPU_FPU | MIPS_CPU_32FPR | MIPS_CPU_COUNTER | MIPS_CPU_WATCH | MIPS_CPU_LLSC; c->tlbsize = 64; break; case PRID_IMP_LOONGSON2: c->cputype = CPU_LOONGSON2; c->isa_level = MIPS_CPU_ISA_III; c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC | MIPS_CPU_32FPR; c->tlbsize = 64; break; }}static char unknown_isa[] __initdata = KERN_ERR \ "Unsupported ISA type, c0.config0: %d.";static inline unsigned int decode_config0(struct cpuinfo_mips *c){ unsigned int config0; int isa; config0 = read_c0_config(); if (((config0 & MIPS_CONF_MT) >> 7) == 1) c->options |= MIPS_CPU_TLB; isa = (config0 & MIPS_CONF_AT) >> 13; switch (isa) { case 0: switch ((config0 & MIPS_CONF_AR) >> 10) { case 0: c->isa_level = MIPS_CPU_ISA_M32R1; break; case 1: c->isa_level = MIPS_CPU_ISA_M32R2; break; default: goto unknown; } break; case 2: switch ((config0 & MIPS_CONF_AR) >> 10) { case 0: c->isa_level = MIPS_CPU_ISA_M64R1; break; case 1: c->isa_level = MIPS_CPU_ISA_M64R2; break; default: goto unknown; } break; default: goto unknown; } return config0 & MIPS_CONF_M;unknown: panic(unknown_isa, config0);}static inline unsigned int decode_config1(struct cpuinfo_mips *c){ unsigned int config1; config1 = read_c0_config1(); if (config1 & MIPS_CONF1_MD) c->ases |= MIPS_ASE_MDMX; if (config1 & MIPS_CONF1_WR) c->options |= MIPS_CPU_WATCH; if (config1 & MIPS_CONF1_CA) c->ases |= MIPS_ASE_MIPS16; if (config1 & MIPS_CONF1_EP) c->options |= MIPS_CPU_EJTAG; if (config1 & MIPS_CONF1_FP) { c->options |= MIPS_CPU_FPU; c->options |= MIPS_CPU_32FPR; } if (cpu_has_tlb) c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1; return config1 & MIPS_CONF_M;}static inline unsigned int decode_config2(struct cpuinfo_mips *c){ unsigned int config2; config2 = read_c0_config2(); if (config2 & MIPS_CONF2_SL) c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; return config2 & MIPS_CONF_M;}static inline unsigned int decode_config3(struct cpuinfo_mips *c){ unsigned int config3; config3 = read_c0_config3(); if (config3 & MIPS_CONF3_SM) c->ases |= MIPS_ASE_SMARTMIPS; if (config3 & MIPS_CONF3_DSP) c->ases |= MIPS_ASE_DSP; if (config3 & MIPS_CONF3_VINT) c->options |= MIPS_CPU_VINT; if (config3 & MIPS_CONF3_VEIC) c->options |= MIPS_CPU_VEIC; if (config3 & MIPS_CONF3_MT) c->ases |= MIPS_ASE_MIPSMT; if (config3 & MIPS_CONF3_ULRI) c->options |= MIPS_CPU_ULRI; return config3 & MIPS_CONF_M;}static void __init decode_configs(struct cpuinfo_mips *c){ /* MIPS32 or MIPS64 compliant CPU. */ c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK; c->scache.flags = MIPS_CACHE_NOT_PRESENT; /* Read Config registers. */ if (!decode_config0(c)) return; /* actually worth a panic() */ if (!decode_config1(c)) return; if (!decode_config2(c)) return; if (!decode_config3(c)) return;}static inline void cpu_probe_mips(struct cpuinfo_mips *c){ decode_configs(c); switch (c->processor_id & 0xff00) { case PRID_IMP_4KC: c->cputype = CPU_4KC; break; case PRID_IMP_4KEC: c->cputype = CPU_4KEC; break; case PRID_IMP_4KECR2: c->cputype = CPU_4KEC; break; case PRID_IMP_4KSC: case PRID_IMP_4KSD: c->cputype = CPU_4KSC; break; case PRID_IMP_5KC: c->cputype = CPU_5KC; break; case PRID_IMP_20KC: c->cputype = CPU_20KC; break; case PRID_IMP_24K: case PRID_IMP_24KE: c->cputype = CPU_24K; break; case PRID_IMP_25KF: c->cputype = CPU_25KF; break; case PRID_IMP_34K: c->cputype = CPU_34K; break; case PRID_IMP_74K: c->cputype = CPU_74K; break; }}static inline void cpu_probe_alchemy(struct cpuinfo_mips *c){ decode_configs(c); switch (c->processor_id & 0xff00) { case PRID_IMP_AU1_REV1: case PRID_IMP_AU1_REV2: switch ((c->processor_id >> 24) & 0xff) { case 0: c->cputype = CPU_AU1000; break; case 1: c->cputype = CPU_AU1500; break; case 2: c->cputype = CPU_AU1100; break; case 3: c->cputype = CPU_AU1550; break; case 4: c->cputype = CPU_AU1200; break; default: panic("Unknown Au Core!"); break; } break; }}static inline void cpu_probe_sibyte(struct cpuinfo_mips *c){ decode_configs(c); switch (c->processor_id & 0xff00) { case PRID_IMP_SB1: c->cputype = CPU_SB1; /* FPU in pass1 is known to have issues. */ if ((c->processor_id & 0xff) < 0x02) c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR); break; case PRID_IMP_SB1A: c->cputype = CPU_SB1A; break; }}static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c){ decode_configs(c); switch (c->processor_id & 0xff00) { case PRID_IMP_SR71000: c->cputype = CPU_SR71000; c->scache.ways = 8; c->tlbsize = 64; break; }}static inline void cpu_probe_philips(struct cpuinfo_mips *c){ decode_configs(c); switch (c->processor_id & 0xff00) { case PRID_IMP_PR4450: c->cputype = CPU_PR4450; c->isa_level = MIPS_CPU_ISA_M32R1; break; default: panic("Unknown Philips Core!"); /* REVISIT: die? */ break; }}static inline void cpu_probe_broadcom(struct cpuinfo_mips *c){ decode_configs(c); switch (c->processor_id & 0xff00) { case PRID_IMP_BCM3302: c->cputype = CPU_BCM3302; break; case PRID_IMP_BCM4710: c->cputype = CPU_BCM4710; break; default: c->cputype = CPU_UNKNOWN; break; }}const char *__cpu_name[NR_CPUS];/* * Name a CPU */static __init const char *cpu_to_name(struct cpuinfo_mips *c){ const char *name = NULL; switch (c->cputype) { case CPU_UNKNOWN: name = "unknown"; break; case CPU_R2000: name = "R2000"; break; case CPU_R3000: name = "R3000"; break; case CPU_R3000A: name = "R3000A"; break; case CPU_R3041: name = "R3041"; break; case CPU_R3051: name = "R3051"; break; case CPU_R3052: name = "R3052"; break; case CPU_R3081: name = "R3081"; break; case CPU_R3081E: name = "R3081E"; break; case CPU_R4000PC: name = "R4000PC"; break; case CPU_R4000SC: name = "R4000SC"; break; case CPU_R4000MC: name = "R4000MC"; break; case CPU_R4200: name = "R4200"; break; case CPU_R4400PC: name = "R4400PC"; break; case CPU_R4400SC: name = "R4400SC"; break; case CPU_R4400MC: name = "R4400MC"; break; case CPU_R4600: name = "R4600"; break; case CPU_R6000: name = "R6000"; break; case CPU_R6000A: name = "R6000A"; break; case CPU_R8000: name = "R8000"; break; case CPU_R10000: name = "R10000"; break; case CPU_R12000: name = "R12000"; break; case CPU_R14000: name = "R14000"; break; case CPU_R4300: name = "R4300"; break; case CPU_R4650: name = "R4650"; break; case CPU_R4700: name = "R4700"; break; case CPU_R5000: name = "R5000"; break; case CPU_R5000A: name = "R5000A"; break; case CPU_R4640: name = "R4640"; break; case CPU_NEVADA: name = "Nevada"; break; case CPU_RM7000: name = "RM7000"; break; case CPU_RM9000: name = "RM9000"; break; case CPU_R5432: name = "R5432"; break; case CPU_4KC: name = "MIPS 4Kc"; break; case CPU_5KC: name = "MIPS 5Kc"; break; case CPU_R4310: name = "R4310"; break; case CPU_SB1: name = "SiByte SB1"; break; case CPU_SB1A: name = "SiByte SB1A"; break; case CPU_TX3912: name = "TX3912"; break; case CPU_TX3922: name = "TX3922"; break; case CPU_TX3927: name = "TX3927"; break; case CPU_AU1000: name = "Au1000"; break; case CPU_AU1500: name = "Au1500"; break; case CPU_AU1100: name = "Au1100"; break; case CPU_AU1550: name = "Au1550"; break; case CPU_AU1200: name = "Au1200"; break; case CPU_4KEC: name = "MIPS 4KEc"; break; case CPU_4KSC: name = "MIPS 4KSc"; break; case CPU_VR41XX: name = "NEC Vr41xx"; break; case CPU_R5500: name = "R5500"; break; case CPU_TX49XX: name = "TX49xx"; break; case CPU_20KC: name = "MIPS 20Kc"; break; case CPU_24K: name = "MIPS 24K"; break; case CPU_25KF: name = "MIPS 25Kf"; break; case CPU_34K: name = "MIPS 34K"; break; case CPU_74K: name = "MIPS 74K"; break; case CPU_VR4111: name = "NEC VR4111"; break; case CPU_VR4121: name = "NEC VR4121"; break; case CPU_VR4122: name = "NEC VR4122"; break; case CPU_VR4131: name = "NEC VR4131"; break; case CPU_VR4133: name = "NEC VR4133"; break; case CPU_VR4181: name = "NEC VR4181"; break; case CPU_VR4181A: name = "NEC VR4181A"; break; case CPU_SR71000: name = "Sandcraft SR71000"; break; case CPU_BCM3302: name = "Broadcom BCM3302"; break; case CPU_BCM4710: name = "Broadcom BCM4710"; break; case CPU_PR4450: name = "Philips PR4450"; break; case CPU_LOONGSON2: name = "ICT Loongson-2"; break; default: BUG(); } return name;}__init void cpu_probe(void){ struct cpuinfo_mips *c = ¤t_cpu_data; unsigned int cpu = smp_processor_id(); c->processor_id = PRID_IMP_UNKNOWN; c->fpu_id = FPIR_IMP_NONE; c->cputype = CPU_UNKNOWN; c->processor_id = read_c0_prid(); switch (c->processor_id & 0xff0000) { case PRID_COMP_LEGACY: cpu_probe_legacy(c); break; case PRID_COMP_MIPS: cpu_probe_mips(c); break; case PRID_COMP_ALCHEMY: cpu_probe_alchemy(c); break; case PRID_COMP_SIBYTE: cpu_probe_sibyte(c); break; case PRID_COMP_BROADCOM: cpu_probe_broadcom(c); break; case PRID_COMP_SANDCRAFT: cpu_probe_sandcraft(c); break; case PRID_COMP_PHILIPS: cpu_probe_philips(c); break; default: c->cputype = CPU_UNKNOWN; } /* * Platform code can force the cpu type to optimize code * generation. In that case be sure the cpu type is correctly * manually setup otherwise it could trigger some nasty bugs. */ BUG_ON(current_cpu_type() != c->cputype); if (c->options & MIPS_CPU_FPU) { c->fpu_id = cpu_get_fpu_id(); if (c->isa_level == MIPS_CPU_ISA_M32R1 || c->isa_level == MIPS_CPU_ISA_M32R2 || c->isa_level == MIPS_CPU_ISA_M64R1 || c->isa_level == MIPS_CPU_ISA_M64R2) { if (c->fpu_id & MIPS_FPIR_3D) c->ases |= MIPS_ASE_MIPS3D; } } __cpu_name[cpu] = cpu_to_name(c); if (cpu_has_mips_r2) c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1; else c->srsets = 1;}__init void cpu_report(void){ struct cpuinfo_mips *c = ¤t_cpu_data; printk(KERN_INFO "CPU revision is: %08x (%s)\n", c->processor_id, cpu_name_string()); if (c->options & MIPS_CPU_FPU) printk(KERN_INFO "FPU revision is: %08x\n", c->fpu_id);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?