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 107void spr_write_MMCR0_ureg(DisasContext *ctx, int sprn, int gprn) 108{ 109 TCGv masked_gprn; 110 111 if (!spr_groupA_write_allowed(ctx)) { 112 return; 113 } 114 115 /* 116 * Filter out all bits but FC, PMAO, and PMAE, according 117 * to ISA v3.1, in 10.4.4 Monitor Mode Control Register 0, 118 * fourth paragraph. 119 */ 120 masked_gprn = masked_gprn_for_spr_write(gprn, SPR_POWER_MMCR0, 121 MMCR0_UREG_MASK); 122 gen_store_spr(SPR_POWER_MMCR0, masked_gprn); 123 124 tcg_temp_free(masked_gprn); 125} 126 127void spr_read_MMCR2_ureg(DisasContext *ctx, int gprn, int sprn) 128{ 129 TCGv t0; 130 131 if (!spr_groupA_read_allowed(ctx)) { 132 return; 133 } 134 135 t0 = tcg_temp_new(); 136 137 /* 138 * On read, filter out all bits that are not FCnP0 bits. 139 * When MMCR0[PMCC] is set to 0b10 or 0b11, providing 140 * problem state programs read/write access to MMCR2, 141 * only the FCnP0 bits can be accessed. All other bits are 142 * not changed when mtspr is executed in problem state, and 143 * all other bits return 0s when mfspr is executed in problem 144 * state, according to ISA v3.1, section 10.4.6 Monitor Mode 145 * Control Register 2, p. 1316, third paragraph. 146 */ 147 gen_load_spr(t0, SPR_POWER_MMCR2); 148 tcg_gen_andi_tl(t0, t0, MMCR2_UREG_MASK); 149 tcg_gen_mov_tl(cpu_gpr[gprn], t0); 150 151 tcg_temp_free(t0); 152} 153 154void spr_write_MMCR2_ureg(DisasContext *ctx, int sprn, int gprn) 155{ 156 TCGv masked_gprn; 157 158 if (!spr_groupA_write_allowed(ctx)) { 159 return; 160 } 161 162 /* 163 * Filter the bits that can be written using MMCR2_UREG_MASK, 164 * similar to what is done in spr_write_MMCR0_ureg(). 165 */ 166 masked_gprn = masked_gprn_for_spr_write(gprn, SPR_POWER_MMCR2, 167 MMCR2_UREG_MASK); 168 gen_store_spr(SPR_POWER_MMCR2, masked_gprn); 169 170 tcg_temp_free(masked_gprn); 171} 172 173void spr_read_PMC14_ureg(DisasContext *ctx, int gprn, int sprn) 174{ 175 if (!spr_groupA_read_allowed(ctx)) { 176 return; 177 } 178 179 spr_read_ureg(ctx, gprn, sprn); 180} 181 182void spr_read_PMC56_ureg(DisasContext *ctx, int gprn, int sprn) 183{ 184 /* 185 * If PMCC = 0b11, PMC5 and PMC6 aren't included in the Performance 186 * Monitor, and a read attempt results in a Facility Unavailable 187 * Interrupt. 188 */ 189 if (ctx->mmcr0_pmcc0 && ctx->mmcr0_pmcc1) { 190 gen_hvpriv_exception(ctx, POWERPC_EXCP_FU); 191 return; 192 } 193 194 /* The remaining steps are similar to PMCs 1-4 userspace read */ 195 spr_read_PMC14_ureg(ctx, gprn, sprn); 196} 197 198void spr_write_PMC14_ureg(DisasContext *ctx, int sprn, int gprn) 199{ 200 if (!spr_groupA_write_allowed(ctx)) { 201 return; 202 } 203 204 spr_write_ureg(ctx, sprn, gprn); 205} 206 207void spr_write_PMC56_ureg(DisasContext *ctx, int sprn, int gprn) 208{ 209 /* 210 * If PMCC = 0b11, PMC5 and PMC6 aren't included in the Performance 211 * Monitor, and a write attempt results in a Facility Unavailable 212 * Interrupt. 213 */ 214 if (ctx->mmcr0_pmcc0 && ctx->mmcr0_pmcc1) { 215 gen_hvpriv_exception(ctx, POWERPC_EXCP_FU); 216 return; 217 } 218 219 /* The remaining steps are similar to PMCs 1-4 userspace write */ 220 spr_write_PMC14_ureg(ctx, sprn, gprn); 221} 222#else 223void spr_read_MMCR0_ureg(DisasContext *ctx, int gprn, int sprn) 224{ 225 spr_read_ureg(ctx, gprn, sprn); 226} 227 228void spr_write_MMCR0_ureg(DisasContext *ctx, int sprn, int gprn) 229{ 230 spr_noaccess(ctx, gprn, sprn); 231} 232 233void spr_read_MMCR2_ureg(DisasContext *ctx, int gprn, int sprn) 234{ 235 spr_read_ureg(ctx, gprn, sprn); 236} 237 238void spr_write_MMCR2_ureg(DisasContext *ctx, int sprn, int gprn) 239{ 240 spr_noaccess(ctx, gprn, sprn); 241} 242 243void spr_read_PMC14_ureg(DisasContext *ctx, int gprn, int sprn) 244{ 245 spr_read_ureg(ctx, gprn, sprn); 246} 247 248void spr_read_PMC56_ureg(DisasContext *ctx, int gprn, int sprn) 249{ 250 spr_read_ureg(ctx, gprn, sprn); 251} 252 253void spr_write_PMC14_ureg(DisasContext *ctx, int sprn, int gprn) 254{ 255 spr_noaccess(ctx, gprn, sprn); 256} 257 258void spr_write_PMC56_ureg(DisasContext *ctx, int sprn, int gprn) 259{ 260 spr_noaccess(ctx, gprn, sprn); 261} 262#endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */ 263