#include <i386/misc_protos.h>
#include <i386/cpuid.h>
+#if MONOTONIC
+#include <kern/monotonic.h>
+#endif /* MONOTONIC */
+
#define PERMIT_PERMCHECK (0)
diagWork dgWork;
uint64_t cpu_insns;
uint64_t cpu_ucc;
uint64_t cpu_urc;
+#if DIAG_ALL_PMCS
+ uint64_t gpmcs[4];
+#endif /* DIAG_ALL_PMCS */
} core_energy_stat_t;
typedef struct {
lastRuptClear = mach_absolute_time(); /* Get the time of clear */
rval = 1; /* Normal return */
+ (void) ml_set_interrupts_enabled(FALSE);
break;
}
* slot */
}
rval = 1;
+ (void) ml_set_interrupts_enabled(FALSE);
break;
case dgPowerStat:
rdmsr64_carefully(MSR_IA32_RING_PERF_STATUS, &pkes.ring_ratio_instantaneous);
pkes.IA_frequency_clipping_cause = ~0ULL;
- rdmsr64_carefully(MSR_IA32_IA_PERF_LIMIT_REASONS, &pkes.IA_frequency_clipping_cause);
+
+ uint32_t ia_perf_limits = MSR_IA32_IA_PERF_LIMIT_REASONS;
+ /* Should perhaps be a generic register map module for these
+ * registers with identical functionality that were renumbered.
+ */
+ switch (cpuid_cpufamily()) {
+ case CPUFAMILY_INTEL_SKYLAKE:
+ case CPUFAMILY_INTEL_KABYLAKE:
+ ia_perf_limits = MSR_IA32_IA_PERF_LIMIT_REASONS_SKL;
+ break;
+ default:
+ break;
+ }
+
+ rdmsr64_carefully(ia_perf_limits, &pkes.IA_frequency_clipping_cause);
pkes.GT_frequency_clipping_cause = ~0ULL;
rdmsr64_carefully(MSR_IA32_GT_PERF_LIMIT_REASONS, &pkes.GT_frequency_clipping_cause);
cest.citime_total = cpu_data_ptr[i]->cpu_itime_total;
cest.crtime_total = cpu_data_ptr[i]->cpu_rtime_total;
- cest.cpu_idle_exits = cpu_data_ptr[i]->cpu_idle_exits;
- cest.cpu_insns = cpu_data_ptr[i]->cpu_cur_insns;
- cest.cpu_ucc = cpu_data_ptr[i]->cpu_cur_ucc;
- cest.cpu_urc = cpu_data_ptr[i]->cpu_cur_urc;
- (void) ml_set_interrupts_enabled(TRUE);
+ cest.cpu_idle_exits = cpu_data_ptr[i]->cpu_idle_exits;
+#if MONOTONIC
+ cest.cpu_insns = cpu_data_ptr[i]->cpu_monotonic.mtc_counts[MT_CORE_INSTRS];
+ cest.cpu_ucc = cpu_data_ptr[i]->cpu_monotonic.mtc_counts[MT_CORE_CYCLES];
+ cest.cpu_urc = cpu_data_ptr[i]->cpu_monotonic.mtc_counts[MT_CORE_REFCYCLES];
+#endif /* MONOTONIC */
+#if DIAG_ALL_PMCS
+ bcopy(&cpu_data_ptr[i]->cpu_gpmcs[0], &cest.gpmcs[0], sizeof(cest.gpmcs));
+#endif /* DIAG_ALL_PMCS */
+ (void) ml_set_interrupts_enabled(TRUE);
copyout(&cest, curpos, sizeof(cest));
curpos += sizeof(cest);
}
rval = 1;
+ (void) ml_set_interrupts_enabled(FALSE);
}
break;
case dgEnaPMC:
rval = 1;
}
break;
-#if DEBUG
+#if DEVELOPMENT || DEBUG
case dgGzallocTest:
{
(void) ml_set_interrupts_enabled(TRUE);
kfree(ptr, 1024);
*ptr = 0x42;
}
+ (void) ml_set_interrupts_enabled(FALSE);
}
break;
#endif
-#if PERMIT_PERMCHECK
+#if DEVELOPMENT || DEBUG
case dgPermCheck:
{
(void) ml_set_interrupts_enabled(TRUE);
if (diagflag)
rval = pmap_permissions_verify(kernel_pmap, kernel_map, 0, ~0ULL);
+ (void) ml_set_interrupts_enabled(FALSE);
}
break;
-#endif /* PERMIT_PERMCHECK */
+#endif /* DEVELOPMENT || DEBUG */
default: /* Handle invalid ones */
rval = 0; /* Return an exception */
}
regs->rax = rval;
+ assert(ml_get_interrupts_enabled() == FALSE);
return rval;
}
cdp->cpu_c7res = ((uint64_t)ch << 32) | cl;
if (diag_pmc_enabled) {
+#if MONOTONIC
+ mt_update_fixed_counts();
+#else /* MONOTONIC */
uint64_t insns = read_pmc(FIXED_PMC0);
uint64_t ucc = read_pmc(FIXED_PMC1);
uint64_t urc = read_pmc(FIXED_PMC2);
+#endif /* !MONOTONIC */
+#if DIAG_ALL_PMCS
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ cdp->cpu_gpmcs[i] = read_pmc(i);
+ }
+#endif /* DIAG_ALL_PMCS */
+#if !MONOTONIC
cdp->cpu_cur_insns = insns;
cdp->cpu_cur_ucc = ucc;
cdp->cpu_cur_urc = urc;
+#endif /* !MONOTONIC */
}
}
void cpu_pmc_control(void *enablep) {
+#if !MONOTONIC
boolean_t enable = *(boolean_t *)enablep;
cpu_data_t *cdp = current_cpu_datap();
set_cr4((get_cr4() & ~CR4_PCE));
}
cdp->cpu_fixed_pmcs_enabled = enable;
+#else /* !MONOTONIC */
+#pragma unused(enablep)
+#endif /* MONOTONIC */
}