void cpu_hatch(void) { char *v = (char*)CPUINFO_VA; int i; for (i = 0; i < 4*PAGE_SIZE; i += sizeof(long)) flush(v + i); cpu_pmap_init(curcpu()); CPUSET_ADD(cpus_active, cpu_number()); cpu_reset_fpustate(); curlwp = curcpu()->ci_data.cpu_idlelwp; membar_Sync(); /* wait for the boot CPU to flip the switch */ while (sync_tick == 0) { /* we do nothing here */ } settick(0); if (curcpu()->ci_system_clockrate[0] != 0) { setstick(0); stickintr_establish(PIL_CLOCK, stickintr); } else { tickintr_establish(PIL_CLOCK, tickintr); } spl0(); }
void cpu_hatch() { char *v = (char*)CPUINFO_VA; int i; for (i = 0; i < 4*PAGE_SIZE; i += sizeof(long)) flush(v + i); cpu_pmap_init(curcpu()); CPUSET_ADD(cpus_active, cpu_number()); cpu_reset_fpustate(); curlwp = curcpu()->ci_data.cpu_idlelwp; membar_sync(); tickintr_establish(PIL_CLOCK, tickintr); spl0(); }
/* * Attach the CPU. * Discover interesting goop about the virtual address cache * (slightly funny place to do it, but this is where it is to be found). */ void cpu_attach(device_t parent, device_t dev, void *aux) { int node; long clk, sclk = 0; struct mainbus_attach_args *ma = aux; struct cpu_info *ci; const char *sep; register int i, l; int bigcache, cachesize; char buf[100]; int totalsize = 0; int linesize, dcachesize, icachesize; /* tell them what we have */ node = ma->ma_node; /* * Allocate cpu_info structure if needed. */ ci = alloc_cpuinfo((u_int)node); /* * Only do this on the boot cpu. Other cpu's call * cpu_reset_fpustate() from cpu_hatch() before they * call into the idle loop. * For other cpus, we need to call mi_cpu_attach() * and complete setting up cpcb. */ if (ci->ci_flags & CPUF_PRIMARY) { fpstate_cache = pool_cache_init(sizeof(struct fpstate64), SPARC64_BLOCK_SIZE, 0, 0, "fpstate", NULL, IPL_NONE, NULL, NULL, NULL); cpu_reset_fpustate(); } #ifdef MULTIPROCESSOR else { mi_cpu_attach(ci); ci->ci_cpcb = lwp_getpcb(ci->ci_data.cpu_idlelwp); } for (i = 0; i < IPI_EVCNT_NUM; ++i) evcnt_attach_dynamic(&ci->ci_ipi_evcnt[i], EVCNT_TYPE_INTR, NULL, device_xname(dev), ipi_evcnt_names[i]); #endif evcnt_attach_dynamic(&ci->ci_tick_evcnt, EVCNT_TYPE_INTR, NULL, device_xname(dev), "timer"); mutex_init(&ci->ci_ctx_lock, MUTEX_SPIN, IPL_VM); clk = prom_getpropint(node, "clock-frequency", 0); if (clk == 0) { /* * Try to find it in the OpenPROM root... */ clk = prom_getpropint(findroot(), "clock-frequency", 0); } if (clk) { /* Tell OS what frequency we run on */ ci->ci_cpu_clockrate[0] = clk; ci->ci_cpu_clockrate[1] = clk / 1000000; } sclk = prom_getpropint(findroot(), "stick-frequency", 0); ci->ci_system_clockrate[0] = sclk; ci->ci_system_clockrate[1] = sclk / 1000000; snprintf(buf, sizeof buf, "%s @ %s MHz", prom_getpropstring(node, "name"), clockfreq(clk)); snprintf(cpu_model, sizeof cpu_model, "%s (%s)", machine_model, buf); aprint_normal(": %s, UPA id %d\n", buf, ci->ci_cpuid); aprint_naive("\n"); if (ci->ci_system_clockrate[0] != 0) { aprint_normal_dev(dev, "system tick frequency %d MHz\n", (int)ci->ci_system_clockrate[1]); } aprint_normal_dev(dev, ""); bigcache = 0; icachesize = prom_getpropint(node, "icache-size", 0); if (icachesize > icache_size) icache_size = icachesize; linesize = l = prom_getpropint(node, "icache-line-size", 0); if (linesize > icache_line_size) icache_line_size = linesize; for (i = 0; (1 << i) < l && l; i++) /* void */; if ((1 << i) != l && l) panic("bad icache line size %d", l); totalsize = icachesize; if (totalsize == 0) totalsize = l * prom_getpropint(node, "icache-nlines", 64) * prom_getpropint(node, "icache-associativity", 1); cachesize = totalsize / prom_getpropint(node, "icache-associativity", 1); bigcache = cachesize; sep = ""; if (totalsize > 0) { aprint_normal("%s%ldK instruction (%ld b/l)", sep, (long)totalsize/1024, (long)linesize); sep = ", "; } dcachesize = prom_getpropint(node, "dcache-size", 0); if (dcachesize > dcache_size) dcache_size = dcachesize; linesize = l = prom_getpropint(node, "dcache-line-size", 0); if (linesize > dcache_line_size) dcache_line_size = linesize; for (i = 0; (1 << i) < l && l; i++) /* void */; if ((1 << i) != l && l) panic("bad dcache line size %d", l); totalsize = dcachesize; if (totalsize == 0) totalsize = l * prom_getpropint(node, "dcache-nlines", 128) * prom_getpropint(node, "dcache-associativity", 1); cachesize = totalsize / prom_getpropint(node, "dcache-associativity", 1); if (cachesize > bigcache) bigcache = cachesize; if (totalsize > 0) { aprint_normal("%s%ldK data (%ld b/l)", sep, (long)totalsize/1024, (long)linesize); sep = ", "; } linesize = l = prom_getpropint(node, "ecache-line-size", 0); for (i = 0; (1 << i) < l && l; i++) /* void */; if ((1 << i) != l && l) panic("bad ecache line size %d", l); totalsize = prom_getpropint(node, "ecache-size", 0); if (totalsize == 0) totalsize = l * prom_getpropint(node, "ecache-nlines", 32768) * prom_getpropint(node, "ecache-associativity", 1); cachesize = totalsize / prom_getpropint(node, "ecache-associativity", 1); if (cachesize > bigcache) bigcache = cachesize; if (totalsize > 0) { aprint_normal("%s%ldK external (%ld b/l)", sep, (long)totalsize/1024, (long)linesize); } aprint_normal("\n"); if (ecache_min_line_size == 0 || linesize < ecache_min_line_size) ecache_min_line_size = linesize; /* * Now that we know the size of the largest cache on this CPU, * re-color our pages. */ uvm_page_recolor(atop(bigcache)); /* XXX */ }