void ppc64_scale_frequency(u_int freq_scale) { u_int64_t psr; int s; s = ppc_intr_disable(); /* Clear PCRH and PCR. */ ppc_mtscomd(0x00000000); ppc_mtscomc(SCOM_PCR << SCOMC_ADDR_SHIFT); ppc_mtscomd(0x80000000); ppc_mtscomc(SCOM_PCR << SCOMC_ADDR_SHIFT); /* Set PCR. */ ppc_mtscomd(ppc_power_mode_data[freq_scale] | 0x80000000); ppc_mtscomc(SCOM_PCR << SCOMC_ADDR_SHIFT); /* Wait until frequency change is completed. */ do { ppc64_mtscomc((SCOM_PSR << SCOMC_ADDR_SHIFT) | SCOMC_READ); psr = ppc64_mfscomd(); ppc64_mfscomc(); if (psr & PSR_CMD_COMPLETED) break; DELAY(100); } while (psr & PSR_CMD_RECEIVED); if ((psr & PSR_FREQ_MASK) == PSR_FREQ_HALF) ppc_curfreq = ppc_maxfreq / 2; else ppc_curfreq = ppc_maxfreq; ppc_intr_enable(s); }
void dosoftint(int pcpl) { struct cpu_info *ci = curcpu(); int sir, q, mask; ppc_intr_enable(1); KERNEL_LOCK(); while ((sir = (ci->ci_ipending & ppc_smask[pcpl])) != 0) { atomic_clearbits_int(&ci->ci_ipending, sir); for (q = SI_NQUEUES - 1; q >= 0; q--) { mask = SI_TO_IRQBIT(q); if (sir & mask) softintr_dispatch(q); } } KERNEL_UNLOCK(); (void)ppc_intr_disable(); }
void cpuattach(struct device *parent, struct device *dev, void *aux) { u_int32_t cpu, pvr, hid0; char name[32]; int qhandle, phandle; u_int32_t clock_freq = 0; struct cpu_info *ci; ci = &cpu_info[dev->dv_unit]; ci->ci_cpuid = dev->dv_unit; ci->ci_intrdepth = -1; ci->ci_dev = dev; pvr = ppc_mfpvr(); cpu = pvr >> 16; switch (cpu) { case PPC_CPU_MPC601: snprintf(cpu_model, sizeof(cpu_model), "601"); break; case PPC_CPU_MPC603: snprintf(cpu_model, sizeof(cpu_model), "603"); break; case PPC_CPU_MPC604: snprintf(cpu_model, sizeof(cpu_model), "604"); break; case PPC_CPU_MPC603e: snprintf(cpu_model, sizeof(cpu_model), "603e"); break; case PPC_CPU_MPC603ev: snprintf(cpu_model, sizeof(cpu_model), "603ev"); break; case PPC_CPU_MPC750: snprintf(cpu_model, sizeof(cpu_model), "750"); break; case PPC_CPU_MPC604ev: snprintf(cpu_model, sizeof(cpu_model), "604ev"); break; case PPC_CPU_MPC7400: ppc_altivec = 1; snprintf(cpu_model, sizeof(cpu_model), "7400"); break; case PPC_CPU_MPC7447A: ppc_altivec = 1; snprintf(cpu_model, sizeof(cpu_model), "7447A"); break; case PPC_CPU_IBM970FX: ppc_altivec = 1; snprintf(cpu_model, sizeof(cpu_model), "970FX"); break; case PPC_CPU_IBM750FX: snprintf(cpu_model, sizeof(cpu_model), "750FX"); break; case PPC_CPU_MPC7410: ppc_altivec = 1; snprintf(cpu_model, sizeof(cpu_model), "7410"); break; case PPC_CPU_MPC7450: ppc_altivec = 1; if ((pvr & 0xf) < 3) snprintf(cpu_model, sizeof(cpu_model), "7450"); else snprintf(cpu_model, sizeof(cpu_model), "7451"); break; case PPC_CPU_MPC7455: ppc_altivec = 1; snprintf(cpu_model, sizeof(cpu_model), "7455"); break; case PPC_CPU_MPC7457: ppc_altivec = 1; snprintf(cpu_model, sizeof(cpu_model), "7457"); break; default: snprintf(cpu_model, sizeof(cpu_model), "Version %x", cpu); break; } snprintf(cpu_model + strlen(cpu_model), sizeof(cpu_model) - strlen(cpu_model), " (Revision 0x%x)", pvr & 0xffff); printf(": %s", cpu_model); /* This should only be executed on openfirmware systems... */ for (qhandle = OF_peer(0); qhandle; qhandle = phandle) { if (OF_getprop(qhandle, "device_type", name, sizeof name) >= 0 && !strcmp(name, "cpu") && OF_getprop(qhandle, "clock-frequency", &clock_freq, sizeof clock_freq) >= 0) { break; } if ((phandle = OF_child(qhandle))) continue; while (qhandle) { if ((phandle = OF_peer(qhandle))) break; qhandle = OF_parent(qhandle); } } if (clock_freq != 0) { /* Openfirmware stores clock in Hz, not MHz */ clock_freq /= 1000000; printf(": %d MHz", clock_freq); ppc_curfreq = ppc_maxfreq = clock_freq; cpu_cpuspeed = ppc_cpuspeed; } if (cpu == PPC_CPU_IBM970FX) { u_int64_t psr; int s; s = ppc_intr_disable(); ppc64_mtscomc((SCOM_PSR << SCOMC_ADDR_SHIFT) | SCOMC_READ); psr = ppc64_mfscomd(); ppc64_mfscomc(); ppc_intr_enable(s); if ((psr & PSR_FREQ_MASK) == PSR_FREQ_HALF) { ppc_curfreq = ppc_maxfreq / 2; perflevel = 50; } if (OF_getprop(qhandle, "power-mode-data", &ppc_power_mode_data, sizeof ppc_power_mode_data) >= 8) cpu_setperf = ppc64_setperf; } /* power savings mode */ if (ppc_proc_is_64b == 0) hid0 = ppc_mfhid0(); switch (cpu) { case PPC_CPU_MPC603: case PPC_CPU_MPC603e: case PPC_CPU_MPC750: case PPC_CPU_MPC7400: case PPC_CPU_IBM750FX: case PPC_CPU_MPC7410: /* select DOZE mode */ hid0 &= ~(HID0_NAP | HID0_SLEEP); hid0 |= HID0_DOZE | HID0_DPM; break; case PPC_CPU_MPC7447A: case PPC_CPU_MPC7450: case PPC_CPU_MPC7455: case PPC_CPU_MPC7457: /* select NAP mode */ hid0 &= ~(HID0_DOZE | HID0_SLEEP); hid0 |= HID0_NAP | HID0_DPM; /* try some other flags */ hid0 |= HID0_SGE | HID0_BTIC; hid0 |= HID0_LRSTK | HID0_FOLD | HID0_BHT; /* Disable BTIC on 7450 Rev 2.0 or earlier */ if (cpu == PPC_CPU_MPC7450 && (pvr & 0xffff) < 0x0200) hid0 &= ~HID0_BTIC; break; case PPC_CPU_IBM970FX: /* select NAP mode */ hid0 &= ~(HID0_DOZE | HID0_SLEEP); hid0 |= HID0_NAP | HID0_DPM; break; } if (ppc_proc_is_64b == 0) ppc_mthid0(hid0); /* if processor is G3 or G4, configure l2 cache */ if (cpu == PPC_CPU_MPC750 || cpu == PPC_CPU_MPC7400 || cpu == PPC_CPU_IBM750FX || cpu == PPC_CPU_MPC7410 || cpu == PPC_CPU_MPC7447A || cpu == PPC_CPU_MPC7450 || cpu == PPC_CPU_MPC7455 || cpu == PPC_CPU_MPC7457) { config_l2cr(cpu); } printf("\n"); }