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 29 /* 30 * BookE uses the msync mnemonic. This means hwsync, except in the 31 * 440, where it an execution serialisation point that requires all 32 * previous storage accesses to have been performed to memory (which 33 * doesn't matter for TCG). 34 */ 35 if (!(ctx->insns_flags & PPC_MEM_SYNC)) { 36 if (ctx->insns_flags & PPC_BOOKE) { 37 tcg_gen_mb(bar | TCG_BAR_SC); 38 return true; 39 } 40 41 return false; 42 } 43 44 if ((l == 1) && (ctx->insns_flags2 & PPC2_MEM_LWSYNC)) { 45 bar = TCG_MO_LD_LD | TCG_MO_LD_ST | TCG_MO_ST_ST; 46 } 47 48 /* 49 * We may need to check for a pending TLB flush. 50 * 51 * We do this on ptesync (l == 2) on ppc64 and any sync on ppc32. 52 * 53 * Additionally, this can only happen in kernel mode however so 54 * check MSR_PR as well. 55 */ 56 if (((l == 2) || !(ctx->insns_flags & PPC_64B)) && !ctx->pr) { 57 gen_check_tlb_flush(ctx, true); 58 } 59 60 tcg_gen_mb(bar | TCG_BAR_SC); 61 62 return true; 63} 64 65static bool trans_EIEIO(DisasContext *ctx, arg_EIEIO *a) 66{ 67 TCGBar bar = TCG_MO_ALL; 68 69 /* 70 * BookE uses the mbar instruction instead of eieio, which is basically 71 * full hwsync memory barrier, but is not execution synchronising. For 72 * the purpose of TCG the distinction is not relevant. 73 */ 74 if (!(ctx->insns_flags & PPC_MEM_EIEIO)) { 75 if ((ctx->insns_flags & PPC_BOOKE) || 76 (ctx->insns_flags2 & PPC2_BOOKE206)) { 77 tcg_gen_mb(bar | TCG_BAR_SC); 78 return true; 79 } 80 return false; 81 } 82 83 /* 84 * eieio has complex semanitcs. It provides memory ordering between 85 * operations in the set: 86 * - loads from CI memory. 87 * - stores to CI memory. 88 * - stores to WT memory. 89 * 90 * It separately also orders memory for operations in the set: 91 * - stores to cacheble memory. 92 * 93 * It also serializes instructions: 94 * - dcbt and dcbst. 95 * 96 * It separately serializes: 97 * - tlbie and tlbsync. 98 * 99 * And separately serializes: 100 * - slbieg, slbiag, and slbsync. 101 * 102 * The end result is that CI memory ordering requires TCG_MO_ALL 103 * and it is not possible to special-case more relaxed ordering for 104 * cacheable accesses. TCG_BAR_SC is required to provide this 105 * serialization. 106 */ 107 108 /* 109 * POWER9 has a eieio instruction variant using bit 6 as a hint to 110 * tell the CPU it is a store-forwarding barrier. 111 */ 112 if (ctx->opcode & 0x2000000) { 113 /* 114 * ISA says that "Reserved fields in instructions are ignored 115 * by the processor". So ignore the bit 6 on non-POWER9 CPU but 116 * as this is not an instruction software should be using, 117 * complain to the user. 118 */ 119 if (!(ctx->insns_flags2 & PPC2_ISA300)) { 120 qemu_log_mask(LOG_GUEST_ERROR, "invalid eieio using bit 6 at @" 121 TARGET_FMT_lx "\n", ctx->cia); 122 } else { 123 bar = TCG_MO_ST_LD; 124 } 125 } 126 127 tcg_gen_mb(bar | TCG_BAR_SC); 128 129 return true; 130} 131