Annotation of sys/arch/arm/arm/cpu.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: cpu.c,v 1.8 2007/07/01 19:09:20 miod Exp $ */
! 2: /* $NetBSD: cpu.c,v 1.56 2004/04/14 04:01:49 bsh Exp $ */
! 3:
! 4:
! 5: /*
! 6: * Copyright (c) 1995 Mark Brinicombe.
! 7: * Copyright (c) 1995 Brini.
! 8: * All rights reserved.
! 9: *
! 10: * Redistribution and use in source and binary forms, with or without
! 11: * modification, are permitted provided that the following conditions
! 12: * are met:
! 13: * 1. Redistributions of source code must retain the above copyright
! 14: * notice, this list of conditions and the following disclaimer.
! 15: * 2. Redistributions in binary form must reproduce the above copyright
! 16: * notice, this list of conditions and the following disclaimer in the
! 17: * documentation and/or other materials provided with the distribution.
! 18: * 3. All advertising materials mentioning features or use of this software
! 19: * must display the following acknowledgement:
! 20: * This product includes software developed by Brini.
! 21: * 4. The name of the company nor the name of the author may be used to
! 22: * endorse or promote products derived from this software without specific
! 23: * prior written permission.
! 24: *
! 25: * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
! 26: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
! 27: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 28: * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
! 29: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
! 30: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
! 31: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 35: * SUCH DAMAGE.
! 36: *
! 37: * RiscBSD kernel project
! 38: *
! 39: * cpu.c
! 40: *
! 41: * Probing and configuration for the master CPU
! 42: *
! 43: * Created : 10/10/95
! 44: */
! 45:
! 46: #include <sys/param.h>
! 47:
! 48: #include <sys/systm.h>
! 49: #include <sys/malloc.h>
! 50: #include <sys/device.h>
! 51: #include <sys/proc.h>
! 52: #include <sys/conf.h>
! 53: #include <uvm/uvm_extern.h>
! 54: #include <machine/cpu.h>
! 55:
! 56: #include <arm/cpuconf.h>
! 57: #include <arm/undefined.h>
! 58:
! 59: #ifdef ARMFPE
! 60: #include <machine/bootconfig.h> /* For boot args */
! 61: #include <arm/fpe-arm/armfpe.h>
! 62: #endif
! 63:
! 64: char cpu_model[256];
! 65:
! 66: /* Prototypes */
! 67: void identify_arm_cpu(struct device *dv, struct cpu_info *);
! 68:
! 69: /*
! 70: * Identify the master (boot) CPU
! 71: */
! 72:
! 73: void
! 74: cpu_attach(struct device *dv)
! 75: {
! 76: #ifdef ARMFPE
! 77: int usearmfpe;
! 78:
! 79: usearmfpe = 1; /* when compiled in, its enabled by default */
! 80: #endif
! 81:
! 82: curcpu()->ci_dev = dv;
! 83:
! 84: /* Get the CPU ID from coprocessor 15 */
! 85:
! 86: curcpu()->ci_arm_cpuid = cpu_id();
! 87: curcpu()->ci_arm_cputype = curcpu()->ci_arm_cpuid & CPU_ID_CPU_MASK;
! 88: curcpu()->ci_arm_cpurev =
! 89: curcpu()->ci_arm_cpuid & CPU_ID_REVISION_MASK;
! 90:
! 91: identify_arm_cpu(dv, curcpu());
! 92:
! 93: if (curcpu()->ci_arm_cputype == CPU_ID_SA110 &&
! 94: curcpu()->ci_arm_cpurev < 3) {
! 95: printf("%s: SA-110 with bugged STM^ instruction\n",
! 96: dv->dv_xname);
! 97: }
! 98:
! 99: #ifdef CPU_ARM8
! 100: if ((curcpu()->ci_arm_cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM810) {
! 101: int clock = arm8_clock_config(0, 0);
! 102: char *fclk;
! 103: aprint_normal("%s: ARM810 cp15=%02x", dv->dv_xname, clock);
! 104: aprint_normal(" clock:%s", (clock & 1) ? " dynamic" : "");
! 105: aprint_normal("%s", (clock & 2) ? " sync" : "");
! 106: switch ((clock >> 2) & 3) {
! 107: case 0:
! 108: fclk = "bus clock";
! 109: break;
! 110: case 1:
! 111: fclk = "ref clock";
! 112: break;
! 113: case 3:
! 114: fclk = "pll";
! 115: break;
! 116: default:
! 117: fclk = "illegal";
! 118: break;
! 119: }
! 120: aprint_normal(" fclk source=%s\n", fclk);
! 121: }
! 122: #endif
! 123:
! 124: #ifdef ARMFPE
! 125: /*
! 126: * Ok now we test for an FPA
! 127: * At this point no floating point emulator has been installed.
! 128: * This means any FP instruction will cause undefined exception.
! 129: * We install a temporay coproc 1 handler which will modify
! 130: * undefined_test if it is called.
! 131: * We then try to read the FP status register. If undefined_test
! 132: * has been decremented then the instruction was not handled by
! 133: * an FPA so we know the FPA is missing. If undefined_test is
! 134: * still 1 then we know the instruction was handled by an FPA.
! 135: * We then remove our test handler and look at the
! 136: * FP status register for identification.
! 137: */
! 138:
! 139: /*
! 140: * Ok if ARMFPE is defined and the boot options request the
! 141: * ARM FPE then it will be installed as the FPE.
! 142: * This is just while I work on integrating the new FPE.
! 143: * It means the new FPE gets installed if compiled int (ARMFPE
! 144: * defined) and also gives me a on/off option when I boot in
! 145: * case the new FPE is causing panics.
! 146: */
! 147:
! 148:
! 149: if (boot_args)
! 150: get_bootconf_option(boot_args, "armfpe",
! 151: BOOTOPT_TYPE_BOOLEAN, &usearmfpe);
! 152: if (usearmfpe)
! 153: initialise_arm_fpe();
! 154: #endif
! 155: }
! 156:
! 157: enum cpu_class {
! 158: CPU_CLASS_NONE,
! 159: CPU_CLASS_ARM2,
! 160: CPU_CLASS_ARM2AS,
! 161: CPU_CLASS_ARM3,
! 162: CPU_CLASS_ARM6,
! 163: CPU_CLASS_ARM7,
! 164: CPU_CLASS_ARM7TDMI,
! 165: CPU_CLASS_ARM8,
! 166: CPU_CLASS_ARM9TDMI,
! 167: CPU_CLASS_ARM9ES,
! 168: CPU_CLASS_ARM10E,
! 169: CPU_CLASS_SA1,
! 170: CPU_CLASS_XSCALE
! 171: };
! 172:
! 173: static const char * const generic_steppings[16] = {
! 174: "rev 0", "rev 1", "rev 2", "rev 3",
! 175: "rev 4", "rev 5", "rev 6", "rev 7",
! 176: "rev 8", "rev 9", "rev 10", "rev 11",
! 177: "rev 12", "rev 13", "rev 14", "rev 15"
! 178: };
! 179:
! 180: static const char * const sa110_steppings[16] = {
! 181: "rev 0", "step J", "step K", "step S",
! 182: "step T", "rev 5", "rev 6", "rev 7",
! 183: "rev 8", "rev 9", "rev 10", "rev 11",
! 184: "rev 12", "rev 13", "rev 14", "rev 15"
! 185: };
! 186:
! 187: static const char * const sa1100_steppings[16] = {
! 188: "rev 0", "step B", "step C", "rev 3",
! 189: "rev 4", "rev 5", "rev 6", "rev 7",
! 190: "step D", "step E", "rev 10" "step G",
! 191: "rev 12", "rev 13", "rev 14", "rev 15"
! 192: };
! 193:
! 194: static const char * const sa1110_steppings[16] = {
! 195: "step A-0", "rev 1", "rev 2", "rev 3",
! 196: "step B-0", "step B-1", "step B-2", "step B-3",
! 197: "step B-4", "step B-5", "rev 10", "rev 11",
! 198: "rev 12", "rev 13", "rev 14", "rev 15"
! 199: };
! 200:
! 201: static const char * const ixp12x0_steppings[16] = {
! 202: "(IXP1200 step A)", "(IXP1200 step B)",
! 203: "rev 2", "(IXP1200 step C)",
! 204: "(IXP1200 step D)", "(IXP1240/1250 step A)",
! 205: "(IXP1240 step B)", "(IXP1250 step B)",
! 206: "rev 8", "rev 9", "rev 10", "rev 11",
! 207: "rev 12", "rev 13", "rev 14", "rev 15"
! 208: };
! 209:
! 210: static const char * const xscale_steppings[16] = {
! 211: "step A-0", "step A-1", "step B-0", "step C-0",
! 212: "step D-0", "rev 5", "rev 6", "rev 7",
! 213: "rev 8", "rev 9", "rev 10", "rev 11",
! 214: "rev 12", "rev 13", "rev 14", "rev 15"
! 215: };
! 216:
! 217: static const char * const i80321_steppings[16] = {
! 218: "step A-0", "step B-0", "rev 2", "rev 3",
! 219: "rev 4", "rev 5", "rev 6", "rev 7",
! 220: "rev 8", "rev 9", "rev 10", "rev 11",
! 221: "rev 12", "rev 13", "rev 14", "rev 15"
! 222: };
! 223:
! 224: static const char * const i80219_steppings[16] = {
! 225: "step A-0", "rev 1", "rev 2", "rev 3",
! 226: "rev 4", "rev 5", "rev 6", "rev 7",
! 227: "rev 8", "rev 9", "rev 10", "rev 11",
! 228: "rev 12", "rev 13", "rev 14", "rev 15",
! 229: };
! 230:
! 231: /* Steppings for PXA2[15]0 */
! 232: static const char * const pxa2x0_steppings[16] = {
! 233: "step A-0", "step A-1", "step B-0", "step B-1",
! 234: "step B-2", "step C-0", "rev 6", "rev 7",
! 235: "rev 8", "rev 9", "rev 10", "rev 11",
! 236: "rev 12", "rev 13", "rev 14", "rev 15"
! 237: };
! 238:
! 239: /* Steppings for PXA255/26x.
! 240: * rev 5: PXA26x B0, rev 6: PXA255 A0
! 241: */
! 242: static const char * const pxa255_steppings[16] = {
! 243: "rev 0", "rev 1", "rev 2", "step A-0",
! 244: "rev 4", "step B-0", "step A-0", "rev 7",
! 245: "rev 8", "rev 9", "rev 10", "rev 11",
! 246: "rev 12", "rev 13", "rev 14", "rev 15"
! 247: };
! 248:
! 249: /* Steppings for PXA270 */
! 250: static const char * const pxa27x_steppings[16] = {
! 251: "step A-0", "step A-1", "step B-0", "step B-1",
! 252: "step C-0", "step ?", "step ?", "step C-5",
! 253: "rev 8", "rev 9", "rev 10", "rev 11",
! 254: "rev 12", "rev 13", "rev 14", "rev 15"
! 255: };
! 256:
! 257: static const char * const ixp425_steppings[16] = {
! 258: "step 0", "rev 1", "rev 2", "rev 3",
! 259: "rev 4", "rev 5", "rev 6", "rev 7",
! 260: "rev 8", "rev 9", "rev 10", "rev 11",
! 261: "rev 12", "rev 13", "rev 14", "rev 15"
! 262: };
! 263:
! 264: struct cpuidtab {
! 265: u_int32_t cpuid;
! 266: enum cpu_class cpu_class;
! 267: const char *cpu_name;
! 268: const char * const *cpu_steppings;
! 269: };
! 270:
! 271: const struct cpuidtab cpuids[] = {
! 272: { CPU_ID_ARM2, CPU_CLASS_ARM2, "ARM2",
! 273: generic_steppings },
! 274: { CPU_ID_ARM250, CPU_CLASS_ARM2AS, "ARM250",
! 275: generic_steppings },
! 276:
! 277: { CPU_ID_ARM3, CPU_CLASS_ARM3, "ARM3",
! 278: generic_steppings },
! 279:
! 280: { CPU_ID_ARM600, CPU_CLASS_ARM6, "ARM600",
! 281: generic_steppings },
! 282: { CPU_ID_ARM610, CPU_CLASS_ARM6, "ARM610",
! 283: generic_steppings },
! 284: { CPU_ID_ARM620, CPU_CLASS_ARM6, "ARM620",
! 285: generic_steppings },
! 286:
! 287: { CPU_ID_ARM700, CPU_CLASS_ARM7, "ARM700",
! 288: generic_steppings },
! 289: { CPU_ID_ARM710, CPU_CLASS_ARM7, "ARM710",
! 290: generic_steppings },
! 291: { CPU_ID_ARM7500, CPU_CLASS_ARM7, "ARM7500",
! 292: generic_steppings },
! 293: { CPU_ID_ARM710A, CPU_CLASS_ARM7, "ARM710a",
! 294: generic_steppings },
! 295: { CPU_ID_ARM7500FE, CPU_CLASS_ARM7, "ARM7500FE",
! 296: generic_steppings },
! 297: { CPU_ID_ARM710T, CPU_CLASS_ARM7TDMI, "ARM710T",
! 298: generic_steppings },
! 299: { CPU_ID_ARM720T, CPU_CLASS_ARM7TDMI, "ARM720T",
! 300: generic_steppings },
! 301: { CPU_ID_ARM740T8K, CPU_CLASS_ARM7TDMI, "ARM740T (8 KB cache)",
! 302: generic_steppings },
! 303: { CPU_ID_ARM740T4K, CPU_CLASS_ARM7TDMI, "ARM740T (4 KB cache)",
! 304: generic_steppings },
! 305:
! 306: { CPU_ID_ARM810, CPU_CLASS_ARM8, "ARM810",
! 307: generic_steppings },
! 308:
! 309: { CPU_ID_ARM920T, CPU_CLASS_ARM9TDMI, "ARM920T",
! 310: generic_steppings },
! 311: { CPU_ID_ARM922T, CPU_CLASS_ARM9TDMI, "ARM922T",
! 312: generic_steppings },
! 313: { CPU_ID_ARM940T, CPU_CLASS_ARM9TDMI, "ARM940T",
! 314: generic_steppings },
! 315: { CPU_ID_ARM946ES, CPU_CLASS_ARM9ES, "ARM946E-S",
! 316: generic_steppings },
! 317: { CPU_ID_ARM966ES, CPU_CLASS_ARM9ES, "ARM966E-S",
! 318: generic_steppings },
! 319: { CPU_ID_ARM966ESR1, CPU_CLASS_ARM9ES, "ARM966E-S",
! 320: generic_steppings },
! 321: { CPU_ID_TI925T, CPU_CLASS_ARM9TDMI, "TI ARM925T",
! 322: generic_steppings },
! 323:
! 324: { CPU_ID_ARM1020E, CPU_CLASS_ARM10E, "ARM1020E",
! 325: generic_steppings },
! 326: { CPU_ID_ARM1022ES, CPU_CLASS_ARM10E, "ARM1022E-S",
! 327: generic_steppings },
! 328:
! 329: { CPU_ID_SA110, CPU_CLASS_SA1, "SA-110",
! 330: sa110_steppings },
! 331: { CPU_ID_SA1100, CPU_CLASS_SA1, "SA-1100",
! 332: sa1100_steppings },
! 333: { CPU_ID_SA1110, CPU_CLASS_SA1, "SA-1110",
! 334: sa1110_steppings },
! 335:
! 336: { CPU_ID_IXP1200, CPU_CLASS_SA1, "IXP1200",
! 337: ixp12x0_steppings },
! 338:
! 339: { CPU_ID_80200, CPU_CLASS_XSCALE, "i80200",
! 340: xscale_steppings },
! 341:
! 342: { CPU_ID_80321_400, CPU_CLASS_XSCALE, "i80321 400MHz",
! 343: i80321_steppings },
! 344: { CPU_ID_80321_600, CPU_CLASS_XSCALE, "i80321 600MHz",
! 345: i80321_steppings },
! 346: { CPU_ID_80321_400_B0, CPU_CLASS_XSCALE, "i80321 400MHz",
! 347: i80321_steppings },
! 348: { CPU_ID_80321_600_B0, CPU_CLASS_XSCALE, "i80321 600MHz",
! 349: i80321_steppings },
! 350:
! 351: { CPU_ID_80219_400, CPU_CLASS_XSCALE, "i80219 400MHz",
! 352: i80219_steppings },
! 353: { CPU_ID_80219_600, CPU_CLASS_XSCALE, "i80219 600MHz",
! 354: i80219_steppings },
! 355:
! 356: { CPU_ID_PXA250A, CPU_CLASS_XSCALE, "PXA250",
! 357: pxa2x0_steppings },
! 358: { CPU_ID_PXA210A, CPU_CLASS_XSCALE, "PXA210",
! 359: pxa2x0_steppings },
! 360: { CPU_ID_PXA250B, CPU_CLASS_XSCALE, "PXA250",
! 361: pxa2x0_steppings },
! 362: { CPU_ID_PXA210B, CPU_CLASS_XSCALE, "PXA210",
! 363: pxa2x0_steppings },
! 364: { CPU_ID_PXA250C, CPU_CLASS_XSCALE, "PXA250",
! 365: pxa2x0_steppings },
! 366: { CPU_ID_PXA27X, CPU_CLASS_XSCALE, "PXA27x",
! 367: pxa27x_steppings },
! 368: { CPU_ID_PXA210C, CPU_CLASS_XSCALE, "PXA210",
! 369: pxa2x0_steppings },
! 370:
! 371: { CPU_ID_IXP425_533, CPU_CLASS_XSCALE, "IXP425 533MHz",
! 372: ixp425_steppings },
! 373: { CPU_ID_IXP425_400, CPU_CLASS_XSCALE, "IXP425 400MHz",
! 374: ixp425_steppings },
! 375: { CPU_ID_IXP425_266, CPU_CLASS_XSCALE, "IXP425 266MHz",
! 376: ixp425_steppings },
! 377:
! 378: { 0, CPU_CLASS_NONE, NULL, NULL }
! 379: };
! 380:
! 381: struct cpu_classtab {
! 382: const char *class_name;
! 383: const char *class_option;
! 384: };
! 385:
! 386: const struct cpu_classtab cpu_classes[] = {
! 387: { "unknown", NULL }, /* CPU_CLASS_NONE */
! 388: { "ARM2", "CPU_ARM2" }, /* CPU_CLASS_ARM2 */
! 389: { "ARM2as", "CPU_ARM250" }, /* CPU_CLASS_ARM2AS */
! 390: { "ARM3", "CPU_ARM3" }, /* CPU_CLASS_ARM3 */
! 391: { "ARM6", "CPU_ARM6" }, /* CPU_CLASS_ARM6 */
! 392: { "ARM7", "CPU_ARM7" }, /* CPU_CLASS_ARM7 */
! 393: { "ARM7TDMI", "CPU_ARM7TDMI" }, /* CPU_CLASS_ARM7TDMI */
! 394: { "ARM8", "CPU_ARM8" }, /* CPU_CLASS_ARM8 */
! 395: { "ARM9TDMI", NULL }, /* CPU_CLASS_ARM9TDMI */
! 396: { "ARM9E-S", NULL }, /* CPU_CLASS_ARM9ES */
! 397: { "ARM10E", "CPU_ARM10" }, /* CPU_CLASS_ARM10E */
! 398: { "SA-1", "CPU_SA110" }, /* CPU_CLASS_SA1 */
! 399: { "XScale", "CPU_XSCALE_..." } /* CPU_CLASS_XSCALE */
! 400: };
! 401:
! 402: /*
! 403: * Report the type of the specified arm processor. This uses the generic and
! 404: * arm specific information in the cpu structure to identify the processor.
! 405: * The remaining fields in the cpu structure are filled in appropriately.
! 406: */
! 407:
! 408: static const char * const wtnames[] = {
! 409: "wr-thru",
! 410: "wr-back",
! 411: "wr-back",
! 412: "**unknown 3**",
! 413: "**unknown 4**",
! 414: "wr-back-lock", /* XXX XScale-specific? */
! 415: "wr-back-lock-A",
! 416: "wr-back-lock-B",
! 417: "**unknown 8**",
! 418: "**unknown 9**",
! 419: "**unknown 10**",
! 420: "**unknown 11**",
! 421: "**unknown 12**",
! 422: "**unknown 13**",
! 423: "**unknown 14**",
! 424: "**unknown 15**"
! 425: };
! 426:
! 427: void
! 428: identify_arm_cpu(struct device *dv, struct cpu_info *ci)
! 429: {
! 430: u_int cpuid;
! 431: enum cpu_class cpu_class = CPU_CLASS_NONE;
! 432: int i;
! 433:
! 434: cpuid = ci->ci_arm_cpuid;
! 435:
! 436: if (cpuid == 0) {
! 437: printf("Processor failed probe - no CPU ID\n");
! 438: return;
! 439: }
! 440:
! 441: for (i = 0; cpuids[i].cpuid != 0; i++)
! 442: if (cpuids[i].cpuid == (cpuid & CPU_ID_CPU_MASK)) {
! 443: cpu_class = cpuids[i].cpu_class;
! 444: snprintf(cpu_model, sizeof(cpu_model),
! 445: "%s %s (%s core)", cpuids[i].cpu_name,
! 446: cpuids[i].cpu_steppings[cpuid &
! 447: CPU_ID_REVISION_MASK],
! 448: cpu_classes[cpu_class].class_name);
! 449: break;
! 450: }
! 451:
! 452: if (cpuids[i].cpuid == 0)
! 453: snprintf(cpu_model, sizeof(cpu_model),
! 454: "unknown CPU (ID = 0x%x)", cpuid);
! 455:
! 456: printf(": %s\n", cpu_model);
! 457:
! 458: printf("%s:", dv->dv_xname);
! 459:
! 460: switch (cpu_class) {
! 461: case CPU_CLASS_ARM6:
! 462: case CPU_CLASS_ARM7:
! 463: case CPU_CLASS_ARM7TDMI:
! 464: case CPU_CLASS_ARM8:
! 465: if ((ci->ci_ctrl & CPU_CONTROL_IDC_ENABLE) == 0)
! 466: printf(" IDC disabled");
! 467: else
! 468: printf(" IDC enabled");
! 469: break;
! 470: case CPU_CLASS_ARM9TDMI:
! 471: case CPU_CLASS_ARM10E:
! 472: case CPU_CLASS_SA1:
! 473: case CPU_CLASS_XSCALE:
! 474: if ((ci->ci_ctrl & CPU_CONTROL_DC_ENABLE) == 0)
! 475: printf(" DC disabled");
! 476: else
! 477: printf(" DC enabled");
! 478: if ((ci->ci_ctrl & CPU_CONTROL_IC_ENABLE) == 0)
! 479: printf(" IC disabled");
! 480: else
! 481: printf(" IC enabled");
! 482: break;
! 483: default:
! 484: break;
! 485: }
! 486: if ((ci->ci_ctrl & CPU_CONTROL_WBUF_ENABLE) == 0)
! 487: printf(" WB disabled");
! 488: else
! 489: printf(" WB enabled");
! 490:
! 491: if (ci->ci_ctrl & CPU_CONTROL_LABT_ENABLE)
! 492: printf(" LABT");
! 493: else
! 494: printf(" EABT");
! 495:
! 496: if (ci->ci_ctrl & CPU_CONTROL_BPRD_ENABLE)
! 497: printf(" branch prediction enabled");
! 498:
! 499: printf("\n");
! 500:
! 501: /* Print cache info. */
! 502: if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0)
! 503: goto skip_pcache;
! 504:
! 505: if (arm_pcache_unified) {
! 506: printf("%s: %dKB/%dB %d-way %s unified cache\n",
! 507: dv->dv_xname, arm_pdcache_size / 1024,
! 508: arm_pdcache_line_size, arm_pdcache_ways,
! 509: wtnames[arm_pcache_type]);
! 510: } else {
! 511: printf("%s: %dKB(%db/l,%dway) I-cache, %dKB(%db/l,%dway) %s D-cache\n",
! 512: dv->dv_xname, arm_picache_size / 1024,
! 513: arm_picache_line_size, arm_picache_ways,
! 514: arm_pdcache_size / 1024, arm_pdcache_line_size,
! 515: arm_pdcache_ways, wtnames[arm_pcache_type]);
! 516: }
! 517:
! 518: skip_pcache:
! 519:
! 520: switch (cpu_class) {
! 521: #ifdef CPU_ARM2
! 522: case CPU_CLASS_ARM2:
! 523: #endif
! 524: #ifdef CPU_ARM250
! 525: case CPU_CLASS_ARM2AS:
! 526: #endif
! 527: #ifdef CPU_ARM3
! 528: case CPU_CLASS_ARM3:
! 529: #endif
! 530: #ifdef CPU_ARM6
! 531: case CPU_CLASS_ARM6:
! 532: #endif
! 533: #ifdef CPU_ARM7
! 534: case CPU_CLASS_ARM7:
! 535: #endif
! 536: #ifdef CPU_ARM7TDMI
! 537: case CPU_CLASS_ARM7TDMI:
! 538: #endif
! 539: #ifdef CPU_ARM8
! 540: case CPU_CLASS_ARM8:
! 541: #endif
! 542: #ifdef CPU_ARM9
! 543: case CPU_CLASS_ARM9TDMI:
! 544: #endif
! 545: #ifdef CPU_ARM10
! 546: case CPU_CLASS_ARM10E:
! 547: #endif
! 548: #if defined(CPU_SA1) || defined(CPU_SA110) || defined(CPU_SA1100) || \
! 549: defined(CPU_SA1110) || defined(CPU_IXP12X0)
! 550: case CPU_CLASS_SA1:
! 551: #endif
! 552: #if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
! 553: defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425)
! 554: case CPU_CLASS_XSCALE:
! 555: #endif
! 556: break;
! 557: default:
! 558: if (cpu_classes[cpu_class].class_option != NULL)
! 559: printf("%s: %s does not fully support this CPU."
! 560: "\n", dv->dv_xname, ostype);
! 561: else {
! 562: printf("%s: This kernel does not fully support "
! 563: "this CPU.\n", dv->dv_xname);
! 564: printf("%s: Recompile with \"options %s\" to "
! 565: "correct this.\n", dv->dv_xname,
! 566: cpu_classes[cpu_class].class_option);
! 567: }
! 568: break;
! 569: }
! 570:
! 571: }
! 572: #ifdef MULTIPROCESSOR
! 573: int
! 574: cpu_alloc_idlepcb(struct cpu_info *ci)
! 575: {
! 576: vaddr_t uaddr;
! 577: struct pcb *pcb;
! 578: struct trapframe *tf;
! 579: int error;
! 580:
! 581: /*
! 582: * Generate a kernel stack and PCB (in essence, a u-area) for the
! 583: * new CPU.
! 584: */
! 585: if (uvm_uarea_alloc(&uaddr)) {
! 586: error = uvm_fault_wire(kernel_map, uaddr, uaddr + USPACE,
! 587: VM_FAULT_WIRE, VM_PROT_READ | VM_PROT_WRITE);
! 588: if (error)
! 589: return error;
! 590: }
! 591: ci->ci_idlepcb = pcb = (struct pcb *)uaddr;
! 592:
! 593: /*
! 594: * This code is largely derived from cpu_fork(), with which it
! 595: * should perhaps be shared.
! 596: */
! 597:
! 598: /* Copy the pcb */
! 599: *pcb = proc0.p_addr->u_pcb;
! 600:
! 601: /* Set up the undefined stack for the process. */
! 602: pcb->pcb_un.un_32.pcb32_und_sp = uaddr + USPACE_UNDEF_STACK_TOP;
! 603: pcb->pcb_un.un_32.pcb32_sp = uaddr + USPACE_SVC_STACK_TOP;
! 604:
! 605: #ifdef STACKCHECKS
! 606: /* Fill the undefined stack with a known pattern */
! 607: memset(((u_char *)uaddr) + USPACE_UNDEF_STACK_BOTTOM, 0xdd,
! 608: (USPACE_UNDEF_STACK_TOP - USPACE_UNDEF_STACK_BOTTOM));
! 609: /* Fill the kernel stack with a known pattern */
! 610: memset(((u_char *)uaddr) + USPACE_SVC_STACK_BOTTOM, 0xdd,
! 611: (USPACE_SVC_STACK_TOP - USPACE_SVC_STACK_BOTTOM));
! 612: #endif /* STACKCHECKS */
! 613:
! 614: pcb->pcb_tf = tf =
! 615: (struct trapframe *)pcb->pcb_un.un_32.pcb32_sp - 1;
! 616: *tf = *proc0.p_addr->u_pcb.pcb_tf;
! 617: return 0;
! 618: }
! 619: #endif /* MULTIPROCESSOR */
! 620:
! 621: /* End of cpu.c */
CVSweb