identcpu-v6.c revision 164423
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 164423 2006-11-19 23:45:33Z sam $"); 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 129164080Scognetstatic const char * const i81342_steppings[16] = { 130164080Scognet "step A-0", "rev 1", "rev 2", "rev 3", 131164080Scognet "rev 4", "rev 5", "rev 6", "rev 7", 132164080Scognet "rev 8", "rev 9", "rev 10", "rev 11", 133164080Scognet "rev 12", "rev 13", "rev 14", "rev 15", 134164080Scognet}; 135164080Scognet 136129198Scognetstatic const char * const pxa2x0_steppings[16] = { 137129198Scognet "step A-0", "step A-1", "step B-0", "step B-1", 138129198Scognet "step B-2", "step C-0", "rev 6", "rev 7", 139129198Scognet "rev 8", "rev 9", "rev 10", "rev 11", 140129198Scognet "rev 12", "rev 13", "rev 14", "rev 15", 141129198Scognet}; 142129198Scognet 143129198Scognetstatic const char * const ixp425_steppings[16] = { 144164423Ssam "step 0 (A0)", "rev 1 (ARMv5TE)", "rev 2", "rev 3", 145129198Scognet "rev 4", "rev 5", "rev 6", "rev 7", 146129198Scognet "rev 8", "rev 9", "rev 10", "rev 11", 147129198Scognet "rev 12", "rev 13", "rev 14", "rev 15", 148129198Scognet}; 149129198Scognet 150129198Scognetstruct cpuidtab { 151129198Scognet u_int32_t cpuid; 152129198Scognet enum cpu_class cpu_class; 153129198Scognet const char *cpu_name; 154129198Scognet const char * const *cpu_steppings; 155129198Scognet}; 156129198Scognet 157129198Scognetconst struct cpuidtab cpuids[] = { 158129198Scognet { CPU_ID_ARM2, CPU_CLASS_ARM2, "ARM2", 159129198Scognet generic_steppings }, 160129198Scognet { CPU_ID_ARM250, CPU_CLASS_ARM2AS, "ARM250", 161129198Scognet generic_steppings }, 162129198Scognet 163129198Scognet { CPU_ID_ARM3, CPU_CLASS_ARM3, "ARM3", 164129198Scognet generic_steppings }, 165129198Scognet 166129198Scognet { CPU_ID_ARM600, CPU_CLASS_ARM6, "ARM600", 167129198Scognet generic_steppings }, 168129198Scognet { CPU_ID_ARM610, CPU_CLASS_ARM6, "ARM610", 169129198Scognet generic_steppings }, 170129198Scognet { CPU_ID_ARM620, CPU_CLASS_ARM6, "ARM620", 171129198Scognet generic_steppings }, 172129198Scognet 173129198Scognet { CPU_ID_ARM700, CPU_CLASS_ARM7, "ARM700", 174129198Scognet generic_steppings }, 175129198Scognet { CPU_ID_ARM710, CPU_CLASS_ARM7, "ARM710", 176129198Scognet generic_steppings }, 177129198Scognet { CPU_ID_ARM7500, CPU_CLASS_ARM7, "ARM7500", 178129198Scognet generic_steppings }, 179129198Scognet { CPU_ID_ARM710A, CPU_CLASS_ARM7, "ARM710a", 180129198Scognet generic_steppings }, 181129198Scognet { CPU_ID_ARM7500FE, CPU_CLASS_ARM7, "ARM7500FE", 182129198Scognet generic_steppings }, 183129198Scognet { CPU_ID_ARM710T, CPU_CLASS_ARM7TDMI, "ARM710T", 184129198Scognet generic_steppings }, 185129198Scognet { CPU_ID_ARM720T, CPU_CLASS_ARM7TDMI, "ARM720T", 186129198Scognet generic_steppings }, 187129198Scognet { CPU_ID_ARM740T8K, CPU_CLASS_ARM7TDMI, "ARM740T (8 KB cache)", 188129198Scognet generic_steppings }, 189129198Scognet { CPU_ID_ARM740T4K, CPU_CLASS_ARM7TDMI, "ARM740T (4 KB cache)", 190129198Scognet generic_steppings }, 191129198Scognet 192129198Scognet { CPU_ID_ARM810, CPU_CLASS_ARM8, "ARM810", 193129198Scognet generic_steppings }, 194129198Scognet 195129198Scognet { CPU_ID_ARM920T, CPU_CLASS_ARM9TDMI, "ARM920T", 196129198Scognet generic_steppings }, 197152653Scognet { CPU_ID_ARM920T_ALT, CPU_CLASS_ARM9TDMI, "ARM920T", 198152653Scognet generic_steppings }, 199129198Scognet { CPU_ID_ARM922T, CPU_CLASS_ARM9TDMI, "ARM922T", 200129198Scognet generic_steppings }, 201129198Scognet { CPU_ID_ARM940T, CPU_CLASS_ARM9TDMI, "ARM940T", 202129198Scognet generic_steppings }, 203129198Scognet { CPU_ID_ARM946ES, CPU_CLASS_ARM9ES, "ARM946E-S", 204129198Scognet generic_steppings }, 205129198Scognet { CPU_ID_ARM966ES, CPU_CLASS_ARM9ES, "ARM966E-S", 206129198Scognet generic_steppings }, 207129198Scognet { CPU_ID_ARM966ESR1, CPU_CLASS_ARM9ES, "ARM966E-S", 208129198Scognet generic_steppings }, 209129198Scognet { CPU_ID_TI925T, CPU_CLASS_ARM9TDMI, "TI ARM925T", 210129198Scognet generic_steppings }, 211129198Scognet 212129198Scognet { CPU_ID_ARM1020E, CPU_CLASS_ARM10E, "ARM1020E", 213129198Scognet generic_steppings }, 214129198Scognet { CPU_ID_ARM1022ES, CPU_CLASS_ARM10E, "ARM1022E-S", 215129198Scognet generic_steppings }, 216129198Scognet 217129198Scognet { CPU_ID_SA110, CPU_CLASS_SA1, "SA-110", 218129198Scognet sa110_steppings }, 219129198Scognet { CPU_ID_SA1100, CPU_CLASS_SA1, "SA-1100", 220129198Scognet sa1100_steppings }, 221129198Scognet { CPU_ID_SA1110, CPU_CLASS_SA1, "SA-1110", 222129198Scognet sa1110_steppings }, 223129198Scognet 224129198Scognet { CPU_ID_IXP1200, CPU_CLASS_SA1, "IXP1200", 225129198Scognet ixp12x0_steppings }, 226129198Scognet 227129198Scognet { CPU_ID_80200, CPU_CLASS_XSCALE, "i80200", 228129198Scognet xscale_steppings }, 229129198Scognet 230129198Scognet { CPU_ID_80321_400, CPU_CLASS_XSCALE, "i80321 400MHz", 231129198Scognet i80321_steppings }, 232129198Scognet { CPU_ID_80321_600, CPU_CLASS_XSCALE, "i80321 600MHz", 233129198Scognet i80321_steppings }, 234129198Scognet { CPU_ID_80321_400_B0, CPU_CLASS_XSCALE, "i80321 400MHz", 235129198Scognet i80321_steppings }, 236129198Scognet { CPU_ID_80321_600_B0, CPU_CLASS_XSCALE, "i80321 600MHz", 237129198Scognet i80321_steppings }, 238129198Scognet 239164080Scognet { CPU_ID_81342, CPU_CLASS_XSCALE, "i81342", 240164080Scognet i81342_steppings }, 241164080Scognet 242161592Scognet { CPU_ID_80219_400, CPU_CLASS_XSCALE, "i80219 400MHz", 243161592Scognet xscale_steppings }, 244161592Scognet 245161592Scognet { CPU_ID_80219_600, CPU_CLASS_XSCALE, "i80219 600MHz", 246161592Scognet xscale_steppings }, 247161592Scognet 248129198Scognet { CPU_ID_PXA250A, CPU_CLASS_XSCALE, "PXA250", 249129198Scognet pxa2x0_steppings }, 250129198Scognet { CPU_ID_PXA210A, CPU_CLASS_XSCALE, "PXA210", 251129198Scognet pxa2x0_steppings }, 252129198Scognet { CPU_ID_PXA250B, CPU_CLASS_XSCALE, "PXA250", 253129198Scognet pxa2x0_steppings }, 254129198Scognet { CPU_ID_PXA210B, CPU_CLASS_XSCALE, "PXA210", 255129198Scognet pxa2x0_steppings }, 256129198Scognet { CPU_ID_PXA250C, CPU_CLASS_XSCALE, "PXA250", 257129198Scognet pxa2x0_steppings }, 258129198Scognet { CPU_ID_PXA210C, CPU_CLASS_XSCALE, "PXA210", 259129198Scognet pxa2x0_steppings }, 260129198Scognet 261129198Scognet { CPU_ID_IXP425_533, CPU_CLASS_XSCALE, "IXP425 533MHz", 262129198Scognet ixp425_steppings }, 263129198Scognet { CPU_ID_IXP425_400, CPU_CLASS_XSCALE, "IXP425 400MHz", 264129198Scognet ixp425_steppings }, 265129198Scognet { CPU_ID_IXP425_266, CPU_CLASS_XSCALE, "IXP425 266MHz", 266129198Scognet ixp425_steppings }, 267129198Scognet 268129198Scognet { 0, CPU_CLASS_NONE, NULL, NULL } 269129198Scognet}; 270129198Scognet 271129198Scognetstruct cpu_classtab { 272129198Scognet const char *class_name; 273129198Scognet const char *class_option; 274129198Scognet}; 275129198Scognet 276129198Scognetconst struct cpu_classtab cpu_classes[] = { 277129198Scognet { "unknown", NULL }, /* CPU_CLASS_NONE */ 278129198Scognet { "ARM2", "CPU_ARM2" }, /* CPU_CLASS_ARM2 */ 279129198Scognet { "ARM2as", "CPU_ARM250" }, /* CPU_CLASS_ARM2AS */ 280129198Scognet { "ARM3", "CPU_ARM3" }, /* CPU_CLASS_ARM3 */ 281129198Scognet { "ARM6", "CPU_ARM6" }, /* CPU_CLASS_ARM6 */ 282129198Scognet { "ARM7", "CPU_ARM7" }, /* CPU_CLASS_ARM7 */ 283129198Scognet { "ARM7TDMI", "CPU_ARM7TDMI" }, /* CPU_CLASS_ARM7TDMI */ 284129198Scognet { "ARM8", "CPU_ARM8" }, /* CPU_CLASS_ARM8 */ 285155242Simp { "ARM9TDMI", "CPU_ARM9TDMI" }, /* CPU_CLASS_ARM9TDMI */ 286129198Scognet { "ARM9E-S", NULL }, /* CPU_CLASS_ARM9ES */ 287129198Scognet { "ARM10E", "CPU_ARM10" }, /* CPU_CLASS_ARM10E */ 288129198Scognet { "SA-1", "CPU_SA110" }, /* CPU_CLASS_SA1 */ 289129198Scognet { "XScale", "CPU_XSCALE_..." }, /* CPU_CLASS_XSCALE */ 290129198Scognet}; 291129198Scognet 292129198Scognet/* 293129198Scognet * Report the type of the specified arm processor. This uses the generic and 294129198Scognet * arm specific information in the cpu structure to identify the processor. 295129198Scognet * The remaining fields in the cpu structure are filled in appropriately. 296129198Scognet */ 297129198Scognet 298129198Scognetstatic const char * const wtnames[] = { 299129198Scognet "write-through", 300129198Scognet "write-back", 301129198Scognet "write-back", 302129198Scognet "**unknown 3**", 303129198Scognet "**unknown 4**", 304129198Scognet "write-back-locking", /* XXX XScale-specific? */ 305129198Scognet "write-back-locking-A", 306129198Scognet "write-back-locking-B", 307129198Scognet "**unknown 8**", 308129198Scognet "**unknown 9**", 309129198Scognet "**unknown 10**", 310129198Scognet "**unknown 11**", 311129198Scognet "**unknown 12**", 312129198Scognet "**unknown 13**", 313129198Scognet "**unknown 14**", 314129198Scognet "**unknown 15**", 315129198Scognet}; 316129198Scognet 317153940Snetchildvoid setPQL2(int *const size, int *const ways); 318153940Snetchild 319153940Snetchildvoid 320153940SnetchildsetPQL2(int *const size, int *const ways) 321153940Snetchild{ 322153940Snetchild return; 323153940Snetchild} 324153940Snetchild 325153940Snetchild 326129198Scognetextern int ctrl; 327129198Scognetvoid 328129198Scognetidentify_arm_cpu(void) 329129198Scognet{ 330129198Scognet u_int cpuid; 331129198Scognet enum cpu_class cpu_class = CPU_CLASS_NONE; 332129198Scognet int i; 333129198Scognet 334129198Scognet cpuid = cpu_id(); 335129198Scognet 336129198Scognet if (cpuid == 0) { 337129198Scognet printf("Processor failed probe - no CPU ID\n"); 338129198Scognet return; 339129198Scognet } 340129198Scognet 341129198Scognet for (i = 0; cpuids[i].cpuid != 0; i++) 342129198Scognet if (cpuids[i].cpuid == (cpuid & CPU_ID_CPU_MASK)) { 343129198Scognet cpu_class = cpuids[i].cpu_class; 344155242Simp printf("CPU: %s %s (%s core)\n", 345129198Scognet cpuids[i].cpu_name, 346129198Scognet cpuids[i].cpu_steppings[cpuid & 347129198Scognet CPU_ID_REVISION_MASK], 348129198Scognet cpu_classes[cpu_class].class_name); 349129198Scognet break; 350129198Scognet } 351129198Scognet if (cpuids[i].cpuid == 0) 352129198Scognet printf("unknown CPU (ID = 0x%x)\n", cpuid); 353129198Scognet 354155242Simp printf(" "); 355129198Scognet switch (cpu_class) { 356129198Scognet case CPU_CLASS_ARM6: 357129198Scognet case CPU_CLASS_ARM7: 358129198Scognet case CPU_CLASS_ARM7TDMI: 359129198Scognet case CPU_CLASS_ARM8: 360129198Scognet if ((ctrl & CPU_CONTROL_IDC_ENABLE) == 0) 361129198Scognet printf(" IDC disabled"); 362129198Scognet else 363129198Scognet printf(" IDC enabled"); 364129198Scognet break; 365129198Scognet case CPU_CLASS_ARM9TDMI: 366129198Scognet case CPU_CLASS_ARM10E: 367129198Scognet case CPU_CLASS_SA1: 368129198Scognet case CPU_CLASS_XSCALE: 369129198Scognet if ((ctrl & CPU_CONTROL_DC_ENABLE) == 0) 370129198Scognet printf(" DC disabled"); 371129198Scognet else 372129198Scognet printf(" DC enabled"); 373129198Scognet if ((ctrl & CPU_CONTROL_IC_ENABLE) == 0) 374129198Scognet printf(" IC disabled"); 375129198Scognet else 376129198Scognet printf(" IC enabled"); 377129198Scognet break; 378129198Scognet default: 379129198Scognet break; 380129198Scognet } 381129198Scognet if ((ctrl & CPU_CONTROL_WBUF_ENABLE) == 0) 382129198Scognet printf(" WB disabled"); 383129198Scognet else 384129198Scognet printf(" WB enabled"); 385129198Scognet 386129198Scognet if (ctrl & CPU_CONTROL_LABT_ENABLE) 387129198Scognet printf(" LABT"); 388129198Scognet else 389129198Scognet printf(" EABT"); 390129198Scognet 391129198Scognet if (ctrl & CPU_CONTROL_BPRD_ENABLE) 392129198Scognet printf(" branch prediction enabled"); 393129198Scognet 394155242Simp printf("\n"); 395137272Scognet /* Print cache info. */ 396137272Scognet if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0) 397137272Scognet return; 398137272Scognet 399137272Scognet if (arm_pcache_unified) { 400155242Simp printf(" %dKB/%dB %d-way %s unified cache\n", 401137272Scognet arm_pdcache_size / 1024, 402137272Scognet arm_pdcache_line_size, arm_pdcache_ways, 403137272Scognet wtnames[arm_pcache_type]); 404137272Scognet } else { 405155242Simp printf(" %dKB/%dB %d-way Instruction cache\n", 406137272Scognet arm_picache_size / 1024, 407137272Scognet arm_picache_line_size, arm_picache_ways); 408155242Simp printf(" %dKB/%dB %d-way %s Data cache\n", 409137272Scognet arm_pdcache_size / 1024, 410137272Scognet arm_pdcache_line_size, arm_pdcache_ways, 411137272Scognet wtnames[arm_pcache_type]); 412137272Scognet } 413129198Scognet} 414129198Scognet 415