int lapic_init() { uint32_t edx = 0; cpu_t *cpu = cpu_this; pic_init(); cpu_id(1,NULL,NULL,NULL,&edx); if (edx&(1<<9) && 0) { isr_uselapic = 1; cpu->uselapic = 1; lapic = memkernel_findvirt(1)+PAGEOFF(LAPIC_PHYS_ADDRESS); if (paging_map(PAGEDOWN(lapic),PAGEDOWN(LAPIC_PHYS_ADDRESS),0,1)<0) panic("Cannot map LAPIC\n"); lapic->tpr = 0x20; lapic->lvt_timer = 0x20030; lapic->lvt_thermal = 0x20031; lapic->lvt_pmc = 0x20032; lapic->lvt_lint0 = 0x08700; lapic->lvt_lint1 = 0x08700; lapic->lvt_error = 0x20035; lapic->spurious = 0x0010F; pic_pit_setinterval(0,LAPIC_PIT_CALIBRATE_INTERVAL); return 0; } else { isr_uselapic = 0; cpu->uselapic = 0; cpu->interval = 10; // IRQ0 all 10 ms pic_pit_setinterval(0,cpu->interval); return -1; } }
// returns 0 for success or negative for failure int kern_pmc_info(struct pmc_info *info) { int status = STATUS_SUCCESS; if (!cpu_id(info)) return STATUS_NO_CPUID; return status; }
void cpu_features_init(void) { /* reset all feature flags */ memset(features, 0, sizeof(features)); /* find max cpuid functions supported */ uint32_t max, max_ext, tmp; cpu_id(CPUID_VENDOR, &max, &tmp, &tmp, &tmp); cpu_id(CPUID_EXT_VENDOR, &max_ext, &tmp, &tmp, &tmp); /* detect 1GB page support */ if (CPUID_EXT_FEATURES <= max_ext) { uint32_t edx; cpu_id(CPUID_EXT_FEATURES, &tmp, &tmp, &tmp, &edx); if (edx & CPUID_EXT_FEATURE_EDX_1GB_PAGE) cpu_feature_set(FEATURE_1G_PAGE); } }
void ioapic_pin_set_vector(unsigned int pin, enum ioapic_trigger_mode trigger_mode, unsigned int vector) { mmio_write32(IOAPIC_BASE + IOAPIC_REG_INDEX, IOAPIC_REDIR_TBL_START + pin * 2 + 1); mmio_write32(IOAPIC_BASE + IOAPIC_REG_DATA, cpu_id() << (56 - 32)); mmio_write32(IOAPIC_BASE + IOAPIC_REG_INDEX, IOAPIC_REDIR_TBL_START + pin * 2); mmio_write32(IOAPIC_BASE + IOAPIC_REG_DATA, trigger_mode | vector); }
void cpu_attach(struct device *dv) { int usearmfpe; usearmfpe = 1; /* when compiled in, its enabled by default */ curcpu()->ci_dev = dv; evcnt_attach_dynamic(&curcpu()->ci_arm700bugcount, EVCNT_TYPE_MISC, NULL, dv->dv_xname, "arm700swibug"); /* Get the cpu ID from coprocessor 15 */ curcpu()->ci_cpuid = cpu_id(); curcpu()->ci_cputype = curcpu()->ci_cpuid & CPU_ID_CPU_MASK; curcpu()->ci_cpurev = curcpu()->ci_cpuid & CPU_ID_REVISION_MASK; identify_arm_cpu(dv, curcpu()); if (curcpu()->ci_cputype == CPU_ID_SA110 && curcpu()->ci_cpurev < 3) { printf("%s: SA-110 with bugged STM^ instruction\n", dv->dv_xname); } #ifdef CPU_ARM8 if ((curcpu()->ci_cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM810) { int clock = arm8_clock_config(0, 0); char *fclk; printf("%s: ARM810 cp15=%02x", dv->dv_xname, clock); printf(" clock:%s", (clock & 1) ? " dynamic" : ""); printf("%s", (clock & 2) ? " sync" : ""); switch ((clock >> 2) & 3) { case 0: fclk = "bus clock"; break; case 1: fclk = "ref clock"; break; case 3: fclk = "pll"; break; default: fclk = "illegal"; break; } printf(" fclk source=%s\n", fclk); }
void cpu_attach(struct device *dv) { curcpu()->ci_dev = dv; /* Get the CPU ID from coprocessor 15 */ curcpu()->ci_arm_cpuid = cpu_id(); curcpu()->ci_arm_cputype = curcpu()->ci_arm_cpuid & CPU_ID_CPU_MASK; curcpu()->ci_arm_cpurev = curcpu()->ci_arm_cpuid & CPU_ID_REVISION_MASK; identify_arm_cpu(dv, curcpu()); vfp_init(); }
void fault_describe(const char *fname, struct fault_ctx *fctx) { char *fault_type = "USER"; if (IS_KERNEL_FAULT(fctx)) { fault_type = "KERNEL"; } kprintf_fault("\n================[%s-SPACE %s #%d]================\n", fault_type, fname, fctx->fault_num); kprintf_fault(" [CPU #%d] Task: %s (PID=%ld, TID=%ld)\n", cpu_id(), current_task()->short_name, current_task()->pid, current_task()->tid); if (fctx->errcode) { kprintf_fault(" Error code: %#x\n", fctx->errcode); } }
void pci_msi_set_vector(u16 bdf, unsigned int vector) { int cap = pci_find_cap(bdf, PCI_CAP_MSI); u16 ctl, data; if (cap < 0) return; pci_write_config(bdf, cap + 0x04, 0xfee00000 | (cpu_id() << 12), 4); ctl = pci_read_config(bdf, cap + 0x02, 2); if (ctl & (1 << 7)) { pci_write_config(bdf, cap + 0x08, 0, 4); data = cap + 0x0c; } else data = cap + 0x08; pci_write_config(bdf, data, vector, 2); pci_write_config(bdf, cap + 0x02, 0x0001, 2); }
void pci_msix_set_vector(u16 bdf, unsigned int vector, u32 index) { int cap = pci_find_cap(bdf, PCI_CAP_MSIX); unsigned int bar; u64 msix_table = 0; u32 addr; u16 ctrl; u32 table; if (cap < 0) return; ctrl = pci_read_config(bdf, cap + 2, 2); /* bounds check */ if (index > (ctrl & 0x3ff)) return; table = pci_read_config(bdf, cap + 4, 4); bar = (table & 7) * 4 + PCI_CFG_BAR; addr = pci_read_config(bdf, bar, 4); if ((addr & 6) == PCI_BAR_64BIT) { msix_table = pci_read_config(bdf, bar + 4, 4); msix_table <<= 32; } msix_table |= addr & ~0xf; msix_table += table & ~7; /* enable and mask */ ctrl |= (MSIX_CTRL_ENABLE | MSIX_CTRL_FMASK); pci_write_config(bdf, cap + 2, ctrl, 2); msix_table += 16 * index; mmio_write32((u32 *)msix_table, 0xfee00000 | cpu_id() << 12); mmio_write32((u32 *)(msix_table + 4), 0); mmio_write32((u32 *)(msix_table + 8), vector); mmio_write32((u32 *)(msix_table + 12), 0); /* enable and unmask */ ctrl &= ~MSIX_CTRL_FMASK; pci_write_config(bdf, cap + 2, ctrl, 2); }
// returns 0 for success or negative for failure //int kern_pmc_init(struct pmc_info *info) int kern_pmc_init(void) { int status = STATUS_UNKNOWN_CPU_INIT; struct pmc_info info; ULONG64 cr4; if (!cpu_id(&info)) return STATUS_NO_CPUID; // we need to at least support MSR registers, RDTSC, & RDPMC if(!(info.features & MSR)) return STATUS_NO_MSR; if(!(info.features & TSC)) return STATUS_NO_TSC; if(!(info.features & MMX)) return STATUS_NO_MMX; // assume MMX tracks RDPMC if (!strncmp(info.vendor, "GenuineIntel", 12)) status = intel_init(info.family,info.stepping,info.model); else if (!strncmp(info.vendor, "AuthenticAMD", 12)) status = amd_init(info.family); // we really don't need to claim support for Cyrix, do we? // else if (!strncmp(info.vendor, "CyrixInstead", 12)) status = cyrix_init(info.family); if(status == STATUS_SUCCESS) set_cr4_pce(); return status; }
void cpu_attach(struct device *dv) { curcpu()->ci_dev = dv; /* Get the CPU ID from coprocessor 15 */ curcpu()->ci_arm_cpuid = cpu_id(); curcpu()->ci_arm_cputype = curcpu()->ci_arm_cpuid & CPU_ID_CPU_MASK; curcpu()->ci_arm_cpurev = curcpu()->ci_arm_cpuid & CPU_ID_REVISION_MASK; identify_arm_cpu(dv, curcpu()); #ifdef CPU_ARM8 if ((curcpu()->ci_arm_cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM810) { int clock = arm8_clock_config(0, 0); char *fclk; aprint_normal("%s: ARM810 cp15=%02x", dv->dv_xname, clock); aprint_normal(" clock:%s", (clock & 1) ? " dynamic" : ""); aprint_normal("%s", (clock & 2) ? " sync" : ""); switch ((clock >> 2) & 3) { case 0: fclk = "bus clock"; break; case 1: fclk = "ref clock"; break; case 3: fclk = "pll"; break; default: fclk = "illegal"; break; } aprint_normal(" fclk source=%s\n", fclk); }
void identify_arm_cpu(void) { u_int cpuid; int i; cpuid = cpu_id(); if (cpuid == 0) { printf("Processor failed probe - no CPU ID\n"); return; } for (i = 0; cpuids[i].cpuid != 0; i++) if (cpuids[i].cpuid == (cpuid & CPU_ID_CPU_MASK)) { cpu_class = cpuids[i].cpu_class; printf("CPU: %s %s (%s core)\n", cpuids[i].cpu_name, cpuids[i].cpu_steppings[cpuid & CPU_ID_REVISION_MASK], cpu_classes[cpu_class].class_name); break; } if (cpuids[i].cpuid == 0) printf("unknown CPU (ID = 0x%x)\n", cpuid); printf(" "); switch (cpu_class) { case CPU_CLASS_ARM6: case CPU_CLASS_ARM7: case CPU_CLASS_ARM7TDMI: case CPU_CLASS_ARM8: if ((ctrl & CPU_CONTROL_IDC_ENABLE) == 0) printf(" IDC disabled"); else printf(" IDC enabled"); break; case CPU_CLASS_ARM9TDMI: case CPU_CLASS_ARM9ES: case CPU_CLASS_ARM9EJS: case CPU_CLASS_ARM10E: case CPU_CLASS_ARM10EJ: case CPU_CLASS_SA1: case CPU_CLASS_XSCALE: case CPU_CLASS_ARM11J: case CPU_CLASS_MARVELL: if ((ctrl & CPU_CONTROL_DC_ENABLE) == 0) printf(" DC disabled"); else printf(" DC enabled"); if ((ctrl & CPU_CONTROL_IC_ENABLE) == 0) printf(" IC disabled"); else printf(" IC enabled"); #ifdef CPU_XSCALE_81342 if ((ctrl & CPU_CONTROL_L2_ENABLE) == 0) printf(" L2 disabled"); else printf(" L2 enabled"); #endif break; default: break; } if ((ctrl & CPU_CONTROL_WBUF_ENABLE) == 0) printf(" WB disabled"); else printf(" WB enabled"); if (ctrl & CPU_CONTROL_LABT_ENABLE) printf(" LABT"); else printf(" EABT"); if (ctrl & CPU_CONTROL_BPRD_ENABLE) printf(" branch prediction enabled"); printf("\n"); /* Print cache info. */ if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0) return; if (arm_pcache_unified) { printf(" %dKB/%dB %d-way %s unified cache\n", arm_pdcache_size / 1024, arm_pdcache_line_size, arm_pdcache_ways, wtnames[arm_pcache_type]); } else { printf(" %dKB/%dB %d-way Instruction cache\n", arm_picache_size / 1024, arm_picache_line_size, arm_picache_ways); printf(" %dKB/%dB %d-way %s Data cache\n", arm_pdcache_size / 1024, arm_pdcache_line_size, arm_pdcache_ways, wtnames[arm_pcache_type]); } }