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