18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Freescale Embedded oprofile support, based on ppc64 oprofile support 48c2ecf20Sopenharmony_ci * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Copyright (c) 2004, 2010 Freescale Semiconductor, Inc 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Author: Andy Fleming 98c2ecf20Sopenharmony_ci * Maintainer: Kumar Gala <galak@kernel.crashing.org> 108c2ecf20Sopenharmony_ci */ 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <linux/oprofile.h> 138c2ecf20Sopenharmony_ci#include <linux/smp.h> 148c2ecf20Sopenharmony_ci#include <asm/ptrace.h> 158c2ecf20Sopenharmony_ci#include <asm/processor.h> 168c2ecf20Sopenharmony_ci#include <asm/cputable.h> 178c2ecf20Sopenharmony_ci#include <asm/reg_fsl_emb.h> 188c2ecf20Sopenharmony_ci#include <asm/page.h> 198c2ecf20Sopenharmony_ci#include <asm/pmc.h> 208c2ecf20Sopenharmony_ci#include <asm/oprofile_impl.h> 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistatic unsigned long reset_value[OP_MAX_COUNTER]; 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_cistatic int num_counters; 258c2ecf20Sopenharmony_cistatic int oprofile_running; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_cistatic inline u32 get_pmlca(int ctr) 288c2ecf20Sopenharmony_ci{ 298c2ecf20Sopenharmony_ci u32 pmlca; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci switch (ctr) { 328c2ecf20Sopenharmony_ci case 0: 338c2ecf20Sopenharmony_ci pmlca = mfpmr(PMRN_PMLCA0); 348c2ecf20Sopenharmony_ci break; 358c2ecf20Sopenharmony_ci case 1: 368c2ecf20Sopenharmony_ci pmlca = mfpmr(PMRN_PMLCA1); 378c2ecf20Sopenharmony_ci break; 388c2ecf20Sopenharmony_ci case 2: 398c2ecf20Sopenharmony_ci pmlca = mfpmr(PMRN_PMLCA2); 408c2ecf20Sopenharmony_ci break; 418c2ecf20Sopenharmony_ci case 3: 428c2ecf20Sopenharmony_ci pmlca = mfpmr(PMRN_PMLCA3); 438c2ecf20Sopenharmony_ci break; 448c2ecf20Sopenharmony_ci case 4: 458c2ecf20Sopenharmony_ci pmlca = mfpmr(PMRN_PMLCA4); 468c2ecf20Sopenharmony_ci break; 478c2ecf20Sopenharmony_ci case 5: 488c2ecf20Sopenharmony_ci pmlca = mfpmr(PMRN_PMLCA5); 498c2ecf20Sopenharmony_ci break; 508c2ecf20Sopenharmony_ci default: 518c2ecf20Sopenharmony_ci panic("Bad ctr number\n"); 528c2ecf20Sopenharmony_ci } 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci return pmlca; 558c2ecf20Sopenharmony_ci} 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_cistatic inline void set_pmlca(int ctr, u32 pmlca) 588c2ecf20Sopenharmony_ci{ 598c2ecf20Sopenharmony_ci switch (ctr) { 608c2ecf20Sopenharmony_ci case 0: 618c2ecf20Sopenharmony_ci mtpmr(PMRN_PMLCA0, pmlca); 628c2ecf20Sopenharmony_ci break; 638c2ecf20Sopenharmony_ci case 1: 648c2ecf20Sopenharmony_ci mtpmr(PMRN_PMLCA1, pmlca); 658c2ecf20Sopenharmony_ci break; 668c2ecf20Sopenharmony_ci case 2: 678c2ecf20Sopenharmony_ci mtpmr(PMRN_PMLCA2, pmlca); 688c2ecf20Sopenharmony_ci break; 698c2ecf20Sopenharmony_ci case 3: 708c2ecf20Sopenharmony_ci mtpmr(PMRN_PMLCA3, pmlca); 718c2ecf20Sopenharmony_ci break; 728c2ecf20Sopenharmony_ci case 4: 738c2ecf20Sopenharmony_ci mtpmr(PMRN_PMLCA4, pmlca); 748c2ecf20Sopenharmony_ci break; 758c2ecf20Sopenharmony_ci case 5: 768c2ecf20Sopenharmony_ci mtpmr(PMRN_PMLCA5, pmlca); 778c2ecf20Sopenharmony_ci break; 788c2ecf20Sopenharmony_ci default: 798c2ecf20Sopenharmony_ci panic("Bad ctr number\n"); 808c2ecf20Sopenharmony_ci } 818c2ecf20Sopenharmony_ci} 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_cistatic inline unsigned int ctr_read(unsigned int i) 848c2ecf20Sopenharmony_ci{ 858c2ecf20Sopenharmony_ci switch(i) { 868c2ecf20Sopenharmony_ci case 0: 878c2ecf20Sopenharmony_ci return mfpmr(PMRN_PMC0); 888c2ecf20Sopenharmony_ci case 1: 898c2ecf20Sopenharmony_ci return mfpmr(PMRN_PMC1); 908c2ecf20Sopenharmony_ci case 2: 918c2ecf20Sopenharmony_ci return mfpmr(PMRN_PMC2); 928c2ecf20Sopenharmony_ci case 3: 938c2ecf20Sopenharmony_ci return mfpmr(PMRN_PMC3); 948c2ecf20Sopenharmony_ci case 4: 958c2ecf20Sopenharmony_ci return mfpmr(PMRN_PMC4); 968c2ecf20Sopenharmony_ci case 5: 978c2ecf20Sopenharmony_ci return mfpmr(PMRN_PMC5); 988c2ecf20Sopenharmony_ci default: 998c2ecf20Sopenharmony_ci return 0; 1008c2ecf20Sopenharmony_ci } 1018c2ecf20Sopenharmony_ci} 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_cistatic inline void ctr_write(unsigned int i, unsigned int val) 1048c2ecf20Sopenharmony_ci{ 1058c2ecf20Sopenharmony_ci switch(i) { 1068c2ecf20Sopenharmony_ci case 0: 1078c2ecf20Sopenharmony_ci mtpmr(PMRN_PMC0, val); 1088c2ecf20Sopenharmony_ci break; 1098c2ecf20Sopenharmony_ci case 1: 1108c2ecf20Sopenharmony_ci mtpmr(PMRN_PMC1, val); 1118c2ecf20Sopenharmony_ci break; 1128c2ecf20Sopenharmony_ci case 2: 1138c2ecf20Sopenharmony_ci mtpmr(PMRN_PMC2, val); 1148c2ecf20Sopenharmony_ci break; 1158c2ecf20Sopenharmony_ci case 3: 1168c2ecf20Sopenharmony_ci mtpmr(PMRN_PMC3, val); 1178c2ecf20Sopenharmony_ci break; 1188c2ecf20Sopenharmony_ci case 4: 1198c2ecf20Sopenharmony_ci mtpmr(PMRN_PMC4, val); 1208c2ecf20Sopenharmony_ci break; 1218c2ecf20Sopenharmony_ci case 5: 1228c2ecf20Sopenharmony_ci mtpmr(PMRN_PMC5, val); 1238c2ecf20Sopenharmony_ci break; 1248c2ecf20Sopenharmony_ci default: 1258c2ecf20Sopenharmony_ci break; 1268c2ecf20Sopenharmony_ci } 1278c2ecf20Sopenharmony_ci} 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_cistatic void init_pmc_stop(int ctr) 1318c2ecf20Sopenharmony_ci{ 1328c2ecf20Sopenharmony_ci u32 pmlca = (PMLCA_FC | PMLCA_FCS | PMLCA_FCU | 1338c2ecf20Sopenharmony_ci PMLCA_FCM1 | PMLCA_FCM0); 1348c2ecf20Sopenharmony_ci u32 pmlcb = 0; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci switch (ctr) { 1378c2ecf20Sopenharmony_ci case 0: 1388c2ecf20Sopenharmony_ci mtpmr(PMRN_PMLCA0, pmlca); 1398c2ecf20Sopenharmony_ci mtpmr(PMRN_PMLCB0, pmlcb); 1408c2ecf20Sopenharmony_ci break; 1418c2ecf20Sopenharmony_ci case 1: 1428c2ecf20Sopenharmony_ci mtpmr(PMRN_PMLCA1, pmlca); 1438c2ecf20Sopenharmony_ci mtpmr(PMRN_PMLCB1, pmlcb); 1448c2ecf20Sopenharmony_ci break; 1458c2ecf20Sopenharmony_ci case 2: 1468c2ecf20Sopenharmony_ci mtpmr(PMRN_PMLCA2, pmlca); 1478c2ecf20Sopenharmony_ci mtpmr(PMRN_PMLCB2, pmlcb); 1488c2ecf20Sopenharmony_ci break; 1498c2ecf20Sopenharmony_ci case 3: 1508c2ecf20Sopenharmony_ci mtpmr(PMRN_PMLCA3, pmlca); 1518c2ecf20Sopenharmony_ci mtpmr(PMRN_PMLCB3, pmlcb); 1528c2ecf20Sopenharmony_ci break; 1538c2ecf20Sopenharmony_ci case 4: 1548c2ecf20Sopenharmony_ci mtpmr(PMRN_PMLCA4, pmlca); 1558c2ecf20Sopenharmony_ci mtpmr(PMRN_PMLCB4, pmlcb); 1568c2ecf20Sopenharmony_ci break; 1578c2ecf20Sopenharmony_ci case 5: 1588c2ecf20Sopenharmony_ci mtpmr(PMRN_PMLCA5, pmlca); 1598c2ecf20Sopenharmony_ci mtpmr(PMRN_PMLCB5, pmlcb); 1608c2ecf20Sopenharmony_ci break; 1618c2ecf20Sopenharmony_ci default: 1628c2ecf20Sopenharmony_ci panic("Bad ctr number!\n"); 1638c2ecf20Sopenharmony_ci } 1648c2ecf20Sopenharmony_ci} 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_cistatic void set_pmc_event(int ctr, int event) 1678c2ecf20Sopenharmony_ci{ 1688c2ecf20Sopenharmony_ci u32 pmlca; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci pmlca = get_pmlca(ctr); 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci pmlca = (pmlca & ~PMLCA_EVENT_MASK) | 1738c2ecf20Sopenharmony_ci ((event << PMLCA_EVENT_SHIFT) & 1748c2ecf20Sopenharmony_ci PMLCA_EVENT_MASK); 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci set_pmlca(ctr, pmlca); 1778c2ecf20Sopenharmony_ci} 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_cistatic void set_pmc_user_kernel(int ctr, int user, int kernel) 1808c2ecf20Sopenharmony_ci{ 1818c2ecf20Sopenharmony_ci u32 pmlca; 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci pmlca = get_pmlca(ctr); 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci if(user) 1868c2ecf20Sopenharmony_ci pmlca &= ~PMLCA_FCU; 1878c2ecf20Sopenharmony_ci else 1888c2ecf20Sopenharmony_ci pmlca |= PMLCA_FCU; 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci if(kernel) 1918c2ecf20Sopenharmony_ci pmlca &= ~PMLCA_FCS; 1928c2ecf20Sopenharmony_ci else 1938c2ecf20Sopenharmony_ci pmlca |= PMLCA_FCS; 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci set_pmlca(ctr, pmlca); 1968c2ecf20Sopenharmony_ci} 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_cistatic void set_pmc_marked(int ctr, int mark0, int mark1) 1998c2ecf20Sopenharmony_ci{ 2008c2ecf20Sopenharmony_ci u32 pmlca = get_pmlca(ctr); 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci if(mark0) 2038c2ecf20Sopenharmony_ci pmlca &= ~PMLCA_FCM0; 2048c2ecf20Sopenharmony_ci else 2058c2ecf20Sopenharmony_ci pmlca |= PMLCA_FCM0; 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci if(mark1) 2088c2ecf20Sopenharmony_ci pmlca &= ~PMLCA_FCM1; 2098c2ecf20Sopenharmony_ci else 2108c2ecf20Sopenharmony_ci pmlca |= PMLCA_FCM1; 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci set_pmlca(ctr, pmlca); 2138c2ecf20Sopenharmony_ci} 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_cistatic void pmc_start_ctr(int ctr, int enable) 2168c2ecf20Sopenharmony_ci{ 2178c2ecf20Sopenharmony_ci u32 pmlca = get_pmlca(ctr); 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci pmlca &= ~PMLCA_FC; 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci if (enable) 2228c2ecf20Sopenharmony_ci pmlca |= PMLCA_CE; 2238c2ecf20Sopenharmony_ci else 2248c2ecf20Sopenharmony_ci pmlca &= ~PMLCA_CE; 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci set_pmlca(ctr, pmlca); 2278c2ecf20Sopenharmony_ci} 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_cistatic void pmc_start_ctrs(int enable) 2308c2ecf20Sopenharmony_ci{ 2318c2ecf20Sopenharmony_ci u32 pmgc0 = mfpmr(PMRN_PMGC0); 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci pmgc0 &= ~PMGC0_FAC; 2348c2ecf20Sopenharmony_ci pmgc0 |= PMGC0_FCECE; 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci if (enable) 2378c2ecf20Sopenharmony_ci pmgc0 |= PMGC0_PMIE; 2388c2ecf20Sopenharmony_ci else 2398c2ecf20Sopenharmony_ci pmgc0 &= ~PMGC0_PMIE; 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci mtpmr(PMRN_PMGC0, pmgc0); 2428c2ecf20Sopenharmony_ci} 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_cistatic void pmc_stop_ctrs(void) 2458c2ecf20Sopenharmony_ci{ 2468c2ecf20Sopenharmony_ci u32 pmgc0 = mfpmr(PMRN_PMGC0); 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci pmgc0 |= PMGC0_FAC; 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci pmgc0 &= ~(PMGC0_PMIE | PMGC0_FCECE); 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci mtpmr(PMRN_PMGC0, pmgc0); 2538c2ecf20Sopenharmony_ci} 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_cistatic int fsl_emb_cpu_setup(struct op_counter_config *ctr) 2568c2ecf20Sopenharmony_ci{ 2578c2ecf20Sopenharmony_ci int i; 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci /* freeze all counters */ 2608c2ecf20Sopenharmony_ci pmc_stop_ctrs(); 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci for (i = 0;i < num_counters;i++) { 2638c2ecf20Sopenharmony_ci init_pmc_stop(i); 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci set_pmc_event(i, ctr[i].event); 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci set_pmc_user_kernel(i, ctr[i].user, ctr[i].kernel); 2688c2ecf20Sopenharmony_ci } 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci return 0; 2718c2ecf20Sopenharmony_ci} 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_cistatic int fsl_emb_reg_setup(struct op_counter_config *ctr, 2748c2ecf20Sopenharmony_ci struct op_system_config *sys, 2758c2ecf20Sopenharmony_ci int num_ctrs) 2768c2ecf20Sopenharmony_ci{ 2778c2ecf20Sopenharmony_ci int i; 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci num_counters = num_ctrs; 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci /* Our counters count up, and "count" refers to 2828c2ecf20Sopenharmony_ci * how much before the next interrupt, and we interrupt 2838c2ecf20Sopenharmony_ci * on overflow. So we calculate the starting value 2848c2ecf20Sopenharmony_ci * which will give us "count" until overflow. 2858c2ecf20Sopenharmony_ci * Then we set the events on the enabled counters */ 2868c2ecf20Sopenharmony_ci for (i = 0; i < num_counters; ++i) 2878c2ecf20Sopenharmony_ci reset_value[i] = 0x80000000UL - ctr[i].count; 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_ci return 0; 2908c2ecf20Sopenharmony_ci} 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_cistatic int fsl_emb_start(struct op_counter_config *ctr) 2938c2ecf20Sopenharmony_ci{ 2948c2ecf20Sopenharmony_ci int i; 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_ci mtmsr(mfmsr() | MSR_PMM); 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci for (i = 0; i < num_counters; ++i) { 2998c2ecf20Sopenharmony_ci if (ctr[i].enabled) { 3008c2ecf20Sopenharmony_ci ctr_write(i, reset_value[i]); 3018c2ecf20Sopenharmony_ci /* Set each enabled counter to only 3028c2ecf20Sopenharmony_ci * count when the Mark bit is *not* set */ 3038c2ecf20Sopenharmony_ci set_pmc_marked(i, 1, 0); 3048c2ecf20Sopenharmony_ci pmc_start_ctr(i, 1); 3058c2ecf20Sopenharmony_ci } else { 3068c2ecf20Sopenharmony_ci ctr_write(i, 0); 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci /* Set the ctr to be stopped */ 3098c2ecf20Sopenharmony_ci pmc_start_ctr(i, 0); 3108c2ecf20Sopenharmony_ci } 3118c2ecf20Sopenharmony_ci } 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci /* Clear the freeze bit, and enable the interrupt. 3148c2ecf20Sopenharmony_ci * The counters won't actually start until the rfi clears 3158c2ecf20Sopenharmony_ci * the PMM bit */ 3168c2ecf20Sopenharmony_ci pmc_start_ctrs(1); 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci oprofile_running = 1; 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci pr_debug("start on cpu %d, pmgc0 %x\n", smp_processor_id(), 3218c2ecf20Sopenharmony_ci mfpmr(PMRN_PMGC0)); 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_ci return 0; 3248c2ecf20Sopenharmony_ci} 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_cistatic void fsl_emb_stop(void) 3278c2ecf20Sopenharmony_ci{ 3288c2ecf20Sopenharmony_ci /* freeze counters */ 3298c2ecf20Sopenharmony_ci pmc_stop_ctrs(); 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_ci oprofile_running = 0; 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci pr_debug("stop on cpu %d, pmgc0 %x\n", smp_processor_id(), 3348c2ecf20Sopenharmony_ci mfpmr(PMRN_PMGC0)); 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ci mb(); 3378c2ecf20Sopenharmony_ci} 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_cistatic void fsl_emb_handle_interrupt(struct pt_regs *regs, 3418c2ecf20Sopenharmony_ci struct op_counter_config *ctr) 3428c2ecf20Sopenharmony_ci{ 3438c2ecf20Sopenharmony_ci unsigned long pc; 3448c2ecf20Sopenharmony_ci int is_kernel; 3458c2ecf20Sopenharmony_ci int val; 3468c2ecf20Sopenharmony_ci int i; 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci pc = regs->nip; 3498c2ecf20Sopenharmony_ci is_kernel = is_kernel_addr(pc); 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci for (i = 0; i < num_counters; ++i) { 3528c2ecf20Sopenharmony_ci val = ctr_read(i); 3538c2ecf20Sopenharmony_ci if (val < 0) { 3548c2ecf20Sopenharmony_ci if (oprofile_running && ctr[i].enabled) { 3558c2ecf20Sopenharmony_ci oprofile_add_ext_sample(pc, regs, i, is_kernel); 3568c2ecf20Sopenharmony_ci ctr_write(i, reset_value[i]); 3578c2ecf20Sopenharmony_ci } else { 3588c2ecf20Sopenharmony_ci ctr_write(i, 0); 3598c2ecf20Sopenharmony_ci } 3608c2ecf20Sopenharmony_ci } 3618c2ecf20Sopenharmony_ci } 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_ci /* The freeze bit was set by the interrupt. */ 3648c2ecf20Sopenharmony_ci /* Clear the freeze bit, and reenable the interrupt. The 3658c2ecf20Sopenharmony_ci * counters won't actually start until the rfi clears the PMM 3668c2ecf20Sopenharmony_ci * bit. The PMM bit should not be set until after the interrupt 3678c2ecf20Sopenharmony_ci * is cleared to avoid it getting lost in some hypervisor 3688c2ecf20Sopenharmony_ci * environments. 3698c2ecf20Sopenharmony_ci */ 3708c2ecf20Sopenharmony_ci mtmsr(mfmsr() | MSR_PMM); 3718c2ecf20Sopenharmony_ci pmc_start_ctrs(1); 3728c2ecf20Sopenharmony_ci} 3738c2ecf20Sopenharmony_ci 3748c2ecf20Sopenharmony_cistruct op_powerpc_model op_model_fsl_emb = { 3758c2ecf20Sopenharmony_ci .reg_setup = fsl_emb_reg_setup, 3768c2ecf20Sopenharmony_ci .cpu_setup = fsl_emb_cpu_setup, 3778c2ecf20Sopenharmony_ci .start = fsl_emb_start, 3788c2ecf20Sopenharmony_ci .stop = fsl_emb_stop, 3798c2ecf20Sopenharmony_ci .handle_interrupt = fsl_emb_handle_interrupt, 3808c2ecf20Sopenharmony_ci}; 381