cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

internal.h (10148B)


      1/*
      2 *  PowerPC internal definitions for qemu.
      3 *
      4 * This library is free software; you can redistribute it and/or
      5 * modify it under the terms of the GNU Lesser General Public
      6 * License as published by the Free Software Foundation; either
      7 * version 2.1 of the License, or (at your option) any later version.
      8 *
      9 * This library is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12 * Lesser General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU Lesser General Public
     15 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
     16 */
     17
     18#ifndef PPC_INTERNAL_H
     19#define PPC_INTERNAL_H
     20
     21#define FUNC_MASK(name, ret_type, size, max_val)                  \
     22static inline ret_type name(uint##size##_t start,                 \
     23                              uint##size##_t end)                 \
     24{                                                                 \
     25    ret_type ret, max_bit = size - 1;                             \
     26                                                                  \
     27    if (likely(start == 0)) {                                     \
     28        ret = max_val << (max_bit - end);                         \
     29    } else if (likely(end == max_bit)) {                          \
     30        ret = max_val >> start;                                   \
     31    } else {                                                      \
     32        ret = (((uint##size##_t)(-1ULL)) >> (start)) ^            \
     33            (((uint##size##_t)(-1ULL) >> (end)) >> 1);            \
     34        if (unlikely(start > end)) {                              \
     35            return ~ret;                                          \
     36        }                                                         \
     37    }                                                             \
     38                                                                  \
     39    return ret;                                                   \
     40}
     41
     42#if defined(TARGET_PPC64)
     43FUNC_MASK(MASK, target_ulong, 64, UINT64_MAX);
     44#else
     45FUNC_MASK(MASK, target_ulong, 32, UINT32_MAX);
     46#endif
     47FUNC_MASK(mask_u32, uint32_t, 32, UINT32_MAX);
     48FUNC_MASK(mask_u64, uint64_t, 64, UINT64_MAX);
     49
     50/*****************************************************************************/
     51/***                           Instruction decoding                        ***/
     52#define EXTRACT_HELPER(name, shift, nb)                                       \
     53static inline uint32_t name(uint32_t opcode)                                  \
     54{                                                                             \
     55    return extract32(opcode, shift, nb);                                      \
     56}
     57
     58#define EXTRACT_SHELPER(name, shift, nb)                                      \
     59static inline int32_t name(uint32_t opcode)                                   \
     60{                                                                             \
     61    return sextract32(opcode, shift, nb);                                     \
     62}
     63
     64#define EXTRACT_HELPER_SPLIT(name, shift1, nb1, shift2, nb2)                  \
     65static inline uint32_t name(uint32_t opcode)                                  \
     66{                                                                             \
     67    return extract32(opcode, shift1, nb1) << nb2 |                            \
     68               extract32(opcode, shift2, nb2);                                \
     69}
     70
     71#define EXTRACT_HELPER_SPLIT_3(name,                                          \
     72                              d0_bits, shift_op_d0, shift_d0,                 \
     73                              d1_bits, shift_op_d1, shift_d1,                 \
     74                              d2_bits, shift_op_d2, shift_d2)                 \
     75static inline int16_t name(uint32_t opcode)                                   \
     76{                                                                             \
     77    return                                                                    \
     78        (((opcode >> (shift_op_d0)) & ((1 << (d0_bits)) - 1)) << (shift_d0)) | \
     79        (((opcode >> (shift_op_d1)) & ((1 << (d1_bits)) - 1)) << (shift_d1)) | \
     80        (((opcode >> (shift_op_d2)) & ((1 << (d2_bits)) - 1)) << (shift_d2));  \
     81}
     82
     83
     84/* Opcode part 1 */
     85EXTRACT_HELPER(opc1, 26, 6);
     86/* Opcode part 2 */
     87EXTRACT_HELPER(opc2, 1, 5);
     88/* Opcode part 3 */
     89EXTRACT_HELPER(opc3, 6, 5);
     90/* Opcode part 4 */
     91EXTRACT_HELPER(opc4, 16, 5);
     92/* Update Cr0 flags */
     93EXTRACT_HELPER(Rc, 0, 1);
     94/* Update Cr6 flags (Altivec) */
     95EXTRACT_HELPER(Rc21, 10, 1);
     96/* Destination */
     97EXTRACT_HELPER(rD, 21, 5);
     98/* Source */
     99EXTRACT_HELPER(rS, 21, 5);
    100/* First operand */
    101EXTRACT_HELPER(rA, 16, 5);
    102/* Second operand */
    103EXTRACT_HELPER(rB, 11, 5);
    104/* Third operand */
    105EXTRACT_HELPER(rC, 6, 5);
    106/***                               Get CRn                                 ***/
    107EXTRACT_HELPER(crfD, 23, 3);
    108EXTRACT_HELPER(BF, 23, 3);
    109EXTRACT_HELPER(crfS, 18, 3);
    110EXTRACT_HELPER(crbD, 21, 5);
    111EXTRACT_HELPER(crbA, 16, 5);
    112EXTRACT_HELPER(crbB, 11, 5);
    113/* SPR / TBL */
    114EXTRACT_HELPER(_SPR, 11, 10);
    115static inline uint32_t SPR(uint32_t opcode)
    116{
    117    uint32_t sprn = _SPR(opcode);
    118
    119    return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
    120}
    121/***                              Get constants                            ***/
    122/* 16 bits signed immediate value */
    123EXTRACT_SHELPER(SIMM, 0, 16);
    124/* 16 bits unsigned immediate value */
    125EXTRACT_HELPER(UIMM, 0, 16);
    126/* 5 bits signed immediate value */
    127EXTRACT_SHELPER(SIMM5, 16, 5);
    128/* 5 bits signed immediate value */
    129EXTRACT_HELPER(UIMM5, 16, 5);
    130/* 4 bits unsigned immediate value */
    131EXTRACT_HELPER(UIMM4, 16, 4);
    132/* Bit count */
    133EXTRACT_HELPER(NB, 11, 5);
    134/* Shift count */
    135EXTRACT_HELPER(SH, 11, 5);
    136/* lwat/stwat/ldat/lwat */
    137EXTRACT_HELPER(FC, 11, 5);
    138/* Vector shift count */
    139EXTRACT_HELPER(VSH, 6, 4);
    140/* Mask start */
    141EXTRACT_HELPER(MB, 6, 5);
    142/* Mask end */
    143EXTRACT_HELPER(ME, 1, 5);
    144/* Trap operand */
    145EXTRACT_HELPER(TO, 21, 5);
    146
    147EXTRACT_HELPER(CRM, 12, 8);
    148
    149#ifndef CONFIG_USER_ONLY
    150EXTRACT_HELPER(SR, 16, 4);
    151#endif
    152
    153/* mtfsf/mtfsfi */
    154EXTRACT_HELPER(FPBF, 23, 3);
    155EXTRACT_HELPER(FPIMM, 12, 4);
    156EXTRACT_HELPER(FPL, 25, 1);
    157EXTRACT_HELPER(FPFLM, 17, 8);
    158EXTRACT_HELPER(FPW, 16, 1);
    159
    160/* mffscrni */
    161EXTRACT_HELPER(RM, 11, 2);
    162
    163/* addpcis */
    164EXTRACT_HELPER_SPLIT_3(DX, 10, 6, 6, 5, 16, 1, 1, 0, 0)
    165#if defined(TARGET_PPC64)
    166/* darn */
    167EXTRACT_HELPER(L, 16, 2);
    168#endif
    169
    170/***                            Jump target decoding                       ***/
    171/* Immediate address */
    172static inline target_ulong LI(uint32_t opcode)
    173{
    174    return (opcode >> 0) & 0x03FFFFFC;
    175}
    176
    177static inline uint32_t BD(uint32_t opcode)
    178{
    179    return (opcode >> 0) & 0xFFFC;
    180}
    181
    182EXTRACT_HELPER(BO, 21, 5);
    183EXTRACT_HELPER(BI, 16, 5);
    184/* Absolute/relative address */
    185EXTRACT_HELPER(AA, 1, 1);
    186/* Link */
    187EXTRACT_HELPER(LK, 0, 1);
    188
    189/* DFP Z22-form */
    190EXTRACT_HELPER(DCM, 10, 6)
    191
    192/* DFP Z23-form */
    193EXTRACT_HELPER(RMC, 9, 2)
    194EXTRACT_HELPER(Rrm, 16, 1)
    195
    196EXTRACT_HELPER_SPLIT(DQxT, 3, 1, 21, 5);
    197EXTRACT_HELPER_SPLIT(xT, 0, 1, 21, 5);
    198EXTRACT_HELPER_SPLIT(xS, 0, 1, 21, 5);
    199EXTRACT_HELPER_SPLIT(xA, 2, 1, 16, 5);
    200EXTRACT_HELPER_SPLIT(xB, 1, 1, 11, 5);
    201EXTRACT_HELPER_SPLIT(xC, 3, 1,  6, 5);
    202EXTRACT_HELPER(DM, 8, 2);
    203EXTRACT_HELPER(UIM, 16, 2);
    204EXTRACT_HELPER(SHW, 8, 2);
    205EXTRACT_HELPER(SP, 19, 2);
    206EXTRACT_HELPER(IMM8, 11, 8);
    207EXTRACT_HELPER(DCMX, 16, 7);
    208EXTRACT_HELPER_SPLIT_3(DCMX_XV, 5, 16, 0, 1, 2, 5, 1, 6, 6);
    209
    210void helper_compute_fprf_float16(CPUPPCState *env, float16 arg);
    211void helper_compute_fprf_float32(CPUPPCState *env, float32 arg);
    212void helper_compute_fprf_float128(CPUPPCState *env, float128 arg);
    213
    214/* Raise a data fault alignment exception for the specified virtual address */
    215void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
    216                                 MMUAccessType access_type, int mmu_idx,
    217                                 uintptr_t retaddr) QEMU_NORETURN;
    218
    219/* translate.c */
    220
    221int ppc_fixup_cpu(PowerPCCPU *cpu);
    222void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp);
    223void destroy_ppc_opcodes(PowerPCCPU *cpu);
    224
    225/* gdbstub.c */
    226void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *ppc);
    227gchar *ppc_gdb_arch_name(CPUState *cs);
    228
    229/**
    230 * prot_for_access_type:
    231 * @access_type: Access type
    232 *
    233 * Return the protection bit required for the given access type.
    234 */
    235static inline int prot_for_access_type(MMUAccessType access_type)
    236{
    237    switch (access_type) {
    238    case MMU_INST_FETCH:
    239        return PAGE_EXEC;
    240    case MMU_DATA_LOAD:
    241        return PAGE_READ;
    242    case MMU_DATA_STORE:
    243        return PAGE_WRITE;
    244    }
    245    g_assert_not_reached();
    246}
    247
    248/* PowerPC MMU emulation */
    249
    250typedef struct mmu_ctx_t mmu_ctx_t;
    251bool ppc_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
    252                      hwaddr *raddrp, int *psizep, int *protp,
    253                      int mmu_idx, bool guest_visible);
    254int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
    255                                     target_ulong eaddr,
    256                                     MMUAccessType access_type, int type,
    257                                     int mmu_idx);
    258/* Software driven TLB helpers */
    259int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr,
    260                                    int way, int is_code);
    261/* Context used internally during MMU translations */
    262struct mmu_ctx_t {
    263    hwaddr raddr;      /* Real address              */
    264    hwaddr eaddr;      /* Effective address         */
    265    int prot;                      /* Protection bits           */
    266    hwaddr hash[2];    /* Pagetable hash values     */
    267    target_ulong ptem;             /* Virtual segment ID | API  */
    268    int key;                       /* Access key                */
    269    int nx;                        /* Non-execute area          */
    270};
    271
    272/* Common routines used by software and hardware TLBs emulation */
    273static inline int pte_is_valid(target_ulong pte0)
    274{
    275    return pte0 & 0x80000000 ? 1 : 0;
    276}
    277
    278static inline void pte_invalidate(target_ulong *pte0)
    279{
    280    *pte0 &= ~0x80000000;
    281}
    282
    283#define PTE_PTEM_MASK 0x7FFFFFBF
    284#define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
    285
    286
    287#endif /* PPC_INTERNAL_H */