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

cpu.h (14614B)


      1/*
      2 *  Alpha emulation cpu definitions for qemu.
      3 *
      4 *  Copyright (c) 2007 Jocelyn Mayer
      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#ifndef ALPHA_CPU_H
     21#define ALPHA_CPU_H
     22
     23#include "cpu-qom.h"
     24#include "exec/cpu-defs.h"
     25
     26/* Alpha processors have a weak memory model */
     27#define TCG_GUEST_DEFAULT_MO      (0)
     28
     29#define ICACHE_LINE_SIZE 32
     30#define DCACHE_LINE_SIZE 32
     31
     32/* Alpha major type */
     33enum {
     34    ALPHA_EV3  = 1,
     35    ALPHA_EV4  = 2,
     36    ALPHA_SIM  = 3,
     37    ALPHA_LCA  = 4,
     38    ALPHA_EV5  = 5, /* 21164 */
     39    ALPHA_EV45 = 6, /* 21064A */
     40    ALPHA_EV56 = 7, /* 21164A */
     41};
     42
     43/* EV4 minor type */
     44enum {
     45    ALPHA_EV4_2 = 0,
     46    ALPHA_EV4_3 = 1,
     47};
     48
     49/* LCA minor type */
     50enum {
     51    ALPHA_LCA_1 = 1, /* 21066 */
     52    ALPHA_LCA_2 = 2, /* 20166 */
     53    ALPHA_LCA_3 = 3, /* 21068 */
     54    ALPHA_LCA_4 = 4, /* 21068 */
     55    ALPHA_LCA_5 = 5, /* 21066A */
     56    ALPHA_LCA_6 = 6, /* 21068A */
     57};
     58
     59/* EV5 minor type */
     60enum {
     61    ALPHA_EV5_1 = 1, /* Rev BA, CA */
     62    ALPHA_EV5_2 = 2, /* Rev DA, EA */
     63    ALPHA_EV5_3 = 3, /* Pass 3 */
     64    ALPHA_EV5_4 = 4, /* Pass 3.2 */
     65    ALPHA_EV5_5 = 5, /* Pass 4 */
     66};
     67
     68/* EV45 minor type */
     69enum {
     70    ALPHA_EV45_1 = 1, /* Pass 1 */
     71    ALPHA_EV45_2 = 2, /* Pass 1.1 */
     72    ALPHA_EV45_3 = 3, /* Pass 2 */
     73};
     74
     75/* EV56 minor type */
     76enum {
     77    ALPHA_EV56_1 = 1, /* Pass 1 */
     78    ALPHA_EV56_2 = 2, /* Pass 2 */
     79};
     80
     81enum {
     82    IMPLVER_2106x = 0, /* EV4, EV45 & LCA45 */
     83    IMPLVER_21164 = 1, /* EV5, EV56 & PCA45 */
     84    IMPLVER_21264 = 2, /* EV6, EV67 & EV68x */
     85    IMPLVER_21364 = 3, /* EV7 & EV79 */
     86};
     87
     88enum {
     89    AMASK_BWX      = 0x00000001,
     90    AMASK_FIX      = 0x00000002,
     91    AMASK_CIX      = 0x00000004,
     92    AMASK_MVI      = 0x00000100,
     93    AMASK_TRAP     = 0x00000200,
     94    AMASK_PREFETCH = 0x00001000,
     95};
     96
     97enum {
     98    VAX_ROUND_NORMAL = 0,
     99    VAX_ROUND_CHOPPED,
    100};
    101
    102enum {
    103    IEEE_ROUND_NORMAL = 0,
    104    IEEE_ROUND_DYNAMIC,
    105    IEEE_ROUND_PLUS,
    106    IEEE_ROUND_MINUS,
    107    IEEE_ROUND_CHOPPED,
    108};
    109
    110/* IEEE floating-point operations encoding */
    111/* Trap mode */
    112enum {
    113    FP_TRAP_I   = 0x0,
    114    FP_TRAP_U   = 0x1,
    115    FP_TRAP_S  = 0x4,
    116    FP_TRAP_SU  = 0x5,
    117    FP_TRAP_SUI = 0x7,
    118};
    119
    120/* Rounding mode */
    121enum {
    122    FP_ROUND_CHOPPED = 0x0,
    123    FP_ROUND_MINUS   = 0x1,
    124    FP_ROUND_NORMAL  = 0x2,
    125    FP_ROUND_DYNAMIC = 0x3,
    126};
    127
    128/* FPCR bits -- right-shifted 32 so we can use a uint32_t.  */
    129#define FPCR_SUM                (1U << (63 - 32))
    130#define FPCR_INED               (1U << (62 - 32))
    131#define FPCR_UNFD               (1U << (61 - 32))
    132#define FPCR_UNDZ               (1U << (60 - 32))
    133#define FPCR_DYN_SHIFT          (58 - 32)
    134#define FPCR_DYN_CHOPPED        (0U << FPCR_DYN_SHIFT)
    135#define FPCR_DYN_MINUS          (1U << FPCR_DYN_SHIFT)
    136#define FPCR_DYN_NORMAL         (2U << FPCR_DYN_SHIFT)
    137#define FPCR_DYN_PLUS           (3U << FPCR_DYN_SHIFT)
    138#define FPCR_DYN_MASK           (3U << FPCR_DYN_SHIFT)
    139#define FPCR_IOV                (1U << (57 - 32))
    140#define FPCR_INE                (1U << (56 - 32))
    141#define FPCR_UNF                (1U << (55 - 32))
    142#define FPCR_OVF                (1U << (54 - 32))
    143#define FPCR_DZE                (1U << (53 - 32))
    144#define FPCR_INV                (1U << (52 - 32))
    145#define FPCR_OVFD               (1U << (51 - 32))
    146#define FPCR_DZED               (1U << (50 - 32))
    147#define FPCR_INVD               (1U << (49 - 32))
    148#define FPCR_DNZ                (1U << (48 - 32))
    149#define FPCR_DNOD               (1U << (47 - 32))
    150#define FPCR_STATUS_MASK        (FPCR_IOV | FPCR_INE | FPCR_UNF \
    151                                 | FPCR_OVF | FPCR_DZE | FPCR_INV)
    152
    153/* The silly software trap enables implemented by the kernel emulation.
    154   These are more or less architecturally required, since the real hardware
    155   has read-as-zero bits in the FPCR when the features aren't implemented.
    156   For the purposes of QEMU, we pretend the FPCR can hold everything.  */
    157#define SWCR_TRAP_ENABLE_INV    (1U << 1)
    158#define SWCR_TRAP_ENABLE_DZE    (1U << 2)
    159#define SWCR_TRAP_ENABLE_OVF    (1U << 3)
    160#define SWCR_TRAP_ENABLE_UNF    (1U << 4)
    161#define SWCR_TRAP_ENABLE_INE    (1U << 5)
    162#define SWCR_TRAP_ENABLE_DNO    (1U << 6)
    163#define SWCR_TRAP_ENABLE_MASK   ((1U << 7) - (1U << 1))
    164
    165#define SWCR_MAP_DMZ            (1U << 12)
    166#define SWCR_MAP_UMZ            (1U << 13)
    167#define SWCR_MAP_MASK           (SWCR_MAP_DMZ | SWCR_MAP_UMZ)
    168
    169#define SWCR_STATUS_INV         (1U << 17)
    170#define SWCR_STATUS_DZE         (1U << 18)
    171#define SWCR_STATUS_OVF         (1U << 19)
    172#define SWCR_STATUS_UNF         (1U << 20)
    173#define SWCR_STATUS_INE         (1U << 21)
    174#define SWCR_STATUS_DNO         (1U << 22)
    175#define SWCR_STATUS_MASK        ((1U << 23) - (1U << 17))
    176
    177#define SWCR_STATUS_TO_EXCSUM_SHIFT  16
    178
    179#define SWCR_MASK  (SWCR_TRAP_ENABLE_MASK | SWCR_MAP_MASK | SWCR_STATUS_MASK)
    180
    181/* MMU modes definitions */
    182
    183/* Alpha has 5 MMU modes: PALcode, Kernel, Executive, Supervisor, and User.
    184   The Unix PALcode only exposes the kernel and user modes; presumably
    185   executive and supervisor are used by VMS.
    186
    187   PALcode itself uses physical mode for code and kernel mode for data;
    188   there are PALmode instructions that can access data via physical mode
    189   or via an os-installed "alternate mode", which is one of the 4 above.
    190
    191   That said, we're only emulating Unix PALcode, and not attempting VMS,
    192   so we don't need to implement Executive and Supervisor.  QEMU's own
    193   PALcode cheats and usees the KSEG mapping for its code+data rather than
    194   physical addresses.  */
    195
    196#define MMU_KERNEL_IDX   0
    197#define MMU_USER_IDX     1
    198#define MMU_PHYS_IDX     2
    199
    200typedef struct CPUAlphaState CPUAlphaState;
    201
    202struct CPUAlphaState {
    203    uint64_t ir[31];
    204    float64 fir[31];
    205    uint64_t pc;
    206    uint64_t unique;
    207    uint64_t lock_addr;
    208    uint64_t lock_value;
    209
    210    /* The FPCR, and disassembled portions thereof.  */
    211    uint32_t fpcr;
    212#ifdef CONFIG_USER_ONLY
    213    uint32_t swcr;
    214#endif
    215    uint32_t fpcr_exc_enable;
    216    float_status fp_status;
    217    uint8_t fpcr_dyn_round;
    218    uint8_t fpcr_flush_to_zero;
    219
    220    /* Mask of PALmode, Processor State et al.  Most of this gets copied
    221       into the TranslatorBlock flags and controls code generation.  */
    222    uint32_t flags;
    223
    224    /* The high 32-bits of the processor cycle counter.  */
    225    uint32_t pcc_ofs;
    226
    227    /* These pass data from the exception logic in the translator and
    228       helpers to the OS entry point.  This is used for both system
    229       emulation and user-mode.  */
    230    uint64_t trap_arg0;
    231    uint64_t trap_arg1;
    232    uint64_t trap_arg2;
    233
    234#if !defined(CONFIG_USER_ONLY)
    235    /* The internal data required by our emulation of the Unix PALcode.  */
    236    uint64_t exc_addr;
    237    uint64_t palbr;
    238    uint64_t ptbr;
    239    uint64_t vptptr;
    240    uint64_t sysval;
    241    uint64_t usp;
    242    uint64_t shadow[8];
    243    uint64_t scratch[24];
    244#endif
    245
    246    /* This alarm doesn't exist in real hardware; we wish it did.  */
    247    uint64_t alarm_expire;
    248
    249    int error_code;
    250
    251    uint32_t features;
    252    uint32_t amask;
    253    int implver;
    254};
    255
    256/**
    257 * AlphaCPU:
    258 * @env: #CPUAlphaState
    259 *
    260 * An Alpha CPU.
    261 */
    262struct AlphaCPU {
    263    /*< private >*/
    264    CPUState parent_obj;
    265    /*< public >*/
    266
    267    CPUNegativeOffsetState neg;
    268    CPUAlphaState env;
    269
    270    /* This alarm doesn't exist in real hardware; we wish it did.  */
    271    QEMUTimer *alarm_timer;
    272};
    273
    274
    275#ifndef CONFIG_USER_ONLY
    276extern const VMStateDescription vmstate_alpha_cpu;
    277
    278void alpha_cpu_do_interrupt(CPUState *cpu);
    279bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req);
    280#endif /* !CONFIG_USER_ONLY */
    281void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags);
    282hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
    283int alpha_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
    284int alpha_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
    285void alpha_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
    286                                   MMUAccessType access_type, int mmu_idx,
    287                                   uintptr_t retaddr) QEMU_NORETURN;
    288
    289#define cpu_list alpha_cpu_list
    290
    291typedef CPUAlphaState CPUArchState;
    292typedef AlphaCPU ArchCPU;
    293
    294#include "exec/cpu-all.h"
    295
    296enum {
    297    FEATURE_ASN    = 0x00000001,
    298    FEATURE_SPS    = 0x00000002,
    299    FEATURE_VIRBND = 0x00000004,
    300    FEATURE_TBCHK  = 0x00000008,
    301};
    302
    303enum {
    304    EXCP_RESET,
    305    EXCP_MCHK,
    306    EXCP_SMP_INTERRUPT,
    307    EXCP_CLK_INTERRUPT,
    308    EXCP_DEV_INTERRUPT,
    309    EXCP_MMFAULT,
    310    EXCP_UNALIGN,
    311    EXCP_OPCDEC,
    312    EXCP_ARITH,
    313    EXCP_FEN,
    314    EXCP_CALL_PAL,
    315};
    316
    317/* Alpha-specific interrupt pending bits.  */
    318#define CPU_INTERRUPT_TIMER	CPU_INTERRUPT_TGT_EXT_0
    319#define CPU_INTERRUPT_SMP	CPU_INTERRUPT_TGT_EXT_1
    320#define CPU_INTERRUPT_MCHK	CPU_INTERRUPT_TGT_EXT_2
    321
    322/* OSF/1 Page table bits.  */
    323enum {
    324    PTE_VALID = 0x0001,
    325    PTE_FOR   = 0x0002,  /* used for page protection (fault on read) */
    326    PTE_FOW   = 0x0004,  /* used for page protection (fault on write) */
    327    PTE_FOE   = 0x0008,  /* used for page protection (fault on exec) */
    328    PTE_ASM   = 0x0010,
    329    PTE_KRE   = 0x0100,
    330    PTE_URE   = 0x0200,
    331    PTE_KWE   = 0x1000,
    332    PTE_UWE   = 0x2000
    333};
    334
    335/* Hardware interrupt (entInt) constants.  */
    336enum {
    337    INT_K_IP,
    338    INT_K_CLK,
    339    INT_K_MCHK,
    340    INT_K_DEV,
    341    INT_K_PERF,
    342};
    343
    344/* Memory management (entMM) constants.  */
    345enum {
    346    MM_K_TNV,
    347    MM_K_ACV,
    348    MM_K_FOR,
    349    MM_K_FOE,
    350    MM_K_FOW
    351};
    352
    353/* Arithmetic exception (entArith) constants.  */
    354enum {
    355    EXC_M_SWC = 1,      /* Software completion */
    356    EXC_M_INV = 2,      /* Invalid operation */
    357    EXC_M_DZE = 4,      /* Division by zero */
    358    EXC_M_FOV = 8,      /* Overflow */
    359    EXC_M_UNF = 16,     /* Underflow */
    360    EXC_M_INE = 32,     /* Inexact result */
    361    EXC_M_IOV = 64      /* Integer Overflow */
    362};
    363
    364/* Processor status constants.  */
    365/* Low 3 bits are interrupt mask level.  */
    366#define PS_INT_MASK   7u
    367
    368/* Bits 4 and 5 are the mmu mode.  The VMS PALcode uses all 4 modes;
    369   The Unix PALcode only uses bit 4.  */
    370#define PS_USER_MODE  8u
    371
    372/* CPUAlphaState->flags constants.  These are layed out so that we
    373   can set or reset the pieces individually by assigning to the byte,
    374   or manipulated as a whole.  */
    375
    376#define ENV_FLAG_PAL_SHIFT    0
    377#define ENV_FLAG_PS_SHIFT     8
    378#define ENV_FLAG_RX_SHIFT     16
    379#define ENV_FLAG_FEN_SHIFT    24
    380
    381#define ENV_FLAG_PAL_MODE     (1u << ENV_FLAG_PAL_SHIFT)
    382#define ENV_FLAG_PS_USER      (PS_USER_MODE << ENV_FLAG_PS_SHIFT)
    383#define ENV_FLAG_RX_FLAG      (1u << ENV_FLAG_RX_SHIFT)
    384#define ENV_FLAG_FEN          (1u << ENV_FLAG_FEN_SHIFT)
    385
    386#define ENV_FLAG_TB_MASK \
    387    (ENV_FLAG_PAL_MODE | ENV_FLAG_PS_USER | ENV_FLAG_FEN)
    388
    389static inline int cpu_mmu_index(CPUAlphaState *env, bool ifetch)
    390{
    391    int ret = env->flags & ENV_FLAG_PS_USER ? MMU_USER_IDX : MMU_KERNEL_IDX;
    392    if (env->flags & ENV_FLAG_PAL_MODE) {
    393        ret = MMU_KERNEL_IDX;
    394    }
    395    return ret;
    396}
    397
    398enum {
    399    IR_V0   = 0,
    400    IR_T0   = 1,
    401    IR_T1   = 2,
    402    IR_T2   = 3,
    403    IR_T3   = 4,
    404    IR_T4   = 5,
    405    IR_T5   = 6,
    406    IR_T6   = 7,
    407    IR_T7   = 8,
    408    IR_S0   = 9,
    409    IR_S1   = 10,
    410    IR_S2   = 11,
    411    IR_S3   = 12,
    412    IR_S4   = 13,
    413    IR_S5   = 14,
    414    IR_S6   = 15,
    415    IR_FP   = IR_S6,
    416    IR_A0   = 16,
    417    IR_A1   = 17,
    418    IR_A2   = 18,
    419    IR_A3   = 19,
    420    IR_A4   = 20,
    421    IR_A5   = 21,
    422    IR_T8   = 22,
    423    IR_T9   = 23,
    424    IR_T10  = 24,
    425    IR_T11  = 25,
    426    IR_RA   = 26,
    427    IR_T12  = 27,
    428    IR_PV   = IR_T12,
    429    IR_AT   = 28,
    430    IR_GP   = 29,
    431    IR_SP   = 30,
    432    IR_ZERO = 31,
    433};
    434
    435void alpha_translate_init(void);
    436
    437#define ALPHA_CPU_TYPE_SUFFIX "-" TYPE_ALPHA_CPU
    438#define ALPHA_CPU_TYPE_NAME(model) model ALPHA_CPU_TYPE_SUFFIX
    439#define CPU_RESOLVING_TYPE TYPE_ALPHA_CPU
    440
    441void alpha_cpu_list(void);
    442bool alpha_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
    443                        MMUAccessType access_type, int mmu_idx,
    444                        bool probe, uintptr_t retaddr);
    445void QEMU_NORETURN dynamic_excp(CPUAlphaState *, uintptr_t, int, int);
    446void QEMU_NORETURN arith_excp(CPUAlphaState *, uintptr_t, int, uint64_t);
    447
    448uint64_t cpu_alpha_load_fpcr (CPUAlphaState *env);
    449void cpu_alpha_store_fpcr (CPUAlphaState *env, uint64_t val);
    450uint64_t cpu_alpha_load_gr(CPUAlphaState *env, unsigned reg);
    451void cpu_alpha_store_gr(CPUAlphaState *env, unsigned reg, uint64_t val);
    452#ifndef CONFIG_USER_ONLY
    453void alpha_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
    454                                     vaddr addr, unsigned size,
    455                                     MMUAccessType access_type,
    456                                     int mmu_idx, MemTxAttrs attrs,
    457                                     MemTxResult response, uintptr_t retaddr);
    458#endif
    459
    460static inline void cpu_get_tb_cpu_state(CPUAlphaState *env, target_ulong *pc,
    461                                        target_ulong *cs_base, uint32_t *pflags)
    462{
    463    *pc = env->pc;
    464    *cs_base = 0;
    465    *pflags = env->flags & ENV_FLAG_TB_MASK;
    466}
    467
    468#ifdef CONFIG_USER_ONLY
    469/* Copied from linux ieee_swcr_to_fpcr.  */
    470static inline uint64_t alpha_ieee_swcr_to_fpcr(uint64_t swcr)
    471{
    472    uint64_t fpcr = 0;
    473
    474    fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
    475    fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
    476    fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
    477                      | SWCR_TRAP_ENABLE_DZE
    478                      | SWCR_TRAP_ENABLE_OVF)) << 48;
    479    fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
    480                      | SWCR_TRAP_ENABLE_INE)) << 57;
    481    fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
    482    fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
    483
    484    return fpcr;
    485}
    486
    487/* Copied from linux ieee_fpcr_to_swcr.  */
    488static inline uint64_t alpha_ieee_fpcr_to_swcr(uint64_t fpcr)
    489{
    490    uint64_t swcr = 0;
    491
    492    swcr |= (fpcr >> 35) & SWCR_STATUS_MASK;
    493    swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
    494    swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
    495                             | SWCR_TRAP_ENABLE_DZE
    496                             | SWCR_TRAP_ENABLE_OVF);
    497    swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF | SWCR_TRAP_ENABLE_INE);
    498    swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
    499    swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
    500
    501    return swcr;
    502}
    503#endif /* CONFIG_USER_ONLY */
    504
    505#endif /* ALPHA_CPU_H */