hwpmc_ppro.c (145615) | hwpmc_ppro.c (145774) |
---|---|
1/*- 2 * Copyright (c) 2003-2005 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 --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2003-2005 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 --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/dev/hwpmc/hwpmc_ppro.c 145615 2005-04-28 08:13:19Z jkoshy $"); | 28__FBSDID("$FreeBSD: head/sys/dev/hwpmc/hwpmc_ppro.c 145774 2005-05-01 14:11:49Z jkoshy $"); |
29 30#include <sys/param.h> 31#include <sys/lock.h> 32#include <sys/mutex.h> 33#include <sys/pmc.h> 34#include <sys/pmckern.h> 35#include <sys/smp.h> 36#include <sys/systm.h> --- 294 unchanged lines hidden (view full) --- 331 return 0; 332} 333 334static int 335p6_switch_in(struct pmc_cpu *pc, struct pmc_process *pp) 336{ 337 (void) pc; 338 | 29 30#include <sys/param.h> 31#include <sys/lock.h> 32#include <sys/mutex.h> 33#include <sys/pmc.h> 34#include <sys/pmckern.h> 35#include <sys/smp.h> 36#include <sys/systm.h> --- 294 unchanged lines hidden (view full) --- 331 return 0; 332} 333 334static int 335p6_switch_in(struct pmc_cpu *pc, struct pmc_process *pp) 336{ 337 (void) pc; 338 |
339 PMCDBG(MDP,SWI,1, "pc=%p pp=%p enable-msr=%d", pc, pp, 340 pp->pp_flags & PMC_PP_ENABLE_MSR_ACCESS); 341 |
|
339 /* allow the RDPMC instruction if needed */ | 342 /* allow the RDPMC instruction if needed */ |
340 if (pp->pp_flags & PMC_FLAG_ENABLE_MSR_ACCESS) | 343 if (pp->pp_flags & PMC_PP_ENABLE_MSR_ACCESS) |
341 load_cr4(rcr4() | CR4_PCE); | 344 load_cr4(rcr4() | CR4_PCE); |
345 346 PMCDBG(MDP,SWI,1, "cr4=0x%x", rcr4()); 347 |
|
342 return 0; 343} 344 345static int 346p6_switch_out(struct pmc_cpu *pc, struct pmc_process *pp) 347{ 348 (void) pc; 349 (void) pp; /* can be NULL */ 350 | 348 return 0; 349} 350 351static int 352p6_switch_out(struct pmc_cpu *pc, struct pmc_process *pp) 353{ 354 (void) pc; 355 (void) pp; /* can be NULL */ 356 |
357 PMCDBG(MDP,SWO,1, "pc=%p pp=%p cr4=0x%x", pc, pp, rcr4()); 358 |
|
351 /* always turn off the RDPMC instruction */ | 359 /* always turn off the RDPMC instruction */ |
352 load_cr4(rcr4() & ~CR4_PCE); | 360 load_cr4(rcr4() & ~CR4_PCE); |
353 354 return 0; 355} 356 357static int 358p6_read_pmc(int cpu, int ri, pmc_value_t *v) 359{ 360 struct pmc_hw *phw; --- 7 unchanged lines hidden (view full) --- 368 369 KASSERT(pm, 370 ("[p6,%d] cpu %d ri %d pmc not configured", __LINE__, cpu, ri)); 371 372 if (pd->pm_descr.pd_class == PMC_CLASS_TSC) 373 return 0; 374 375 tmp = rdmsr(pd->pm_pmc_msr) & P6_PERFCTR_MASK; | 361 362 return 0; 363} 364 365static int 366p6_read_pmc(int cpu, int ri, pmc_value_t *v) 367{ 368 struct pmc_hw *phw; --- 7 unchanged lines hidden (view full) --- 376 377 KASSERT(pm, 378 ("[p6,%d] cpu %d ri %d pmc not configured", __LINE__, cpu, ri)); 379 380 if (pd->pm_descr.pd_class == PMC_CLASS_TSC) 381 return 0; 382 383 tmp = rdmsr(pd->pm_pmc_msr) & P6_PERFCTR_MASK; |
376 if (PMC_IS_SAMPLING_MODE(pm->pm_mode)) | 384 if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) |
377 *v = -tmp; 378 else 379 *v = tmp; 380 381 PMCDBG(MDP,REA,1, "p6-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri, 382 pd->pm_pmc_msr, *v); 383 384 return 0; --- 14 unchanged lines hidden (view full) --- 399 ("[p6,%d] cpu %d ri %d pmc not configured", __LINE__, cpu, ri)); 400 401 if (pd->pm_descr.pd_class == PMC_CLASS_TSC) 402 return 0; 403 404 PMCDBG(MDP,WRI,1, "p6-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri, 405 pd->pm_pmc_msr, v); 406 | 385 *v = -tmp; 386 else 387 *v = tmp; 388 389 PMCDBG(MDP,REA,1, "p6-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri, 390 pd->pm_pmc_msr, *v); 391 392 return 0; --- 14 unchanged lines hidden (view full) --- 407 ("[p6,%d] cpu %d ri %d pmc not configured", __LINE__, cpu, ri)); 408 409 if (pd->pm_descr.pd_class == PMC_CLASS_TSC) 410 return 0; 411 412 PMCDBG(MDP,WRI,1, "p6-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri, 413 pd->pm_pmc_msr, v); 414 |
407 if (PMC_IS_SAMPLING_MODE(pm->pm_mode)) | 415 if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) |
408 v = -v; 409 410 wrmsr(pd->pm_pmc_msr, v & P6_PERFCTR_MASK); 411 412 return 0; 413} 414 415static int --- 5 unchanged lines hidden (view full) --- 421 422 phw = pmc_pcpu[cpu]->pc_hwpmcs[ri]; 423 phw->phw_pmc = pm; 424 425 return 0; 426} 427 428/* | 416 v = -v; 417 418 wrmsr(pd->pm_pmc_msr, v & P6_PERFCTR_MASK); 419 420 return 0; 421} 422 423static int --- 5 unchanged lines hidden (view full) --- 429 430 phw = pmc_pcpu[cpu]->pc_hwpmcs[ri]; 431 phw->phw_pmc = pm; 432 433 return 0; 434} 435 436/* |
437 * Retrieve a configured PMC pointer from hardware state. 438 */ 439 440static int 441p6_get_config(int cpu, int ri, struct pmc **ppm) 442{ 443 *ppm = pmc_pcpu[cpu]->pc_hwpmcs[ri]->phw_pmc; 444 445 return 0; 446} 447 448 449/* |
|
429 * A pmc may be allocated to a given row index if: 430 * - the event is valid for this CPU 431 * - the event is valid for this counter index 432 */ 433 434static int 435p6_allocate_pmc(int cpu, int ri, struct pmc *pm, 436 const struct pmc_op_pmcallocate *a) --- 12 unchanged lines hidden (view full) --- 449 450 pd = &p6_pmcdesc[ri]; 451 452 PMCDBG(MDP,ALL,1, "p6-allocate ri=%d class=%d pmccaps=0x%x " 453 "reqcaps=0x%x", ri, pd->pm_descr.pd_class, pd->pm_descr.pd_caps, 454 pm->pm_caps); 455 456 /* check class */ | 450 * A pmc may be allocated to a given row index if: 451 * - the event is valid for this CPU 452 * - the event is valid for this counter index 453 */ 454 455static int 456p6_allocate_pmc(int cpu, int ri, struct pmc *pm, 457 const struct pmc_op_pmcallocate *a) --- 12 unchanged lines hidden (view full) --- 470 471 pd = &p6_pmcdesc[ri]; 472 473 PMCDBG(MDP,ALL,1, "p6-allocate ri=%d class=%d pmccaps=0x%x " 474 "reqcaps=0x%x", ri, pd->pm_descr.pd_class, pd->pm_descr.pd_caps, 475 pm->pm_caps); 476 477 /* check class */ |
457 if (pd->pm_descr.pd_class != pm->pm_class) | 478 if (pd->pm_descr.pd_class != a->pm_class) |
458 return EINVAL; 459 460 /* check requested capabilities */ 461 caps = a->pm_caps; 462 if ((pd->pm_descr.pd_caps & caps) != caps) 463 return EPERM; 464 465 if (pd->pm_descr.pd_class == PMC_CLASS_TSC) { --- 204 unchanged lines hidden (view full) --- 670 phw = pmc_pcpu[cpu]->pc_hwpmcs[ri]; 671 pd = &p6_pmcdesc[ri]; 672 673 if ((error = copystr(pd->pm_descr.pd_name, pi->pm_name, 674 PMC_NAME_MAX, &copied)) != 0) 675 return error; 676 677 pi->pm_class = pd->pm_descr.pd_class; | 479 return EINVAL; 480 481 /* check requested capabilities */ 482 caps = a->pm_caps; 483 if ((pd->pm_descr.pd_caps & caps) != caps) 484 return EPERM; 485 486 if (pd->pm_descr.pd_class == PMC_CLASS_TSC) { --- 204 unchanged lines hidden (view full) --- 691 phw = pmc_pcpu[cpu]->pc_hwpmcs[ri]; 692 pd = &p6_pmcdesc[ri]; 693 694 if ((error = copystr(pd->pm_descr.pd_name, pi->pm_name, 695 PMC_NAME_MAX, &copied)) != 0) 696 return error; 697 698 pi->pm_class = pd->pm_descr.pd_class; |
678 pi->pm_caps = pd->pm_descr.pd_caps; 679 pi->pm_width = pd->pm_descr.pd_width; | |
680 681 if (phw->phw_state & PMC_PHW_FLAG_IS_ENABLED) { 682 pi->pm_enabled = TRUE; 683 *ppmc = phw->phw_pmc; 684 } else { 685 pi->pm_enabled = FALSE; 686 *ppmc = NULL; 687 } 688 689 return 0; 690} 691 692static int 693p6_get_msr(int ri, uint32_t *msr) 694{ 695 KASSERT(ri >= 0 && ri < P6_NPMCS, 696 ("[p6,%d ri %d out of range", __LINE__, ri)); 697 | 699 700 if (phw->phw_state & PMC_PHW_FLAG_IS_ENABLED) { 701 pi->pm_enabled = TRUE; 702 *ppmc = phw->phw_pmc; 703 } else { 704 pi->pm_enabled = FALSE; 705 *ppmc = NULL; 706 } 707 708 return 0; 709} 710 711static int 712p6_get_msr(int ri, uint32_t *msr) 713{ 714 KASSERT(ri >= 0 && ri < P6_NPMCS, 715 ("[p6,%d ri %d out of range", __LINE__, ri)); 716 |
698 *msr = p6_pmcdesc[ri].pm_pmc_msr; | 717 *msr = p6_pmcdesc[ri].pm_pmc_msr - P6_MSR_PERFCTR0; |
699 return 0; 700} 701 702int 703pmc_initialize_p6(struct pmc_mdep *pmc_mdep) 704{ 705 KASSERT(strcmp(cpu_vendor, "GenuineIntel") == 0, 706 ("[p6,%d] Initializing non-intel processor", __LINE__)); --- 10 unchanged lines hidden (view full) --- 717 case PMC_CPU_INTEL_CL: 718 case PMC_CPU_INTEL_PII: 719 case PMC_CPU_INTEL_PIII: 720 case PMC_CPU_INTEL_PM: 721 722 p6_cputype = pmc_mdep->pmd_cputype; 723 724 pmc_mdep->pmd_npmc = P6_NPMCS; | 718 return 0; 719} 720 721int 722pmc_initialize_p6(struct pmc_mdep *pmc_mdep) 723{ 724 KASSERT(strcmp(cpu_vendor, "GenuineIntel") == 0, 725 ("[p6,%d] Initializing non-intel processor", __LINE__)); --- 10 unchanged lines hidden (view full) --- 736 case PMC_CPU_INTEL_CL: 737 case PMC_CPU_INTEL_PII: 738 case PMC_CPU_INTEL_PIII: 739 case PMC_CPU_INTEL_PM: 740 741 p6_cputype = pmc_mdep->pmd_cputype; 742 743 pmc_mdep->pmd_npmc = P6_NPMCS; |
725 pmc_mdep->pmd_classes[1] = PMC_CLASS_P6; | 744 pmc_mdep->pmd_classes[1].pm_class = PMC_CLASS_P6; 745 pmc_mdep->pmd_classes[1].pm_caps = P6_PMC_CAPS; 746 pmc_mdep->pmd_classes[1].pm_width = 40; |
726 pmc_mdep->pmd_nclasspmcs[1] = 2; 727 728 pmc_mdep->pmd_init = p6_init; 729 pmc_mdep->pmd_cleanup = p6_cleanup; 730 pmc_mdep->pmd_switch_in = p6_switch_in; 731 pmc_mdep->pmd_switch_out = p6_switch_out; 732 pmc_mdep->pmd_read_pmc = p6_read_pmc; 733 pmc_mdep->pmd_write_pmc = p6_write_pmc; 734 pmc_mdep->pmd_config_pmc = p6_config_pmc; | 747 pmc_mdep->pmd_nclasspmcs[1] = 2; 748 749 pmc_mdep->pmd_init = p6_init; 750 pmc_mdep->pmd_cleanup = p6_cleanup; 751 pmc_mdep->pmd_switch_in = p6_switch_in; 752 pmc_mdep->pmd_switch_out = p6_switch_out; 753 pmc_mdep->pmd_read_pmc = p6_read_pmc; 754 pmc_mdep->pmd_write_pmc = p6_write_pmc; 755 pmc_mdep->pmd_config_pmc = p6_config_pmc; |
756 pmc_mdep->pmd_get_config = p6_get_config; |
|
735 pmc_mdep->pmd_allocate_pmc = p6_allocate_pmc; 736 pmc_mdep->pmd_release_pmc = p6_release_pmc; 737 pmc_mdep->pmd_start_pmc = p6_start_pmc; 738 pmc_mdep->pmd_stop_pmc = p6_stop_pmc; 739 pmc_mdep->pmd_intr = p6_intr; 740 pmc_mdep->pmd_describe = p6_describe; 741 pmc_mdep->pmd_get_msr = p6_get_msr; /* i386 */ 742 743 break; 744 default: 745 KASSERT(0,("[p6,%d] Unknown CPU type", __LINE__)); 746 return ENOSYS; 747 } 748 749 return 0; 750} | 757 pmc_mdep->pmd_allocate_pmc = p6_allocate_pmc; 758 pmc_mdep->pmd_release_pmc = p6_release_pmc; 759 pmc_mdep->pmd_start_pmc = p6_start_pmc; 760 pmc_mdep->pmd_stop_pmc = p6_stop_pmc; 761 pmc_mdep->pmd_intr = p6_intr; 762 pmc_mdep->pmd_describe = p6_describe; 763 pmc_mdep->pmd_get_msr = p6_get_msr; /* i386 */ 764 765 break; 766 default: 767 KASSERT(0,("[p6,%d] Unknown CPU type", __LINE__)); 768 return ENOSYS; 769 } 770 771 return 0; 772} |