hwpmc_piv.c (145615) | hwpmc_piv.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_piv.c 145615 2005-04-28 08:13:19Z jkoshy $"); | 28__FBSDID("$FreeBSD: head/sys/dev/hwpmc/hwpmc_piv.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> 37 | 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> 37 |
38#include <machine/cputypes.h> | 38#include <machine/apicreg.h> |
39#include <machine/md_var.h> 40 41/* 42 * PENTIUM 4 SUPPORT 43 * 44 * The P4 has 18 PMCs, divided into 4 groups with 4,4,4 and 6 PMCs 45 * respectively. Each PMC comprises of two model specific registers: 46 * a counter configuration control register (CCCR) and a counter --- 44 unchanged lines hidden (view full) --- 91 * cpus as independent CPUs and can schedule kernel threads on them 92 * independently. However, the two logical CPUs share the same set of 93 * PMC resources. We need to ensure that: 94 * - PMCs that use the PMC_F_DESCENDANTS semantics are handled correctly, 95 * and, 96 * - Threads of multi-threaded processes that get scheduled on the same 97 * physical CPU are handled correctly. 98 * | 39#include <machine/md_var.h> 40 41/* 42 * PENTIUM 4 SUPPORT 43 * 44 * The P4 has 18 PMCs, divided into 4 groups with 4,4,4 and 6 PMCs 45 * respectively. Each PMC comprises of two model specific registers: 46 * a counter configuration control register (CCCR) and a counter --- 44 unchanged lines hidden (view full) --- 91 * cpus as independent CPUs and can schedule kernel threads on them 92 * independently. However, the two logical CPUs share the same set of 93 * PMC resources. We need to ensure that: 94 * - PMCs that use the PMC_F_DESCENDANTS semantics are handled correctly, 95 * and, 96 * - Threads of multi-threaded processes that get scheduled on the same 97 * physical CPU are handled correctly. 98 * |
99 * HTT Detection 100 * |
|
99 * Not all HTT capable systems will have HTT enabled since users may 100 * have turned HTT support off using the appropriate sysctls | 101 * Not all HTT capable systems will have HTT enabled since users may 102 * have turned HTT support off using the appropriate sysctls |
101 * (machdep.hlt_logical_cpus and machdep.logical_cpus_mask). We 102 * detect the presence of HTT by remembering if an initialization was 103 * done for a logical CPU. | 103 * (machdep.hlt_logical_cpus or machdep.logical_cpus_mask). We detect 104 * the presence of HTT by remembering if 'p4_init()' was called for a 105 * logical CPU. Note that hwpmc(4) cannot deal with a change in HTT 106 * status once it is loaded. |
104 * | 107 * |
108 * Handling HTT READ / WRITE / START / STOP 109 * 110 * PMC resources are shared across multiple logical CPUs. In each 111 * physical CPU's state we keep track of a 'runcount' which reflects 112 * the number of PMC-using processes that have been scheduled on the 113 * logical CPUs of this physical CPU. Process-mode PMC operations 114 * will actually 'start' or 'stop' hardware only if these are the 115 * first or last processes respectively to use the hardware. PMC 116 * values written by a 'write' operation are saved and are transferred 117 * to hardware at PMC 'start' time if the runcount is 0. If the 118 * runcount is greater than 0 at the time of a 'start' operation, we 119 * keep track of the actual hardware value at the time of the 'start' 120 * operation and use this to adjust the final readings at PMC 'stop' 121 * or 'read' time. 122 * 123 * Execution sequences: 124 * 125 * Case 1: CPUx +...- (no overlap) 126 * CPUy +...- 127 * RC 0 1 0 1 0 128 * 129 * Case 2: CPUx +........- (partial overlap) 130 * CPUy +........- 131 * RC 0 1 2 1 0 132 * 133 * Case 3: CPUx +..............- (fully overlapped) 134 * CPUy +.....- 135 * RC 0 1 2 1 0 136 * 137 * Here CPUx and CPUy are one of the two logical processors on a HTT CPU. 138 * 139 * Handling HTT CONFIG 140 * 141 * Different processes attached to the same PMC may get scheduled on 142 * the two logical processors in the package. We keep track of config 143 * and de-config operations using the CFGFLAGS fields of the per-physical 144 * cpu state. |
|
105 */ 106 107#define P4_PMCS() \ 108 P4_PMC(BPU_COUNTER0) \ 109 P4_PMC(BPU_COUNTER1) \ 110 P4_PMC(BPU_COUNTER2) \ 111 P4_PMC(BPU_COUNTER3) \ 112 P4_PMC(MS_COUNTER0) \ --- 268 unchanged lines hidden (view full) --- 381/* 382 * Per-CPU data structure for P4 class CPUs 383 * 384 * [common stuff] 385 * [19 struct pmc_hw pointers] 386 * [19 struct pmc_hw structures] 387 * [45 ESCRs status bytes] 388 * [per-cpu spin mutex] | 145 */ 146 147#define P4_PMCS() \ 148 P4_PMC(BPU_COUNTER0) \ 149 P4_PMC(BPU_COUNTER1) \ 150 P4_PMC(BPU_COUNTER2) \ 151 P4_PMC(BPU_COUNTER3) \ 152 P4_PMC(MS_COUNTER0) \ --- 268 unchanged lines hidden (view full) --- 421/* 422 * Per-CPU data structure for P4 class CPUs 423 * 424 * [common stuff] 425 * [19 struct pmc_hw pointers] 426 * [19 struct pmc_hw structures] 427 * [45 ESCRs status bytes] 428 * [per-cpu spin mutex] |
389 * [19 flags for holding the config count and runcount] 390 * [19*2 saved value fields] (Thread mode PMC support) 391 * [19*2 pmc value fields] (-do-) | 429 * [19 flag fields for holding config flags and a runcount] 430 * [19*2 hw value fields] (Thread mode PMC support) 431 * or 432 * [19*2 EIP values] (Sampling mode PMCs) 433 * [19*2 pmc value fields] (Thread mode PMC support)) |
392 */ 393 394struct p4_cpu { 395 struct pmc_cpu pc_common; 396 struct pmc_hw *pc_hwpmcs[P4_NPMCS]; 397 struct pmc_hw pc_p4pmcs[P4_NPMCS]; 398 char pc_escrs[P4_NESCR]; 399 struct mtx pc_mtx; /* spin lock */ 400 unsigned char pc_flags[P4_NPMCS]; /* 4 bits each: {cfg,run}count */ | 434 */ 435 436struct p4_cpu { 437 struct pmc_cpu pc_common; 438 struct pmc_hw *pc_hwpmcs[P4_NPMCS]; 439 struct pmc_hw pc_p4pmcs[P4_NPMCS]; 440 char pc_escrs[P4_NESCR]; 441 struct mtx pc_mtx; /* spin lock */ 442 unsigned char pc_flags[P4_NPMCS]; /* 4 bits each: {cfg,run}count */ |
401 pmc_value_t pc_saved[P4_NPMCS * P4_NHTT]; | 443 union { 444 pmc_value_t pc_hw[P4_NPMCS * P4_NHTT]; 445 uintptr_t pc_ip[P4_NPMCS * P4_NHTT]; 446 } pc_si; |
402 pmc_value_t pc_pmc_values[P4_NPMCS * P4_NHTT]; 403}; 404 | 447 pmc_value_t pc_pmc_values[P4_NPMCS * P4_NHTT]; 448}; 449 |
405#define P4_PCPU_SAVED_VALUE(PC,RI,CPU) (PC)->pc_saved[(RI)*((CPU) & 1)] 406#define P4_PCPU_PMC_VALUE(P,R,C) (P)->pc_pmc_values[(R)*((C) & 1)] | 450#define P4_PCPU_PMC_VALUE(PC,RI,CPU) (PC)->pc_pmc_values[(RI)*((CPU) & 1)] 451#define P4_PCPU_HW_VALUE(PC,RI,CPU) (PC)->pc_si.pc_hw[(RI)*((CPU) & 1)] 452#define P4_PCPU_SAVED_IP(PC,RI,CPU) (PC)->pc_si.pc_ip[(RI)*((CPU) & 1)] |
407 408#define P4_PCPU_GET_FLAGS(PC,RI,MASK) ((PC)->pc_flags[(RI)] & (MASK)) 409#define P4_PCPU_SET_FLAGS(PC,RI,MASK,VAL) do { \ 410 char _tmp; \ 411 _tmp = (PC)->pc_flags[(RI)]; \ 412 _tmp &= ~(MASK); \ 413 _tmp |= (VAL) & (MASK); \ 414 (PC)->pc_flags[(RI)] = _tmp; \ 415} while (0) 416 417#define P4_PCPU_GET_RUNCOUNT(PC,RI) P4_PCPU_GET_FLAGS(PC,RI,0x0F) 418#define P4_PCPU_SET_RUNCOUNT(PC,RI,V) P4_PCPU_SET_FLAGS(PC,RI,0x0F,V) 419 | 453 454#define P4_PCPU_GET_FLAGS(PC,RI,MASK) ((PC)->pc_flags[(RI)] & (MASK)) 455#define P4_PCPU_SET_FLAGS(PC,RI,MASK,VAL) do { \ 456 char _tmp; \ 457 _tmp = (PC)->pc_flags[(RI)]; \ 458 _tmp &= ~(MASK); \ 459 _tmp |= (VAL) & (MASK); \ 460 (PC)->pc_flags[(RI)] = _tmp; \ 461} while (0) 462 463#define P4_PCPU_GET_RUNCOUNT(PC,RI) P4_PCPU_GET_FLAGS(PC,RI,0x0F) 464#define P4_PCPU_SET_RUNCOUNT(PC,RI,V) P4_PCPU_SET_FLAGS(PC,RI,0x0F,V) 465 |
420#define P4_PCPU_GET_CFGCOUNT(PC,RI) (P4_PCPU_GET_FLAGS(PC,RI,0xF0) >> 4) 421#define P4_PCPU_SET_CFGCOUNT(PC,RI,C) P4_PCPU_SET_FLAGS(PC,RI,0xF0,((C) <<4)) | 466#define P4_PCPU_GET_CFGFLAGS(PC,RI) (P4_PCPU_GET_FLAGS(PC,RI,0xF0) >> 4) 467#define P4_PCPU_SET_CFGFLAGS(PC,RI,C) P4_PCPU_SET_FLAGS(PC,RI,0xF0,((C) <<4)) |
422 | 468 |
469#define P4_CPU_TO_FLAG(C) (pmc_cpu_is_logical(cpu) ? 0x2 : 0x1) 470 |
|
423/* ESCR row disposition */ 424static int p4_escrdisp[P4_NESCR]; 425 426#define P4_ESCR_ROW_DISP_IS_THREAD(E) (p4_escrdisp[(E)] > 0) 427#define P4_ESCR_ROW_DISP_IS_STANDALONE(E) (p4_escrdisp[(E)] < 0) 428#define P4_ESCR_ROW_DISP_IS_FREE(E) (p4_escrdisp[(E)] == 0) 429 430#define P4_ESCR_MARK_ROW_STANDALONE(E) do { \ --- 147 unchanged lines hidden (view full) --- 578 */ 579 580static int 581p4_switch_in(struct pmc_cpu *pc, struct pmc_process *pp) 582{ 583 (void) pc; 584 585 PMCDBG(MDP,SWI,1, "pc=%p pp=%p enable-msr=%d", pc, pp, | 471/* ESCR row disposition */ 472static int p4_escrdisp[P4_NESCR]; 473 474#define P4_ESCR_ROW_DISP_IS_THREAD(E) (p4_escrdisp[(E)] > 0) 475#define P4_ESCR_ROW_DISP_IS_STANDALONE(E) (p4_escrdisp[(E)] < 0) 476#define P4_ESCR_ROW_DISP_IS_FREE(E) (p4_escrdisp[(E)] == 0) 477 478#define P4_ESCR_MARK_ROW_STANDALONE(E) do { \ --- 147 unchanged lines hidden (view full) --- 626 */ 627 628static int 629p4_switch_in(struct pmc_cpu *pc, struct pmc_process *pp) 630{ 631 (void) pc; 632 633 PMCDBG(MDP,SWI,1, "pc=%p pp=%p enable-msr=%d", pc, pp, |
586 (pp->pp_flags & PMC_FLAG_ENABLE_MSR_ACCESS) != 0); | 634 (pp->pp_flags & PMC_PP_ENABLE_MSR_ACCESS) != 0); |
587 588 /* enable the RDPMC instruction */ | 635 636 /* enable the RDPMC instruction */ |
589 if (pp->pp_flags & PMC_FLAG_ENABLE_MSR_ACCESS) | 637 if (pp->pp_flags & PMC_PP_ENABLE_MSR_ACCESS) |
590 load_cr4(rcr4() | CR4_PCE); 591 592 PMCDBG(MDP,SWI,2, "cr4=0x%x", rcr4()); 593 594 return 0; 595} 596 597/* --- 39 unchanged lines hidden (view full) --- 637 phw = pc->pc_hwpmcs[ri]; 638 pd = &p4_pmcdesc[ri]; 639 pm = phw->phw_pmc; 640 641 KASSERT(pm != NULL, 642 ("[p4,%d] No owner for HWPMC [cpu%d,pmc%d]", __LINE__, 643 cpu, ri)); 644 | 638 load_cr4(rcr4() | CR4_PCE); 639 640 PMCDBG(MDP,SWI,2, "cr4=0x%x", rcr4()); 641 642 return 0; 643} 644 645/* --- 39 unchanged lines hidden (view full) --- 685 phw = pc->pc_hwpmcs[ri]; 686 pd = &p4_pmcdesc[ri]; 687 pm = phw->phw_pmc; 688 689 KASSERT(pm != NULL, 690 ("[p4,%d] No owner for HWPMC [cpu%d,pmc%d]", __LINE__, 691 cpu, ri)); 692 |
645 mode = pm->pm_mode; | 693 KASSERT(pd->pm_descr.pd_class == PMC_TO_CLASS(pm), 694 ("[p4,%d] class mismatch pd %d != id class %d", __LINE__, 695 pd->pm_descr.pd_class, PMC_TO_CLASS(pm))); |
646 | 696 |
697 mode = PMC_TO_MODE(pm); 698 |
|
647 PMCDBG(MDP,REA,1, "p4-read cpu=%d ri=%d mode=%d", cpu, ri, mode); 648 | 699 PMCDBG(MDP,REA,1, "p4-read cpu=%d ri=%d mode=%d", cpu, ri, mode); 700 |
649 if (pd->pm_descr.pd_class == PMC_CLASS_TSC) { | 701 if (PMC_TO_CLASS(pm) == PMC_CLASS_TSC) { |
650 KASSERT(PMC_IS_COUNTING_MODE(mode), 651 ("[p4,%d] TSC counter in non-counting mode", __LINE__)); 652 *v = rdtsc(); 653 PMCDBG(MDP,REA,2, "p4-read -> %jx", *v); 654 return 0; 655 } 656 657 KASSERT(pd->pm_descr.pd_class == PMC_CLASS_P4, 658 ("[p4,%d] unknown PMC class %d", __LINE__, pd->pm_descr.pd_class)); 659 | 702 KASSERT(PMC_IS_COUNTING_MODE(mode), 703 ("[p4,%d] TSC counter in non-counting mode", __LINE__)); 704 *v = rdtsc(); 705 PMCDBG(MDP,REA,2, "p4-read -> %jx", *v); 706 return 0; 707 } 708 709 KASSERT(pd->pm_descr.pd_class == PMC_CLASS_P4, 710 ("[p4,%d] unknown PMC class %d", __LINE__, pd->pm_descr.pd_class)); 711 |
660 if (PMC_IS_SYSTEM_MODE(pm->pm_mode)) 661 tmp = rdmsr(p4_pmcdesc[ri].pm_pmc_msr); 662 else 663 tmp = P4_PCPU_PMC_VALUE(pc,ri,cpu); | 712 tmp = rdmsr(p4_pmcdesc[ri].pm_pmc_msr); |
664 | 713 |
665 if (PMC_IS_SAMPLING_MODE(mode)) 666 *v = -(tmp + 1); /* undo transformation */ | 714 if (PMC_IS_VIRTUAL_MODE(mode)) { 715 if (tmp < P4_PCPU_HW_VALUE(pc,ri,cpu)) /* 40 bit overflow */ 716 tmp += (P4_PERFCTR_MASK + 1) - 717 P4_PCPU_HW_VALUE(pc,ri,cpu); 718 else 719 tmp -= P4_PCPU_HW_VALUE(pc,ri,cpu); 720 tmp += P4_PCPU_PMC_VALUE(pc,ri,cpu); 721 } 722 723 if (PMC_IS_SAMPLING_MODE(mode)) /* undo transformation */ 724 *v = P4_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp); |
667 else 668 *v = tmp; 669 670 PMCDBG(MDP,REA,2, "p4-read -> %jx", *v); 671 return 0; 672} 673 674/* 675 * Write a PMC 676 */ 677 678static int 679p4_write_pmc(int cpu, int ri, pmc_value_t v) 680{ | 725 else 726 *v = tmp; 727 728 PMCDBG(MDP,REA,2, "p4-read -> %jx", *v); 729 return 0; 730} 731 732/* 733 * Write a PMC 734 */ 735 736static int 737p4_write_pmc(int cpu, int ri, pmc_value_t v) 738{ |
739 enum pmc_mode mode; |
|
681 struct pmc *pm; 682 struct p4_cpu *pc; 683 const struct pmc_hw *phw; 684 const struct p4pmc_descr *pd; 685 686 KASSERT(cpu >= 0 && cpu < mp_ncpus, 687 ("[amd,%d] illegal CPU value %d", __LINE__, cpu)); 688 KASSERT(ri >= 0 && ri < P4_NPMCS, 689 ("[amd,%d] illegal row-index %d", __LINE__, ri)); 690 691 pc = (struct p4_cpu *) pmc_pcpu[P4_TO_PHYSICAL_CPU(cpu)]; 692 phw = pc->pc_hwpmcs[ri]; 693 pm = phw->phw_pmc; 694 pd = &p4_pmcdesc[ri]; 695 696 KASSERT(pm != NULL, 697 ("[p4,%d] No owner for HWPMC [cpu%d,pmc%d]", __LINE__, 698 cpu, ri)); 699 | 740 struct pmc *pm; 741 struct p4_cpu *pc; 742 const struct pmc_hw *phw; 743 const struct p4pmc_descr *pd; 744 745 KASSERT(cpu >= 0 && cpu < mp_ncpus, 746 ("[amd,%d] illegal CPU value %d", __LINE__, cpu)); 747 KASSERT(ri >= 0 && ri < P4_NPMCS, 748 ("[amd,%d] illegal row-index %d", __LINE__, ri)); 749 750 pc = (struct p4_cpu *) pmc_pcpu[P4_TO_PHYSICAL_CPU(cpu)]; 751 phw = pc->pc_hwpmcs[ri]; 752 pm = phw->phw_pmc; 753 pd = &p4_pmcdesc[ri]; 754 755 KASSERT(pm != NULL, 756 ("[p4,%d] No owner for HWPMC [cpu%d,pmc%d]", __LINE__, 757 cpu, ri)); 758 |
759 mode = PMC_TO_MODE(pm); 760 |
|
700 PMCDBG(MDP,WRI,1, "p4-write cpu=%d ri=%d mode=%d v=%jx", cpu, ri, | 761 PMCDBG(MDP,WRI,1, "p4-write cpu=%d ri=%d mode=%d v=%jx", cpu, ri, |
701 pm->pm_mode, v); | 762 mode, v); |
702 703 /* 704 * The P4's TSC register is writeable, but we don't allow a 705 * write as changing the TSC's value could interfere with | 763 764 /* 765 * The P4's TSC register is writeable, but we don't allow a 766 * write as changing the TSC's value could interfere with |
706 * other parts of the system. | 767 * timekeeping and other system functions. |
707 */ | 768 */ |
708 if (pd->pm_descr.pd_class == PMC_CLASS_TSC) | 769 if (PMC_TO_CLASS(pm) == PMC_CLASS_TSC) |
709 return 0; 710 711 /* 712 * write the PMC value to the register/saved value: for 713 * sampling mode PMCs, the value to be programmed into the PMC 714 * counter is -(C+1) where 'C' is the requested sample rate. 715 */ | 770 return 0; 771 772 /* 773 * write the PMC value to the register/saved value: for 774 * sampling mode PMCs, the value to be programmed into the PMC 775 * counter is -(C+1) where 'C' is the requested sample rate. 776 */ |
716 if (PMC_IS_SAMPLING_MODE(pm->pm_mode)) 717 v = -(v + 1); | 777 if (PMC_IS_SAMPLING_MODE(mode)) 778 v = P4_RELOAD_COUNT_TO_PERFCTR_VALUE(v); |
718 | 779 |
719 if (PMC_IS_SYSTEM_MODE(pm->pm_mode)) | 780 if (PMC_IS_SYSTEM_MODE(mode)) |
720 wrmsr(pd->pm_pmc_msr, v); 721 else 722 P4_PCPU_PMC_VALUE(pc,ri,cpu) = v; 723 724 return 0; 725} 726 727/* 728 * Configure a PMC 'pm' on the given CPU and row-index. 729 * 730 * 'pm' may be NULL to indicate de-configuration. 731 * 732 * On HTT systems, a PMC may get configured twice, once for each | 781 wrmsr(pd->pm_pmc_msr, v); 782 else 783 P4_PCPU_PMC_VALUE(pc,ri,cpu) = v; 784 785 return 0; 786} 787 788/* 789 * Configure a PMC 'pm' on the given CPU and row-index. 790 * 791 * 'pm' may be NULL to indicate de-configuration. 792 * 793 * On HTT systems, a PMC may get configured twice, once for each |
733 * "logical" CPU. | 794 * "logical" CPU. We track this using the CFGFLAGS field of the 795 * per-cpu state; this field is a bit mask with one bit each for 796 * logical CPUs 0 & 1. |
734 */ 735 736static int 737p4_config_pmc(int cpu, int ri, struct pmc *pm) 738{ 739 struct pmc_hw *phw; 740 struct p4_cpu *pc; | 797 */ 798 799static int 800p4_config_pmc(int cpu, int ri, struct pmc *pm) 801{ 802 struct pmc_hw *phw; 803 struct p4_cpu *pc; |
741 int cfgcount; | 804 int cfgflags, cpuflag; |
742 743 KASSERT(cpu >= 0 && cpu < mp_ncpus, 744 ("[p4,%d] illegal CPU %d", __LINE__, cpu)); 745 KASSERT(ri >= 0 && ri < P4_NPMCS, 746 ("[p4,%d] illegal row-index %d", __LINE__, ri)); 747 748 pc = (struct p4_cpu *) pmc_pcpu[P4_TO_PHYSICAL_CPU(cpu)]; 749 phw = pc->pc_hwpmcs[ri]; 750 751 KASSERT(pm == NULL || phw->phw_pmc == NULL || 752 (p4_system_has_htt && phw->phw_pmc == pm), 753 ("[p4,%d] hwpmc not unconfigured before re-config", __LINE__)); 754 755 mtx_lock_spin(&pc->pc_mtx); | 805 806 KASSERT(cpu >= 0 && cpu < mp_ncpus, 807 ("[p4,%d] illegal CPU %d", __LINE__, cpu)); 808 KASSERT(ri >= 0 && ri < P4_NPMCS, 809 ("[p4,%d] illegal row-index %d", __LINE__, ri)); 810 811 pc = (struct p4_cpu *) pmc_pcpu[P4_TO_PHYSICAL_CPU(cpu)]; 812 phw = pc->pc_hwpmcs[ri]; 813 814 KASSERT(pm == NULL || phw->phw_pmc == NULL || 815 (p4_system_has_htt && phw->phw_pmc == pm), 816 ("[p4,%d] hwpmc not unconfigured before re-config", __LINE__)); 817 818 mtx_lock_spin(&pc->pc_mtx); |
756 cfgcount = P4_PCPU_GET_CFGCOUNT(pc,ri); | 819 cfgflags = P4_PCPU_GET_CFGFLAGS(pc,ri); |
757 | 820 |
758 KASSERT(cfgcount >= 0 || cfgcount <= 2, 759 ("[p4,%d] illegal cfgcount cfg=%d on cpu=%d ri=%d", __LINE__, 760 cfgcount, cpu, ri)); | 821 KASSERT(cfgflags >= 0 || cfgflags <= 3, 822 ("[p4,%d] illegal cfgflags cfg=%d on cpu=%d ri=%d", __LINE__, 823 cfgflags, cpu, ri)); |
761 | 824 |
762 KASSERT(cfgcount == 0 || phw->phw_pmc, | 825 KASSERT(cfgflags == 0 || phw->phw_pmc, |
763 ("[p4,%d] cpu=%d ri=%d pmc configured with zero cfg count", 764 __LINE__, cpu, ri)); 765 | 826 ("[p4,%d] cpu=%d ri=%d pmc configured with zero cfg count", 827 __LINE__, cpu, ri)); 828 |
766 PMCDBG(MDP,CFG,1, "cpu=%d ri=%d cfg=%d pm=%p", cpu, ri, cfgcount, | 829 PMCDBG(MDP,CFG,1, "cpu=%d ri=%d cfg=%d pm=%p", cpu, ri, cfgflags, |
767 pm); 768 | 830 pm); 831 |
832 cpuflag = P4_CPU_TO_FLAG(cpu); 833 |
|
769 if (pm) { /* config */ | 834 if (pm) { /* config */ |
770 if (cfgcount == 0) | 835 if (cfgflags == 0) |
771 phw->phw_pmc = pm; 772 773 KASSERT(phw->phw_pmc == pm, 774 ("[p4,%d] cpu=%d ri=%d config %p != hw %p", 775 __LINE__, cpu, ri, pm, phw->phw_pmc)); 776 | 836 phw->phw_pmc = pm; 837 838 KASSERT(phw->phw_pmc == pm, 839 ("[p4,%d] cpu=%d ri=%d config %p != hw %p", 840 __LINE__, cpu, ri, pm, phw->phw_pmc)); 841 |
777 cfgcount++; | 842 cfgflags |= cpuflag; |
778 } else { /* unconfig */ | 843 } else { /* unconfig */ |
779 --cfgcount; 780 if (cfgcount == 0) | 844 cfgflags &= ~cpuflag; 845 846 if (cfgflags == 0) |
781 phw->phw_pmc = NULL; 782 } 783 | 847 phw->phw_pmc = NULL; 848 } 849 |
784 KASSERT(cfgcount >= 0 || cfgcount <= 2, | 850 KASSERT(cfgflags >= 0 || cfgflags <= 3, |
785 ("[p4,%d] illegal runcount cfg=%d on cpu=%d ri=%d", __LINE__, | 851 ("[p4,%d] illegal runcount cfg=%d on cpu=%d ri=%d", __LINE__, |
786 cfgcount, cpu, ri)); | 852 cfgflags, cpu, ri)); |
787 | 853 |
788 P4_PCPU_SET_CFGCOUNT(pc,ri,cfgcount); | 854 P4_PCPU_SET_CFGFLAGS(pc,ri,cfgflags); |
789 790 mtx_unlock_spin(&pc->pc_mtx); 791 792 return 0; 793} 794 795/* | 855 856 mtx_unlock_spin(&pc->pc_mtx); 857 858 return 0; 859} 860 861/* |
862 * Retrieve a configured PMC pointer from hardware state. 863 */ 864 865static int 866p4_get_config(int cpu, int ri, struct pmc **ppm) 867{ 868 struct p4_cpu *pc; 869 struct pmc_hw *phw; 870 int cfgflags; 871 872 pc = (struct p4_cpu *) pmc_pcpu[P4_TO_PHYSICAL_CPU(cpu)]; 873 phw = pc->pc_hwpmcs[ri]; 874 875 mtx_lock_spin(&pc->pc_mtx); 876 cfgflags = P4_PCPU_GET_CFGFLAGS(pc,ri); 877 mtx_unlock_spin(&pc->pc_mtx); 878 879 if (cfgflags & P4_CPU_TO_FLAG(cpu)) 880 *ppm = phw->phw_pmc; /* PMC config'ed on this CPU */ 881 else 882 *ppm = NULL; 883 884 return 0; 885} 886 887/* |
|
796 * Allocate a PMC. 797 * 798 * The allocation strategy differs between HTT and non-HTT systems. 799 * 800 * The non-HTT case: 801 * - Given the desired event and the PMC row-index, lookup the 802 * list of valid ESCRs for the event. 803 * - For each valid ESCR: --- 36 unchanged lines hidden (view full) --- 840 KASSERT(cpu >= 0 && cpu < mp_ncpus, 841 ("[p4,%d] illegal CPU %d", __LINE__, cpu)); 842 KASSERT(ri >= 0 && ri < P4_NPMCS, 843 ("[p4,%d] illegal row-index value %d", __LINE__, ri)); 844 845 pd = &p4_pmcdesc[ri]; 846 847 PMCDBG(MDP,ALL,1, "p4-allocate ri=%d class=%d pmccaps=0x%x " | 888 * Allocate a PMC. 889 * 890 * The allocation strategy differs between HTT and non-HTT systems. 891 * 892 * The non-HTT case: 893 * - Given the desired event and the PMC row-index, lookup the 894 * list of valid ESCRs for the event. 895 * - For each valid ESCR: --- 36 unchanged lines hidden (view full) --- 932 KASSERT(cpu >= 0 && cpu < mp_ncpus, 933 ("[p4,%d] illegal CPU %d", __LINE__, cpu)); 934 KASSERT(ri >= 0 && ri < P4_NPMCS, 935 ("[p4,%d] illegal row-index value %d", __LINE__, ri)); 936 937 pd = &p4_pmcdesc[ri]; 938 939 PMCDBG(MDP,ALL,1, "p4-allocate ri=%d class=%d pmccaps=0x%x " |
848 "reqcaps=0x%x\n", ri, pd->pm_descr.pd_class, pd->pm_descr.pd_caps, | 940 "reqcaps=0x%x", ri, pd->pm_descr.pd_class, pd->pm_descr.pd_caps, |
849 pm->pm_caps); 850 851 /* check class */ | 941 pm->pm_caps); 942 943 /* check class */ |
852 if (pd->pm_descr.pd_class != pm->pm_class) | 944 if (pd->pm_descr.pd_class != a->pm_class) |
853 return EINVAL; 854 855 /* check requested capabilities */ 856 caps = a->pm_caps; 857 if ((pd->pm_descr.pd_caps & caps) != caps) 858 return EPERM; 859 860 if (pd->pm_descr.pd_class == PMC_CLASS_TSC) { --- 6 unchanged lines hidden (view full) --- 867 868 /* 869 * If the system has HTT enabled, and the desired allocation 870 * mode is process-private, and the PMC row disposition is not 871 * FREE (0), decline the allocation. 872 */ 873 874 if (p4_system_has_htt && | 945 return EINVAL; 946 947 /* check requested capabilities */ 948 caps = a->pm_caps; 949 if ((pd->pm_descr.pd_caps & caps) != caps) 950 return EPERM; 951 952 if (pd->pm_descr.pd_class == PMC_CLASS_TSC) { --- 6 unchanged lines hidden (view full) --- 959 960 /* 961 * If the system has HTT enabled, and the desired allocation 962 * mode is process-private, and the PMC row disposition is not 963 * FREE (0), decline the allocation. 964 */ 965 966 if (p4_system_has_htt && |
875 PMC_IS_VIRTUAL_MODE(pm->pm_mode) && | 967 PMC_IS_VIRTUAL_MODE(PMC_TO_MODE(pm)) && |
876 pmc_getrowdisp(ri) != 0) 877 return EBUSY; 878 879 KASSERT(pd->pm_descr.pd_class == PMC_CLASS_P4, 880 ("[p4,%d] unknown PMC class %d", __LINE__, 881 pd->pm_descr.pd_class)); 882 883 if (pm->pm_event < PMC_EV_P4_FIRST || --- 9 unchanged lines hidden (view full) --- 893 894 /* 895 * Some PMC events are 'thread independent'and therefore 896 * cannot be used for process-private modes if HTT is being 897 * used. 898 */ 899 900 if (P4_EVENT_IS_TI(pevent) && | 968 pmc_getrowdisp(ri) != 0) 969 return EBUSY; 970 971 KASSERT(pd->pm_descr.pd_class == PMC_CLASS_P4, 972 ("[p4,%d] unknown PMC class %d", __LINE__, 973 pd->pm_descr.pd_class)); 974 975 if (pm->pm_event < PMC_EV_P4_FIRST || --- 9 unchanged lines hidden (view full) --- 985 986 /* 987 * Some PMC events are 'thread independent'and therefore 988 * cannot be used for process-private modes if HTT is being 989 * used. 990 */ 991 992 if (P4_EVENT_IS_TI(pevent) && |
901 PMC_IS_VIRTUAL_MODE(pm->pm_mode) && p4_system_has_htt) | 993 PMC_IS_VIRTUAL_MODE(PMC_TO_MODE(pm)) && 994 p4_system_has_htt) |
902 return EINVAL; 903 904 pc = (struct p4_cpu *) pmc_pcpu[P4_TO_PHYSICAL_CPU(cpu)]; 905 906 found = 0; 907 908 /* look for a suitable ESCR for this event */ 909 for (n = 0; n < P4_MAX_ESCR_PER_EVENT && !found; n++) { 910 if ((escr = pevent->pm_escrs[n]) == P4_ESCR_NONE) 911 break; /* out of ESCRs */ 912 /* 913 * Check ESCR row disposition. 914 * 915 * If the request is for a system-mode PMC, then the 916 * ESCR row should not be in process-virtual mode, and 917 * should also be free on the current CPU. 918 */ 919 | 995 return EINVAL; 996 997 pc = (struct p4_cpu *) pmc_pcpu[P4_TO_PHYSICAL_CPU(cpu)]; 998 999 found = 0; 1000 1001 /* look for a suitable ESCR for this event */ 1002 for (n = 0; n < P4_MAX_ESCR_PER_EVENT && !found; n++) { 1003 if ((escr = pevent->pm_escrs[n]) == P4_ESCR_NONE) 1004 break; /* out of ESCRs */ 1005 /* 1006 * Check ESCR row disposition. 1007 * 1008 * If the request is for a system-mode PMC, then the 1009 * ESCR row should not be in process-virtual mode, and 1010 * should also be free on the current CPU. 1011 */ 1012 |
920 if (PMC_IS_SYSTEM_MODE(pm->pm_mode)) { | 1013 if (PMC_IS_SYSTEM_MODE(PMC_TO_MODE(pm))) { |
921 if (P4_ESCR_ROW_DISP_IS_THREAD(escr) || 922 pc->pc_escrs[escr] != P4_INVALID_PMC_INDEX) 923 continue; 924 } 925 926 /* 927 * If the request is for a process-virtual PMC, and if 928 * HTT is not enabled, we can use an ESCR row that is 929 * either FREE or already in process mode. 930 * 931 * If HTT is enabled, then we need to ensure that a 932 * given ESCR is never allocated to two PMCS that 933 * could run simultaneously on the two logical CPUs of 934 * a CPU package. We ensure this be only allocating 935 * ESCRs from rows marked as 'FREE'. 936 */ 937 | 1014 if (P4_ESCR_ROW_DISP_IS_THREAD(escr) || 1015 pc->pc_escrs[escr] != P4_INVALID_PMC_INDEX) 1016 continue; 1017 } 1018 1019 /* 1020 * If the request is for a process-virtual PMC, and if 1021 * HTT is not enabled, we can use an ESCR row that is 1022 * either FREE or already in process mode. 1023 * 1024 * If HTT is enabled, then we need to ensure that a 1025 * given ESCR is never allocated to two PMCS that 1026 * could run simultaneously on the two logical CPUs of 1027 * a CPU package. We ensure this be only allocating 1028 * ESCRs from rows marked as 'FREE'. 1029 */ 1030 |
938 if (PMC_IS_VIRTUAL_MODE(pm->pm_mode)) { | 1031 if (PMC_IS_VIRTUAL_MODE(PMC_TO_MODE(pm))) { |
939 if (p4_system_has_htt) { 940 if (!P4_ESCR_ROW_DISP_IS_FREE(escr)) 941 continue; 942 } else 943 if (P4_ESCR_ROW_DISP_IS_STANDALONE(escr)) 944 continue; 945 } 946 --- 11 unchanged lines hidden (view full) --- 958 959 if (found == 0) 960 return ESRCH; 961 962 KASSERT((int) escr >= 0 && escr < P4_NESCR, 963 ("[p4,%d] illegal ESCR value %d", __LINE__, escr)); 964 965 /* mark ESCR row mode */ | 1032 if (p4_system_has_htt) { 1033 if (!P4_ESCR_ROW_DISP_IS_FREE(escr)) 1034 continue; 1035 } else 1036 if (P4_ESCR_ROW_DISP_IS_STANDALONE(escr)) 1037 continue; 1038 } 1039 --- 11 unchanged lines hidden (view full) --- 1051 1052 if (found == 0) 1053 return ESRCH; 1054 1055 KASSERT((int) escr >= 0 && escr < P4_NESCR, 1056 ("[p4,%d] illegal ESCR value %d", __LINE__, escr)); 1057 1058 /* mark ESCR row mode */ |
966 if (PMC_IS_SYSTEM_MODE(pm->pm_mode)) { | 1059 if (PMC_IS_SYSTEM_MODE(PMC_TO_MODE(pm))) { |
967 pc->pc_escrs[escr] = ri; /* mark ESCR as in use on this cpu */ 968 P4_ESCR_MARK_ROW_STANDALONE(escr); 969 } else { 970 KASSERT(pc->pc_escrs[escr] == P4_INVALID_PMC_INDEX, 971 ("[p4,%d] escr[%d] already in use", __LINE__, escr)); 972 P4_ESCR_MARK_ROW_THREAD(escr); 973 } 974 --- 44 unchanged lines hidden (view full) --- 1019 if (tflags == 0) 1020 tflags = (P4_ESCR_T0_OS|P4_ESCR_T0_USR); 1021 escrvalue |= tflags; 1022 1023 pm->pm_md.pm_p4.pm_p4_cccrvalue = cccrvalue; 1024 pm->pm_md.pm_p4.pm_p4_escrvalue = escrvalue; 1025 1026 PMCDBG(MDP,ALL,2, "p4-allocate cccrsel=0x%x cccrval=0x%x " | 1060 pc->pc_escrs[escr] = ri; /* mark ESCR as in use on this cpu */ 1061 P4_ESCR_MARK_ROW_STANDALONE(escr); 1062 } else { 1063 KASSERT(pc->pc_escrs[escr] == P4_INVALID_PMC_INDEX, 1064 ("[p4,%d] escr[%d] already in use", __LINE__, escr)); 1065 P4_ESCR_MARK_ROW_THREAD(escr); 1066 } 1067 --- 44 unchanged lines hidden (view full) --- 1112 if (tflags == 0) 1113 tflags = (P4_ESCR_T0_OS|P4_ESCR_T0_USR); 1114 escrvalue |= tflags; 1115 1116 pm->pm_md.pm_p4.pm_p4_cccrvalue = cccrvalue; 1117 pm->pm_md.pm_p4.pm_p4_escrvalue = escrvalue; 1118 1119 PMCDBG(MDP,ALL,2, "p4-allocate cccrsel=0x%x cccrval=0x%x " |
1027 "escr=%d escrmsr=0x%x escrval=0x%x\n", pevent->pm_cccr_select, | 1120 "escr=%d escrmsr=0x%x escrval=0x%x", pevent->pm_cccr_select, |
1028 cccrvalue, escr, pm->pm_md.pm_p4.pm_p4_escrmsr, escrvalue); 1029 1030 return 0; 1031} 1032 1033/* 1034 * release a PMC. 1035 */ --- 7 unchanged lines hidden (view full) --- 1043 1044 if (p4_pmcdesc[ri].pm_descr.pd_class == PMC_CLASS_TSC) 1045 return 0; 1046 1047 escr = pm->pm_md.pm_p4.pm_p4_escr; 1048 1049 PMCDBG(MDP,REL,1, "p4-release cpu=%d ri=%d escr=%d", cpu, ri, escr); 1050 | 1121 cccrvalue, escr, pm->pm_md.pm_p4.pm_p4_escrmsr, escrvalue); 1122 1123 return 0; 1124} 1125 1126/* 1127 * release a PMC. 1128 */ --- 7 unchanged lines hidden (view full) --- 1136 1137 if (p4_pmcdesc[ri].pm_descr.pd_class == PMC_CLASS_TSC) 1138 return 0; 1139 1140 escr = pm->pm_md.pm_p4.pm_p4_escr; 1141 1142 PMCDBG(MDP,REL,1, "p4-release cpu=%d ri=%d escr=%d", cpu, ri, escr); 1143 |
1051 if (PMC_IS_SYSTEM_MODE(pm->pm_mode)) { | 1144 if (PMC_IS_SYSTEM_MODE(PMC_TO_MODE(pm))) { |
1052 pc = (struct p4_cpu *) pmc_pcpu[P4_TO_PHYSICAL_CPU(cpu)]; 1053 phw = pc->pc_hwpmcs[ri]; 1054 1055 KASSERT(phw->phw_pmc == NULL, 1056 ("[p4,%d] releasing configured PMC ri=%d", __LINE__, ri)); 1057 1058 P4_ESCR_UNMARK_ROW_STANDALONE(escr); 1059 KASSERT(pc->pc_escrs[escr] == ri, --- 55 unchanged lines hidden (view full) --- 1115 escrvalue &= ~(P4_ESCR_T0_OS|P4_ESCR_T0_USR); 1116 1117 if (pmc_cpu_is_logical(cpu)) { /* shift T0 bits to T1 position */ 1118 cccrtbits <<= 1; 1119 escrtbits >>= 2; 1120 } 1121 1122 /* start system mode PMCs directly */ | 1145 pc = (struct p4_cpu *) pmc_pcpu[P4_TO_PHYSICAL_CPU(cpu)]; 1146 phw = pc->pc_hwpmcs[ri]; 1147 1148 KASSERT(phw->phw_pmc == NULL, 1149 ("[p4,%d] releasing configured PMC ri=%d", __LINE__, ri)); 1150 1151 P4_ESCR_UNMARK_ROW_STANDALONE(escr); 1152 KASSERT(pc->pc_escrs[escr] == ri, --- 55 unchanged lines hidden (view full) --- 1208 escrvalue &= ~(P4_ESCR_T0_OS|P4_ESCR_T0_USR); 1209 1210 if (pmc_cpu_is_logical(cpu)) { /* shift T0 bits to T1 position */ 1211 cccrtbits <<= 1; 1212 escrtbits >>= 2; 1213 } 1214 1215 /* start system mode PMCs directly */ |
1123 if (PMC_IS_SYSTEM_MODE(pm->pm_mode)) { | 1216 if (PMC_IS_SYSTEM_MODE(PMC_TO_MODE(pm))) { |
1124 wrmsr(escrmsr, escrvalue | escrtbits); 1125 wrmsr(pd->pm_cccr_msr, cccrvalue | cccrtbits | P4_CCCR_ENABLE); 1126 return 0; 1127 } 1128 1129 /* 1130 * Thread mode PMCs 1131 * --- 7 unchanged lines hidden (view full) --- 1139 mtx_lock_spin(&pc->pc_mtx); 1140 1141 rc = P4_PCPU_GET_RUNCOUNT(pc,ri); 1142 KASSERT(rc == 0 || rc == 1, 1143 ("[p4,%d] illegal runcount cpu=%d ri=%d rc=%d", __LINE__, cpu, ri, 1144 rc)); 1145 1146 if (rc == 0) { /* 1st CPU and the non-HTT case */ | 1217 wrmsr(escrmsr, escrvalue | escrtbits); 1218 wrmsr(pd->pm_cccr_msr, cccrvalue | cccrtbits | P4_CCCR_ENABLE); 1219 return 0; 1220 } 1221 1222 /* 1223 * Thread mode PMCs 1224 * --- 7 unchanged lines hidden (view full) --- 1232 mtx_lock_spin(&pc->pc_mtx); 1233 1234 rc = P4_PCPU_GET_RUNCOUNT(pc,ri); 1235 KASSERT(rc == 0 || rc == 1, 1236 ("[p4,%d] illegal runcount cpu=%d ri=%d rc=%d", __LINE__, cpu, ri, 1237 rc)); 1238 1239 if (rc == 0) { /* 1st CPU and the non-HTT case */ |
1147 /* 1148 * Enable the correct bits for this CPU. 1149 */ 1150 escrvalue |= escrtbits; 1151 cccrvalue |= cccrtbits | P4_CCCR_ENABLE; | |
1152 1153 KASSERT(P4_PMC_IS_STOPPED(pd->pm_cccr_msr), 1154 ("[p4,%d] cpu=%d ri=%d cccr=0x%x not stopped", __LINE__, 1155 cpu, ri, pd->pm_cccr_msr)); 1156 1157 /* write out the low 40 bits of the saved value to hardware */ 1158 wrmsr(pd->pm_pmc_msr, 1159 P4_PCPU_PMC_VALUE(pc,ri,cpu) & P4_PERFCTR_MASK); | 1240 1241 KASSERT(P4_PMC_IS_STOPPED(pd->pm_cccr_msr), 1242 ("[p4,%d] cpu=%d ri=%d cccr=0x%x not stopped", __LINE__, 1243 cpu, ri, pd->pm_cccr_msr)); 1244 1245 /* write out the low 40 bits of the saved value to hardware */ 1246 wrmsr(pd->pm_pmc_msr, 1247 P4_PCPU_PMC_VALUE(pc,ri,cpu) & P4_PERFCTR_MASK); |
1160 P4_PCPU_SAVED_VALUE(pc,ri,cpu) = P4_PCPU_PMC_VALUE(pc,ri,cpu) & 1161 P4_PERFCTR_MASK; | |
1162 | 1248 |
1163 /* Program the ESCR and CCCR and start the PMC */ 1164 wrmsr(escrmsr, escrvalue); 1165 wrmsr(pd->pm_cccr_msr, cccrvalue); 1166 1167 PMCDBG(MDP,STA,2,"p4-start cpu=%d rc=%d ri=%d escr=%d " 1168 "escrmsr=0x%x escrvalue=0x%x cccr_config=0x%x\n", cpu, rc, 1169 ri, pm->pm_md.pm_p4.pm_p4_escr, escrmsr, escrvalue, 1170 cccrvalue); 1171 | |
1172 } else if (rc == 1) { /* 2nd CPU */ 1173 1174 /* | 1249 } else if (rc == 1) { /* 2nd CPU */ 1250 1251 /* |
1175 * Retrieve the CCCR and ESCR values from their MSRs, 1176 * and turn on the addition T[0/1] bits for the 2nd 1177 * CPU. Remember the difference between the saved 1178 * value from the previous 'write()' operation to this 1179 * (PMC,CPU) pair and the current PMC reading; this is 1180 * used at PMCSTOP time to derive the correct 1181 * increment. | 1252 * Stop the PMC and retrieve the CCCR and ESCR values 1253 * from their MSRs, and turn on the additional T[0/1] 1254 * bits for the 2nd CPU. |
1182 */ 1183 1184 cccrvalue = rdmsr(pd->pm_cccr_msr); | 1255 */ 1256 1257 cccrvalue = rdmsr(pd->pm_cccr_msr); |
1258 wrmsr(pd->pm_cccr_msr, cccrvalue & ~P4_CCCR_ENABLE); |
|
1185 | 1259 |
1260 /* check that the configuration bits read back match the PMC */ |
|
1186 KASSERT((cccrvalue & P4_CCCR_Tx_MASK) == 1187 (pm->pm_md.pm_p4.pm_p4_cccrvalue & P4_CCCR_Tx_MASK), | 1261 KASSERT((cccrvalue & P4_CCCR_Tx_MASK) == 1262 (pm->pm_md.pm_p4.pm_p4_cccrvalue & P4_CCCR_Tx_MASK), |
1188 ("[p4,%d] cpu=%d rc=%d ri=%d CCCR bits 0x%x PMC 0x%x", 1189 __LINE__, cpu, rc, ri, cccrvalue & P4_CCCR_Tx_MASK, | 1263 ("[p4,%d] Extra CCCR bits cpu=%d rc=%d ri=%d " 1264 "cccr=0x%x PMC=0x%x", __LINE__, cpu, rc, ri, 1265 cccrvalue & P4_CCCR_Tx_MASK, |
1190 pm->pm_md.pm_p4.pm_p4_cccrvalue & P4_CCCR_Tx_MASK)); 1191 KASSERT(cccrvalue & P4_CCCR_ENABLE, 1192 ("[p4,%d] 2nd cpu rc=%d cpu=%d ri=%d not running", 1193 __LINE__, rc, cpu, ri)); 1194 KASSERT((cccrvalue & cccrtbits) == 0, 1195 ("[p4,%d] CCCR T0/T1 mismatch rc=%d cpu=%d ri=%d" 1196 "cccrvalue=0x%x tbits=0x%x", __LINE__, rc, cpu, ri, 1197 cccrvalue, cccrtbits)); 1198 | 1266 pm->pm_md.pm_p4.pm_p4_cccrvalue & P4_CCCR_Tx_MASK)); 1267 KASSERT(cccrvalue & P4_CCCR_ENABLE, 1268 ("[p4,%d] 2nd cpu rc=%d cpu=%d ri=%d not running", 1269 __LINE__, rc, cpu, ri)); 1270 KASSERT((cccrvalue & cccrtbits) == 0, 1271 ("[p4,%d] CCCR T0/T1 mismatch rc=%d cpu=%d ri=%d" 1272 "cccrvalue=0x%x tbits=0x%x", __LINE__, rc, cpu, ri, 1273 cccrvalue, cccrtbits)); 1274 |
1199 /* stop PMC */ 1200 wrmsr(pd->pm_cccr_msr, cccrvalue & ~P4_CCCR_ENABLE); 1201 | |
1202 escrvalue = rdmsr(escrmsr); 1203 1204 KASSERT((escrvalue & P4_ESCR_Tx_MASK) == 1205 (pm->pm_md.pm_p4.pm_p4_escrvalue & P4_ESCR_Tx_MASK), 1206 ("[p4,%d] Extra ESCR bits cpu=%d rc=%d ri=%d " 1207 "escr=0x%x pm=0x%x", __LINE__, cpu, rc, ri, 1208 escrvalue & P4_ESCR_Tx_MASK, 1209 pm->pm_md.pm_p4.pm_p4_escrvalue & P4_ESCR_Tx_MASK)); | 1275 escrvalue = rdmsr(escrmsr); 1276 1277 KASSERT((escrvalue & P4_ESCR_Tx_MASK) == 1278 (pm->pm_md.pm_p4.pm_p4_escrvalue & P4_ESCR_Tx_MASK), 1279 ("[p4,%d] Extra ESCR bits cpu=%d rc=%d ri=%d " 1280 "escr=0x%x pm=0x%x", __LINE__, cpu, rc, ri, 1281 escrvalue & P4_ESCR_Tx_MASK, 1282 pm->pm_md.pm_p4.pm_p4_escrvalue & P4_ESCR_Tx_MASK)); |
1210 | |
1211 KASSERT((escrvalue & escrtbits) == 0, 1212 ("[p4,%d] ESCR T0/T1 mismatch rc=%d cpu=%d ri=%d " 1213 "escrmsr=0x%x escrvalue=0x%x tbits=0x%x", __LINE__, 1214 rc, cpu, ri, escrmsr, escrvalue, escrtbits)); | 1283 KASSERT((escrvalue & escrtbits) == 0, 1284 ("[p4,%d] ESCR T0/T1 mismatch rc=%d cpu=%d ri=%d " 1285 "escrmsr=0x%x escrvalue=0x%x tbits=0x%x", __LINE__, 1286 rc, cpu, ri, escrmsr, escrvalue, escrtbits)); |
1287 } |
|
1215 | 1288 |
1216 /* read current value and save it */ 1217 P4_PCPU_SAVED_VALUE(pc,ri,cpu) = 1218 rdmsr(pd->pm_pmc_msr) & P4_PERFCTR_MASK; | 1289 /* Enable the correct bits for this CPU. */ 1290 escrvalue |= escrtbits; 1291 cccrvalue |= cccrtbits | P4_CCCR_ENABLE; |
1219 | 1292 |
1220 /* 1221 * program the new bits into the ESCR and CCCR, 1222 * starting the PMC in the process. 1223 */ | 1293 /* Save HW value at the time of starting hardware */ 1294 P4_PCPU_HW_VALUE(pc,ri,cpu) = rdmsr(pd->pm_pmc_msr); |
1224 | 1295 |
1225 escrvalue |= escrtbits; 1226 cccrvalue |= cccrvalue; | 1296 /* Program the ESCR and CCCR and start the PMC */ 1297 wrmsr(escrmsr, escrvalue); 1298 wrmsr(pd->pm_cccr_msr, cccrvalue); |
1227 | 1299 |
1228 wrmsr(escrmsr, escrvalue); 1229 wrmsr(pd->pm_cccr_msr, cccrvalue); 1230 1231 PMCDBG(MDP,STA,2,"p4-start/2 cpu=%d rc=%d ri=%d escr=%d" 1232 "escrmsr=0x%x escrvalue=0x%x cccr_config=0x%x", 1233 cpu, rc, ri, pm->pm_md.pm_p4.pm_p4_escr, escrmsr, 1234 escrvalue, cccrvalue); 1235 1236 } else 1237 panic("invalid runcount %d\n", rc); 1238 | |
1239 ++rc; 1240 P4_PCPU_SET_RUNCOUNT(pc,ri,rc); 1241 1242 mtx_unlock_spin(&pc->pc_mtx); 1243 | 1300 ++rc; 1301 P4_PCPU_SET_RUNCOUNT(pc,ri,rc); 1302 1303 mtx_unlock_spin(&pc->pc_mtx); 1304 |
1305 PMCDBG(MDP,STA,2,"p4-start cpu=%d rc=%d ri=%d escr=%d " 1306 "escrmsr=0x%x escrvalue=0x%x cccr_config=0x%x v=%jx", cpu, rc, 1307 ri, pm->pm_md.pm_p4.pm_p4_escr, escrmsr, escrvalue, 1308 cccrvalue, P4_PCPU_HW_VALUE(pc,ri,cpu)); 1309 |
|
1244 return 0; 1245} 1246 1247/* 1248 * Stop a PMC. 1249 */ 1250 1251static int --- 25 unchanged lines hidden (view full) --- 1277 1278 pm = phw->phw_pmc; 1279 1280 KASSERT(pm != NULL, 1281 ("[p4,%d] null pmc for cpu%d, ri%d", __LINE__, cpu, ri)); 1282 1283 PMCDBG(MDP,STO,1, "p4-stop cpu=%d ri=%d", cpu, ri); 1284 | 1310 return 0; 1311} 1312 1313/* 1314 * Stop a PMC. 1315 */ 1316 1317static int --- 25 unchanged lines hidden (view full) --- 1343 1344 pm = phw->phw_pmc; 1345 1346 KASSERT(pm != NULL, 1347 ("[p4,%d] null pmc for cpu%d, ri%d", __LINE__, cpu, ri)); 1348 1349 PMCDBG(MDP,STO,1, "p4-stop cpu=%d ri=%d", cpu, ri); 1350 |
1285 if (PMC_IS_SYSTEM_MODE(pm->pm_mode)) { | 1351 if (PMC_IS_SYSTEM_MODE(PMC_TO_MODE(pm))) { |
1286 wrmsr(pd->pm_cccr_msr, 1287 pm->pm_md.pm_p4.pm_p4_cccrvalue & ~P4_CCCR_ENABLE); 1288 return 0; 1289 } 1290 1291 /* 1292 * Thread mode PMCs. 1293 * 1294 * On HTT machines, this PMC may be in use by two threads 1295 * running on two logical CPUS. Thus we look at the 1296 * 'pm_runcount' field and only turn off the appropriate TO/T1 | 1352 wrmsr(pd->pm_cccr_msr, 1353 pm->pm_md.pm_p4.pm_p4_cccrvalue & ~P4_CCCR_ENABLE); 1354 return 0; 1355 } 1356 1357 /* 1358 * Thread mode PMCs. 1359 * 1360 * On HTT machines, this PMC may be in use by two threads 1361 * running on two logical CPUS. Thus we look at the 1362 * 'pm_runcount' field and only turn off the appropriate TO/T1 |
1297 * bits (and keep the PMC running). | 1363 * bits (and keep the PMC running) if two logical CPUs were 1364 * using the PMC. |
1298 * | 1365 * |
1299 * The 'pc_saved' field has the 'diff' between the value in 1300 * the hardware register at PMCSTART time and the nominal 1301 * start value for the PMC. This diff is added to the current 1302 * PMC reading to derived the correct (absolute) return value. | |
1303 */ 1304 1305 /* bits to mask */ 1306 cccrtbits = P4_CCCR_OVF_PMI_T0; 1307 escrtbits = P4_ESCR_T0_OS | P4_ESCR_T0_USR; 1308 if (pmc_cpu_is_logical(cpu)) { 1309 cccrtbits <<= 1; 1310 escrtbits >>= 2; --- 13 unchanged lines hidden (view full) --- 1324 1325 /* Stop this PMC */ 1326 cccrvalue = rdmsr(pd->pm_cccr_msr); 1327 wrmsr(pd->pm_cccr_msr, cccrvalue & ~P4_CCCR_ENABLE); 1328 1329 escrmsr = pm->pm_md.pm_p4.pm_p4_escrmsr; 1330 escrvalue = rdmsr(escrmsr); 1331 | 1366 */ 1367 1368 /* bits to mask */ 1369 cccrtbits = P4_CCCR_OVF_PMI_T0; 1370 escrtbits = P4_ESCR_T0_OS | P4_ESCR_T0_USR; 1371 if (pmc_cpu_is_logical(cpu)) { 1372 cccrtbits <<= 1; 1373 escrtbits >>= 2; --- 13 unchanged lines hidden (view full) --- 1387 1388 /* Stop this PMC */ 1389 cccrvalue = rdmsr(pd->pm_cccr_msr); 1390 wrmsr(pd->pm_cccr_msr, cccrvalue & ~P4_CCCR_ENABLE); 1391 1392 escrmsr = pm->pm_md.pm_p4.pm_p4_escrmsr; 1393 escrvalue = rdmsr(escrmsr); 1394 |
1332 /* get the current PMC reading */ 1333 tmp = rdmsr(pd->pm_pmc_msr) & P4_PERFCTR_MASK; | 1395 /* The current CPU should be running on this PMC */ 1396 KASSERT(escrvalue & escrtbits, 1397 ("[p4,%d] ESCR T0/T1 mismatch cpu=%d rc=%d ri=%d escrmsr=0x%x " 1398 "escrvalue=0x%x tbits=0x%x", __LINE__, cpu, rc, ri, escrmsr, 1399 escrvalue, escrtbits)); 1400 KASSERT(PMC_IS_COUNTING_MODE(PMC_TO_MODE(pm)) || 1401 (cccrvalue & cccrtbits), 1402 ("[p4,%d] CCCR T0/T1 mismatch cpu=%d ri=%d cccrvalue=0x%x " 1403 "tbits=0x%x", __LINE__, cpu, ri, cccrvalue, cccrtbits)); |
1334 | 1404 |
1335 if (rc == 1) { /* need to keep the PMC running */ | 1405 /* get the current hardware reading */ 1406 tmp = rdmsr(pd->pm_pmc_msr); |
1336 | 1407 |
1337 KASSERT(escrvalue & escrtbits, 1338 ("[p4,%d] ESCR T0/T1 mismatch cpu=%d ri=%d escrmsr=0x%x " 1339 "escrvalue=0x%x tbits=0x%x", __LINE__, cpu, ri, escrmsr, 1340 escrvalue, escrtbits)); 1341 1342 KASSERT(PMC_IS_COUNTING_MODE(pm->pm_mode) || 1343 (cccrvalue & cccrtbits), 1344 ("[p4,%d] CCCR T0/T1 mismatch cpu=%d ri=%d cccrvalue=0x%x " 1345 "tbits=0x%x", __LINE__, cpu, ri, cccrvalue, cccrtbits)); 1346 | 1408 if (rc == 1) { /* need to keep the PMC running */ |
1347 escrvalue &= ~escrtbits; 1348 cccrvalue &= ~cccrtbits; | 1409 escrvalue &= ~escrtbits; 1410 cccrvalue &= ~cccrtbits; |
1349 | |
1350 wrmsr(escrmsr, escrvalue); 1351 wrmsr(pd->pm_cccr_msr, cccrvalue); | 1411 wrmsr(escrmsr, escrvalue); 1412 wrmsr(pd->pm_cccr_msr, cccrvalue); |
1352 | |
1353 } 1354 | 1413 } 1414 |
1355 PMCDBG(MDP,STO,2, "p4-stop/2 cpu=%d rc=%d ri=%d escrmsr=0x%x escrval=0x%x " 1356 "cccrval=0x%x", cpu, rc, ri, escrmsr, escrvalue, cccrvalue); | 1415 mtx_unlock_spin(&pc->pc_mtx); |
1357 | 1416 |
1358 /* get the incremental count from this context switch */ 1359 tmp -= P4_PCPU_SAVED_VALUE(pc,ri,cpu); 1360 if ((int64_t) tmp < 0) /* counter wrap-around */ 1361 tmp = -tmp + 1; | 1417 PMCDBG(MDP,STO,2, "p4-stop cpu=%d rc=%d ri=%d escrmsr=0x%x " 1418 "escrval=0x%x cccrval=0x%x v=%jx", cpu, rc, ri, escrmsr, 1419 escrvalue, cccrvalue, tmp); |
1362 | 1420 |
1421 if (tmp < P4_PCPU_HW_VALUE(pc,ri,cpu)) /* 40 bit counter overflow */ 1422 tmp += (P4_PERFCTR_MASK + 1) - P4_PCPU_HW_VALUE(pc,ri,cpu); 1423 else 1424 tmp -= P4_PCPU_HW_VALUE(pc,ri,cpu); 1425 |
|
1363 P4_PCPU_PMC_VALUE(pc,ri,cpu) += tmp; 1364 | 1426 P4_PCPU_PMC_VALUE(pc,ri,cpu) += tmp; 1427 |
1365 mtx_unlock_spin(&pc->pc_mtx); | |
1366 return 0; 1367} 1368 1369/* 1370 * Handle an interrupt. | 1428 return 0; 1429} 1430 1431/* 1432 * Handle an interrupt. |
1433 * 1434 * The hardware sets the CCCR_OVF whenever a counter overflow occurs, so the handler 1435 * examines all the 18 CCCR registers, processing the counters that have overflowed. 1436 * 1437 * On HTT machines, multiple logical CPUs may try to enter the NMI service 1438 * routine at the same time. |
|
1371 */ 1372 | 1439 */ 1440 |
1441extern volatile lapic_t *lapic; 1442 1443static void 1444p4_lapic_enable_pmc_interrupt(void) 1445{ 1446 uint32_t value; 1447 1448 value = lapic->lvt_pcint; 1449 value &= ~APIC_LVT_M; 1450 lapic->lvt_pcint = value; 1451} 1452 1453 |
|
1373static int 1374p4_intr(int cpu, uintptr_t eip) 1375{ | 1454static int 1455p4_intr(int cpu, uintptr_t eip) 1456{ |
1376 (void) cpu; | 1457 int i, pmc_interrupted; 1458 uint32_t cccrval, pmi_ovf_mask; 1459 struct p4_cpu *pc; 1460 struct pmc_hw *phw; 1461 struct pmc *pm; 1462 pmc_value_t v; 1463 |
1377 (void) eip; | 1464 (void) eip; |
1465 PMCDBG(MDP,INT, 1, "cpu=%d eip=%x pcint=0x%x", cpu, eip, 1466 lapic->lvt_pcint); |
|
1378 | 1467 |
1379 return 0; | 1468 pmc_interrupted = 0; 1469 pc = (struct p4_cpu *) pmc_pcpu[cpu]; 1470 1471 pmi_ovf_mask = pmc_cpu_is_logical(cpu) ? 1472 P4_CCCR_OVF_PMI_T1 : P4_CCCR_OVF_PMI_T0; 1473 pmi_ovf_mask |= P4_CCCR_OVF; 1474 1475 /* 1476 * Loop through all CCCRs, looking for ones that have the 1477 * OVF_PMI bit set for our logical CPU. 1478 */ 1479 1480 for (i = 1; i < P4_NPMCS; i++) { 1481 cccrval = rdmsr(P4_CCCR_MSR_FIRST + i - 1); 1482 1483 if ((cccrval & pmi_ovf_mask) != pmi_ovf_mask) 1484 continue; 1485 1486 v = rdmsr(P4_PERFCTR_MSR_FIRST + i - 1); 1487 1488 pmc_interrupted = 1; 1489 1490 PMCDBG(MDP,INT, 2, "ri=%d v=%jx", i, v); 1491 1492 /* Stop the counter, and turn off the overflow bit */ 1493 cccrval &= ~(P4_CCCR_OVF | P4_CCCR_ENABLE); 1494 wrmsr(P4_CCCR_MSR_FIRST + i - 1, cccrval); 1495 1496 phw = pc->pc_hwpmcs[i]; 1497 pm = phw->phw_pmc; 1498 1499 /* 1500 * Ignore de-configured or stopped PMCs. 1501 * Also ignore counting mode PMCs that may 1502 * have overflowed their counters. 1503 */ 1504 if (pm == NULL || 1505 pm->pm_state != PMC_STATE_RUNNING || 1506 !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) 1507 continue; 1508 1509 /* 1510 * If the previous sample hasn't been read yet, the 1511 * sampling interrupt is coming in too fast for the 1512 * rest of the system to cope. Do not re-enable the 1513 * counter. 1514 */ 1515 1516 if (P4_PCPU_SAVED_IP(pc,i,cpu)) { 1517 atomic_add_int(&pmc_stats.pm_intr_ignored, 1); 1518 continue; 1519 } 1520 1521 /* 1522 * write the the reload count and restart the 1523 * hardware. 1524 */ 1525 1526 v = P4_RELOAD_COUNT_TO_PERFCTR_VALUE( 1527 pm->pm_sc.pm_reloadcount); 1528 wrmsr(P4_PERFCTR_MSR_FIRST + i - 1, v); 1529 wrmsr(P4_CCCR_MSR_FIRST + i - 1, 1530 cccrval | P4_CCCR_ENABLE); 1531 } 1532 1533 if (pmc_interrupted) { 1534 1535 /* 1536 * On Intel CPUs, the PMC 'pcint' entry in the LAPIC 1537 * gets masked when a PMC interrupts the CPU. We need 1538 * to unmask this. 1539 */ 1540 p4_lapic_enable_pmc_interrupt(); 1541 1542 /* XXX: Invoke helper (non-NMI) interrupt here */ 1543 } 1544 1545 return pmc_interrupted; |
1380} 1381 1382/* 1383 * Describe a CPU's PMC state. 1384 */ 1385 1386static int 1387p4_describe(int cpu, int ri, struct pmc_info *pi, --- 17 unchanged lines hidden (view full) --- 1405 phw = pmc_pcpu[cpu]->pc_hwpmcs[ri]; 1406 pd = &p4_pmcdesc[ri]; 1407 1408 if ((error = copystr(pd->pm_descr.pd_name, pi->pm_name, 1409 PMC_NAME_MAX, &copied)) != 0) 1410 return error; 1411 1412 pi->pm_class = pd->pm_descr.pd_class; | 1546} 1547 1548/* 1549 * Describe a CPU's PMC state. 1550 */ 1551 1552static int 1553p4_describe(int cpu, int ri, struct pmc_info *pi, --- 17 unchanged lines hidden (view full) --- 1571 phw = pmc_pcpu[cpu]->pc_hwpmcs[ri]; 1572 pd = &p4_pmcdesc[ri]; 1573 1574 if ((error = copystr(pd->pm_descr.pd_name, pi->pm_name, 1575 PMC_NAME_MAX, &copied)) != 0) 1576 return error; 1577 1578 pi->pm_class = pd->pm_descr.pd_class; |
1413 pi->pm_caps = pd->pm_descr.pd_caps; 1414 pi->pm_width = pd->pm_descr.pd_width; | |
1415 1416 if (phw->phw_state & PMC_PHW_FLAG_IS_ENABLED) { 1417 pi->pm_enabled = TRUE; 1418 *ppmc = phw->phw_pmc; 1419 } else { 1420 pi->pm_enabled = FALSE; 1421 *ppmc = NULL; 1422 } --- 28 unchanged lines hidden (view full) --- 1451 ("[p4,%d] Initializing non-intel processor", __LINE__)); 1452 1453 PMCDBG(MDP,INI,1, "%s", "p4-initialize"); 1454 1455 switch (pmc_mdep->pmd_cputype) { 1456 case PMC_CPU_INTEL_PIV: 1457 1458 pmc_mdep->pmd_npmc = P4_NPMCS; | 1579 1580 if (phw->phw_state & PMC_PHW_FLAG_IS_ENABLED) { 1581 pi->pm_enabled = TRUE; 1582 *ppmc = phw->phw_pmc; 1583 } else { 1584 pi->pm_enabled = FALSE; 1585 *ppmc = NULL; 1586 } --- 28 unchanged lines hidden (view full) --- 1615 ("[p4,%d] Initializing non-intel processor", __LINE__)); 1616 1617 PMCDBG(MDP,INI,1, "%s", "p4-initialize"); 1618 1619 switch (pmc_mdep->pmd_cputype) { 1620 case PMC_CPU_INTEL_PIV: 1621 1622 pmc_mdep->pmd_npmc = P4_NPMCS; |
1459 pmc_mdep->pmd_classes[1] = PMC_CLASS_P4; | 1623 pmc_mdep->pmd_classes[1].pm_class = PMC_CLASS_P4; 1624 pmc_mdep->pmd_classes[1].pm_caps = P4_PMC_CAPS; 1625 pmc_mdep->pmd_classes[1].pm_width = 40; |
1460 pmc_mdep->pmd_nclasspmcs[1] = 18; 1461 1462 pmc_mdep->pmd_init = p4_init; 1463 pmc_mdep->pmd_cleanup = p4_cleanup; 1464 pmc_mdep->pmd_switch_in = p4_switch_in; 1465 pmc_mdep->pmd_switch_out = p4_switch_out; 1466 pmc_mdep->pmd_read_pmc = p4_read_pmc; 1467 pmc_mdep->pmd_write_pmc = p4_write_pmc; 1468 pmc_mdep->pmd_config_pmc = p4_config_pmc; | 1626 pmc_mdep->pmd_nclasspmcs[1] = 18; 1627 1628 pmc_mdep->pmd_init = p4_init; 1629 pmc_mdep->pmd_cleanup = p4_cleanup; 1630 pmc_mdep->pmd_switch_in = p4_switch_in; 1631 pmc_mdep->pmd_switch_out = p4_switch_out; 1632 pmc_mdep->pmd_read_pmc = p4_read_pmc; 1633 pmc_mdep->pmd_write_pmc = p4_write_pmc; 1634 pmc_mdep->pmd_config_pmc = p4_config_pmc; |
1635 pmc_mdep->pmd_get_config = p4_get_config; |
|
1469 pmc_mdep->pmd_allocate_pmc = p4_allocate_pmc; 1470 pmc_mdep->pmd_release_pmc = p4_release_pmc; 1471 pmc_mdep->pmd_start_pmc = p4_start_pmc; 1472 pmc_mdep->pmd_stop_pmc = p4_stop_pmc; 1473 pmc_mdep->pmd_intr = p4_intr; 1474 pmc_mdep->pmd_describe = p4_describe; 1475 pmc_mdep->pmd_get_msr = p4_get_msr; /* i386 */ 1476 --- 22 unchanged lines hidden --- | 1636 pmc_mdep->pmd_allocate_pmc = p4_allocate_pmc; 1637 pmc_mdep->pmd_release_pmc = p4_release_pmc; 1638 pmc_mdep->pmd_start_pmc = p4_start_pmc; 1639 pmc_mdep->pmd_stop_pmc = p4_stop_pmc; 1640 pmc_mdep->pmd_intr = p4_intr; 1641 pmc_mdep->pmd_describe = p4_describe; 1642 pmc_mdep->pmd_get_msr = p4_get_msr; /* i386 */ 1643 --- 22 unchanged lines hidden --- |