]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/i386/Diagnostics.c
xnu-3789.70.16.tar.gz
[apple/xnu.git] / osfmk / i386 / Diagnostics.c
index 88a86c31bb816aca08e0a58f5495719b4a561960..bd2ca2140b56c4f1781d44d7ca101176a3589a9d 100644 (file)
@@ -94,6 +94,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 +153,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 +179,7 @@ diagCall64(x86_saved_state_t * state)
                                                                         * slot */
                }
                rval = 1;
+               (void) ml_set_interrupts_enabled(FALSE);
                break;
 
        case dgPowerStat:
@@ -218,7 +223,20 @@ 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:
+                       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);
@@ -262,12 +280,16 @@ diagCall64(x86_saved_state_t * state)
                        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;
+#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 +307,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 +316,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;
 }
 
@@ -344,6 +369,13 @@ void cpu_powerstats(__unused void *arg) {
                uint64_t insns = read_pmc(FIXED_PMC0);
                uint64_t ucc = read_pmc(FIXED_PMC1);
                uint64_t urc = read_pmc(FIXED_PMC2);
+#if DIAG_ALL_PMCS
+               int i;
+
+               for (i = 0; i < 4; i++) {
+                       cdp->cpu_gpmcs[i] = read_pmc(i);
+               }
+#endif /* DIAG_ALL_PMCS */
                cdp->cpu_cur_insns = insns;
                cdp->cpu_cur_ucc = ucc;
                cdp->cpu_cur_urc = urc;