/* * Start is called from boot; the first routine that is called * in kernel. Kernel stack is setup somewhere in a safe place; * but we need to move it to a better known place. Memory * management is disabled, and no interrupt system is active. */ void start(struct rpb *prpb) { extern void *scratch; mtpr(AST_NO, PR_ASTLVL); /* Turn off ASTs */ findcpu(); /* Set up the CPU identifying variables */ if (vax_confdata & 0x80) strlcpy(cpu_model, "MicroVAX ", sizeof cpu_model); else strlcpy(cpu_model, "VAXstation ", sizeof cpu_model); switch (vax_boardtype) { #if VAX780 case VAX_BTYP_780: dep_call = &ka780_calls; strlcpy(cpu_model,"VAX 11/780", sizeof cpu_model); if (vax_cpudata & 0x100) cpu_model[9] = '5'; break; #endif #if VAX750 case VAX_BTYP_750: dep_call = &ka750_calls; strlcpy(cpu_model, "VAX 11/750", sizeof cpu_model); break; #endif #if VAX8600 case VAX_BTYP_790: dep_call = &ka860_calls; strlcpy(cpu_model,"VAX 8600", sizeof cpu_model); if (vax_cpudata & 0x100) cpu_model[6] = '5'; break; #endif #if VAX410 case VAX_BTYP_420: /* They are very similar */ dep_call = &ka410_calls; strlcat(cpu_model, "3100", sizeof cpu_model); switch ((vax_siedata >> 8) & 0xff) { case 0x00: strlcat(cpu_model, "/m{30,40}", sizeof cpu_model); break; case 0x01: strlcat(cpu_model, "/m{38,48}", sizeof cpu_model); break; case 0x02: strlcat(cpu_model, "/m{10,20}{,e}", sizeof cpu_model); break; } break; case VAX_BTYP_410: dep_call = &ka410_calls; strlcat(cpu_model, "2000", sizeof cpu_model); break; #endif #if VAX43 case VAX_BTYP_43: dep_call = &ka43_calls; strlcat(cpu_model, "3100/m76", sizeof cpu_model); break; #endif #if VAX46 case VAX_BTYP_46: dep_call = &ka46_calls; switch(vax_siedata & 0xff) { case VAX_VTYP_47: strlcpy(cpu_model, "MicroVAX 3100 m80", sizeof cpu_model); break; case VAX_VTYP_46: strlcpy(cpu_model, "VAXstation 4000/60", sizeof cpu_model); break; default: strlcat(cpu_model, " - Unknown Mariah", sizeof cpu_model); } break; #endif #ifdef VXT case VAX_BTYP_VXT: dep_call = &vxt_calls; strlcpy(cpu_model, "VXT2000", sizeof cpu_model); break; #endif #if VAX48 case VAX_BTYP_48: dep_call = &ka48_calls; switch ((vax_siedata >> 8) & 0xff) { case VAX_STYP_45: strlcpy(cpu_model, "MicroVAX 3100/m{30,40}", sizeof cpu_model); break; case VAX_STYP_48: strlcpy(cpu_model, "VAXstation 4000/VLC", sizeof cpu_model); break; default: strlcat(cpu_model, " - Unknown SOC", sizeof cpu_model); } break; #endif #if VAX49 case VAX_BTYP_49: dep_call = &ka49_calls; strlcpy(cpu_model, "VAXstation 4000/90", sizeof cpu_model); break; #endif #if VAX53 case VAX_BTYP_1303: dep_call = &ka53_calls; switch ((vax_siedata >> 8) & 0xff) { case VAX_STYP_50: strlcpy(cpu_model, "MicroVAX 3100 model 85 or 90", sizeof cpu_model); break; case VAX_STYP_51: strlcpy(cpu_model, "MicroVAX 3100 model 90 or 95", sizeof cpu_model); break; case VAX_STYP_52: strlcpy(cpu_model, "VAX 4000 100", sizeof cpu_model); break; case VAX_STYP_53: strlcpy(cpu_model, "VAX 4000 105A", sizeof cpu_model); break; default: strlcpy(cpu_model, "VAX - Unknown Cheetah Class", sizeof cpu_model); } break; #endif #if VAX630 case VAX_BTYP_630: dep_call = &ka630_calls; strlcpy(cpu_model,"MicroVAX II", sizeof cpu_model); break; #endif #if VAX650 case VAX_BTYP_650: dep_call = &ka650_calls; strlcpy(cpu_model,"MicroVAX ", sizeof cpu_model); switch ((vax_siedata >> 8) & 255) { case VAX_SIE_KA640: strlcat(cpu_model, "3300/3400", sizeof cpu_model); break; case VAX_SIE_KA650: strlcat(cpu_model, "3500/3600", sizeof cpu_model); break; case VAX_SIE_KA655: strlcat(cpu_model, "3800/3900", sizeof cpu_model); break; default: strlcat(cpu_model, "III", sizeof cpu_model); break; } break; #endif #if VAX660 case VAX_BTYP_660: dep_call = &ka660_calls; strlcpy(cpu_model,"VAX 4000 200", sizeof cpu_model); break; #endif #if VAX670 case VAX_BTYP_670: dep_call = &ka670_calls; strlcpy(cpu_model,"VAX 4000 300", sizeof cpu_model); break; #endif #if VAX680 case VAX_BTYP_1301: dep_call = &ka680_calls; strlcpy(cpu_model,"VAX 4000 ", sizeof cpu_model); switch ((vax_siedata >> 8) & 0xff) { case VAX_STYP_675: strlcat(cpu_model,"400", sizeof cpu_model); break; case VAX_STYP_680: strlcat(cpu_model,"500", sizeof cpu_model); break; case VAX_STYP_690: strlcat(cpu_model,"600", sizeof cpu_model); break; default: strlcat(cpu_model,"- Unknown Omega Class", sizeof cpu_model); } break; case VAX_BTYP_1305: dep_call = &ka680_calls; strlcpy(cpu_model,"VAX 4000 ", sizeof cpu_model); switch ((vax_siedata >> 8) & 0xff) { case VAX_STYP_681: strlcat(cpu_model,"500A", sizeof cpu_model); break; case VAX_STYP_691: strlcat(cpu_model,"605A", sizeof cpu_model); break; case VAX_STYP_694: if (vax_cpudata & 0x1000) strlcat(cpu_model,"705A", sizeof cpu_model); else strlcat(cpu_model,"700A", sizeof cpu_model); break; default: strlcat(cpu_model,"- Unknown Legacy Class", sizeof cpu_model); } break; #endif #if VAX8200 case VAX_BTYP_8000: mastercpu = mfpr(PR_BINID); dep_call = &ka820_calls; strlcpy(cpu_model, "VAX 8200", sizeof cpu_model); break; #endif default: /* CPU not supported, just give up */ asm("halt"); } /* * Machines older than MicroVAX II have their boot blocks * loaded directly or the boot program loaded from console * media, so we need to figure out their memory size. * This is not easily done on MicroVAXen, so we get it from * VMB instead. * * In post-1.4 a RPB is always provided from the boot blocks. */ #if 1 /* compat with old bootblocks */ if (prpb == 0) { bzero((caddr_t)proc0paddr + REDZONEADDR, sizeof(struct rpb)); prpb = (struct rpb *)(proc0paddr + REDZONEADDR); prpb->pfncnt = avail_end >> VAX_PGSHIFT; prpb->rpb_base = (void *)-1; /* RPB is fake */ } else
static int est_init(void) { char hwmodel[128]; int mib[] = { CTL_HW, HW_MODEL }; size_t modellen = sizeof(hwmodel); struct sysctl_oid *oid, *leaf; uint64_t msr; int mv; size_t len, freq_len; int err; size_t i; if ((cpu_feature2 & CPUID2_EST) == 0) { kprintf("Enhanced SpeedStep unsupported on this hardware.\n"); return(EOPNOTSUPP); } modellen = sizeof(hwmodel); err = kernel_sysctl(mib, 2, hwmodel, &modellen, NULL, 0, NULL); if (err) { kprintf("kernel_sysctl hw.model failed\n"); return(err); } msr = rdmsr(MSR_PERF_STATUS); mv = MSR2MV(msr); kprintf("%s (%d mV) ", est_desc, mv); est_fqlist = findcpu(hwmodel, mv); if (est_fqlist == NULL) { kprintf(" - unknown CPU or operating point" "(cpu_id:%#x, msr:%#jx).\n", cpu_id, (intmax_t)msr); return(EOPNOTSUPP); } /* * OK, tell the user the available frequencies. */ fsbmult = est_fqlist->fsbmult; kprintf("%d MHz\n", MSR2MHZ(msr)); freq_len = est_fqlist->tablec * (sizeof("9999 ")-1) + 1; if (freq_len >= sizeof(freqs_available)) { kprintf("increase the size of freqs_available[]\n"); return(ENOMEM); } freqs_available[0] = '\0'; len = 0; for (i = 0; i < est_fqlist->tablec; i++) { len += ksnprintf(freqs_available + len, freq_len - len, "%d%s", est_fqlist->table[i].mhz, i < est_fqlist->tablec - 1 ? " " : ""); } kprintf("%s frequencies available (MHz): %s\n", est_desc, freqs_available); /* * Setup the sysctl sub-tree machdep.est.* */ oid = SYSCTL_ADD_NODE(&machdep_est_ctx, SYSCTL_STATIC_CHILDREN(_machdep), OID_AUTO, "est", CTLFLAG_RD, NULL, ""); if (oid == NULL) return(EOPNOTSUPP); oid = SYSCTL_ADD_NODE(&machdep_est_ctx, SYSCTL_CHILDREN(oid), OID_AUTO, "frequency", CTLFLAG_RD, NULL, ""); if (oid == NULL) return(EOPNOTSUPP); leaf = SYSCTL_ADD_PROC(&machdep_est_ctx, SYSCTL_CHILDREN(oid), OID_AUTO, "target", CTLTYPE_INT | CTLFLAG_RW, NULL, 0, est_sysctl_helper, "I", "Target CPU frequency for Enhanced SpeedStep"); if (leaf == NULL) return(EOPNOTSUPP); leaf = SYSCTL_ADD_PROC(&machdep_est_ctx, SYSCTL_CHILDREN(oid), OID_AUTO, "current", CTLTYPE_INT | CTLFLAG_RD, NULL, 0, est_sysctl_helper, "I", "Current CPU frequency for Enhanced SpeedStep"); if (leaf == NULL) return(EOPNOTSUPP); leaf = SYSCTL_ADD_STRING(&machdep_est_ctx, SYSCTL_CHILDREN(oid), OID_AUTO, "available", CTLFLAG_RD, freqs_available, sizeof(freqs_available), "CPU frequencies supported by Enhanced SpeedStep"); if (leaf == NULL) return(EOPNOTSUPP); return(0); }