hwpmc_core.c (206684) | hwpmc_core.c (210012) |
---|---|
1/*- 2 * Copyright (c) 2008 Joseph Koshy 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 15 unchanged lines hidden (view full) --- 24 * SUCH DAMAGE. 25 */ 26 27/* 28 * Intel Core, Core 2 and Atom PMCs. 29 */ 30 31#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2008 Joseph Koshy 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 15 unchanged lines hidden (view full) --- 24 * SUCH DAMAGE. 25 */ 26 27/* 28 * Intel Core, Core 2 and Atom PMCs. 29 */ 30 31#include <sys/cdefs.h> |
32__FBSDID("$FreeBSD: head/sys/dev/hwpmc/hwpmc_core.c 206684 2010-04-15 19:45:03Z fabient $"); | 32__FBSDID("$FreeBSD: head/sys/dev/hwpmc/hwpmc_core.c 210012 2010-07-13 19:37:45Z gnn $"); |
33 34#include <sys/param.h> 35#include <sys/bus.h> 36#include <sys/pmc.h> 37#include <sys/pmckern.h> 38#include <sys/systm.h> 39 40#include <machine/intr_machdep.h> --- 101 unchanged lines hidden (view full) --- 142} 143 144static int 145core_pcpu_fini(struct pmc_mdep *md, int cpu) 146{ 147 int core_ri, n, npmc; 148 struct pmc_cpu *pc; 149 struct core_cpu *cc; | 33 34#include <sys/param.h> 35#include <sys/bus.h> 36#include <sys/pmc.h> 37#include <sys/pmckern.h> 38#include <sys/systm.h> 39 40#include <machine/intr_machdep.h> --- 101 unchanged lines hidden (view full) --- 142} 143 144static int 145core_pcpu_fini(struct pmc_mdep *md, int cpu) 146{ 147 int core_ri, n, npmc; 148 struct pmc_cpu *pc; 149 struct core_cpu *cc; |
150 uint64_t msr = 0; |
|
150 151 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 152 ("[core,%d] insane cpu number (%d)", __LINE__, cpu)); 153 154 PMCDBG(MDP,INI,1,"core-pcpu-fini cpu=%d", cpu); 155 156 if ((cc = core_pcpu[cpu]) == NULL) 157 return (0); 158 159 core_pcpu[cpu] = NULL; 160 161 pc = pmc_pcpu[cpu]; 162 163 KASSERT(pc != NULL, ("[core,%d] NULL per-cpu %d state", __LINE__, 164 cpu)); 165 166 npmc = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAP].pcd_num; 167 core_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAP].pcd_ri; 168 | 151 152 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 153 ("[core,%d] insane cpu number (%d)", __LINE__, cpu)); 154 155 PMCDBG(MDP,INI,1,"core-pcpu-fini cpu=%d", cpu); 156 157 if ((cc = core_pcpu[cpu]) == NULL) 158 return (0); 159 160 core_pcpu[cpu] = NULL; 161 162 pc = pmc_pcpu[cpu]; 163 164 KASSERT(pc != NULL, ("[core,%d] NULL per-cpu %d state", __LINE__, 165 cpu)); 166 167 npmc = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAP].pcd_num; 168 core_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAP].pcd_ri; 169 |
169 for (n = 0; n < npmc; n++) 170 wrmsr(IAP_EVSEL0 + n, 0); | 170 for (n = 0; n < npmc; n++) { 171 msr = rdmsr(IAP_EVSEL0 + n); 172 wrmsr(IAP_EVSEL0 + n, msr & ~IAP_EVSEL_MASK); 173 } |
171 172 if (core_cputype != PMC_CPU_INTEL_CORE) { | 174 175 if (core_cputype != PMC_CPU_INTEL_CORE) { |
173 wrmsr(IAF_CTRL, 0); | 176 msr = rdmsr(IAF_CTRL); 177 wrmsr(IAF_CTRL, msr & ~IAF_CTRL_MASK); |
174 npmc += md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAF].pcd_num; 175 } 176 177 for (n = 0; n < npmc; n++) 178 pc->pc_hwpmcs[n + core_ri] = NULL; 179 180 free(cc, M_PMC); 181 --- 187 unchanged lines hidden (view full) --- 369 return (0); 370} 371 372static int 373iaf_start_pmc(int cpu, int ri) 374{ 375 struct pmc *pm; 376 struct core_cpu *iafc; | 178 npmc += md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAF].pcd_num; 179 } 180 181 for (n = 0; n < npmc; n++) 182 pc->pc_hwpmcs[n + core_ri] = NULL; 183 184 free(cc, M_PMC); 185 --- 187 unchanged lines hidden (view full) --- 373 return (0); 374} 375 376static int 377iaf_start_pmc(int cpu, int ri) 378{ 379 struct pmc *pm; 380 struct core_cpu *iafc; |
381 uint64_t msr = 0; |
|
377 378 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 379 ("[core,%d] illegal CPU value %d", __LINE__, cpu)); 380 KASSERT(ri >= 0 && ri < core_iaf_npmc, 381 ("[core,%d] illegal row-index %d", __LINE__, ri)); 382 383 PMCDBG(MDP,STA,1,"iaf-start cpu=%d ri=%d", cpu, ri); 384 385 iafc = core_pcpu[cpu]; 386 pm = iafc->pc_corepmcs[ri + core_iaf_ri].phw_pmc; 387 388 iafc->pc_iafctrl |= pm->pm_md.pm_iaf.pm_iaf_ctrl; 389 | 382 383 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 384 ("[core,%d] illegal CPU value %d", __LINE__, cpu)); 385 KASSERT(ri >= 0 && ri < core_iaf_npmc, 386 ("[core,%d] illegal row-index %d", __LINE__, ri)); 387 388 PMCDBG(MDP,STA,1,"iaf-start cpu=%d ri=%d", cpu, ri); 389 390 iafc = core_pcpu[cpu]; 391 pm = iafc->pc_corepmcs[ri + core_iaf_ri].phw_pmc; 392 393 iafc->pc_iafctrl |= pm->pm_md.pm_iaf.pm_iaf_ctrl; 394 |
390 wrmsr(IAF_CTRL, iafc->pc_iafctrl); | 395 msr = rdmsr(IAF_CTRL); 396 wrmsr(IAF_CTRL, msr | (iafc->pc_iafctrl & IAF_CTRL_MASK)); |
391 392 do { 393 iafc->pc_resync = 0; 394 iafc->pc_globalctrl |= (1ULL << (ri + IAF_OFFSET)); | 397 398 do { 399 iafc->pc_resync = 0; 400 iafc->pc_globalctrl |= (1ULL << (ri + IAF_OFFSET)); |
395 wrmsr(IA_GLOBAL_CTRL, iafc->pc_globalctrl); | 401 msr = rdmsr(IA_GLOBAL_CTRL); 402 wrmsr(IA_GLOBAL_CTRL, msr | (iafc->pc_globalctrl & 403 IAF_GLOBAL_CTRL_MASK)); |
396 } while (iafc->pc_resync != 0); 397 398 PMCDBG(MDP,STA,1,"iafctrl=%x(%x) globalctrl=%jx(%jx)", 399 iafc->pc_iafctrl, (uint32_t) rdmsr(IAF_CTRL), 400 iafc->pc_globalctrl, rdmsr(IA_GLOBAL_CTRL)); 401 402 return (0); 403} 404 405static int 406iaf_stop_pmc(int cpu, int ri) 407{ 408 uint32_t fc; 409 struct core_cpu *iafc; | 404 } while (iafc->pc_resync != 0); 405 406 PMCDBG(MDP,STA,1,"iafctrl=%x(%x) globalctrl=%jx(%jx)", 407 iafc->pc_iafctrl, (uint32_t) rdmsr(IAF_CTRL), 408 iafc->pc_globalctrl, rdmsr(IA_GLOBAL_CTRL)); 409 410 return (0); 411} 412 413static int 414iaf_stop_pmc(int cpu, int ri) 415{ 416 uint32_t fc; 417 struct core_cpu *iafc; |
418 uint64_t msr = 0; |
|
410 411 PMCDBG(MDP,STO,1,"iaf-stop cpu=%d ri=%d", cpu, ri); 412 413 iafc = core_pcpu[cpu]; 414 415 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 416 ("[core,%d] illegal CPU value %d", __LINE__, cpu)); 417 KASSERT(ri >= 0 && ri < core_iaf_npmc, 418 ("[core,%d] illegal row-index %d", __LINE__, ri)); 419 420 fc = (IAF_MASK << (ri * 4)); 421 422 if (core_cputype != PMC_CPU_INTEL_ATOM) 423 fc &= ~IAF_ANY; 424 425 iafc->pc_iafctrl &= ~fc; 426 427 PMCDBG(MDP,STO,1,"iaf-stop iafctrl=%x", iafc->pc_iafctrl); | 419 420 PMCDBG(MDP,STO,1,"iaf-stop cpu=%d ri=%d", cpu, ri); 421 422 iafc = core_pcpu[cpu]; 423 424 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 425 ("[core,%d] illegal CPU value %d", __LINE__, cpu)); 426 KASSERT(ri >= 0 && ri < core_iaf_npmc, 427 ("[core,%d] illegal row-index %d", __LINE__, ri)); 428 429 fc = (IAF_MASK << (ri * 4)); 430 431 if (core_cputype != PMC_CPU_INTEL_ATOM) 432 fc &= ~IAF_ANY; 433 434 iafc->pc_iafctrl &= ~fc; 435 436 PMCDBG(MDP,STO,1,"iaf-stop iafctrl=%x", iafc->pc_iafctrl); |
428 wrmsr(IAF_CTRL, iafc->pc_iafctrl); | 437 msr = rdmsr(IAF_CTRL); 438 wrmsr(IAF_CTRL, msr | (iafc->pc_iafctrl & IAF_CTRL_MASK)); |
429 430 do { 431 iafc->pc_resync = 0; 432 iafc->pc_globalctrl &= ~(1ULL << (ri + IAF_OFFSET)); | 439 440 do { 441 iafc->pc_resync = 0; 442 iafc->pc_globalctrl &= ~(1ULL << (ri + IAF_OFFSET)); |
433 wrmsr(IA_GLOBAL_CTRL, iafc->pc_globalctrl); | 443 msr = rdmsr(IA_GLOBAL_CTRL); 444 wrmsr(IA_GLOBAL_CTRL, msr | (iafc->pc_globalctrl & 445 IAF_GLOBAL_CTRL_MASK)); |
434 } while (iafc->pc_resync != 0); 435 436 PMCDBG(MDP,STO,1,"iafctrl=%x(%x) globalctrl=%jx(%jx)", 437 iafc->pc_iafctrl, (uint32_t) rdmsr(IAF_CTRL), 438 iafc->pc_globalctrl, rdmsr(IA_GLOBAL_CTRL)); 439 440 return (0); 441} 442 443static int 444iaf_write_pmc(int cpu, int ri, pmc_value_t v) 445{ 446 struct core_cpu *cc; 447 struct pmc *pm; | 446 } while (iafc->pc_resync != 0); 447 448 PMCDBG(MDP,STO,1,"iafctrl=%x(%x) globalctrl=%jx(%jx)", 449 iafc->pc_iafctrl, (uint32_t) rdmsr(IAF_CTRL), 450 iafc->pc_globalctrl, rdmsr(IA_GLOBAL_CTRL)); 451 452 return (0); 453} 454 455static int 456iaf_write_pmc(int cpu, int ri, pmc_value_t v) 457{ 458 struct core_cpu *cc; 459 struct pmc *pm; |
460 uint64_t msr; |
|
448 449 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 450 ("[core,%d] illegal cpu value %d", __LINE__, cpu)); 451 KASSERT(ri >= 0 && ri < core_iaf_npmc, 452 ("[core,%d] illegal row-index %d", __LINE__, ri)); 453 454 cc = core_pcpu[cpu]; 455 pm = cc->pc_corepmcs[ri + core_iaf_ri].phw_pmc; 456 457 KASSERT(pm, 458 ("[core,%d] cpu %d ri %d pmc not configured", __LINE__, cpu, ri)); 459 460 if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) 461 v = iaf_reload_count_to_perfctr_value(v); 462 | 461 462 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 463 ("[core,%d] illegal cpu value %d", __LINE__, cpu)); 464 KASSERT(ri >= 0 && ri < core_iaf_npmc, 465 ("[core,%d] illegal row-index %d", __LINE__, ri)); 466 467 cc = core_pcpu[cpu]; 468 pm = cc->pc_corepmcs[ri + core_iaf_ri].phw_pmc; 469 470 KASSERT(pm, 471 ("[core,%d] cpu %d ri %d pmc not configured", __LINE__, cpu, ri)); 472 473 if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) 474 v = iaf_reload_count_to_perfctr_value(v); 475 |
463 wrmsr(IAF_CTRL, 0); /* Turn off fixed counters */ 464 wrmsr(IAF_CTR0 + ri, v); 465 wrmsr(IAF_CTRL, cc->pc_iafctrl); | 476 msr = rdmsr(IAF_CTRL); 477 wrmsr(IAF_CTRL, msr & ~IAF_CTRL_MASK); 478 wrmsr(IAF_CTR0 + ri, v & ((1ULL << core_iaf_width) - 1)); 479 msr = rdmsr(IAF_CTRL); 480 wrmsr(IAF_CTRL, msr | (cc->pc_iafctrl & IAF_CTRL_MASK)); |
466 467 PMCDBG(MDP,WRI,1, "iaf-write cpu=%d ri=%d msr=0x%x v=%jx iafctrl=%jx " 468 "pmc=%jx", cpu, ri, IAF_RI_TO_MSR(ri), v, 469 (uintmax_t) rdmsr(IAF_CTRL), 470 (uintmax_t) rdpmc(IAF_RI_TO_MSR(ri))); 471 472 return (0); 473} --- 1400 unchanged lines hidden (view full) --- 1874 return (0); 1875} 1876 1877static int 1878iap_stop_pmc(int cpu, int ri) 1879{ 1880 struct pmc *pm; 1881 struct core_cpu *cc; | 481 482 PMCDBG(MDP,WRI,1, "iaf-write cpu=%d ri=%d msr=0x%x v=%jx iafctrl=%jx " 483 "pmc=%jx", cpu, ri, IAF_RI_TO_MSR(ri), v, 484 (uintmax_t) rdmsr(IAF_CTRL), 485 (uintmax_t) rdpmc(IAF_RI_TO_MSR(ri))); 486 487 return (0); 488} --- 1400 unchanged lines hidden (view full) --- 1889 return (0); 1890} 1891 1892static int 1893iap_stop_pmc(int cpu, int ri) 1894{ 1895 struct pmc *pm; 1896 struct core_cpu *cc; |
1897 uint64_t msr; |
|
1882 1883 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 1884 ("[core,%d] illegal cpu value %d", __LINE__, cpu)); 1885 KASSERT(ri >= 0 && ri < core_iap_npmc, 1886 ("[core,%d] illegal row index %d", __LINE__, ri)); 1887 1888 cc = core_pcpu[cpu]; 1889 pm = cc->pc_corepmcs[ri].phw_pmc; 1890 1891 KASSERT(pm, 1892 ("[core,%d] cpu%d ri%d no configured PMC to stop", __LINE__, 1893 cpu, ri)); 1894 1895 PMCDBG(MDP,STO,1, "iap-stop cpu=%d ri=%d", cpu, ri); 1896 | 1898 1899 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 1900 ("[core,%d] illegal cpu value %d", __LINE__, cpu)); 1901 KASSERT(ri >= 0 && ri < core_iap_npmc, 1902 ("[core,%d] illegal row index %d", __LINE__, ri)); 1903 1904 cc = core_pcpu[cpu]; 1905 pm = cc->pc_corepmcs[ri].phw_pmc; 1906 1907 KASSERT(pm, 1908 ("[core,%d] cpu%d ri%d no configured PMC to stop", __LINE__, 1909 cpu, ri)); 1910 1911 PMCDBG(MDP,STO,1, "iap-stop cpu=%d ri=%d", cpu, ri); 1912 |
1897 wrmsr(IAP_EVSEL0 + ri, 0); /* stop hw */ | 1913 msr = rdmsr(IAP_EVSEL0 + ri); 1914 wrmsr(IAP_EVSEL0 + ri, msr & IAP_EVSEL_MASK); /* stop hw */ |
1898 1899 if (core_cputype == PMC_CPU_INTEL_CORE) 1900 return (0); 1901 1902 do { 1903 cc->pc_resync = 0; 1904 cc->pc_globalctrl &= ~(1ULL << ri); 1905 wrmsr(IA_GLOBAL_CTRL, cc->pc_globalctrl); --- 26 unchanged lines hidden (view full) --- 1932 if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) 1933 v = iap_reload_count_to_perfctr_value(v); 1934 1935 /* 1936 * Write the new value to the counter. The counter will be in 1937 * a stopped state when the pcd_write() entry point is called. 1938 */ 1939 | 1915 1916 if (core_cputype == PMC_CPU_INTEL_CORE) 1917 return (0); 1918 1919 do { 1920 cc->pc_resync = 0; 1921 cc->pc_globalctrl &= ~(1ULL << ri); 1922 wrmsr(IA_GLOBAL_CTRL, cc->pc_globalctrl); --- 26 unchanged lines hidden (view full) --- 1949 if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) 1950 v = iap_reload_count_to_perfctr_value(v); 1951 1952 /* 1953 * Write the new value to the counter. The counter will be in 1954 * a stopped state when the pcd_write() entry point is called. 1955 */ 1956 |
1940 wrmsr(IAP_PMC0 + ri, v); | 1957 wrmsr(IAP_PMC0 + ri, v & ((1ULL << core_iap_width) - 1)); |
1941 1942 return (0); 1943} 1944 1945 1946static void 1947iap_initialize(struct pmc_mdep *md, int maxcpu, int npmc, int pmcwidth, 1948 int flags) --- 33 unchanged lines hidden (view full) --- 1982 1983static int 1984core_intr(int cpu, struct trapframe *tf) 1985{ 1986 pmc_value_t v; 1987 struct pmc *pm; 1988 struct core_cpu *cc; 1989 int error, found_interrupt, ri; | 1958 1959 return (0); 1960} 1961 1962 1963static void 1964iap_initialize(struct pmc_mdep *md, int maxcpu, int npmc, int pmcwidth, 1965 int flags) --- 33 unchanged lines hidden (view full) --- 1999 2000static int 2001core_intr(int cpu, struct trapframe *tf) 2002{ 2003 pmc_value_t v; 2004 struct pmc *pm; 2005 struct core_cpu *cc; 2006 int error, found_interrupt, ri; |
2007 uint64_t msr = 0; |
|
1990 1991 PMCDBG(MDP,INT, 1, "cpu=%d tf=0x%p um=%d", cpu, (void *) tf, 1992 TRAPF_USERMODE(tf)); 1993 1994 found_interrupt = 0; 1995 cc = core_pcpu[cpu]; 1996 1997 for (ri = 0; ri < core_iap_npmc; ri++) { --- 15 unchanged lines hidden (view full) --- 2013 2014 v = pm->pm_sc.pm_reloadcount; 2015 v = iaf_reload_count_to_perfctr_value(v); 2016 2017 /* 2018 * Stop the counter, reload it but only restart it if 2019 * the PMC is not stalled. 2020 */ | 2008 2009 PMCDBG(MDP,INT, 1, "cpu=%d tf=0x%p um=%d", cpu, (void *) tf, 2010 TRAPF_USERMODE(tf)); 2011 2012 found_interrupt = 0; 2013 cc = core_pcpu[cpu]; 2014 2015 for (ri = 0; ri < core_iap_npmc; ri++) { --- 15 unchanged lines hidden (view full) --- 2031 2032 v = pm->pm_sc.pm_reloadcount; 2033 v = iaf_reload_count_to_perfctr_value(v); 2034 2035 /* 2036 * Stop the counter, reload it but only restart it if 2037 * the PMC is not stalled. 2038 */ |
2021 wrmsr(IAP_EVSEL0 + ri, 0); | 2039 msr = rdmsr(IAP_EVSEL0 + ri); 2040 wrmsr(IAP_EVSEL0 + ri, msr & ~IAP_EVSEL_MASK); |
2022 wrmsr(IAP_PMC0 + ri, v); 2023 2024 if (error) 2025 continue; 2026 2027 wrmsr(IAP_EVSEL0 + ri, 2028 pm->pm_md.pm_iap.pm_iap_evsel | IAP_EN); 2029 } --- 226 unchanged lines hidden --- | 2041 wrmsr(IAP_PMC0 + ri, v); 2042 2043 if (error) 2044 continue; 2045 2046 wrmsr(IAP_EVSEL0 + ri, 2047 pm->pm_md.pm_iap.pm_iap_evsel | IAP_EN); 2048 } --- 226 unchanged lines hidden --- |