hwpmc_piv.c (168856) | hwpmc_piv.c (174395) |
---|---|
1/*- | 1/*- |
2 * Copyright (c) 2003-2005 Joseph Koshy | 2 * Copyright (c) 2003-2007 Joseph Koshy 3 * Copyright (c) 2007 The FreeBSD Foundation |
3 * All rights reserved. 4 * | 4 * All rights reserved. 5 * |
6 * Portions of this software were developed by A. Joseph Koshy under 7 * sponsorship from the FreeBSD Foundation and Google, Inc. 8 * |
|
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 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. --- 7 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> | 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. --- 7 unchanged lines hidden (view full) --- 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/dev/hwpmc/hwpmc_piv.c 168856 2007-04-19 08:02:51Z jkoshy $"); | 32__FBSDID("$FreeBSD: head/sys/dev/hwpmc/hwpmc_piv.c 174395 2007-12-07 08:20:17Z 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 | 33 34#include <sys/param.h> 35#include <sys/lock.h> 36#include <sys/mutex.h> 37#include <sys/pmc.h> 38#include <sys/pmckern.h> 39#include <sys/smp.h> 40#include <sys/systm.h> 41 |
42#include <machine/cpu.h> |
|
38#include <machine/cpufunc.h> 39#include <machine/md_var.h> 40#include <machine/specialreg.h> 41 42/* 43 * PENTIUM 4 SUPPORT 44 * 45 * The P4 has 18 PMCs, divided into 4 groups with 4,4,4 and 6 PMCs --- 1427 unchanged lines hidden (view full) --- 1473 return 0; 1474 } 1475 1476 /* 1477 * Thread mode PMCs. 1478 * 1479 * On HTT machines, this PMC may be in use by two threads 1480 * running on two logical CPUS. Thus we look at the | 43#include <machine/cpufunc.h> 44#include <machine/md_var.h> 45#include <machine/specialreg.h> 46 47/* 48 * PENTIUM 4 SUPPORT 49 * 50 * The P4 has 18 PMCs, divided into 4 groups with 4,4,4 and 6 PMCs --- 1427 unchanged lines hidden (view full) --- 1478 return 0; 1479 } 1480 1481 /* 1482 * Thread mode PMCs. 1483 * 1484 * On HTT machines, this PMC may be in use by two threads 1485 * running on two logical CPUS. Thus we look at the |
1481 * 'pm_runcount' field and only turn off the appropriate TO/T1 | 1486 * 'runcount' field and only turn off the appropriate TO/T1 |
1482 * bits (and keep the PMC running) if two logical CPUs were 1483 * using the PMC. 1484 * 1485 */ 1486 1487 /* bits to mask */ 1488 cccrtbits = P4_CCCR_OVF_PMI_T0; 1489 escrtbits = P4_ESCR_T0_OS | P4_ESCR_T0_USR; --- 67 unchanged lines hidden (view full) --- 1557 * On HTT machines, the CCCR register is shared and will interrupt 1558 * both logical processors if so configured. Thus multiple logical 1559 * CPUs could enter the NMI service routine at the same time. These 1560 * will get serialized using a per-cpu spinlock dedicated for use in 1561 * the NMI handler. 1562 */ 1563 1564static int | 1487 * bits (and keep the PMC running) if two logical CPUs were 1488 * using the PMC. 1489 * 1490 */ 1491 1492 /* bits to mask */ 1493 cccrtbits = P4_CCCR_OVF_PMI_T0; 1494 escrtbits = P4_ESCR_T0_OS | P4_ESCR_T0_USR; --- 67 unchanged lines hidden (view full) --- 1562 * On HTT machines, the CCCR register is shared and will interrupt 1563 * both logical processors if so configured. Thus multiple logical 1564 * CPUs could enter the NMI service routine at the same time. These 1565 * will get serialized using a per-cpu spinlock dedicated for use in 1566 * the NMI handler. 1567 */ 1568 1569static int |
1565p4_intr(int cpu, uintptr_t eip, int usermode) | 1570p4_intr(int cpu, struct trapframe *tf) |
1566{ | 1571{ |
1567 int i, did_interrupt, error, ri; | |
1568 uint32_t cccrval, ovf_mask, ovf_partner; | 1572 uint32_t cccrval, ovf_mask, ovf_partner; |
1569 struct p4_cpu *pc; | 1573 int i, did_interrupt, error, ri; |
1570 struct pmc_hw *phw; | 1574 struct pmc_hw *phw; |
1575 struct p4_cpu *pc; |
|
1571 struct pmc *pm; 1572 pmc_value_t v; 1573 | 1576 struct pmc *pm; 1577 pmc_value_t v; 1578 |
1574 PMCDBG(MDP,INT, 1, "cpu=%d eip=%p um=%d", cpu, (void *) eip, usermode); | 1579 PMCDBG(MDP,INT, 1, "cpu=%d tf=0x%p um=%d", cpu, (void *) tf, 1580 TRAPF_USERMODE(tf)); |
1575 1576 pc = (struct p4_cpu *) pmc_pcpu[P4_TO_HTT_PRIMARY(cpu)]; 1577 1578 ovf_mask = P4_CPU_IS_HTT_SECONDARY(cpu) ? 1579 P4_CCCR_OVF_PMI_T1 : P4_CCCR_OVF_PMI_T0; 1580 ovf_mask |= P4_CCCR_OVF; 1581 if (p4_system_has_htt) | 1581 1582 pc = (struct p4_cpu *) pmc_pcpu[P4_TO_HTT_PRIMARY(cpu)]; 1583 1584 ovf_mask = P4_CPU_IS_HTT_SECONDARY(cpu) ? 1585 P4_CCCR_OVF_PMI_T1 : P4_CCCR_OVF_PMI_T0; 1586 ovf_mask |= P4_CCCR_OVF; 1587 if (p4_system_has_htt) |
1582 ovf_partner = P4_CPU_IS_HTT_SECONDARY(cpu) ? P4_CCCR_OVF_PMI_T0 : 1583 P4_CCCR_OVF_PMI_T1; | 1588 ovf_partner = P4_CPU_IS_HTT_SECONDARY(cpu) ? 1589 P4_CCCR_OVF_PMI_T0 : P4_CCCR_OVF_PMI_T1; |
1584 else 1585 ovf_partner = 0; 1586 did_interrupt = 0; 1587 1588 if (p4_system_has_htt) 1589 P4_PCPU_ACQ_INTR_SPINLOCK(pc); 1590 1591 /* --- 20 unchanged lines hidden (view full) --- 1612 */ 1613 phw = pc->pc_hwpmcs[ri]; 1614 pm = phw->phw_pmc; 1615 if (pm == NULL || 1616 pm->pm_state != PMC_STATE_RUNNING || 1617 !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) { 1618 continue; 1619 } | 1590 else 1591 ovf_partner = 0; 1592 did_interrupt = 0; 1593 1594 if (p4_system_has_htt) 1595 P4_PCPU_ACQ_INTR_SPINLOCK(pc); 1596 1597 /* --- 20 unchanged lines hidden (view full) --- 1618 */ 1619 phw = pc->pc_hwpmcs[ri]; 1620 pm = phw->phw_pmc; 1621 if (pm == NULL || 1622 pm->pm_state != PMC_STATE_RUNNING || 1623 !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) { 1624 continue; 1625 } |
1620 (void) pmc_process_interrupt(cpu, pm, eip, usermode); | 1626 (void) pmc_process_interrupt(cpu, pm, tf, 1627 TRAPF_USERMODE(tf)); |
1621 continue; 1622 } 1623 1624 /* 1625 * Fresh interrupt. Look for the CCCR_OVF bit 1626 * and the OVF_Tx bit for this logical 1627 * processor being set. 1628 */ --- 33 unchanged lines hidden (view full) --- 1662 !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) { 1663 continue; 1664 } 1665 1666 /* 1667 * Process the interrupt. Re-enable the PMC if 1668 * processing was successful. 1669 */ | 1628 continue; 1629 } 1630 1631 /* 1632 * Fresh interrupt. Look for the CCCR_OVF bit 1633 * and the OVF_Tx bit for this logical 1634 * processor being set. 1635 */ --- 33 unchanged lines hidden (view full) --- 1669 !PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) { 1670 continue; 1671 } 1672 1673 /* 1674 * Process the interrupt. Re-enable the PMC if 1675 * processing was successful. 1676 */ |
1670 error = pmc_process_interrupt(cpu, pm, eip, usermode); | 1677 error = pmc_process_interrupt(cpu, pm, tf, 1678 TRAPF_USERMODE(tf)); |
1671 1672 /* 1673 * Only the first processor executing the NMI handler 1674 * in a HTT pair will restart a PMC, and that too 1675 * only if there were no errors. 1676 */ 1677 v = P4_RELOAD_COUNT_TO_PERFCTR_VALUE( 1678 pm->pm_sc.pm_reloadcount); --- 14 unchanged lines hidden (view full) --- 1693 */ 1694 1695 if (did_interrupt) 1696 pmc_x86_lapic_enable_pmc_interrupt(); 1697 1698 atomic_add_int(did_interrupt ? &pmc_stats.pm_intr_processed : 1699 &pmc_stats.pm_intr_ignored, 1); 1700 | 1679 1680 /* 1681 * Only the first processor executing the NMI handler 1682 * in a HTT pair will restart a PMC, and that too 1683 * only if there were no errors. 1684 */ 1685 v = P4_RELOAD_COUNT_TO_PERFCTR_VALUE( 1686 pm->pm_sc.pm_reloadcount); --- 14 unchanged lines hidden (view full) --- 1701 */ 1702 1703 if (did_interrupt) 1704 pmc_x86_lapic_enable_pmc_interrupt(); 1705 1706 atomic_add_int(did_interrupt ? &pmc_stats.pm_intr_processed : 1707 &pmc_stats.pm_intr_ignored, 1); 1708 |
1701 return did_interrupt; | 1709 return (did_interrupt); |
1702} 1703 1704/* 1705 * Describe a CPU's PMC state. 1706 */ 1707 1708static int 1709p4_describe(int cpu, int ri, struct pmc_info *pi, --- 112 unchanged lines hidden --- | 1710} 1711 1712/* 1713 * Describe a CPU's PMC state. 1714 */ 1715 1716static int 1717p4_describe(int cpu, int ri, struct pmc_info *pi, --- 112 unchanged lines hidden --- |