1/* 2 * PMU register read/write functions for TCG IBM POWER chips 3 * 4 * Copyright IBM Corp. 2021 5 * 6 * Authors: 7 * Daniel Henrique Barboza <danielhb413@gmail.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2 or later. 10 * See the COPYING file in the top-level directory. 11 */ 12 13#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) 14 15/* 16 * Checks whether the Group A SPR (MMCR0, MMCR2, MMCRA, and the 17 * PMCs) has problem state read access. 18 * 19 * Read acccess is granted for all PMCC values but 0b01, where a 20 * Facility Unavailable Interrupt will occur. 21 */ 22static bool spr_groupA_read_allowed(DisasContext *ctx) 23{ 24 if (!ctx->mmcr0_pmcc0 && ctx->mmcr0_pmcc1) { 25 gen_hvpriv_exception(ctx, POWERPC_EXCP_FU); 26 return false; 27 } 28 29 return true; 30} 31 32/* 33 * Checks whether the Group A SPR (MMCR0, MMCR2, MMCRA, and the 34 * PMCs) has problem state write access. 35 * 36 * Write acccess is granted for PMCC values 0b10 and 0b11. Userspace 37 * writing with PMCC 0b00 will generate a Hypervisor Emulation 38 * Assistance Interrupt. Userspace writing with PMCC 0b01 will 39 * generate a Facility Unavailable Interrupt. 40 */ 41static bool spr_groupA_write_allowed(DisasContext *ctx) 42{ 43 if (ctx->mmcr0_pmcc0) { 44 return true; 45 } 46 47 if (ctx->mmcr0_pmcc1) { 48 /* PMCC = 0b01 */ 49 gen_hvpriv_exception(ctx, POWERPC_EXCP_FU); 50 } else { 51 /* PMCC = 0b00 */ 52 gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR); 53 } 54 55 return false; 56} 57 58/* 59 * Helper function to avoid code repetition between MMCR0 and 60 * MMCR2 problem state write functions. 61 * 62 * 'ret' must be tcg_temp_freed() by the caller. 63 */ 64static TCGv masked_gprn_for_spr_write(int gprn, int sprn, 65 uint64_t spr_mask) 66{ 67 TCGv ret = tcg_temp_new(); 68 TCGv t0 = tcg_temp_new(); 69 70 /* 'ret' starts with all mask bits cleared */ 71 gen_load_spr(ret, sprn); 72 tcg_gen_andi_tl(ret, ret, ~(spr_mask)); 73 74 /* Apply the mask into 'gprn' in a temp var */ 75 tcg_gen_andi_tl(t0, cpu_gpr[gprn], spr_mask); 76 77 /* Add the masked gprn bits into 'ret' */ 78 tcg_gen_or_tl(ret, ret, t0); 79 80 tcg_temp_free(t0); 81 82 return ret; 83} 84 85void spr_read_MMCR0_ureg(DisasContext *ctx, int gprn, int sprn) 86{ 87 TCGv t0; 88 89 if (!spr_groupA_read_allowed(ctx)) { 90 return; 91 } 92 93 t0 = tcg_temp_new(); 94 95 /* 96 * Filter out all bits but FC, PMAO, and PMAE, according 97 * to ISA v3.1, in 10.4.4 Monitor Mode Control Register 0, 98 * fourth paragraph. 99 */ 100 gen_load_spr(t0, SPR_POWER_MMCR0); 101 tcg_gen_andi_tl(t0, t0, MMCR0_UREG_MASK); 102 tcg_gen_mov_tl(cpu_gpr[gprn], t0); 103 104 tcg_temp_free(t0); 105} 106 107static void write_MMCR0_common(DisasContext *ctx, TCGv val) 108{ 109 /* 110 * helper_store_mmcr0 will make clock based operations that 111 * will cause 'bad icount read' errors if we do not execute 112 * gen_icount_io_start() beforehand. 113 */ 114 gen_icount_io_start(ctx); 115 gen_helper_store_mmcr0(cpu_env, val); 116 117 /* 118 * End the translation block because MMCR0 writes can change 119 * ctx->pmu_insn_cnt. 120 */ 121 ctx->base.is_jmp = DISAS_EXIT_UPDATE; 122} 123 124void spr_write_MMCR0_ureg(DisasContext *ctx, int sprn, int gprn) 125{ 126 TCGv masked_gprn; 127 128 if (!spr_groupA_write_allowed(ctx)) { 129 return; 130 } 131 132 /* 133 * Filter out all bits but FC, PMAO, and PMAE, according 134 * to ISA v3.1, in 10.4.4 Monitor Mode Control Register 0, 135 * fourth paragraph. 136 */ 137 masked_gprn = masked_gprn_for_spr_write(gprn, SPR_POWER_MMCR0, 138 MMCR0_UREG_MASK); 139 write_MMCR0_common(ctx, masked_gprn); 140 141 tcg_temp_free(masked_gprn); 142} 143 144void spr_read_MMCR2_ureg(DisasContext *ctx, int gprn, int sprn) 145{ 146 TCGv t0; 147 148 if (!spr_groupA_read_allowed(ctx)) { 149 return; 150 } 151 152 t0 = tcg_temp_new(); 153 154 /* 155 * On read, filter out all bits that are not FCnP0 bits. 156 * When MMCR0[PMCC] is set to 0b10 or 0b11, providing 157 * problem state programs read/write access to MMCR2, 158 * only the FCnP0 bits can be accessed. All other bits are 159 * not changed when mtspr is executed in problem state, and 160 * all other bits return 0s when mfspr is executed in problem 161 * state, according to ISA v3.1, section 10.4.6 Monitor Mode 162 * Control Register 2, p. 1316, third paragraph. 163 */ 164 gen_load_spr(t0, SPR_POWER_MMCR2); 165 tcg_gen_andi_tl(t0, t0, MMCR2_UREG_MASK); 166 tcg_gen_mov_tl(cpu_gpr[gprn], t0); 167 168 tcg_temp_free(t0); 169} 170 171void spr_write_MMCR2_ureg(DisasContext *ctx, int sprn, int gprn) 172{ 173 TCGv masked_gprn; 174 175 if (!spr_groupA_write_allowed(ctx)) { 176 return; 177 } 178 179 /* 180 * Filter the bits that can be written using MMCR2_UREG_MASK, 181 * similar to what is done in spr_write_MMCR0_ureg(). 182 */ 183 masked_gprn = masked_gprn_for_spr_write(gprn, SPR_POWER_MMCR2, 184 MMCR2_UREG_MASK); 185 gen_store_spr(SPR_POWER_MMCR2, masked_gprn); 186 187 tcg_temp_free(masked_gprn); 188} 189 190void spr_read_PMC(DisasContext *ctx, int gprn, int sprn) 191{ 192 TCGv_i32 t_sprn = tcg_const_i32(sprn); 193 194 gen_icount_io_start(ctx); 195 gen_helper_read_pmc(cpu_gpr[gprn], cpu_env, t_sprn); 196 197 tcg_temp_free_i32(t_sprn); 198} 199 200void spr_read_PMC14_ureg(DisasContext *ctx, int gprn, int sprn) 201{ 202 if (!spr_groupA_read_allowed(ctx)) { 203 return; 204 } 205 206 spr_read_PMC(ctx, gprn, sprn + 0x10); 207} 208 209void spr_read_PMC56_ureg(DisasContext *ctx, int gprn, int sprn) 210{ 211 /* 212 * If PMCC = 0b11, PMC5 and PMC6 aren't included in the Performance 213 * Monitor, and a read attempt results in a Facility Unavailable 214 * Interrupt. 215 */ 216 if (ctx->mmcr0_pmcc0 && ctx->mmcr0_pmcc1) { 217 gen_hvpriv_exception(ctx, POWERPC_EXCP_FU); 218 return; 219 } 220 221 /* The remaining steps are similar to PMCs 1-4 userspace read */ 222 spr_read_PMC14_ureg(ctx, gprn, sprn); 223} 224 225void spr_write_PMC(DisasContext *ctx, int sprn, int gprn) 226{ 227 TCGv_i32 t_sprn = tcg_const_i32(sprn); 228 229 gen_icount_io_start(ctx); 230 gen_helper_store_pmc(cpu_env, t_sprn, cpu_gpr[gprn]); 231 232 tcg_temp_free_i32(t_sprn); 233} 234 235void spr_write_PMC14_ureg(DisasContext *ctx, int sprn, int gprn) 236{ 237 if (!spr_groupA_write_allowed(ctx)) { 238 return; 239 } 240 241 spr_write_PMC(ctx, sprn + 0x10, gprn); 242} 243 244void spr_write_PMC56_ureg(DisasContext *ctx, int sprn, int gprn) 245{ 246 /* 247 * If PMCC = 0b11, PMC5 and PMC6 aren't included in the Performance 248 * Monitor, and a write attempt results in a Facility Unavailable 249 * Interrupt. 250 */ 251 if (ctx->mmcr0_pmcc0 && ctx->mmcr0_pmcc1) { 252 gen_hvpriv_exception(ctx, POWERPC_EXCP_FU); 253 return; 254 } 255 256 /* The remaining steps are similar to PMCs 1-4 userspace write */ 257 spr_write_PMC14_ureg(ctx, sprn, gprn); 258} 259 260void spr_write_MMCR0(DisasContext *ctx, int sprn, int gprn) 261{ 262 write_MMCR0_common(ctx, cpu_gpr[gprn]); 263} 264 265void spr_write_MMCR1(DisasContext *ctx, int sprn, int gprn) 266{ 267 gen_icount_io_start(ctx); 268 gen_helper_store_mmcr1(cpu_env, cpu_gpr[gprn]); 269} 270#else 271void spr_read_MMCR0_ureg(DisasContext *ctx, int gprn, int sprn) 272{ 273 spr_read_ureg(ctx, gprn, sprn); 274} 275 276void spr_write_MMCR0_ureg(DisasContext *ctx, int sprn, int gprn) 277{ 278 spr_noaccess(ctx, gprn, sprn); 279} 280 281void spr_read_MMCR2_ureg(DisasContext *ctx, int gprn, int sprn) 282{ 283 spr_read_ureg(ctx, gprn, sprn); 284} 285 286void spr_write_MMCR2_ureg(DisasContext *ctx, int sprn, int gprn) 287{ 288 spr_noaccess(ctx, gprn, sprn); 289} 290 291void spr_read_PMC14_ureg(DisasContext *ctx, int gprn, int sprn) 292{ 293 spr_read_ureg(ctx, gprn, sprn); 294} 295 296void spr_read_PMC56_ureg(DisasContext *ctx, int gprn, int sprn) 297{ 298 spr_read_ureg(ctx, gprn, sprn); 299} 300 301void spr_write_PMC14_ureg(DisasContext *ctx, int sprn, int gprn) 302{ 303 spr_noaccess(ctx, gprn, sprn); 304} 305 306void spr_write_PMC56_ureg(DisasContext *ctx, int sprn, int gprn) 307{ 308 spr_noaccess(ctx, gprn, sprn); 309} 310 311void spr_write_MMCR0(DisasContext *ctx, int sprn, int gprn) 312{ 313 spr_write_generic(ctx, sprn, gprn); 314} 315 316void spr_write_MMCR1(DisasContext *ctx, int sprn, int gprn) 317{ 318 spr_write_generic(ctx, sprn, gprn); 319} 320 321void spr_write_PMC(DisasContext *ctx, int sprn, int gprn) 322{ 323 spr_write_generic(ctx, sprn, gprn); 324} 325#endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */ 326