The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/hwpmc/hwpmc_intel.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2008 Joseph Koshy
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  */
   28 
   29 /*
   30  * Common code for handling Intel CPUs.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __FBSDID("$FreeBSD$");
   35 
   36 #include <sys/param.h>
   37 #include <sys/pmc.h>
   38 #include <sys/pmckern.h>
   39 #include <sys/systm.h>
   40 
   41 #include <machine/cpu.h>
   42 #include <machine/cputypes.h>
   43 #include <machine/md_var.h>
   44 #include <machine/specialreg.h>
   45 
   46 static int
   47 intel_switch_in(struct pmc_cpu *pc, struct pmc_process *pp)
   48 {
   49         (void) pc;
   50 
   51         PMCDBG3(MDP,SWI,1, "pc=%p pp=%p enable-msr=%d", pc, pp,
   52             pp->pp_flags & PMC_PP_ENABLE_MSR_ACCESS);
   53 
   54         /* allow the RDPMC instruction if needed */
   55         if (pp->pp_flags & PMC_PP_ENABLE_MSR_ACCESS)
   56                 load_cr4(rcr4() | CR4_PCE);
   57 
   58         PMCDBG1(MDP,SWI,1, "cr4=0x%jx", (uintmax_t) rcr4());
   59 
   60         return 0;
   61 }
   62 
   63 static int
   64 intel_switch_out(struct pmc_cpu *pc, struct pmc_process *pp)
   65 {
   66         (void) pc;
   67         (void) pp;              /* can be NULL */
   68 
   69         PMCDBG3(MDP,SWO,1, "pc=%p pp=%p cr4=0x%jx", pc, pp,
   70             (uintmax_t) rcr4());
   71 
   72         /* always turn off the RDPMC instruction */
   73         load_cr4(rcr4() & ~CR4_PCE);
   74 
   75         return 0;
   76 }
   77 
   78 struct pmc_mdep *
   79 pmc_intel_initialize(void)
   80 {
   81         struct pmc_mdep *pmc_mdep;
   82         enum pmc_cputype cputype;
   83         int error, family, model, nclasses, ncpus, stepping, verov;
   84 
   85         KASSERT(cpu_vendor_id == CPU_VENDOR_INTEL,
   86             ("[intel,%d] Initializing non-intel processor", __LINE__));
   87 
   88         PMCDBG1(MDP,INI,0, "intel-initialize cpuid=0x%x", cpu_id);
   89 
   90         cputype = -1;
   91         nclasses = 2;
   92         error = 0;
   93         verov = 0;
   94         family = CPUID_TO_FAMILY(cpu_id);
   95         model = CPUID_TO_MODEL(cpu_id);
   96         stepping = CPUID_TO_STEPPING(cpu_id);
   97 
   98         snprintf(pmc_cpuid, sizeof(pmc_cpuid), "GenuineIntel-%d-%02X-%X",
   99             family, model, stepping);
  100 
  101         switch (cpu_id & 0xF00) {
  102         case 0x600:             /* Pentium Pro, Celeron, Pentium II & III */
  103                 switch (model) {
  104                 case 0xE:
  105                         cputype = PMC_CPU_INTEL_CORE;
  106                         break;
  107                 case 0xF:
  108                         /* Per Intel document 315338-020. */
  109                         if (stepping == 0x7) {
  110                                 cputype = PMC_CPU_INTEL_CORE;
  111                                 verov = 1;
  112                         } else {
  113                                 cputype = PMC_CPU_INTEL_CORE2;
  114                                 nclasses = 3;
  115                         }
  116                         break;
  117                 case 0x17:
  118                         cputype = PMC_CPU_INTEL_CORE2EXTREME;
  119                         nclasses = 3;
  120                         break;
  121                 case 0x1A:
  122                 case 0x1E:      /*
  123                                  * Per Intel document 253669-032 9/2009,
  124                                  * pages A-2 and A-57
  125                                  */
  126                 case 0x1F:      /*
  127                                  * Per Intel document 253669-032 9/2009,
  128                                  * pages A-2 and A-57
  129                                  */
  130                         cputype = PMC_CPU_INTEL_COREI7;
  131                         nclasses = 5;
  132                         break;
  133                 case 0x2E:
  134                         cputype = PMC_CPU_INTEL_NEHALEM_EX;
  135                         nclasses = 3;
  136                         break;
  137                 case 0x25:      /* Per Intel document 253669-033US 12/2009. */
  138                 case 0x2C:      /* Per Intel document 253669-033US 12/2009. */
  139                         cputype = PMC_CPU_INTEL_WESTMERE;
  140                         nclasses = 5;
  141                         break;
  142                 case 0x2F:      /* Westmere-EX, seen in wild */
  143                         cputype = PMC_CPU_INTEL_WESTMERE_EX;
  144                         nclasses = 3;
  145                         break;
  146                 case 0x2A:      /* Per Intel document 253669-039US 05/2011. */
  147                         cputype = PMC_CPU_INTEL_SANDYBRIDGE;
  148                         nclasses = 3;
  149                         break;
  150                 case 0x2D:      /* Per Intel document 253669-044US 08/2012. */
  151                         cputype = PMC_CPU_INTEL_SANDYBRIDGE_XEON;
  152                         nclasses = 3;
  153                         break;
  154                 case 0x3A:      /* Per Intel document 253669-043US 05/2012. */
  155                         cputype = PMC_CPU_INTEL_IVYBRIDGE;
  156                         nclasses = 3;
  157                         break;
  158                 case 0x3E:      /* Per Intel document 325462-045US 01/2013. */
  159                         cputype = PMC_CPU_INTEL_IVYBRIDGE_XEON;
  160                         nclasses = 3;
  161                         break;
  162                 case 0x3D:
  163                 case 0x47:
  164                         cputype = PMC_CPU_INTEL_BROADWELL;
  165                         nclasses = 3;
  166                         break;
  167                 case 0x4f:
  168                 case 0x56:
  169                         cputype = PMC_CPU_INTEL_BROADWELL_XEON;
  170                         nclasses = 3;
  171                         break;
  172                 case 0x3C:      /* Per Intel document 325462-045US 01/2013. */
  173                 case 0x45:      /* Per Intel document 325462-045US 09/2014. */
  174                         cputype = PMC_CPU_INTEL_HASWELL;
  175                         nclasses = 3;
  176                         break;
  177                 case 0x3F:      /* Per Intel document 325462-045US 09/2014. */
  178                 case 0x46:      /* Per Intel document 325462-045US 09/2014. */
  179                                 /* Should 46 be XEON. probably its own? */
  180                         cputype = PMC_CPU_INTEL_HASWELL_XEON;
  181                         nclasses = 3;
  182                         break;
  183                         /* Skylake */
  184                 case 0x4e:
  185                 case 0x5e:
  186                         /* Kabylake */
  187                 case 0x8E:      /* Per Intel document 325462-063US July 2017. */
  188                 case 0x9E:      /* Per Intel document 325462-063US July 2017. */
  189                         /* Cometlake */
  190                 case 0xA5:
  191                 case 0xA6:
  192                         cputype = PMC_CPU_INTEL_SKYLAKE;
  193                         nclasses = 3;
  194                         break;
  195                 case 0x55:      /* SDM rev 63 */
  196                         cputype = PMC_CPU_INTEL_SKYLAKE_XEON;
  197                         nclasses = 3;
  198                         break;
  199                         /* Icelake */
  200                 case 0x7D:
  201                 case 0x7E:
  202                         /* Tigerlake */
  203                 case 0x8C:
  204                 case 0x8D:
  205                         /* Rocketlake */
  206                 case 0xA7:
  207                         cputype = PMC_CPU_INTEL_ICELAKE;
  208                         nclasses = 3;
  209                         break;
  210                 case 0x6A:
  211                 case 0x6C:
  212                         cputype = PMC_CPU_INTEL_ICELAKE_XEON;
  213                         nclasses = 3;
  214                         break;
  215                 case 0x97:
  216                 case 0x9A:
  217                         cputype = PMC_CPU_INTEL_ALDERLAKE;
  218                         nclasses = 3;
  219                         break;
  220                 case 0x1C:      /* Per Intel document 320047-002. */
  221                 case 0x26:
  222                 case 0x27:
  223                 case 0x35:
  224                 case 0x36:
  225                         cputype = PMC_CPU_INTEL_ATOM;
  226                         nclasses = 3;
  227                         break;
  228                 case 0x37:
  229                 case 0x4A:
  230                 case 0x4D:      /* Per Intel document 330061-001 01/2014. */
  231                 case 0x5A:
  232                 case 0x5D:
  233                         cputype = PMC_CPU_INTEL_ATOM_SILVERMONT;
  234                         nclasses = 3;
  235                         break;
  236                 case 0x5C:      /* Per Intel document 325462-071US 10/2019. */
  237                 case 0x5F:
  238                         cputype = PMC_CPU_INTEL_ATOM_GOLDMONT;
  239                         nclasses = 3;
  240                         break;
  241                 case 0x7A:
  242                         cputype = PMC_CPU_INTEL_ATOM_GOLDMONT_P;
  243                         nclasses = 3;
  244                         break;
  245                 case 0x86:
  246                 case 0x96:
  247                         cputype = PMC_CPU_INTEL_ATOM_TREMONT;
  248                         nclasses = 3;
  249                         break;
  250                 }
  251                 break;
  252         }
  253 
  254 
  255         if ((int) cputype == -1) {
  256                 printf("pmc: Unknown Intel CPU.\n");
  257                 return (NULL);
  258         }
  259 
  260         /* Allocate base class and initialize machine dependent struct */
  261         pmc_mdep = pmc_mdep_alloc(nclasses);
  262 
  263         pmc_mdep->pmd_cputype    = cputype;
  264         pmc_mdep->pmd_switch_in  = intel_switch_in;
  265         pmc_mdep->pmd_switch_out = intel_switch_out;
  266 
  267         ncpus = pmc_cpu_max();
  268         error = pmc_tsc_initialize(pmc_mdep, ncpus);
  269         if (error)
  270                 goto error;
  271 
  272         MPASS(nclasses >= PMC_MDEP_CLASS_INDEX_IAF);
  273         error = pmc_core_initialize(pmc_mdep, ncpus, verov);
  274         if (error) {
  275                 pmc_tsc_finalize(pmc_mdep);
  276                 goto error;
  277         }
  278 
  279         /*
  280          * Init the uncore class.
  281          */
  282         switch (cputype) {
  283                 /*
  284                  * Intel Corei7 and Westmere processors.
  285                  */
  286         case PMC_CPU_INTEL_COREI7:
  287         case PMC_CPU_INTEL_WESTMERE:
  288 #ifdef notyet
  289         /*
  290          * TODO: re-enable uncore class on these processors.
  291          *
  292          * The uncore unit was reworked beginning with Sandy Bridge, including
  293          * the MSRs required to program it. In particular, we need to:
  294          *  - Parse the MSR_UNC_CBO_CONFIG MSR for number of C-box units in the
  295          *    system
  296          *  - Support reading and writing to ARB and C-box units, depending on
  297          *    the requested event
  298          *  - Create some kind of mapping between C-box <--> CPU
  299          *
  300          * Also TODO: support other later changes to these interfaces, to
  301          * enable the uncore class on generations newer than Broadwell.
  302          * Skylake+ appears to use newer addresses for the uncore MSRs.
  303          */
  304         case PMC_CPU_INTEL_HASWELL:
  305         case PMC_CPU_INTEL_BROADWELL:
  306         case PMC_CPU_INTEL_SANDYBRIDGE:
  307 #endif
  308                 MPASS(nclasses >= PMC_MDEP_CLASS_INDEX_UCF);
  309                 error = pmc_uncore_initialize(pmc_mdep, ncpus);
  310                 break;
  311         default:
  312                 break;
  313         }
  314   error:
  315         if (error) {
  316                 pmc_mdep_free(pmc_mdep);
  317                 pmc_mdep = NULL;
  318         }
  319 
  320         return (pmc_mdep);
  321 }
  322 
  323 void
  324 pmc_intel_finalize(struct pmc_mdep *md)
  325 {
  326         pmc_tsc_finalize(md);
  327 
  328         pmc_core_finalize(md);
  329 
  330         /*
  331          * Uncore.
  332          */
  333         switch (md->pmd_cputype) {
  334         case PMC_CPU_INTEL_COREI7:
  335         case PMC_CPU_INTEL_WESTMERE:
  336 #ifdef notyet
  337         case PMC_CPU_INTEL_HASWELL:
  338         case PMC_CPU_INTEL_BROADWELL:
  339         case PMC_CPU_INTEL_SANDYBRIDGE:
  340 #endif
  341                 pmc_uncore_finalize(md);
  342                 break;
  343         default:
  344                 break;
  345         }
  346 }

Cache object: 86ea452179ef9420d4c4b5503a1827ca


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.