113f50867SNicholas Piggin/* 213f50867SNicholas Piggin * Power ISA decode for misc instructions 313f50867SNicholas Piggin * 413f50867SNicholas Piggin * Copyright (c) 2024, IBM Corporation. 513f50867SNicholas Piggin * 613f50867SNicholas Piggin * This library is free software; you can redistribute it and/or 713f50867SNicholas Piggin * modify it under the terms of the GNU Lesser General Public 813f50867SNicholas Piggin * License as published by the Free Software Foundation; either 913f50867SNicholas Piggin * version 2.1 of the License, or (at your option) any later version. 1013f50867SNicholas Piggin * 1113f50867SNicholas Piggin * This library is distributed in the hope that it will be useful, 1213f50867SNicholas Piggin * but WITHOUT ANY WARRANTY; without even the implied warranty of 1313f50867SNicholas Piggin * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1413f50867SNicholas Piggin * Lesser General Public License for more details. 1513f50867SNicholas Piggin * 1613f50867SNicholas Piggin * You should have received a copy of the GNU Lesser General Public 1713f50867SNicholas Piggin * License along with this library; if not, see <http://www.gnu.org/licenses/>. 1813f50867SNicholas Piggin */ 1913f50867SNicholas Piggin 2013f50867SNicholas Piggin/* 2113f50867SNicholas Piggin * Memory Barrier Instructions 2213f50867SNicholas Piggin */ 2313f50867SNicholas Piggin 2413f50867SNicholas Pigginstatic bool trans_SYNC(DisasContext *ctx, arg_X_sync *a) 2513f50867SNicholas Piggin{ 2613f50867SNicholas Piggin TCGBar bar = TCG_MO_ALL; 2713f50867SNicholas Piggin uint32_t l = a->l; 28b3cfa2ddSNicholas Piggin uint32_t sc = a->sc; 2913f50867SNicholas Piggin 3013f50867SNicholas Piggin /* 3113f50867SNicholas Piggin * BookE uses the msync mnemonic. This means hwsync, except in the 3213f50867SNicholas Piggin * 440, where it an execution serialisation point that requires all 3313f50867SNicholas Piggin * previous storage accesses to have been performed to memory (which 3413f50867SNicholas Piggin * doesn't matter for TCG). 3513f50867SNicholas Piggin */ 3613f50867SNicholas Piggin if (!(ctx->insns_flags & PPC_MEM_SYNC)) { 3713f50867SNicholas Piggin if (ctx->insns_flags & PPC_BOOKE) { 38ab4f174bSNicholas Piggin tcg_gen_mb(bar | TCG_BAR_SC); 3913f50867SNicholas Piggin return true; 4013f50867SNicholas Piggin } 4113f50867SNicholas Piggin 4213f50867SNicholas Piggin return false; 4313f50867SNicholas Piggin } 4413f50867SNicholas Piggin 45b3cfa2ddSNicholas Piggin /* 46b3cfa2ddSNicholas Piggin * In ISA v3.1, the L field grew one bit. Mask that out to ignore it in 47b3cfa2ddSNicholas Piggin * older processors. It also added the SC field, zero this to ignore 48b3cfa2ddSNicholas Piggin * it too. 49b3cfa2ddSNicholas Piggin */ 50b3cfa2ddSNicholas Piggin if (!(ctx->insns_flags2 & PPC2_ISA310)) { 51b3cfa2ddSNicholas Piggin l &= 0x3; 52b3cfa2ddSNicholas Piggin sc = 0; 53b3cfa2ddSNicholas Piggin } 54b3cfa2ddSNicholas Piggin 55b3cfa2ddSNicholas Piggin if (sc) { 56b3cfa2ddSNicholas Piggin /* Store syncs [stsync, stcisync, stncisync]. These ignore L. */ 57b3cfa2ddSNicholas Piggin bar = TCG_MO_ST_ST; 58b3cfa2ddSNicholas Piggin } else { 59b3cfa2ddSNicholas Piggin if (((l == 1) && (ctx->insns_flags2 & PPC2_MEM_LWSYNC)) || (l == 5)) { 60b3cfa2ddSNicholas Piggin /* lwsync, or plwsync on POWER10 and later */ 6113f50867SNicholas Piggin bar = TCG_MO_LD_LD | TCG_MO_LD_ST | TCG_MO_ST_ST; 6213f50867SNicholas Piggin } 6313f50867SNicholas Piggin 6413f50867SNicholas Piggin /* 6513f50867SNicholas Piggin * We may need to check for a pending TLB flush. 6613f50867SNicholas Piggin * 6713f50867SNicholas Piggin * We do this on ptesync (l == 2) on ppc64 and any sync on ppc32. 6813f50867SNicholas Piggin * 6913f50867SNicholas Piggin * Additionally, this can only happen in kernel mode however so 7013f50867SNicholas Piggin * check MSR_PR as well. 7113f50867SNicholas Piggin */ 7213f50867SNicholas Piggin if (((l == 2) || !(ctx->insns_flags & PPC_64B)) && !ctx->pr) { 7313f50867SNicholas Piggin gen_check_tlb_flush(ctx, true); 7413f50867SNicholas Piggin } 75b3cfa2ddSNicholas Piggin } 7613f50867SNicholas Piggin 7713f50867SNicholas Piggin tcg_gen_mb(bar | TCG_BAR_SC); 7813f50867SNicholas Piggin 7913f50867SNicholas Piggin return true; 8013f50867SNicholas Piggin} 8113f50867SNicholas Piggin 8213f50867SNicholas Pigginstatic bool trans_EIEIO(DisasContext *ctx, arg_EIEIO *a) 8313f50867SNicholas Piggin{ 8413f50867SNicholas Piggin TCGBar bar = TCG_MO_ALL; 8513f50867SNicholas Piggin 8613f50867SNicholas Piggin /* 8713f50867SNicholas Piggin * BookE uses the mbar instruction instead of eieio, which is basically 8813f50867SNicholas Piggin * full hwsync memory barrier, but is not execution synchronising. For 8913f50867SNicholas Piggin * the purpose of TCG the distinction is not relevant. 9013f50867SNicholas Piggin */ 9113f50867SNicholas Piggin if (!(ctx->insns_flags & PPC_MEM_EIEIO)) { 9213f50867SNicholas Piggin if ((ctx->insns_flags & PPC_BOOKE) || 9313f50867SNicholas Piggin (ctx->insns_flags2 & PPC2_BOOKE206)) { 94ab4f174bSNicholas Piggin tcg_gen_mb(bar | TCG_BAR_SC); 9513f50867SNicholas Piggin return true; 9613f50867SNicholas Piggin } 9713f50867SNicholas Piggin return false; 9813f50867SNicholas Piggin } 9913f50867SNicholas Piggin 10013f50867SNicholas Piggin /* 10113f50867SNicholas Piggin * eieio has complex semanitcs. It provides memory ordering between 10213f50867SNicholas Piggin * operations in the set: 10313f50867SNicholas Piggin * - loads from CI memory. 10413f50867SNicholas Piggin * - stores to CI memory. 10513f50867SNicholas Piggin * - stores to WT memory. 10613f50867SNicholas Piggin * 10713f50867SNicholas Piggin * It separately also orders memory for operations in the set: 10813f50867SNicholas Piggin * - stores to cacheble memory. 10913f50867SNicholas Piggin * 11013f50867SNicholas Piggin * It also serializes instructions: 11113f50867SNicholas Piggin * - dcbt and dcbst. 11213f50867SNicholas Piggin * 11313f50867SNicholas Piggin * It separately serializes: 11413f50867SNicholas Piggin * - tlbie and tlbsync. 11513f50867SNicholas Piggin * 11613f50867SNicholas Piggin * And separately serializes: 11713f50867SNicholas Piggin * - slbieg, slbiag, and slbsync. 11813f50867SNicholas Piggin * 11913f50867SNicholas Piggin * The end result is that CI memory ordering requires TCG_MO_ALL 12013f50867SNicholas Piggin * and it is not possible to special-case more relaxed ordering for 12113f50867SNicholas Piggin * cacheable accesses. TCG_BAR_SC is required to provide this 12213f50867SNicholas Piggin * serialization. 12313f50867SNicholas Piggin */ 12413f50867SNicholas Piggin 12513f50867SNicholas Piggin /* 12613f50867SNicholas Piggin * POWER9 has a eieio instruction variant using bit 6 as a hint to 12713f50867SNicholas Piggin * tell the CPU it is a store-forwarding barrier. 12813f50867SNicholas Piggin */ 12913f50867SNicholas Piggin if (ctx->opcode & 0x2000000) { 13013f50867SNicholas Piggin /* 13113f50867SNicholas Piggin * ISA says that "Reserved fields in instructions are ignored 13213f50867SNicholas Piggin * by the processor". So ignore the bit 6 on non-POWER9 CPU but 13313f50867SNicholas Piggin * as this is not an instruction software should be using, 13413f50867SNicholas Piggin * complain to the user. 13513f50867SNicholas Piggin */ 13613f50867SNicholas Piggin if (!(ctx->insns_flags2 & PPC2_ISA300)) { 13713f50867SNicholas Piggin qemu_log_mask(LOG_GUEST_ERROR, "invalid eieio using bit 6 at @" 13813f50867SNicholas Piggin TARGET_FMT_lx "\n", ctx->cia); 13913f50867SNicholas Piggin } else { 14013f50867SNicholas Piggin bar = TCG_MO_ST_LD; 14113f50867SNicholas Piggin } 14213f50867SNicholas Piggin } 14313f50867SNicholas Piggin 14413f50867SNicholas Piggin tcg_gen_mb(bar | TCG_BAR_SC); 14513f50867SNicholas Piggin 14613f50867SNicholas Piggin return true; 14713f50867SNicholas Piggin} 148*45693f94SNicholas Piggin 149*45693f94SNicholas Pigginstatic bool trans_ATTN(DisasContext *ctx, arg_ATTN *a) 150*45693f94SNicholas Piggin{ 151*45693f94SNicholas Piggin#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) 152*45693f94SNicholas Piggin gen_helper_attn(tcg_env); 153*45693f94SNicholas Piggin return true; 154*45693f94SNicholas Piggin#else 155*45693f94SNicholas Piggin return false; 156*45693f94SNicholas Piggin#endif 157*45693f94SNicholas Piggin} 158