X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/fe8ab488e9161c46dd9885d58fc52996dc0249ff..d9a64523371fa019c4575bb400cbbc3a50ac9903:/osfmk/i386/Diagnostics.c diff --git a/osfmk/i386/Diagnostics.c b/osfmk/i386/Diagnostics.c index 88a86c31b..90eeb4192 100644 --- a/osfmk/i386/Diagnostics.c +++ b/osfmk/i386/Diagnostics.c @@ -75,6 +75,10 @@ #include #include +#if MONOTONIC +#include +#endif /* MONOTONIC */ + #define PERMIT_PERMCHECK (0) diagWork dgWork; @@ -94,6 +98,9 @@ typedef struct { 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 { @@ -150,6 +157,7 @@ diagCall64(x86_saved_state_t * state) lastRuptClear = mach_absolute_time(); /* Get the time of clear */ rval = 1; /* Normal return */ + (void) ml_set_interrupts_enabled(FALSE); break; } @@ -175,6 +183,7 @@ diagCall64(x86_saved_state_t * state) * slot */ } rval = 1; + (void) ml_set_interrupts_enabled(FALSE); break; case dgPowerStat: @@ -218,7 +227,21 @@ diagCall64(x86_saved_state_t * state) 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); @@ -258,16 +281,22 @@ diagCall64(x86_saved_state_t * state) 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: @@ -285,7 +314,7 @@ diagCall64(x86_saved_state_t * state) rval = 1; } break; -#if DEBUG +#if DEVELOPMENT || DEBUG case dgGzallocTest: { (void) ml_set_interrupts_enabled(TRUE); @@ -294,25 +323,28 @@ diagCall64(x86_saved_state_t * state) 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; } @@ -341,16 +373,30 @@ void cpu_powerstats(__unused void *arg) { 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(); @@ -365,4 +411,7 @@ void cpu_pmc_control(void *enablep) { set_cr4((get_cr4() & ~CR4_PCE)); } cdp->cpu_fixed_pmcs_enabled = enable; +#else /* !MONOTONIC */ +#pragma unused(enablep) +#endif /* MONOTONIC */ }