hwpmc_amd.c (6b8c8cd85fae1f4947956b06ec59b4f808951f29) hwpmc_amd.c (c5153e190bd2410c60a50e108a7a60cde9a3c4bc)
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

--- 346 unchanged lines hidden (view full) ---

355 phw = pmc_pcpu[cpu]->pc_hwpmcs[ri];
356 pd = &amd_pmcdesc[ri];
357 pm = phw->phw_pmc;
358
359 KASSERT(pm != NULL,
360 ("[amd,%d] No owner for HWPMC [cpu%d,pmc%d]", __LINE__,
361 cpu, ri));
362
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

--- 346 unchanged lines hidden (view full) ---

355 phw = pmc_pcpu[cpu]->pc_hwpmcs[ri];
356 pd = &amd_pmcdesc[ri];
357 pm = phw->phw_pmc;
358
359 KASSERT(pm != NULL,
360 ("[amd,%d] No owner for HWPMC [cpu%d,pmc%d]", __LINE__,
361 cpu, ri));
362
363 mode = pm->pm_mode;
363 mode = PMC_TO_MODE(pm);
364
365 PMCDBG(MDP,REA,1,"amd-read id=%d class=%d", ri, pd->pm_descr.pd_class);
366
367 /* Reading the TSC is a special case */
368 if (pd->pm_descr.pd_class == PMC_CLASS_TSC) {
369 KASSERT(PMC_IS_COUNTING_MODE(mode),
370 ("[amd,%d] TSC counter in non-counting mode", __LINE__));
371 *v = rdtsc();

--- 36 unchanged lines hidden (view full) ---

408 phw = pmc_pcpu[cpu]->pc_hwpmcs[ri];
409 pd = &amd_pmcdesc[ri];
410 pm = phw->phw_pmc;
411
412 KASSERT(pm != NULL,
413 ("[amd,%d] PMC not owned (cpu%d,pmc%d)", __LINE__,
414 cpu, ri));
415
364
365 PMCDBG(MDP,REA,1,"amd-read id=%d class=%d", ri, pd->pm_descr.pd_class);
366
367 /* Reading the TSC is a special case */
368 if (pd->pm_descr.pd_class == PMC_CLASS_TSC) {
369 KASSERT(PMC_IS_COUNTING_MODE(mode),
370 ("[amd,%d] TSC counter in non-counting mode", __LINE__));
371 *v = rdtsc();

--- 36 unchanged lines hidden (view full) ---

408 phw = pmc_pcpu[cpu]->pc_hwpmcs[ri];
409 pd = &amd_pmcdesc[ri];
410 pm = phw->phw_pmc;
411
412 KASSERT(pm != NULL,
413 ("[amd,%d] PMC not owned (cpu%d,pmc%d)", __LINE__,
414 cpu, ri));
415
416 mode = pm->pm_mode;
416 mode = PMC_TO_MODE(pm);
417
418 if (pd->pm_descr.pd_class == PMC_CLASS_TSC)
419 return 0;
420
421 KASSERT(pd->pm_descr.pd_class == AMD_PMC_CLASS,
422 ("[amd,%d] unknown PMC class (%d)", __LINE__,
423 pd->pm_descr.pd_class));
424

--- 31 unchanged lines hidden (view full) ---

456 ("[amd,%d] pm=%p phw->pm=%p hwpmc not unconfigured",
457 __LINE__, pm, phw->phw_pmc));
458
459 phw->phw_pmc = pm;
460 return 0;
461}
462
463/*
417
418 if (pd->pm_descr.pd_class == PMC_CLASS_TSC)
419 return 0;
420
421 KASSERT(pd->pm_descr.pd_class == AMD_PMC_CLASS,
422 ("[amd,%d] unknown PMC class (%d)", __LINE__,
423 pd->pm_descr.pd_class));
424

--- 31 unchanged lines hidden (view full) ---

456 ("[amd,%d] pm=%p phw->pm=%p hwpmc not unconfigured",
457 __LINE__, pm, phw->phw_pmc));
458
459 phw->phw_pmc = pm;
460 return 0;
461}
462
463/*
464 * Retrieve a configured PMC pointer from hardware state.
465 */
466
467static int
468amd_get_config(int cpu, int ri, struct pmc **ppm)
469{
470 *ppm = pmc_pcpu[cpu]->pc_hwpmcs[ri]->phw_pmc;
471
472 return 0;
473}
474
475/*
464 * Machine dependent actions taken during the context switch in of a
465 * thread.
466 */
467
468static int
469amd_switch_in(struct pmc_cpu *pc, struct pmc_process *pp)
470{
471 (void) pc;
472
473 PMCDBG(MDP,SWI,1, "pc=%p pp=%p enable-msr=%d", pc, pp,
476 * Machine dependent actions taken during the context switch in of a
477 * thread.
478 */
479
480static int
481amd_switch_in(struct pmc_cpu *pc, struct pmc_process *pp)
482{
483 (void) pc;
484
485 PMCDBG(MDP,SWI,1, "pc=%p pp=%p enable-msr=%d", pc, pp,
474 (pp->pp_flags & PMC_FLAG_ENABLE_MSR_ACCESS) != 0);
486 (pp->pp_flags & PMC_PP_ENABLE_MSR_ACCESS) != 0);
475
476 /* enable the RDPMC instruction if needed */
487
488 /* enable the RDPMC instruction if needed */
477 if (pp->pp_flags & PMC_FLAG_ENABLE_MSR_ACCESS)
489 if (pp->pp_flags & PMC_PP_ENABLE_MSR_ACCESS)
478 load_cr4(rcr4() | CR4_PCE);
479
480 return 0;
481}
482
483/*
484 * Machine dependent actions taken during the context switch out of a
485 * thread.
486 */
487
488static int
489amd_switch_out(struct pmc_cpu *pc, struct pmc_process *pp)
490{
491 (void) pc;
492 (void) pp; /* can be NULL */
493
494 PMCDBG(MDP,SWO,1, "pc=%p pp=%p enable-msr=%d", pc, pp, pp ?
490 load_cr4(rcr4() | CR4_PCE);
491
492 return 0;
493}
494
495/*
496 * Machine dependent actions taken during the context switch out of a
497 * thread.
498 */
499
500static int
501amd_switch_out(struct pmc_cpu *pc, struct pmc_process *pp)
502{
503 (void) pc;
504 (void) pp; /* can be NULL */
505
506 PMCDBG(MDP,SWO,1, "pc=%p pp=%p enable-msr=%d", pc, pp, pp ?
495 (pp->pp_flags & PMC_FLAG_ENABLE_MSR_ACCESS) == 1 : 0);
507 (pp->pp_flags & PMC_PP_ENABLE_MSR_ACCESS) == 1 : 0);
496
497 /* always turn off the RDPMC instruction */
498 load_cr4(rcr4() & ~CR4_PCE);
499
500 return 0;
501}
502
503/*

--- 14 unchanged lines hidden (view full) ---

518 KASSERT(cpu >= 0 && cpu < mp_ncpus,
519 ("[amd,%d] illegal CPU value %d", __LINE__, cpu));
520 KASSERT(ri >= 0 && ri < AMD_NPMCS,
521 ("[amd,%d] illegal row index %d", __LINE__, ri));
522
523 pd = &amd_pmcdesc[ri].pm_descr;
524
525 /* check class match */
508
509 /* always turn off the RDPMC instruction */
510 load_cr4(rcr4() & ~CR4_PCE);
511
512 return 0;
513}
514
515/*

--- 14 unchanged lines hidden (view full) ---

530 KASSERT(cpu >= 0 && cpu < mp_ncpus,
531 ("[amd,%d] illegal CPU value %d", __LINE__, cpu));
532 KASSERT(ri >= 0 && ri < AMD_NPMCS,
533 ("[amd,%d] illegal row index %d", __LINE__, ri));
534
535 pd = &amd_pmcdesc[ri].pm_descr;
536
537 /* check class match */
526 if (pd->pd_class != pm->pm_class)
538 if (pd->pd_class != a->pm_class)
527 return EINVAL;
528
529 caps = pm->pm_caps;
530
531 PMCDBG(MDP,ALL,1,"amd-allocate ri=%d caps=0x%x", ri, caps);
532
533 if ((pd->pd_caps & caps) != caps)
534 return EPERM;

--- 225 unchanged lines hidden (view full) ---

760 KASSERT(phw != NULL, ("[amd,%d] null PHW pointer", __LINE__));
761
762 if ((pm = phw->phw_pmc) == NULL ||
763 pm->pm_state != PMC_STATE_RUNNING) {
764 atomic_add_int(&pmc_stats.pm_intr_ignored, 1);
765 continue;
766 }
767
539 return EINVAL;
540
541 caps = pm->pm_caps;
542
543 PMCDBG(MDP,ALL,1,"amd-allocate ri=%d caps=0x%x", ri, caps);
544
545 if ((pd->pd_caps & caps) != caps)
546 return EPERM;

--- 225 unchanged lines hidden (view full) ---

772 KASSERT(phw != NULL, ("[amd,%d] null PHW pointer", __LINE__));
773
774 if ((pm = phw->phw_pmc) == NULL ||
775 pm->pm_state != PMC_STATE_RUNNING) {
776 atomic_add_int(&pmc_stats.pm_intr_ignored, 1);
777 continue;
778 }
779
768 mode = pm->pm_mode;
780 mode = PMC_TO_MODE(pm);
769 if (PMC_IS_SAMPLING_MODE(mode) &&
770 AMD_PMC_HAS_OVERFLOWED(perfctr)) {
771 atomic_add_int(&pmc_stats.pm_intr_processed, 1);
772 if (PMC_IS_SYSTEM_MODE(mode))
773 pmc_update_histogram(phw, eip);
774 else if (PMC_IS_VIRTUAL_MODE(mode))
775 pmc_send_signal(pm);
776 retval = 1;

--- 21 unchanged lines hidden (view full) ---

798 phw = pmc_pcpu[cpu]->pc_hwpmcs[ri];
799 pd = &amd_pmcdesc[ri];
800
801 if ((error = copystr(pd->pm_descr.pd_name, pi->pm_name,
802 PMC_NAME_MAX, &copied)) != 0)
803 return error;
804
805 pi->pm_class = pd->pm_descr.pd_class;
781 if (PMC_IS_SAMPLING_MODE(mode) &&
782 AMD_PMC_HAS_OVERFLOWED(perfctr)) {
783 atomic_add_int(&pmc_stats.pm_intr_processed, 1);
784 if (PMC_IS_SYSTEM_MODE(mode))
785 pmc_update_histogram(phw, eip);
786 else if (PMC_IS_VIRTUAL_MODE(mode))
787 pmc_send_signal(pm);
788 retval = 1;

--- 21 unchanged lines hidden (view full) ---

810 phw = pmc_pcpu[cpu]->pc_hwpmcs[ri];
811 pd = &amd_pmcdesc[ri];
812
813 if ((error = copystr(pd->pm_descr.pd_name, pi->pm_name,
814 PMC_NAME_MAX, &copied)) != 0)
815 return error;
816
817 pi->pm_class = pd->pm_descr.pd_class;
806 pi->pm_caps = pd->pm_descr.pd_caps;
807 pi->pm_width = pd->pm_descr.pd_width;
808
809 if (phw->phw_state & PMC_PHW_FLAG_IS_ENABLED) {
810 pi->pm_enabled = TRUE;
811 *ppmc = phw->phw_pmc;
812 } else {
813 pi->pm_enabled = FALSE;
814 *ppmc = NULL;
815 }

--- 161 unchanged lines hidden (view full) ---

977#else
978#error Unknown AMD CPU type.
979#endif
980
981 pmc_mdep->pmd_npmc = AMD_NPMCS;
982
983 /* this processor has two classes of usable PMCs */
984 pmc_mdep->pmd_nclass = 2;
818
819 if (phw->phw_state & PMC_PHW_FLAG_IS_ENABLED) {
820 pi->pm_enabled = TRUE;
821 *ppmc = phw->phw_pmc;
822 } else {
823 pi->pm_enabled = FALSE;
824 *ppmc = NULL;
825 }

--- 161 unchanged lines hidden (view full) ---

987#else
988#error Unknown AMD CPU type.
989#endif
990
991 pmc_mdep->pmd_npmc = AMD_NPMCS;
992
993 /* this processor has two classes of usable PMCs */
994 pmc_mdep->pmd_nclass = 2;
985 pmc_mdep->pmd_classes[0] = PMC_CLASS_TSC;
986 pmc_mdep->pmd_classes[1] = AMD_PMC_CLASS;
995
996 /* TSC */
997 pmc_mdep->pmd_classes[0].pm_class = PMC_CLASS_TSC;
998 pmc_mdep->pmd_classes[0].pm_caps = PMC_CAP_READ;
999 pmc_mdep->pmd_classes[0].pm_width = 64;
1000
1001 /* AMD K7/K8 PMCs */
1002 pmc_mdep->pmd_classes[1].pm_class = AMD_PMC_CLASS;
1003 pmc_mdep->pmd_classes[1].pm_caps = AMD_PMC_CAPS;
1004 pmc_mdep->pmd_classes[1].pm_width = 48;
1005
987 pmc_mdep->pmd_nclasspmcs[0] = 1;
988 pmc_mdep->pmd_nclasspmcs[1] = (AMD_NPMCS-1);
989
990 pmc_mdep->pmd_init = amd_init;
991 pmc_mdep->pmd_cleanup = amd_cleanup;
992 pmc_mdep->pmd_switch_in = amd_switch_in;
993 pmc_mdep->pmd_switch_out = amd_switch_out;
994 pmc_mdep->pmd_read_pmc = amd_read_pmc;
995 pmc_mdep->pmd_write_pmc = amd_write_pmc;
996 pmc_mdep->pmd_config_pmc = amd_config_pmc;
1006 pmc_mdep->pmd_nclasspmcs[0] = 1;
1007 pmc_mdep->pmd_nclasspmcs[1] = (AMD_NPMCS-1);
1008
1009 pmc_mdep->pmd_init = amd_init;
1010 pmc_mdep->pmd_cleanup = amd_cleanup;
1011 pmc_mdep->pmd_switch_in = amd_switch_in;
1012 pmc_mdep->pmd_switch_out = amd_switch_out;
1013 pmc_mdep->pmd_read_pmc = amd_read_pmc;
1014 pmc_mdep->pmd_write_pmc = amd_write_pmc;
1015 pmc_mdep->pmd_config_pmc = amd_config_pmc;
1016 pmc_mdep->pmd_get_config = amd_get_config;
997 pmc_mdep->pmd_allocate_pmc = amd_allocate_pmc;
998 pmc_mdep->pmd_release_pmc = amd_release_pmc;
999 pmc_mdep->pmd_start_pmc = amd_start_pmc;
1000 pmc_mdep->pmd_stop_pmc = amd_stop_pmc;
1001 pmc_mdep->pmd_intr = amd_intr;
1002 pmc_mdep->pmd_describe = amd_describe;
1003 pmc_mdep->pmd_get_msr = amd_get_msr; /* i386 */
1004
1005 PMCDBG(MDP,INI,0,"%s","amd-initialize");
1006
1007 return pmc_mdep;
1008}
1017 pmc_mdep->pmd_allocate_pmc = amd_allocate_pmc;
1018 pmc_mdep->pmd_release_pmc = amd_release_pmc;
1019 pmc_mdep->pmd_start_pmc = amd_start_pmc;
1020 pmc_mdep->pmd_stop_pmc = amd_stop_pmc;
1021 pmc_mdep->pmd_intr = amd_intr;
1022 pmc_mdep->pmd_describe = amd_describe;
1023 pmc_mdep->pmd_get_msr = amd_get_msr; /* i386 */
1024
1025 PMCDBG(MDP,INI,0,"%s","amd-initialize");
1026
1027 return pmc_mdep;
1028}