identcpu-v4.c revision 155242
1129198Scognet/* $NetBSD: cpu.c,v 1.55 2004/02/13 11:36:10 wiz Exp $ */ 2129198Scognet 3139735Simp/*- 4129198Scognet * Copyright (c) 1995 Mark Brinicombe. 5129198Scognet * Copyright (c) 1995 Brini. 6129198Scognet * All rights reserved. 7129198Scognet * 8129198Scognet * Redistribution and use in source and binary forms, with or without 9129198Scognet * modification, are permitted provided that the following conditions 10129198Scognet * are met: 11129198Scognet * 1. Redistributions of source code must retain the above copyright 12129198Scognet * notice, this list of conditions and the following disclaimer. 13129198Scognet * 2. Redistributions in binary form must reproduce the above copyright 14129198Scognet * notice, this list of conditions and the following disclaimer in the 15129198Scognet * documentation and/or other materials provided with the distribution. 16129198Scognet * 3. All advertising materials mentioning features or use of this software 17129198Scognet * must display the following acknowledgement: 18129198Scognet * This product includes software developed by Brini. 19129198Scognet * 4. The name of the company nor the name of the author may be used to 20129198Scognet * endorse or promote products derived from this software without specific 21129198Scognet * prior written permission. 22129198Scognet * 23129198Scognet * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED 24129198Scognet * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 25129198Scognet * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26129198Scognet * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27129198Scognet * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28129198Scognet * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29129198Scognet * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30129198Scognet * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31129198Scognet * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32129198Scognet * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33129198Scognet * SUCH DAMAGE. 34129198Scognet * 35129198Scognet * RiscBSD kernel project 36129198Scognet * 37129198Scognet * cpu.c 38129198Scognet * 39129198Scognet * Probing and configuration for the master CPU 40129198Scognet * 41129198Scognet * Created : 10/10/95 42129198Scognet */ 43129198Scognet 44129198Scognet#include <sys/cdefs.h> 45129198Scognet__FBSDID("$FreeBSD: head/sys/arm/arm/identcpu.c 155242 2006-02-03 06:39:57Z imp $"); 46129198Scognet#include <sys/systm.h> 47129198Scognet#include <sys/param.h> 48129198Scognet#include <sys/malloc.h> 49129198Scognet#include <sys/time.h> 50129198Scognet#include <sys/proc.h> 51129198Scognet#include <sys/conf.h> 52135652Scognet#include <sys/kernel.h> 53135652Scognet#include <sys/sysctl.h> 54129198Scognet#include <machine/cpu.h> 55129198Scognet 56129198Scognet#include <machine/cpuconf.h> 57129198Scognet 58129198Scognetchar machine[] = "arm"; 59129198Scognet 60135652ScognetSYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, 61135652Scognet machine, 0, "Machine class"); 62129198Scognetenum cpu_class { 63129198Scognet CPU_CLASS_NONE, 64129198Scognet CPU_CLASS_ARM2, 65129198Scognet CPU_CLASS_ARM2AS, 66129198Scognet CPU_CLASS_ARM3, 67129198Scognet CPU_CLASS_ARM6, 68129198Scognet CPU_CLASS_ARM7, 69129198Scognet CPU_CLASS_ARM7TDMI, 70129198Scognet CPU_CLASS_ARM8, 71129198Scognet CPU_CLASS_ARM9TDMI, 72129198Scognet CPU_CLASS_ARM9ES, 73129198Scognet CPU_CLASS_ARM10E, 74129198Scognet CPU_CLASS_SA1, 75129198Scognet CPU_CLASS_XSCALE 76129198Scognet}; 77129198Scognet 78129198Scognetstatic const char * const generic_steppings[16] = { 79129198Scognet "rev 0", "rev 1", "rev 2", "rev 3", 80129198Scognet "rev 4", "rev 5", "rev 6", "rev 7", 81129198Scognet "rev 8", "rev 9", "rev 10", "rev 11", 82129198Scognet "rev 12", "rev 13", "rev 14", "rev 15", 83129198Scognet}; 84129198Scognet 85129198Scognetstatic const char * const sa110_steppings[16] = { 86129198Scognet "rev 0", "step J", "step K", "step S", 87129198Scognet "step T", "rev 5", "rev 6", "rev 7", 88129198Scognet "rev 8", "rev 9", "rev 10", "rev 11", 89129198Scognet "rev 12", "rev 13", "rev 14", "rev 15", 90129198Scognet}; 91129198Scognet 92129198Scognetstatic const char * const sa1100_steppings[16] = { 93129198Scognet "rev 0", "step B", "step C", "rev 3", 94129198Scognet "rev 4", "rev 5", "rev 6", "rev 7", 95129198Scognet "step D", "step E", "rev 10" "step G", 96129198Scognet "rev 12", "rev 13", "rev 14", "rev 15", 97129198Scognet}; 98129198Scognet 99129198Scognetstatic const char * const sa1110_steppings[16] = { 100129198Scognet "step A-0", "rev 1", "rev 2", "rev 3", 101129198Scognet "step B-0", "step B-1", "step B-2", "step B-3", 102129198Scognet "step B-4", "step B-5", "rev 10", "rev 11", 103129198Scognet "rev 12", "rev 13", "rev 14", "rev 15", 104129198Scognet}; 105129198Scognet 106129198Scognetstatic const char * const ixp12x0_steppings[16] = { 107129198Scognet "(IXP1200 step A)", "(IXP1200 step B)", 108129198Scognet "rev 2", "(IXP1200 step C)", 109129198Scognet "(IXP1200 step D)", "(IXP1240/1250 step A)", 110129198Scognet "(IXP1240 step B)", "(IXP1250 step B)", 111129198Scognet "rev 8", "rev 9", "rev 10", "rev 11", 112129198Scognet "rev 12", "rev 13", "rev 14", "rev 15", 113129198Scognet}; 114129198Scognet 115129198Scognetstatic const char * const xscale_steppings[16] = { 116129198Scognet "step A-0", "step A-1", "step B-0", "step C-0", 117129198Scognet "step D-0", "rev 5", "rev 6", "rev 7", 118129198Scognet "rev 8", "rev 9", "rev 10", "rev 11", 119129198Scognet "rev 12", "rev 13", "rev 14", "rev 15", 120129198Scognet}; 121129198Scognet 122129198Scognetstatic const char * const i80321_steppings[16] = { 123129198Scognet "step A-0", "step B-0", "rev 2", "rev 3", 124129198Scognet "rev 4", "rev 5", "rev 6", "rev 7", 125129198Scognet "rev 8", "rev 9", "rev 10", "rev 11", 126129198Scognet "rev 12", "rev 13", "rev 14", "rev 15", 127129198Scognet}; 128129198Scognet 129129198Scognetstatic const char * const pxa2x0_steppings[16] = { 130129198Scognet "step A-0", "step A-1", "step B-0", "step B-1", 131129198Scognet "step B-2", "step C-0", "rev 6", "rev 7", 132129198Scognet "rev 8", "rev 9", "rev 10", "rev 11", 133129198Scognet "rev 12", "rev 13", "rev 14", "rev 15", 134129198Scognet}; 135129198Scognet 136129198Scognetstatic const char * const ixp425_steppings[16] = { 137129198Scognet "step 0", "rev 1", "rev 2", "rev 3", 138129198Scognet "rev 4", "rev 5", "rev 6", "rev 7", 139129198Scognet "rev 8", "rev 9", "rev 10", "rev 11", 140129198Scognet "rev 12", "rev 13", "rev 14", "rev 15", 141129198Scognet}; 142129198Scognet 143129198Scognetstruct cpuidtab { 144129198Scognet u_int32_t cpuid; 145129198Scognet enum cpu_class cpu_class; 146129198Scognet const char *cpu_name; 147129198Scognet const char * const *cpu_steppings; 148129198Scognet}; 149129198Scognet 150129198Scognetconst struct cpuidtab cpuids[] = { 151129198Scognet { CPU_ID_ARM2, CPU_CLASS_ARM2, "ARM2", 152129198Scognet generic_steppings }, 153129198Scognet { CPU_ID_ARM250, CPU_CLASS_ARM2AS, "ARM250", 154129198Scognet generic_steppings }, 155129198Scognet 156129198Scognet { CPU_ID_ARM3, CPU_CLASS_ARM3, "ARM3", 157129198Scognet generic_steppings }, 158129198Scognet 159129198Scognet { CPU_ID_ARM600, CPU_CLASS_ARM6, "ARM600", 160129198Scognet generic_steppings }, 161129198Scognet { CPU_ID_ARM610, CPU_CLASS_ARM6, "ARM610", 162129198Scognet generic_steppings }, 163129198Scognet { CPU_ID_ARM620, CPU_CLASS_ARM6, "ARM620", 164129198Scognet generic_steppings }, 165129198Scognet 166129198Scognet { CPU_ID_ARM700, CPU_CLASS_ARM7, "ARM700", 167129198Scognet generic_steppings }, 168129198Scognet { CPU_ID_ARM710, CPU_CLASS_ARM7, "ARM710", 169129198Scognet generic_steppings }, 170129198Scognet { CPU_ID_ARM7500, CPU_CLASS_ARM7, "ARM7500", 171129198Scognet generic_steppings }, 172129198Scognet { CPU_ID_ARM710A, CPU_CLASS_ARM7, "ARM710a", 173129198Scognet generic_steppings }, 174129198Scognet { CPU_ID_ARM7500FE, CPU_CLASS_ARM7, "ARM7500FE", 175129198Scognet generic_steppings }, 176129198Scognet { CPU_ID_ARM710T, CPU_CLASS_ARM7TDMI, "ARM710T", 177129198Scognet generic_steppings }, 178129198Scognet { CPU_ID_ARM720T, CPU_CLASS_ARM7TDMI, "ARM720T", 179129198Scognet generic_steppings }, 180129198Scognet { CPU_ID_ARM740T8K, CPU_CLASS_ARM7TDMI, "ARM740T (8 KB cache)", 181129198Scognet generic_steppings }, 182129198Scognet { CPU_ID_ARM740T4K, CPU_CLASS_ARM7TDMI, "ARM740T (4 KB cache)", 183129198Scognet generic_steppings }, 184129198Scognet 185129198Scognet { CPU_ID_ARM810, CPU_CLASS_ARM8, "ARM810", 186129198Scognet generic_steppings }, 187129198Scognet 188129198Scognet { CPU_ID_ARM920T, CPU_CLASS_ARM9TDMI, "ARM920T", 189129198Scognet generic_steppings }, 190152653Scognet { CPU_ID_ARM920T_ALT, CPU_CLASS_ARM9TDMI, "ARM920T", 191152653Scognet generic_steppings }, 192129198Scognet { CPU_ID_ARM922T, CPU_CLASS_ARM9TDMI, "ARM922T", 193129198Scognet generic_steppings }, 194129198Scognet { CPU_ID_ARM940T, CPU_CLASS_ARM9TDMI, "ARM940T", 195129198Scognet generic_steppings }, 196129198Scognet { CPU_ID_ARM946ES, CPU_CLASS_ARM9ES, "ARM946E-S", 197129198Scognet generic_steppings }, 198129198Scognet { CPU_ID_ARM966ES, CPU_CLASS_ARM9ES, "ARM966E-S", 199129198Scognet generic_steppings }, 200129198Scognet { CPU_ID_ARM966ESR1, CPU_CLASS_ARM9ES, "ARM966E-S", 201129198Scognet generic_steppings }, 202129198Scognet { CPU_ID_TI925T, CPU_CLASS_ARM9TDMI, "TI ARM925T", 203129198Scognet generic_steppings }, 204129198Scognet 205129198Scognet { CPU_ID_ARM1020E, CPU_CLASS_ARM10E, "ARM1020E", 206129198Scognet generic_steppings }, 207129198Scognet { CPU_ID_ARM1022ES, CPU_CLASS_ARM10E, "ARM1022E-S", 208129198Scognet generic_steppings }, 209129198Scognet 210129198Scognet { CPU_ID_SA110, CPU_CLASS_SA1, "SA-110", 211129198Scognet sa110_steppings }, 212129198Scognet { CPU_ID_SA1100, CPU_CLASS_SA1, "SA-1100", 213129198Scognet sa1100_steppings }, 214129198Scognet { CPU_ID_SA1110, CPU_CLASS_SA1, "SA-1110", 215129198Scognet sa1110_steppings }, 216129198Scognet 217129198Scognet { CPU_ID_IXP1200, CPU_CLASS_SA1, "IXP1200", 218129198Scognet ixp12x0_steppings }, 219129198Scognet 220129198Scognet { CPU_ID_80200, CPU_CLASS_XSCALE, "i80200", 221129198Scognet xscale_steppings }, 222129198Scognet 223129198Scognet { CPU_ID_80321_400, CPU_CLASS_XSCALE, "i80321 400MHz", 224129198Scognet i80321_steppings }, 225129198Scognet { CPU_ID_80321_600, CPU_CLASS_XSCALE, "i80321 600MHz", 226129198Scognet i80321_steppings }, 227129198Scognet { CPU_ID_80321_400_B0, CPU_CLASS_XSCALE, "i80321 400MHz", 228129198Scognet i80321_steppings }, 229129198Scognet { CPU_ID_80321_600_B0, CPU_CLASS_XSCALE, "i80321 600MHz", 230129198Scognet i80321_steppings }, 231129198Scognet 232129198Scognet { CPU_ID_PXA250A, CPU_CLASS_XSCALE, "PXA250", 233129198Scognet pxa2x0_steppings }, 234129198Scognet { CPU_ID_PXA210A, CPU_CLASS_XSCALE, "PXA210", 235129198Scognet pxa2x0_steppings }, 236129198Scognet { CPU_ID_PXA250B, CPU_CLASS_XSCALE, "PXA250", 237129198Scognet pxa2x0_steppings }, 238129198Scognet { CPU_ID_PXA210B, CPU_CLASS_XSCALE, "PXA210", 239129198Scognet pxa2x0_steppings }, 240129198Scognet { CPU_ID_PXA250C, CPU_CLASS_XSCALE, "PXA250", 241129198Scognet pxa2x0_steppings }, 242129198Scognet { CPU_ID_PXA210C, CPU_CLASS_XSCALE, "PXA210", 243129198Scognet pxa2x0_steppings }, 244129198Scognet 245129198Scognet { CPU_ID_IXP425_533, CPU_CLASS_XSCALE, "IXP425 533MHz", 246129198Scognet ixp425_steppings }, 247129198Scognet { CPU_ID_IXP425_400, CPU_CLASS_XSCALE, "IXP425 400MHz", 248129198Scognet ixp425_steppings }, 249129198Scognet { CPU_ID_IXP425_266, CPU_CLASS_XSCALE, "IXP425 266MHz", 250129198Scognet ixp425_steppings }, 251129198Scognet 252129198Scognet { 0, CPU_CLASS_NONE, NULL, NULL } 253129198Scognet}; 254129198Scognet 255129198Scognetstruct cpu_classtab { 256129198Scognet const char *class_name; 257129198Scognet const char *class_option; 258129198Scognet}; 259129198Scognet 260129198Scognetconst struct cpu_classtab cpu_classes[] = { 261129198Scognet { "unknown", NULL }, /* CPU_CLASS_NONE */ 262129198Scognet { "ARM2", "CPU_ARM2" }, /* CPU_CLASS_ARM2 */ 263129198Scognet { "ARM2as", "CPU_ARM250" }, /* CPU_CLASS_ARM2AS */ 264129198Scognet { "ARM3", "CPU_ARM3" }, /* CPU_CLASS_ARM3 */ 265129198Scognet { "ARM6", "CPU_ARM6" }, /* CPU_CLASS_ARM6 */ 266129198Scognet { "ARM7", "CPU_ARM7" }, /* CPU_CLASS_ARM7 */ 267129198Scognet { "ARM7TDMI", "CPU_ARM7TDMI" }, /* CPU_CLASS_ARM7TDMI */ 268129198Scognet { "ARM8", "CPU_ARM8" }, /* CPU_CLASS_ARM8 */ 269155242Simp { "ARM9TDMI", "CPU_ARM9TDMI" }, /* CPU_CLASS_ARM9TDMI */ 270129198Scognet { "ARM9E-S", NULL }, /* CPU_CLASS_ARM9ES */ 271129198Scognet { "ARM10E", "CPU_ARM10" }, /* CPU_CLASS_ARM10E */ 272129198Scognet { "SA-1", "CPU_SA110" }, /* CPU_CLASS_SA1 */ 273129198Scognet { "XScale", "CPU_XSCALE_..." }, /* CPU_CLASS_XSCALE */ 274129198Scognet}; 275129198Scognet 276129198Scognet/* 277129198Scognet * Report the type of the specified arm processor. This uses the generic and 278129198Scognet * arm specific information in the cpu structure to identify the processor. 279129198Scognet * The remaining fields in the cpu structure are filled in appropriately. 280129198Scognet */ 281129198Scognet 282129198Scognetstatic const char * const wtnames[] = { 283129198Scognet "write-through", 284129198Scognet "write-back", 285129198Scognet "write-back", 286129198Scognet "**unknown 3**", 287129198Scognet "**unknown 4**", 288129198Scognet "write-back-locking", /* XXX XScale-specific? */ 289129198Scognet "write-back-locking-A", 290129198Scognet "write-back-locking-B", 291129198Scognet "**unknown 8**", 292129198Scognet "**unknown 9**", 293129198Scognet "**unknown 10**", 294129198Scognet "**unknown 11**", 295129198Scognet "**unknown 12**", 296129198Scognet "**unknown 13**", 297129198Scognet "**unknown 14**", 298129198Scognet "**unknown 15**", 299129198Scognet}; 300129198Scognet 301153940Snetchildvoid setPQL2(int *const size, int *const ways); 302153940Snetchild 303153940Snetchildvoid 304153940SnetchildsetPQL2(int *const size, int *const ways) 305153940Snetchild{ 306153940Snetchild return; 307153940Snetchild} 308153940Snetchild 309153940Snetchild 310129198Scognetextern int ctrl; 311129198Scognetvoid 312129198Scognetidentify_arm_cpu(void) 313129198Scognet{ 314129198Scognet u_int cpuid; 315129198Scognet enum cpu_class cpu_class = CPU_CLASS_NONE; 316129198Scognet int i; 317129198Scognet 318129198Scognet cpuid = cpu_id(); 319129198Scognet 320129198Scognet if (cpuid == 0) { 321129198Scognet printf("Processor failed probe - no CPU ID\n"); 322129198Scognet return; 323129198Scognet } 324129198Scognet 325129198Scognet for (i = 0; cpuids[i].cpuid != 0; i++) 326129198Scognet if (cpuids[i].cpuid == (cpuid & CPU_ID_CPU_MASK)) { 327129198Scognet cpu_class = cpuids[i].cpu_class; 328155242Simp printf("CPU: %s %s (%s core)\n", 329129198Scognet cpuids[i].cpu_name, 330129198Scognet cpuids[i].cpu_steppings[cpuid & 331129198Scognet CPU_ID_REVISION_MASK], 332129198Scognet cpu_classes[cpu_class].class_name); 333129198Scognet break; 334129198Scognet } 335129198Scognet if (cpuids[i].cpuid == 0) 336129198Scognet printf("unknown CPU (ID = 0x%x)\n", cpuid); 337129198Scognet 338155242Simp printf(" "); 339129198Scognet switch (cpu_class) { 340129198Scognet case CPU_CLASS_ARM6: 341129198Scognet case CPU_CLASS_ARM7: 342129198Scognet case CPU_CLASS_ARM7TDMI: 343129198Scognet case CPU_CLASS_ARM8: 344129198Scognet if ((ctrl & CPU_CONTROL_IDC_ENABLE) == 0) 345129198Scognet printf(" IDC disabled"); 346129198Scognet else 347129198Scognet printf(" IDC enabled"); 348129198Scognet break; 349129198Scognet case CPU_CLASS_ARM9TDMI: 350129198Scognet case CPU_CLASS_ARM10E: 351129198Scognet case CPU_CLASS_SA1: 352129198Scognet case CPU_CLASS_XSCALE: 353129198Scognet if ((ctrl & CPU_CONTROL_DC_ENABLE) == 0) 354129198Scognet printf(" DC disabled"); 355129198Scognet else 356129198Scognet printf(" DC enabled"); 357129198Scognet if ((ctrl & CPU_CONTROL_IC_ENABLE) == 0) 358129198Scognet printf(" IC disabled"); 359129198Scognet else 360129198Scognet printf(" IC enabled"); 361129198Scognet break; 362129198Scognet default: 363129198Scognet break; 364129198Scognet } 365129198Scognet if ((ctrl & CPU_CONTROL_WBUF_ENABLE) == 0) 366129198Scognet printf(" WB disabled"); 367129198Scognet else 368129198Scognet printf(" WB enabled"); 369129198Scognet 370129198Scognet if (ctrl & CPU_CONTROL_LABT_ENABLE) 371129198Scognet printf(" LABT"); 372129198Scognet else 373129198Scognet printf(" EABT"); 374129198Scognet 375129198Scognet if (ctrl & CPU_CONTROL_BPRD_ENABLE) 376129198Scognet printf(" branch prediction enabled"); 377129198Scognet 378155242Simp printf("\n"); 379137272Scognet /* Print cache info. */ 380137272Scognet if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0) 381137272Scognet return; 382137272Scognet 383137272Scognet if (arm_pcache_unified) { 384155242Simp printf(" %dKB/%dB %d-way %s unified cache\n", 385137272Scognet arm_pdcache_size / 1024, 386137272Scognet arm_pdcache_line_size, arm_pdcache_ways, 387137272Scognet wtnames[arm_pcache_type]); 388137272Scognet } else { 389155242Simp printf(" %dKB/%dB %d-way Instruction cache\n", 390137272Scognet arm_picache_size / 1024, 391137272Scognet arm_picache_line_size, arm_picache_ways); 392155242Simp printf(" %dKB/%dB %d-way %s Data cache\n", 393137272Scognet arm_pdcache_size / 1024, 394137272Scognet arm_pdcache_line_size, arm_pdcache_ways, 395137272Scognet wtnames[arm_pcache_type]); 396137272Scognet } 397129198Scognet} 398129198Scognet 399