1 /*- 2 * Copyright (c) 2010 Fabien Thomas 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 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. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 /* 28 * Intel Uncore PMCs. 29 */ 30 31 #include <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include <sys/param.h> 35 #include <sys/bus.h> 36 #include <sys/pmc.h> 37 #include <sys/pmckern.h> 38 #include <sys/systm.h> 39 40 #include <machine/intr_machdep.h> 41 #if (__FreeBSD_version >= 1100000) 42 #include <x86/apicvar.h> 43 #else 44 #include <machine/apicvar.h> 45 #endif 46 #include <machine/cpu.h> 47 #include <machine/cpufunc.h> 48 #include <machine/specialreg.h> 49 50 #define UCF_PMC_CAPS \ 51 (PMC_CAP_READ | PMC_CAP_WRITE) 52 53 #define UCP_PMC_CAPS \ 54 (PMC_CAP_EDGE | PMC_CAP_THRESHOLD | PMC_CAP_READ | PMC_CAP_WRITE | \ 55 PMC_CAP_INVERT | PMC_CAP_QUALIFIER | PMC_CAP_PRECISE) 56 57 #define SELECTSEL(x) \ 58 (((x) == PMC_CPU_INTEL_SANDYBRIDGE || (x) == PMC_CPU_INTEL_HASWELL) ? \ 59 UCP_CB0_EVSEL0 : UCP_EVSEL0) 60 61 #define SELECTOFF(x) \ 62 (((x) == PMC_CPU_INTEL_SANDYBRIDGE || (x) == PMC_CPU_INTEL_HASWELL) ? \ 63 UCF_OFFSET_SB : UCF_OFFSET) 64 65 static enum pmc_cputype uncore_cputype; 66 67 struct uncore_cpu { 68 volatile uint32_t pc_resync; 69 volatile uint32_t pc_ucfctrl; /* Fixed function control. */ 70 volatile uint64_t pc_globalctrl; /* Global control register. */ 71 struct pmc_hw pc_uncorepmcs[]; 72 }; 73 74 static struct uncore_cpu **uncore_pcpu; 75 76 static uint64_t uncore_pmcmask; 77 78 static int uncore_ucf_ri; /* relative index of fixed counters */ 79 static int uncore_ucf_width; 80 static int uncore_ucf_npmc; 81 82 static int uncore_ucp_width; 83 static int uncore_ucp_npmc; 84 85 static int 86 uncore_pcpu_noop(struct pmc_mdep *md, int cpu) 87 { 88 (void) md; 89 (void) cpu; 90 return (0); 91 } 92 93 static int 94 uncore_pcpu_init(struct pmc_mdep *md, int cpu) 95 { 96 struct pmc_cpu *pc; 97 struct uncore_cpu *cc; 98 struct pmc_hw *phw; 99 int uncore_ri, n, npmc; 100 101 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 102 ("[ucf,%d] insane cpu number %d", __LINE__, cpu)); 103 104 PMCDBG1(MDP,INI,1,"uncore-init cpu=%d", cpu); 105 106 uncore_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP].pcd_ri; 107 npmc = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP].pcd_num; 108 npmc += md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCF].pcd_num; 109 110 cc = malloc(sizeof(struct uncore_cpu) + npmc * sizeof(struct pmc_hw), 111 M_PMC, M_WAITOK | M_ZERO); 112 113 uncore_pcpu[cpu] = cc; 114 pc = pmc_pcpu[cpu]; 115 116 KASSERT(pc != NULL && cc != NULL, 117 ("[uncore,%d] NULL per-cpu structures cpu=%d", __LINE__, cpu)); 118 119 for (n = 0, phw = cc->pc_uncorepmcs; n < npmc; n++, phw++) { 120 phw->phw_state = PMC_PHW_FLAG_IS_ENABLED | 121 PMC_PHW_CPU_TO_STATE(cpu) | 122 PMC_PHW_INDEX_TO_STATE(n + uncore_ri); 123 phw->phw_pmc = NULL; 124 pc->pc_hwpmcs[n + uncore_ri] = phw; 125 } 126 127 return (0); 128 } 129 130 static int 131 uncore_pcpu_fini(struct pmc_mdep *md, int cpu) 132 { 133 int uncore_ri, n, npmc; 134 struct pmc_cpu *pc; 135 struct uncore_cpu *cc; 136 137 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 138 ("[uncore,%d] insane cpu number (%d)", __LINE__, cpu)); 139 140 PMCDBG1(MDP,INI,1,"uncore-pcpu-fini cpu=%d", cpu); 141 142 if ((cc = uncore_pcpu[cpu]) == NULL) 143 return (0); 144 145 uncore_pcpu[cpu] = NULL; 146 147 pc = pmc_pcpu[cpu]; 148 149 KASSERT(pc != NULL, ("[uncore,%d] NULL per-cpu %d state", __LINE__, 150 cpu)); 151 152 npmc = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP].pcd_num; 153 uncore_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP].pcd_ri; 154 155 for (n = 0; n < npmc; n++) 156 wrmsr(SELECTSEL(uncore_cputype) + n, 0); 157 158 wrmsr(UCF_CTRL, 0); 159 npmc += md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCF].pcd_num; 160 161 for (n = 0; n < npmc; n++) 162 pc->pc_hwpmcs[n + uncore_ri] = NULL; 163 164 free(cc, M_PMC); 165 166 return (0); 167 } 168 169 /* 170 * Fixed function counters. 171 */ 172 173 static pmc_value_t 174 ucf_perfctr_value_to_reload_count(pmc_value_t v) 175 { 176 v &= (1ULL << uncore_ucf_width) - 1; 177 return (1ULL << uncore_ucf_width) - v; 178 } 179 180 static pmc_value_t 181 ucf_reload_count_to_perfctr_value(pmc_value_t rlc) 182 { 183 return (1ULL << uncore_ucf_width) - rlc; 184 } 185 186 static int 187 ucf_allocate_pmc(int cpu, int ri, struct pmc *pm, 188 const struct pmc_op_pmcallocate *a) 189 { 190 enum pmc_event ev; 191 uint32_t caps, flags; 192 193 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 194 ("[uncore,%d] illegal CPU %d", __LINE__, cpu)); 195 196 PMCDBG2(MDP,ALL,1, "ucf-allocate ri=%d reqcaps=0x%x", ri, pm->pm_caps); 197 198 if (ri < 0 || ri > uncore_ucf_npmc) 199 return (EINVAL); 200 201 caps = a->pm_caps; 202 203 if (a->pm_class != PMC_CLASS_UCF || 204 (caps & UCF_PMC_CAPS) != caps) 205 return (EINVAL); 206 207 ev = pm->pm_event; 208 if (ev < PMC_EV_UCF_FIRST || ev > PMC_EV_UCF_LAST) 209 return (EINVAL); 210 211 flags = UCF_EN; 212 213 pm->pm_md.pm_ucf.pm_ucf_ctrl = (flags << (ri * 4)); 214 215 PMCDBG1(MDP,ALL,2, "ucf-allocate config=0x%jx", 216 (uintmax_t) pm->pm_md.pm_ucf.pm_ucf_ctrl); 217 218 return (0); 219 } 220 221 static int 222 ucf_config_pmc(int cpu, int ri, struct pmc *pm) 223 { 224 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 225 ("[uncore,%d] illegal CPU %d", __LINE__, cpu)); 226 227 KASSERT(ri >= 0 && ri < uncore_ucf_npmc, 228 ("[uncore,%d] illegal row-index %d", __LINE__, ri)); 229 230 PMCDBG3(MDP,CFG,1, "ucf-config cpu=%d ri=%d pm=%p", cpu, ri, pm); 231 232 KASSERT(uncore_pcpu[cpu] != NULL, ("[uncore,%d] null per-cpu %d", __LINE__, 233 cpu)); 234 235 uncore_pcpu[cpu]->pc_uncorepmcs[ri + uncore_ucf_ri].phw_pmc = pm; 236 237 return (0); 238 } 239 240 static int 241 ucf_describe(int cpu, int ri, struct pmc_info *pi, struct pmc **ppmc) 242 { 243 int error; 244 struct pmc_hw *phw; 245 char ucf_name[PMC_NAME_MAX]; 246 247 phw = &uncore_pcpu[cpu]->pc_uncorepmcs[ri + uncore_ucf_ri]; 248 249 (void) snprintf(ucf_name, sizeof(ucf_name), "UCF-%d", ri); 250 if ((error = copystr(ucf_name, pi->pm_name, PMC_NAME_MAX, 251 NULL)) != 0) 252 return (error); 253 254 pi->pm_class = PMC_CLASS_UCF; 255 256 if (phw->phw_state & PMC_PHW_FLAG_IS_ENABLED) { 257 pi->pm_enabled = TRUE; 258 *ppmc = phw->phw_pmc; 259 } else { 260 pi->pm_enabled = FALSE; 261 *ppmc = NULL; 262 } 263 264 return (0); 265 } 266 267 static int 268 ucf_get_config(int cpu, int ri, struct pmc **ppm) 269 { 270 *ppm = uncore_pcpu[cpu]->pc_uncorepmcs[ri + uncore_ucf_ri].phw_pmc; 271 272 return (0); 273 } 274 275 static int 276 ucf_read_pmc(int cpu, int ri, pmc_value_t *v) 277 { 278 struct pmc *pm; 279 pmc_value_t tmp; 280 281 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 282 ("[uncore,%d] illegal cpu value %d", __LINE__, cpu)); 283 KASSERT(ri >= 0 && ri < uncore_ucf_npmc, 284 ("[uncore,%d] illegal row-index %d", __LINE__, ri)); 285 286 pm = uncore_pcpu[cpu]->pc_uncorepmcs[ri + uncore_ucf_ri].phw_pmc; 287 288 KASSERT(pm, 289 ("[uncore,%d] cpu %d ri %d(%d) pmc not configured", __LINE__, cpu, 290 ri, ri + uncore_ucf_ri)); 291 292 tmp = rdmsr(UCF_CTR0 + ri); 293 294 if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) 295 *v = ucf_perfctr_value_to_reload_count(tmp); 296 else 297 *v = tmp; 298 299 PMCDBG3(MDP,REA,1, "ucf-read cpu=%d ri=%d -> v=%jx", cpu, ri, *v); 300 301 return (0); 302 } 303 304 static int 305 ucf_release_pmc(int cpu, int ri, struct pmc *pmc) 306 { 307 PMCDBG3(MDP,REL,1, "ucf-release cpu=%d ri=%d pm=%p", cpu, ri, pmc); 308 309 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 310 ("[uncore,%d] illegal CPU value %d", __LINE__, cpu)); 311 KASSERT(ri >= 0 && ri < uncore_ucf_npmc, 312 ("[uncore,%d] illegal row-index %d", __LINE__, ri)); 313 314 KASSERT(uncore_pcpu[cpu]->pc_uncorepmcs[ri + uncore_ucf_ri].phw_pmc == NULL, 315 ("[uncore,%d] PHW pmc non-NULL", __LINE__)); 316 317 return (0); 318 } 319 320 static int 321 ucf_start_pmc(int cpu, int ri) 322 { 323 struct pmc *pm; 324 struct uncore_cpu *ucfc; 325 326 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 327 ("[uncore,%d] illegal CPU value %d", __LINE__, cpu)); 328 KASSERT(ri >= 0 && ri < uncore_ucf_npmc, 329 ("[uncore,%d] illegal row-index %d", __LINE__, ri)); 330 331 PMCDBG2(MDP,STA,1,"ucf-start cpu=%d ri=%d", cpu, ri); 332 333 ucfc = uncore_pcpu[cpu]; 334 pm = ucfc->pc_uncorepmcs[ri + uncore_ucf_ri].phw_pmc; 335 336 ucfc->pc_ucfctrl |= pm->pm_md.pm_ucf.pm_ucf_ctrl; 337 338 wrmsr(UCF_CTRL, ucfc->pc_ucfctrl); 339 340 do { 341 ucfc->pc_resync = 0; 342 ucfc->pc_globalctrl |= (1ULL << (ri + SELECTOFF(uncore_cputype))); 343 wrmsr(UC_GLOBAL_CTRL, ucfc->pc_globalctrl); 344 } while (ucfc->pc_resync != 0); 345 346 PMCDBG4(MDP,STA,1,"ucfctrl=%x(%x) globalctrl=%jx(%jx)", 347 ucfc->pc_ucfctrl, (uint32_t) rdmsr(UCF_CTRL), 348 ucfc->pc_globalctrl, rdmsr(UC_GLOBAL_CTRL)); 349 350 return (0); 351 } 352 353 static int 354 ucf_stop_pmc(int cpu, int ri) 355 { 356 uint32_t fc; 357 struct uncore_cpu *ucfc; 358 359 PMCDBG2(MDP,STO,1,"ucf-stop cpu=%d ri=%d", cpu, ri); 360 361 ucfc = uncore_pcpu[cpu]; 362 363 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 364 ("[uncore,%d] illegal CPU value %d", __LINE__, cpu)); 365 KASSERT(ri >= 0 && ri < uncore_ucf_npmc, 366 ("[uncore,%d] illegal row-index %d", __LINE__, ri)); 367 368 fc = (UCF_MASK << (ri * 4)); 369 370 ucfc->pc_ucfctrl &= ~fc; 371 372 PMCDBG1(MDP,STO,1,"ucf-stop ucfctrl=%x", ucfc->pc_ucfctrl); 373 wrmsr(UCF_CTRL, ucfc->pc_ucfctrl); 374 375 do { 376 ucfc->pc_resync = 0; 377 ucfc->pc_globalctrl &= ~(1ULL << (ri + SELECTOFF(uncore_cputype))); 378 wrmsr(UC_GLOBAL_CTRL, ucfc->pc_globalctrl); 379 } while (ucfc->pc_resync != 0); 380 381 PMCDBG4(MDP,STO,1,"ucfctrl=%x(%x) globalctrl=%jx(%jx)", 382 ucfc->pc_ucfctrl, (uint32_t) rdmsr(UCF_CTRL), 383 ucfc->pc_globalctrl, rdmsr(UC_GLOBAL_CTRL)); 384 385 return (0); 386 } 387 388 static int 389 ucf_write_pmc(int cpu, int ri, pmc_value_t v) 390 { 391 struct uncore_cpu *cc; 392 struct pmc *pm; 393 394 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 395 ("[uncore,%d] illegal cpu value %d", __LINE__, cpu)); 396 KASSERT(ri >= 0 && ri < uncore_ucf_npmc, 397 ("[uncore,%d] illegal row-index %d", __LINE__, ri)); 398 399 cc = uncore_pcpu[cpu]; 400 pm = cc->pc_uncorepmcs[ri + uncore_ucf_ri].phw_pmc; 401 402 KASSERT(pm, 403 ("[uncore,%d] cpu %d ri %d pmc not configured", __LINE__, cpu, ri)); 404 405 if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) 406 v = ucf_reload_count_to_perfctr_value(v); 407 408 wrmsr(UCF_CTRL, 0); /* Turn off fixed counters */ 409 wrmsr(UCF_CTR0 + ri, v); 410 wrmsr(UCF_CTRL, cc->pc_ucfctrl); 411 412 PMCDBG4(MDP,WRI,1, "ucf-write cpu=%d ri=%d v=%jx ucfctrl=%jx ", 413 cpu, ri, v, (uintmax_t) rdmsr(UCF_CTRL)); 414 415 return (0); 416 } 417 418 419 static void 420 ucf_initialize(struct pmc_mdep *md, int maxcpu, int npmc, int pmcwidth) 421 { 422 struct pmc_classdep *pcd; 423 424 KASSERT(md != NULL, ("[ucf,%d] md is NULL", __LINE__)); 425 426 PMCDBG0(MDP,INI,1, "ucf-initialize"); 427 428 pcd = &md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCF]; 429 430 pcd->pcd_caps = UCF_PMC_CAPS; 431 pcd->pcd_class = PMC_CLASS_UCF; 432 pcd->pcd_num = npmc; 433 pcd->pcd_ri = md->pmd_npmc; 434 pcd->pcd_width = pmcwidth; 435 436 pcd->pcd_allocate_pmc = ucf_allocate_pmc; 437 pcd->pcd_config_pmc = ucf_config_pmc; 438 pcd->pcd_describe = ucf_describe; 439 pcd->pcd_get_config = ucf_get_config; 440 pcd->pcd_get_msr = NULL; 441 pcd->pcd_pcpu_fini = uncore_pcpu_noop; 442 pcd->pcd_pcpu_init = uncore_pcpu_noop; 443 pcd->pcd_read_pmc = ucf_read_pmc; 444 pcd->pcd_release_pmc = ucf_release_pmc; 445 pcd->pcd_start_pmc = ucf_start_pmc; 446 pcd->pcd_stop_pmc = ucf_stop_pmc; 447 pcd->pcd_write_pmc = ucf_write_pmc; 448 449 md->pmd_npmc += npmc; 450 } 451 452 /* 453 * Intel programmable PMCs. 454 */ 455 456 /* 457 * Event descriptor tables. 458 * 459 * For each event id, we track: 460 * 461 * 1. The CPUs that the event is valid for. 462 * 463 * 2. If the event uses a fixed UMASK, the value of the umask field. 464 * If the event doesn't use a fixed UMASK, a mask of legal bits 465 * to check against. 466 */ 467 468 struct ucp_event_descr { 469 enum pmc_event ucp_ev; 470 unsigned char ucp_evcode; 471 unsigned char ucp_umask; 472 unsigned char ucp_flags; 473 }; 474 475 #define UCP_F_I7 (1 << 0) /* CPU: Core i7 */ 476 #define UCP_F_WM (1 << 1) /* CPU: Westmere */ 477 #define UCP_F_SB (1 << 2) /* CPU: Sandy Bridge */ 478 #define UCP_F_HW (1 << 3) /* CPU: Haswell */ 479 #define UCP_F_FM (1 << 4) /* Fixed mask */ 480 481 #define UCP_F_ALLCPUS \ 482 (UCP_F_I7 | UCP_F_WM) 483 484 #define UCP_F_CMASK 0xFF000000 485 486 static struct ucp_event_descr ucp_events[] = { 487 #undef UCPDESCR 488 #define UCPDESCR(N,EV,UM,FLAGS) { \ 489 .ucp_ev = PMC_EV_UCP_EVENT_##N, \ 490 .ucp_evcode = (EV), \ 491 .ucp_umask = (UM), \ 492 .ucp_flags = (FLAGS) \ 493 } 494 495 UCPDESCR(00H_01H, 0x00, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 496 UCPDESCR(00H_02H, 0x00, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 497 UCPDESCR(00H_04H, 0x00, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 498 499 UCPDESCR(01H_01H, 0x01, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 500 UCPDESCR(01H_02H, 0x01, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 501 UCPDESCR(01H_04H, 0x01, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 502 503 UCPDESCR(02H_01H, 0x02, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 504 UCPDESCR(03H_01H, 0x03, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 505 UCPDESCR(03H_02H, 0x03, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 506 UCPDESCR(03H_04H, 0x03, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 507 UCPDESCR(03H_08H, 0x03, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 508 UCPDESCR(03H_10H, 0x03, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 509 UCPDESCR(03H_20H, 0x03, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 510 UCPDESCR(03H_40H, 0x03, 0x40, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 511 512 UCPDESCR(04H_01H, 0x04, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 513 UCPDESCR(04H_02H, 0x04, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 514 UCPDESCR(04H_04H, 0x04, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 515 UCPDESCR(04H_08H, 0x04, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 516 UCPDESCR(04H_10H, 0x04, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 517 518 UCPDESCR(05H_01H, 0x05, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 519 UCPDESCR(05H_02H, 0x05, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 520 UCPDESCR(05H_04H, 0x05, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 521 522 UCPDESCR(06H_01H, 0x06, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 523 UCPDESCR(06H_02H, 0x06, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 524 UCPDESCR(06H_04H, 0x06, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 525 UCPDESCR(06H_08H, 0x06, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 526 UCPDESCR(06H_10H, 0x06, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 527 UCPDESCR(06H_20H, 0x06, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 528 529 UCPDESCR(07H_01H, 0x07, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 530 UCPDESCR(07H_02H, 0x07, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 531 UCPDESCR(07H_04H, 0x07, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 532 UCPDESCR(07H_08H, 0x07, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 533 UCPDESCR(07H_10H, 0x07, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 534 UCPDESCR(07H_20H, 0x07, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 535 UCPDESCR(07H_24H, 0x07, 0x24, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 536 537 UCPDESCR(08H_01H, 0x08, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 538 UCPDESCR(08H_02H, 0x08, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 539 UCPDESCR(08H_04H, 0x08, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 540 UCPDESCR(08H_03H, 0x08, 0x03, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 541 542 UCPDESCR(09H_01H, 0x09, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 543 UCPDESCR(09H_02H, 0x09, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 544 UCPDESCR(09H_04H, 0x09, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 545 UCPDESCR(09H_03H, 0x09, 0x03, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 546 547 UCPDESCR(0AH_01H, 0x0A, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 548 UCPDESCR(0AH_02H, 0x0A, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 549 UCPDESCR(0AH_04H, 0x0A, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 550 UCPDESCR(0AH_08H, 0x0A, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 551 UCPDESCR(0AH_0FH, 0x0A, 0x0F, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 552 553 UCPDESCR(0BH_01H, 0x0B, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 554 UCPDESCR(0BH_02H, 0x0B, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 555 UCPDESCR(0BH_04H, 0x0B, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 556 UCPDESCR(0BH_08H, 0x0B, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 557 UCPDESCR(0BH_10H, 0x0B, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 558 UCPDESCR(0BH_1FH, 0x0B, 0x1F, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 559 560 UCPDESCR(0CH_01H, 0x0C, 0x01, UCP_F_FM | UCP_F_WM), 561 UCPDESCR(0CH_02H, 0x0C, 0x02, UCP_F_FM | UCP_F_WM), 562 UCPDESCR(0CH_04H_E, 0x0C, 0x04, UCP_F_FM | UCP_F_WM), 563 UCPDESCR(0CH_04H_F, 0x0C, 0x04, UCP_F_FM | UCP_F_WM), 564 UCPDESCR(0CH_04H_M, 0x0C, 0x04, UCP_F_FM | UCP_F_WM), 565 UCPDESCR(0CH_04H_S, 0x0C, 0x04, UCP_F_FM | UCP_F_WM), 566 UCPDESCR(0CH_08H_E, 0x0C, 0x08, UCP_F_FM | UCP_F_WM), 567 UCPDESCR(0CH_08H_F, 0x0C, 0x08, UCP_F_FM | UCP_F_WM), 568 UCPDESCR(0CH_08H_M, 0x0C, 0x08, UCP_F_FM | UCP_F_WM), 569 UCPDESCR(0CH_08H_S, 0x0C, 0x08, UCP_F_FM | UCP_F_WM), 570 571 UCPDESCR(20H_01H, 0x20, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 572 UCPDESCR(20H_02H, 0x20, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 573 UCPDESCR(20H_04H, 0x20, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 574 UCPDESCR(20H_08H, 0x20, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 575 UCPDESCR(20H_10H, 0x20, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 576 UCPDESCR(20H_20H, 0x20, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 577 578 UCPDESCR(21H_01H, 0x21, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 579 UCPDESCR(21H_02H, 0x21, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 580 UCPDESCR(21H_04H, 0x21, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 581 582 UCPDESCR(22H_01H, 0x22, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM | 583 UCP_F_SB | UCP_F_HW), 584 UCPDESCR(22H_02H, 0x22, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM | 585 UCP_F_SB | UCP_F_HW), 586 UCPDESCR(22H_04H, 0x22, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM | 587 UCP_F_SB | UCP_F_HW), 588 UCPDESCR(22H_08H, 0x22, 0x08, UCP_F_FM | UCP_F_SB | UCP_F_HW), 589 UCPDESCR(22H_10H, 0x22, 0x10, UCP_F_FM | UCP_F_HW), 590 UCPDESCR(22H_20H, 0x22, 0x20, UCP_F_FM | UCP_F_SB | UCP_F_HW), 591 UCPDESCR(22H_40H, 0x22, 0x40, UCP_F_FM | UCP_F_SB | UCP_F_HW), 592 UCPDESCR(22H_80H, 0x22, 0x80, UCP_F_FM | UCP_F_SB | UCP_F_HW), 593 594 UCPDESCR(23H_01H, 0x23, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 595 UCPDESCR(23H_02H, 0x23, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 596 UCPDESCR(23H_04H, 0x23, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 597 598 UCPDESCR(24H_02H, 0x24, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 599 UCPDESCR(24H_04H, 0x24, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 600 601 UCPDESCR(25H_01H, 0x25, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 602 UCPDESCR(25H_02H, 0x25, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 603 UCPDESCR(25H_04H, 0x25, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 604 605 UCPDESCR(26H_01H, 0x26, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 606 607 UCPDESCR(27H_01H, 0x27, 0x01, UCP_F_FM | UCP_F_I7), 608 UCPDESCR(27H_02H, 0x27, 0x02, UCP_F_FM | UCP_F_I7), 609 UCPDESCR(27H_04H, 0x27, 0x04, UCP_F_FM | UCP_F_I7), 610 UCPDESCR(27H_08H, 0x27, 0x08, UCP_F_FM | UCP_F_I7), 611 UCPDESCR(27H_10H, 0x27, 0x10, UCP_F_FM | UCP_F_I7), 612 UCPDESCR(27H_20H, 0x27, 0x20, UCP_F_FM | UCP_F_I7), 613 614 UCPDESCR(28H_01H, 0x28, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 615 UCPDESCR(28H_02H, 0x28, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 616 UCPDESCR(28H_04H, 0x28, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 617 UCPDESCR(28H_08H, 0x28, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 618 UCPDESCR(28H_10H, 0x28, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 619 UCPDESCR(28H_20H, 0x28, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 620 621 UCPDESCR(29H_01H, 0x29, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 622 UCPDESCR(29H_02H, 0x29, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 623 UCPDESCR(29H_04H, 0x29, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 624 UCPDESCR(29H_08H, 0x29, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 625 UCPDESCR(29H_10H, 0x29, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 626 UCPDESCR(29H_20H, 0x29, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 627 628 UCPDESCR(2AH_01H, 0x2A, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 629 UCPDESCR(2AH_02H, 0x2A, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 630 UCPDESCR(2AH_04H, 0x2A, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 631 UCPDESCR(2AH_07H, 0x2A, 0x07, UCP_F_FM | UCP_F_WM), 632 633 UCPDESCR(2BH_01H, 0x2B, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 634 UCPDESCR(2BH_02H, 0x2B, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 635 UCPDESCR(2BH_04H, 0x2B, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 636 UCPDESCR(2BH_07H, 0x2B, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 637 638 UCPDESCR(2CH_01H, 0x2C, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 639 UCPDESCR(2CH_02H, 0x2C, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 640 UCPDESCR(2CH_04H, 0x2C, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 641 UCPDESCR(2CH_07H, 0x2C, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 642 643 UCPDESCR(2DH_01H, 0x2D, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 644 UCPDESCR(2DH_02H, 0x2D, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 645 UCPDESCR(2DH_04H, 0x2D, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 646 UCPDESCR(2DH_07H, 0x2D, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 647 648 UCPDESCR(2EH_01H, 0x2E, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 649 UCPDESCR(2EH_02H, 0x2E, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 650 UCPDESCR(2EH_04H, 0x2E, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 651 UCPDESCR(2EH_07H, 0x2E, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 652 653 UCPDESCR(2FH_01H, 0x2F, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 654 UCPDESCR(2FH_02H, 0x2F, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 655 UCPDESCR(2FH_04H, 0x2F, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 656 UCPDESCR(2FH_07H, 0x2F, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 657 UCPDESCR(2FH_08H, 0x2F, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 658 UCPDESCR(2FH_10H, 0x2F, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 659 UCPDESCR(2FH_20H, 0x2F, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 660 UCPDESCR(2FH_38H, 0x2F, 0x38, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 661 662 UCPDESCR(30H_01H, 0x30, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 663 UCPDESCR(30H_02H, 0x30, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 664 UCPDESCR(30H_04H, 0x30, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 665 UCPDESCR(30H_07H, 0x30, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 666 667 UCPDESCR(31H_01H, 0x31, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 668 UCPDESCR(31H_02H, 0x31, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 669 UCPDESCR(31H_04H, 0x31, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 670 UCPDESCR(31H_07H, 0x31, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 671 672 UCPDESCR(32H_01H, 0x32, 0x01, UCP_F_FM | UCP_F_WM), 673 UCPDESCR(32H_02H, 0x32, 0x02, UCP_F_FM | UCP_F_WM), 674 UCPDESCR(32H_04H, 0x32, 0x04, UCP_F_FM | UCP_F_WM), 675 UCPDESCR(32H_07H, 0x32, 0x07, UCP_F_FM | UCP_F_WM), 676 677 UCPDESCR(33H_01H, 0x33, 0x01, UCP_F_FM | UCP_F_WM), 678 UCPDESCR(33H_02H, 0x33, 0x02, UCP_F_FM | UCP_F_WM), 679 UCPDESCR(33H_04H, 0x33, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 680 UCPDESCR(33H_07H, 0x33, 0x07, UCP_F_FM | UCP_F_WM), 681 682 UCPDESCR(34H_01H, 0x34, 0x01, UCP_F_FM | UCP_F_WM | UCP_F_SB | 683 UCP_F_HW), 684 UCPDESCR(34H_02H, 0x34, 0x02, UCP_F_FM | UCP_F_WM | UCP_F_SB), 685 UCPDESCR(34H_04H, 0x34, 0x04, UCP_F_FM | UCP_F_WM | UCP_F_SB), 686 UCPDESCR(34H_06H, 0x34, 0x06, UCP_F_FM | UCP_F_HW), 687 UCPDESCR(34H_08H, 0x34, 0x08, UCP_F_FM | UCP_F_WM | UCP_F_SB | 688 UCP_F_HW), 689 UCPDESCR(34H_10H, 0x34, 0x10, UCP_F_FM | UCP_F_WM | UCP_F_SB | 690 UCP_F_HW), 691 UCPDESCR(34H_20H, 0x34, 0x20, UCP_F_FM | UCP_F_WM | UCP_F_SB | 692 UCP_F_HW), 693 UCPDESCR(34H_40H, 0x34, 0x40, UCP_F_FM | UCP_F_SB | UCP_F_HW), 694 UCPDESCR(34H_80H, 0x34, 0x80, UCP_F_FM | UCP_F_SB | UCP_F_HW), 695 696 UCPDESCR(35H_01H, 0x35, 0x01, UCP_F_FM | UCP_F_WM), 697 UCPDESCR(35H_02H, 0x35, 0x02, UCP_F_FM | UCP_F_WM), 698 UCPDESCR(35H_04H, 0x35, 0x04, UCP_F_FM | UCP_F_WM), 699 700 UCPDESCR(40H_01H, 0x40, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 701 UCPDESCR(40H_02H, 0x40, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 702 UCPDESCR(40H_04H, 0x40, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 703 UCPDESCR(40H_08H, 0x40, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 704 UCPDESCR(40H_10H, 0x40, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 705 UCPDESCR(40H_20H, 0x40, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 706 UCPDESCR(40H_07H, 0x40, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 707 UCPDESCR(40H_38H, 0x40, 0x38, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 708 709 UCPDESCR(41H_01H, 0x41, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 710 UCPDESCR(41H_02H, 0x41, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 711 UCPDESCR(41H_04H, 0x41, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 712 UCPDESCR(41H_08H, 0x41, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 713 UCPDESCR(41H_10H, 0x41, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 714 UCPDESCR(41H_20H, 0x41, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 715 UCPDESCR(41H_07H, 0x41, 0x07, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 716 UCPDESCR(41H_38H, 0x41, 0x38, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 717 718 UCPDESCR(42H_01H, 0x42, 0x01, UCP_F_FM | UCP_F_WM), 719 UCPDESCR(42H_02H, 0x42, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 720 UCPDESCR(42H_04H, 0x42, 0x04, UCP_F_FM | UCP_F_WM), 721 UCPDESCR(42H_08H, 0x42, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 722 723 UCPDESCR(43H_01H, 0x43, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 724 UCPDESCR(43H_02H, 0x43, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 725 726 UCPDESCR(60H_01H, 0x60, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 727 UCPDESCR(60H_02H, 0x60, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 728 UCPDESCR(60H_04H, 0x60, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 729 730 UCPDESCR(61H_01H, 0x61, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 731 UCPDESCR(61H_02H, 0x61, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 732 UCPDESCR(61H_04H, 0x61, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 733 734 UCPDESCR(62H_01H, 0x62, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 735 UCPDESCR(62H_02H, 0x62, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 736 UCPDESCR(62H_04H, 0x62, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 737 738 UCPDESCR(63H_01H, 0x63, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 739 UCPDESCR(63H_02H, 0x63, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 740 UCPDESCR(63H_04H, 0x63, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 741 UCPDESCR(63H_08H, 0x63, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 742 UCPDESCR(63H_10H, 0x63, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 743 UCPDESCR(63H_20H, 0x63, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 744 745 UCPDESCR(64H_01H, 0x64, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 746 UCPDESCR(64H_02H, 0x64, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 747 UCPDESCR(64H_04H, 0x64, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 748 UCPDESCR(64H_08H, 0x64, 0x08, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 749 UCPDESCR(64H_10H, 0x64, 0x10, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 750 UCPDESCR(64H_20H, 0x64, 0x20, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 751 752 UCPDESCR(65H_01H, 0x65, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 753 UCPDESCR(65H_02H, 0x65, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 754 UCPDESCR(65H_04H, 0x65, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 755 756 UCPDESCR(66H_01H, 0x66, 0x01, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 757 UCPDESCR(66H_02H, 0x66, 0x02, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 758 UCPDESCR(66H_04H, 0x66, 0x04, UCP_F_FM | UCP_F_I7 | UCP_F_WM), 759 760 UCPDESCR(67H_01H, 0x67, 0x01, UCP_F_FM | UCP_F_WM), 761 762 UCPDESCR(80H_01H, 0x80, 0x01, UCP_F_FM | UCP_F_WM | UCP_F_SB | 763 UCP_F_HW), 764 UCPDESCR(80H_02H, 0x80, 0x02, UCP_F_FM | UCP_F_WM), 765 UCPDESCR(80H_04H, 0x80, 0x04, UCP_F_FM | UCP_F_WM), 766 UCPDESCR(80H_08H, 0x80, 0x08, UCP_F_FM | UCP_F_WM), 767 768 UCPDESCR(81H_01H, 0x81, 0x01, UCP_F_FM | UCP_F_WM | UCP_F_SB | 769 UCP_F_HW), 770 UCPDESCR(81H_02H, 0x81, 0x02, UCP_F_FM | UCP_F_WM), 771 UCPDESCR(81H_04H, 0x81, 0x04, UCP_F_FM | UCP_F_WM), 772 UCPDESCR(81H_08H, 0x81, 0x08, UCP_F_FM | UCP_F_WM), 773 UCPDESCR(81H_20H, 0x81, 0x20, UCP_F_FM | UCP_F_SB | UCP_F_HW), 774 UCPDESCR(81H_80H, 0x81, 0x80, UCP_F_FM | UCP_F_SB | UCP_F_HW), 775 776 UCPDESCR(82H_01H, 0x82, 0x01, UCP_F_FM | UCP_F_WM), 777 778 UCPDESCR(83H_01H, 0x83, 0x01, UCP_F_FM | UCP_F_WM | UCP_F_SB | 779 UCP_F_HW), 780 UCPDESCR(83H_02H, 0x83, 0x02, UCP_F_FM | UCP_F_WM), 781 UCPDESCR(83H_04H, 0x83, 0x04, UCP_F_FM | UCP_F_WM), 782 UCPDESCR(83H_08H, 0x83, 0x08, UCP_F_FM | UCP_F_WM), 783 784 UCPDESCR(84H_01H, 0x84, 0x01, UCP_F_FM | UCP_F_WM | UCP_F_SB | 785 UCP_F_HW), 786 UCPDESCR(84H_02H, 0x84, 0x02, UCP_F_FM | UCP_F_WM), 787 UCPDESCR(84H_04H, 0x84, 0x04, UCP_F_FM | UCP_F_WM), 788 UCPDESCR(84H_08H, 0x84, 0x08, UCP_F_FM | UCP_F_WM), 789 UCPDESCR(85H_02H, 0x85, 0x02, UCP_F_FM | UCP_F_WM), 790 UCPDESCR(86H_01H, 0x86, 0x01, UCP_F_FM | UCP_F_WM) 791 }; 792 793 static const int nucp_events = sizeof(ucp_events) / sizeof(ucp_events[0]); 794 795 static pmc_value_t 796 ucp_perfctr_value_to_reload_count(pmc_value_t v) 797 { 798 v &= (1ULL << uncore_ucp_width) - 1; 799 return (1ULL << uncore_ucp_width) - v; 800 } 801 802 static pmc_value_t 803 ucp_reload_count_to_perfctr_value(pmc_value_t rlc) 804 { 805 return (1ULL << uncore_ucp_width) - rlc; 806 } 807 808 /* 809 * Counter specific event information for Sandybridge and Haswell 810 */ 811 static int 812 ucp_event_sb_hw_ok_on_counter(enum pmc_event pe, int ri) 813 { 814 uint32_t mask; 815 816 switch (pe) { 817 /* 818 * Events valid only on counter 0. 819 */ 820 case PMC_EV_UCP_EVENT_80H_01H: 821 case PMC_EV_UCP_EVENT_83H_01H: 822 mask = (1 << 0); 823 break; 824 825 default: 826 mask = ~0; /* Any row index is ok. */ 827 } 828 829 return (mask & (1 << ri)); 830 } 831 832 static int 833 ucp_allocate_pmc(int cpu, int ri, struct pmc *pm, 834 const struct pmc_op_pmcallocate *a) 835 { 836 int n; 837 enum pmc_event ev; 838 struct ucp_event_descr *ie; 839 uint32_t caps, config, cpuflag, evsel; 840 841 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 842 ("[uncore,%d] illegal CPU %d", __LINE__, cpu)); 843 KASSERT(ri >= 0 && ri < uncore_ucp_npmc, 844 ("[uncore,%d] illegal row-index value %d", __LINE__, ri)); 845 846 /* check requested capabilities */ 847 caps = a->pm_caps; 848 if ((UCP_PMC_CAPS & caps) != caps) 849 return (EPERM); 850 851 ev = pm->pm_event; 852 853 switch (uncore_cputype) { 854 case PMC_CPU_INTEL_HASWELL: 855 case PMC_CPU_INTEL_SANDYBRIDGE: 856 if (ucp_event_sb_hw_ok_on_counter(ev, ri) == 0) 857 return (EINVAL); 858 break; 859 default: 860 break; 861 } 862 863 864 /* 865 * Look for an event descriptor with matching CPU and event id 866 * fields. 867 */ 868 869 switch (uncore_cputype) { 870 case PMC_CPU_INTEL_COREI7: 871 cpuflag = UCP_F_I7; 872 break; 873 case PMC_CPU_INTEL_HASWELL: 874 cpuflag = UCP_F_HW; 875 break; 876 case PMC_CPU_INTEL_SANDYBRIDGE: 877 cpuflag = UCP_F_SB; 878 break; 879 case PMC_CPU_INTEL_WESTMERE: 880 cpuflag = UCP_F_WM; 881 break; 882 default: 883 return (EINVAL); 884 } 885 886 for (n = 0, ie = ucp_events; n < nucp_events; n++, ie++) 887 if (ie->ucp_ev == ev && ie->ucp_flags & cpuflag) 888 break; 889 890 if (n == nucp_events) 891 return (EINVAL); 892 893 /* 894 * A matching event descriptor has been found, so start 895 * assembling the contents of the event select register. 896 */ 897 evsel = ie->ucp_evcode | UCP_EN; 898 899 config = a->pm_md.pm_ucp.pm_ucp_config & ~UCP_F_CMASK; 900 901 /* 902 * If the event uses a fixed umask value, reject any umask 903 * bits set by the user. 904 */ 905 if (ie->ucp_flags & UCP_F_FM) { 906 907 if (UCP_UMASK(config) != 0) 908 return (EINVAL); 909 910 evsel |= (ie->ucp_umask << 8); 911 912 } else 913 return (EINVAL); 914 915 if (caps & PMC_CAP_THRESHOLD) 916 evsel |= (a->pm_md.pm_ucp.pm_ucp_config & UCP_F_CMASK); 917 if (caps & PMC_CAP_EDGE) 918 evsel |= UCP_EDGE; 919 if (caps & PMC_CAP_INVERT) 920 evsel |= UCP_INV; 921 922 pm->pm_md.pm_ucp.pm_ucp_evsel = evsel; 923 924 return (0); 925 } 926 927 static int 928 ucp_config_pmc(int cpu, int ri, struct pmc *pm) 929 { 930 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 931 ("[uncore,%d] illegal CPU %d", __LINE__, cpu)); 932 933 KASSERT(ri >= 0 && ri < uncore_ucp_npmc, 934 ("[uncore,%d] illegal row-index %d", __LINE__, ri)); 935 936 PMCDBG3(MDP,CFG,1, "ucp-config cpu=%d ri=%d pm=%p", cpu, ri, pm); 937 938 KASSERT(uncore_pcpu[cpu] != NULL, ("[uncore,%d] null per-cpu %d", __LINE__, 939 cpu)); 940 941 uncore_pcpu[cpu]->pc_uncorepmcs[ri].phw_pmc = pm; 942 943 return (0); 944 } 945 946 static int 947 ucp_describe(int cpu, int ri, struct pmc_info *pi, struct pmc **ppmc) 948 { 949 int error; 950 struct pmc_hw *phw; 951 char ucp_name[PMC_NAME_MAX]; 952 953 phw = &uncore_pcpu[cpu]->pc_uncorepmcs[ri]; 954 955 (void) snprintf(ucp_name, sizeof(ucp_name), "UCP-%d", ri); 956 if ((error = copystr(ucp_name, pi->pm_name, PMC_NAME_MAX, 957 NULL)) != 0) 958 return (error); 959 960 pi->pm_class = PMC_CLASS_UCP; 961 962 if (phw->phw_state & PMC_PHW_FLAG_IS_ENABLED) { 963 pi->pm_enabled = TRUE; 964 *ppmc = phw->phw_pmc; 965 } else { 966 pi->pm_enabled = FALSE; 967 *ppmc = NULL; 968 } 969 970 return (0); 971 } 972 973 static int 974 ucp_get_config(int cpu, int ri, struct pmc **ppm) 975 { 976 *ppm = uncore_pcpu[cpu]->pc_uncorepmcs[ri].phw_pmc; 977 978 return (0); 979 } 980 981 static int 982 ucp_read_pmc(int cpu, int ri, pmc_value_t *v) 983 { 984 struct pmc *pm; 985 pmc_value_t tmp; 986 987 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 988 ("[uncore,%d] illegal cpu value %d", __LINE__, cpu)); 989 KASSERT(ri >= 0 && ri < uncore_ucp_npmc, 990 ("[uncore,%d] illegal row-index %d", __LINE__, ri)); 991 992 pm = uncore_pcpu[cpu]->pc_uncorepmcs[ri].phw_pmc; 993 994 KASSERT(pm, 995 ("[uncore,%d] cpu %d ri %d pmc not configured", __LINE__, cpu, 996 ri)); 997 998 tmp = rdmsr(UCP_PMC0 + ri); 999 if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) 1000 *v = ucp_perfctr_value_to_reload_count(tmp); 1001 else 1002 *v = tmp; 1003 1004 PMCDBG4(MDP,REA,1, "ucp-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri, 1005 ri, *v); 1006 1007 return (0); 1008 } 1009 1010 static int 1011 ucp_release_pmc(int cpu, int ri, struct pmc *pm) 1012 { 1013 (void) pm; 1014 1015 PMCDBG3(MDP,REL,1, "ucp-release cpu=%d ri=%d pm=%p", cpu, ri, 1016 pm); 1017 1018 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 1019 ("[uncore,%d] illegal CPU value %d", __LINE__, cpu)); 1020 KASSERT(ri >= 0 && ri < uncore_ucp_npmc, 1021 ("[uncore,%d] illegal row-index %d", __LINE__, ri)); 1022 1023 KASSERT(uncore_pcpu[cpu]->pc_uncorepmcs[ri].phw_pmc 1024 == NULL, ("[uncore,%d] PHW pmc non-NULL", __LINE__)); 1025 1026 return (0); 1027 } 1028 1029 static int 1030 ucp_start_pmc(int cpu, int ri) 1031 { 1032 struct pmc *pm; 1033 uint32_t evsel; 1034 struct uncore_cpu *cc; 1035 1036 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 1037 ("[uncore,%d] illegal CPU value %d", __LINE__, cpu)); 1038 KASSERT(ri >= 0 && ri < uncore_ucp_npmc, 1039 ("[uncore,%d] illegal row-index %d", __LINE__, ri)); 1040 1041 cc = uncore_pcpu[cpu]; 1042 pm = cc->pc_uncorepmcs[ri].phw_pmc; 1043 1044 KASSERT(pm, 1045 ("[uncore,%d] starting cpu%d,ri%d with no pmc configured", 1046 __LINE__, cpu, ri)); 1047 1048 PMCDBG2(MDP,STA,1, "ucp-start cpu=%d ri=%d", cpu, ri); 1049 1050 evsel = pm->pm_md.pm_ucp.pm_ucp_evsel; 1051 1052 PMCDBG4(MDP,STA,2, 1053 "ucp-start/2 cpu=%d ri=%d evselmsr=0x%x evsel=0x%x", 1054 cpu, ri, SELECTSEL(uncore_cputype) + ri, evsel); 1055 1056 /* Event specific configuration. */ 1057 switch (pm->pm_event) { 1058 case PMC_EV_UCP_EVENT_0CH_04H_E: 1059 case PMC_EV_UCP_EVENT_0CH_08H_E: 1060 wrmsr(MSR_GQ_SNOOP_MESF,0x2); 1061 break; 1062 case PMC_EV_UCP_EVENT_0CH_04H_F: 1063 case PMC_EV_UCP_EVENT_0CH_08H_F: 1064 wrmsr(MSR_GQ_SNOOP_MESF,0x8); 1065 break; 1066 case PMC_EV_UCP_EVENT_0CH_04H_M: 1067 case PMC_EV_UCP_EVENT_0CH_08H_M: 1068 wrmsr(MSR_GQ_SNOOP_MESF,0x1); 1069 break; 1070 case PMC_EV_UCP_EVENT_0CH_04H_S: 1071 case PMC_EV_UCP_EVENT_0CH_08H_S: 1072 wrmsr(MSR_GQ_SNOOP_MESF,0x4); 1073 break; 1074 default: 1075 break; 1076 } 1077 1078 wrmsr(SELECTSEL(uncore_cputype) + ri, evsel); 1079 1080 do { 1081 cc->pc_resync = 0; 1082 cc->pc_globalctrl |= (1ULL << ri); 1083 wrmsr(UC_GLOBAL_CTRL, cc->pc_globalctrl); 1084 } while (cc->pc_resync != 0); 1085 1086 return (0); 1087 } 1088 1089 static int 1090 ucp_stop_pmc(int cpu, int ri) 1091 { 1092 struct pmc *pm; 1093 struct uncore_cpu *cc; 1094 1095 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 1096 ("[uncore,%d] illegal cpu value %d", __LINE__, cpu)); 1097 KASSERT(ri >= 0 && ri < uncore_ucp_npmc, 1098 ("[uncore,%d] illegal row index %d", __LINE__, ri)); 1099 1100 cc = uncore_pcpu[cpu]; 1101 pm = cc->pc_uncorepmcs[ri].phw_pmc; 1102 1103 KASSERT(pm, 1104 ("[uncore,%d] cpu%d ri%d no configured PMC to stop", __LINE__, 1105 cpu, ri)); 1106 1107 PMCDBG2(MDP,STO,1, "ucp-stop cpu=%d ri=%d", cpu, ri); 1108 1109 /* stop hw. */ 1110 wrmsr(SELECTSEL(uncore_cputype) + ri, 0); 1111 1112 do { 1113 cc->pc_resync = 0; 1114 cc->pc_globalctrl &= ~(1ULL << ri); 1115 wrmsr(UC_GLOBAL_CTRL, cc->pc_globalctrl); 1116 } while (cc->pc_resync != 0); 1117 1118 return (0); 1119 } 1120 1121 static int 1122 ucp_write_pmc(int cpu, int ri, pmc_value_t v) 1123 { 1124 struct pmc *pm; 1125 struct uncore_cpu *cc; 1126 1127 KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), 1128 ("[uncore,%d] illegal cpu value %d", __LINE__, cpu)); 1129 KASSERT(ri >= 0 && ri < uncore_ucp_npmc, 1130 ("[uncore,%d] illegal row index %d", __LINE__, ri)); 1131 1132 cc = uncore_pcpu[cpu]; 1133 pm = cc->pc_uncorepmcs[ri].phw_pmc; 1134 1135 KASSERT(pm, 1136 ("[uncore,%d] cpu%d ri%d no configured PMC to stop", __LINE__, 1137 cpu, ri)); 1138 1139 PMCDBG4(MDP,WRI,1, "ucp-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri, 1140 UCP_PMC0 + ri, v); 1141 1142 if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) 1143 v = ucp_reload_count_to_perfctr_value(v); 1144 1145 /* 1146 * Write the new value to the counter. The counter will be in 1147 * a stopped state when the pcd_write() entry point is called. 1148 */ 1149 1150 wrmsr(UCP_PMC0 + ri, v); 1151 1152 return (0); 1153 } 1154 1155 1156 static void 1157 ucp_initialize(struct pmc_mdep *md, int maxcpu, int npmc, int pmcwidth) 1158 { 1159 struct pmc_classdep *pcd; 1160 1161 KASSERT(md != NULL, ("[ucp,%d] md is NULL", __LINE__)); 1162 1163 PMCDBG0(MDP,INI,1, "ucp-initialize"); 1164 1165 pcd = &md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP]; 1166 1167 pcd->pcd_caps = UCP_PMC_CAPS; 1168 pcd->pcd_class = PMC_CLASS_UCP; 1169 pcd->pcd_num = npmc; 1170 pcd->pcd_ri = md->pmd_npmc; 1171 pcd->pcd_width = pmcwidth; 1172 1173 pcd->pcd_allocate_pmc = ucp_allocate_pmc; 1174 pcd->pcd_config_pmc = ucp_config_pmc; 1175 pcd->pcd_describe = ucp_describe; 1176 pcd->pcd_get_config = ucp_get_config; 1177 pcd->pcd_get_msr = NULL; 1178 pcd->pcd_pcpu_fini = uncore_pcpu_fini; 1179 pcd->pcd_pcpu_init = uncore_pcpu_init; 1180 pcd->pcd_read_pmc = ucp_read_pmc; 1181 pcd->pcd_release_pmc = ucp_release_pmc; 1182 pcd->pcd_start_pmc = ucp_start_pmc; 1183 pcd->pcd_stop_pmc = ucp_stop_pmc; 1184 pcd->pcd_write_pmc = ucp_write_pmc; 1185 1186 md->pmd_npmc += npmc; 1187 } 1188 1189 int 1190 pmc_uncore_initialize(struct pmc_mdep *md, int maxcpu) 1191 { 1192 uncore_cputype = md->pmd_cputype; 1193 uncore_pmcmask = 0; 1194 1195 /* 1196 * Initialize programmable counters. 1197 */ 1198 1199 uncore_ucp_npmc = 8; 1200 uncore_ucp_width = 48; 1201 1202 uncore_pmcmask |= ((1ULL << uncore_ucp_npmc) - 1); 1203 1204 ucp_initialize(md, maxcpu, uncore_ucp_npmc, uncore_ucp_width); 1205 1206 /* 1207 * Initialize fixed function counters, if present. 1208 */ 1209 uncore_ucf_ri = uncore_ucp_npmc; 1210 uncore_ucf_npmc = 1; 1211 uncore_ucf_width = 48; 1212 1213 ucf_initialize(md, maxcpu, uncore_ucf_npmc, uncore_ucf_width); 1214 uncore_pmcmask |= ((1ULL << uncore_ucf_npmc) - 1) << SELECTOFF(uncore_cputype); 1215 1216 PMCDBG2(MDP,INI,1,"uncore-init pmcmask=0x%jx ucfri=%d", uncore_pmcmask, 1217 uncore_ucf_ri); 1218 1219 uncore_pcpu = malloc(sizeof(*uncore_pcpu) * maxcpu, M_PMC, 1220 M_ZERO | M_WAITOK); 1221 1222 return (0); 1223 } 1224 1225 void 1226 pmc_uncore_finalize(struct pmc_mdep *md) 1227 { 1228 PMCDBG0(MDP,INI,1, "uncore-finalize"); 1229 1230 free(uncore_pcpu, M_PMC); 1231 uncore_pcpu = NULL; 1232 } 1233