Deleted Added
full compact
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}