+ rval = 1;
+ break;
+ case dgPowerStat:
+ {
+ uint32_t c2l = 0, c2h = 0, c3l = 0, c3h = 0, c6l = 0, c6h = 0, c7l = 0, c7h = 0;
+ uint32_t pkg_unit_l = 0, pkg_unit_h = 0, pkg_ecl = 0, pkg_ech = 0;
+
+ pkg_energy_statistics_t pkes;
+ core_energy_stat_t cest;
+
+ bzero(&pkes, sizeof(pkes));
+ bzero(&cest, sizeof(cest));
+
+ rdmsr_carefully(MSR_IA32_PKG_C2_RESIDENCY, &c2l, &c2h);
+ rdmsr_carefully(MSR_IA32_PKG_C3_RESIDENCY, &c3l, &c3h);
+ rdmsr_carefully(MSR_IA32_PKG_C6_RESIDENCY, &c6l, &c6h);
+ rdmsr_carefully(MSR_IA32_PKG_C7_RESIDENCY, &c7l, &c7h);
+
+ pkes.pkg_cres[0][0] = ((uint64_t)c2h << 32) | c2l;
+ pkes.pkg_cres[0][1] = ((uint64_t)c3h << 32) | c3l;
+ pkes.pkg_cres[0][2] = ((uint64_t)c6h << 32) | c6l;
+ pkes.pkg_cres[0][3] = ((uint64_t)c7h << 32) | c7l;
+
+ rdmsr_carefully(MSR_IA32_PKG_POWER_SKU_UNIT, &pkg_unit_l, &pkg_unit_h);
+ rdmsr_carefully(MSR_IA32_PKG_ENERGY_STATUS, &pkg_ecl, &pkg_ech);
+
+ pkes.pkg_power_unit = ((uint64_t)pkg_unit_h << 32) | pkg_unit_l;
+ pkes.pkg_energy = ((uint64_t)pkg_ech << 32) | pkg_ecl;
+
+ pkes.ncpus = real_ncpus;
+
+ (void) ml_set_interrupts_enabled(TRUE);
+
+ copyout(&pkes, regs->rsi, sizeof(pkes));
+ curpos = regs->rsi + sizeof(pkes);
+
+ mp_cpus_call(CPUMASK_ALL, ASYNC, cpu_powerstats, NULL);
+
+ for (i = 0; i < real_ncpus; i++) {
+ cest.caperf = cpu_data_ptr[i]->cpu_aperf;
+ cest.cmperf = cpu_data_ptr[i]->cpu_mperf;
+ cest.ccres[0] = cpu_data_ptr[i]->cpu_c3res;
+ cest.ccres[1] = cpu_data_ptr[i]->cpu_c6res;
+ cest.ccres[2] = cpu_data_ptr[i]->cpu_c7res;
+
+ bcopy(&cpu_data_ptr[i]->cpu_rtimes[0], &cest.crtimes[0], sizeof(cest.crtimes));
+ bcopy(&cpu_data_ptr[i]->cpu_itimes[0], &cest.citimes[0], sizeof(cest.citimes));
+ cest.citime_total = cpu_data_ptr[i]->cpu_itime_total;
+ cest.crtime_total = cpu_data_ptr[i]->cpu_rtime_total;
+
+ copyout(&cest, curpos, sizeof(cest));
+ curpos += sizeof(cest);
+ }
+ rval = 1;
+ }
+ break;