* Attempt to identify the MIPS CPU as much as possible. * * XXX: Assumes the CPU is MIPS{32,64}{,r2} compliant. * XXX: For now, skip config register selections 2 and 3 * as we don't currently use L2/L3 cache or additional * MIPS32 processor features. */
| 94 | * MIPS32 processor features. |
| 95 | */ |
| 96 | static void |
| 97 | mips_get_identity(struct mips_cpuinfo *cpuinfo) |
| 98 | { |
| 99 | u_int32_t prid; |
| 100 | u_int32_t cfg0; |
| 101 | u_int32_t cfg1; |
| 102 | u_int32_t cfg2; |
| 103 | u_int32_t cfg3; |
| 104 | #if defined(CPU_CNMIPS) |
| 105 | u_int32_t cfg4; |
| 106 | #endif |
| 107 | u_int32_t tmp; |
| 108 | |
| 109 | memset(cpuinfo, 0, sizeof(struct mips_cpuinfo)); |
| 110 | |
| 111 | /* Read and store the PrID ID for CPU identification. */ |
| 112 | prid = mips_rd_prid(); |
| 113 | cpuinfo->cpu_vendor = MIPS_PRID_CID(prid); |
| 114 | cpuinfo->cpu_rev = MIPS_PRID_REV(prid); |
| 115 | cpuinfo->cpu_impl = MIPS_PRID_IMPL(prid); |
| 116 | |
| 117 | /* Read config register selection 0 to learn TLB type. */ |
| 118 | cfg0 = mips_rd_config(); |
| 119 | |
| 120 | cpuinfo->tlb_type = |
| 121 | ((cfg0 & MIPS_CONFIG0_MT_MASK) >> MIPS_CONFIG0_MT_SHIFT); |
| 122 | cpuinfo->icache_virtual = cfg0 & MIPS_CONFIG0_VI; |
| 123 | |
| 124 | /* If config register selection 1 does not exist, return. */ |
| 125 | if (!(cfg0 & MIPS_CONFIG0_M)) |
| 126 | return; |
| 127 | |
| 128 | /* Learn TLB size and L1 cache geometry. */ |
| 129 | cfg1 = mips_rd_config1(); |
| 130 | |
| 131 | /* Get the Config2 and Config3 registers as well. */ |
| 132 | cfg2 = 0; |
| 133 | cfg3 = 0; |
| 134 | if (cfg1 & MIPS_CONFIG1_M) { |
| 135 | cfg2 = mips_rd_config2(); |
| 136 | if (cfg2 & MIPS_CONFIG2_M) |
| 137 | cfg3 = mips_rd_config3(); |
| 138 | } |
| 139 | |
| 140 | /* Save FP implementation revision if FP is present. */ |
| 141 | if (cfg1 & MIPS_CONFIG1_FP) |
| 142 | cpuinfo->fpu_id = MipsFPID(); |
| 143 | |
| 144 | /* Check to see if UserLocal register is implemented. */ |
| 145 | if (cfg3 & MIPS_CONFIG3_ULR) { |
| 146 | /* UserLocal register is implemented, enable it. */ |
| 147 | cpuinfo->userlocal_reg = true; |
| 148 | tmp = mips_rd_hwrena(); |
| 149 | mips_wr_hwrena(tmp | MIPS_HWRENA_UL); |
| 150 | } else { |
| 151 | /* |
| 152 | * UserLocal register is not implemented. Patch |
| 153 | * cpu_switch() and remove unsupported code. |
no test coverage detected