1/* 2 * Power ISA decode for misc instructions 3 * 4 * Copyright (c) 2024, IBM Corporation. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20/* 21 * Memory Barrier Instructions 22 */ 23 24static bool trans_SYNC(DisasContext *ctx, arg_X_sync *a) 25{ 26 TCGBar bar = TCG_MO_ALL; 27 uint32_t l = a->l; 28 uint32_t sc = a->sc; 29 30 /* 31 * BookE uses the msync mnemonic. This means hwsync, except in the 32 * 440, where it an execution serialisation point that requires all 33 * previous storage accesses to have been performed to memory (which 34 * doesn't matter for TCG). 35 */ 36 if (!(ctx->insns_flags & PPC_MEM_SYNC)) { 37 if (ctx->insns_flags & PPC_BOOKE) { 38 tcg_gen_mb(bar | TCG_BAR_SC); 39 return true; 40 } 41 42 return false; 43 } 44 45 /* 46 * In ISA v3.1, the L field grew one bit. Mask that out to ignore it in 47 * older processors. It also added the SC field, zero this to ignore 48 * it too. 49 */ 50 if (!(ctx->insns_flags2 & PPC2_ISA310)) { 51 l &= 0x3; 52 sc = 0; 53 } 54 55 if (sc) { 56 /* Store syncs [stsync, stcisync, stncisync]. These ignore L. */ 57 bar = TCG_MO_ST_ST; 58 } else { 59 if (((l == 1) && (ctx->insns_flags2 & PPC2_MEM_LWSYNC)) || (l == 5)) { 60 /* lwsync, or plwsync on POWER10 and later */ 61 bar = TCG_MO_LD_LD | TCG_MO_LD_ST | TCG_MO_ST_ST; 62 } 63 64 /* 65 * We may need to check for a pending TLB flush. 66 * 67 * We do this on ptesync (l == 2) on ppc64 and any sync on ppc32. 68 * 69 * Additionally, this can only happen in kernel mode however so 70 * check MSR_PR as well. 71 */ 72 if (((l == 2) || !(ctx->insns_flags & PPC_64B)) && !ctx->pr) { 73 gen_check_tlb_flush(ctx, true); 74 } 75 } 76 77 tcg_gen_mb(bar | TCG_BAR_SC); 78 79 return true; 80} 81 82static bool trans_EIEIO(DisasContext *ctx, arg_EIEIO *a) 83{ 84 TCGBar bar = TCG_MO_ALL; 85 86 /* 87 * BookE uses the mbar instruction instead of eieio, which is basically 88 * full hwsync memory barrier, but is not execution synchronising. For 89 * the purpose of TCG the distinction is not relevant. 90 */ 91 if (!(ctx->insns_flags & PPC_MEM_EIEIO)) { 92 if ((ctx->insns_flags & PPC_BOOKE) || 93 (ctx->insns_flags2 & PPC2_BOOKE206)) { 94 tcg_gen_mb(bar | TCG_BAR_SC); 95 return true; 96 } 97 return false; 98 } 99 100 /* 101 * eieio has complex semanitcs. It provides memory ordering between 102 * operations in the set: 103 * - loads from CI memory. 104 * - stores to CI memory. 105 * - stores to WT memory. 106 * 107 * It separately also orders memory for operations in the set: 108 * - stores to cacheble memory. 109 * 110 * It also serializes instructions: 111 * - dcbt and dcbst. 112 * 113 * It separately serializes: 114 * - tlbie and tlbsync. 115 * 116 * And separately serializes: 117 * - slbieg, slbiag, and slbsync. 118 * 119 * The end result is that CI memory ordering requires TCG_MO_ALL 120 * and it is not possible to special-case more relaxed ordering for 121 * cacheable accesses. TCG_BAR_SC is required to provide this 122 * serialization. 123 */ 124 125 /* 126 * POWER9 has a eieio instruction variant using bit 6 as a hint to 127 * tell the CPU it is a store-forwarding barrier. 128 */ 129 if (ctx->opcode & 0x2000000) { 130 /* 131 * ISA says that "Reserved fields in instructions are ignored 132 * by the processor". So ignore the bit 6 on non-POWER9 CPU but 133 * as this is not an instruction software should be using, 134 * complain to the user. 135 */ 136 if (!(ctx->insns_flags2 & PPC2_ISA300)) { 137 qemu_log_mask(LOG_GUEST_ERROR, "invalid eieio using bit 6 at @" 138 TARGET_FMT_lx "\n", ctx->cia); 139 } else { 140 bar = TCG_MO_ST_LD; 141 } 142 } 143 144 tcg_gen_mb(bar | TCG_BAR_SC); 145 146 return true; 147} 148