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 (11442B)


      1/*
      2 * OpenRISC virtual CPU header.
      3 *
      4 * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
      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 OPENRISC_CPU_H
     21#define OPENRISC_CPU_H
     22
     23#include "exec/cpu-defs.h"
     24#include "hw/core/cpu.h"
     25#include "qom/object.h"
     26
     27/* cpu_openrisc_map_address_* in CPUOpenRISCTLBContext need this decl.  */
     28struct OpenRISCCPU;
     29
     30#define TYPE_OPENRISC_CPU "or1k-cpu"
     31
     32OBJECT_DECLARE_TYPE(OpenRISCCPU, OpenRISCCPUClass,
     33                    OPENRISC_CPU)
     34
     35/**
     36 * OpenRISCCPUClass:
     37 * @parent_realize: The parent class' realize handler.
     38 * @parent_reset: The parent class' reset handler.
     39 *
     40 * A OpenRISC CPU model.
     41 */
     42struct OpenRISCCPUClass {
     43    /*< private >*/
     44    CPUClass parent_class;
     45    /*< public >*/
     46
     47    DeviceRealize parent_realize;
     48    DeviceReset parent_reset;
     49};
     50
     51#define TARGET_INSN_START_EXTRA_WORDS 1
     52
     53enum {
     54    MMU_NOMMU_IDX = 0,
     55    MMU_SUPERVISOR_IDX = 1,
     56    MMU_USER_IDX = 2,
     57};
     58
     59#define SET_FP_CAUSE(reg, v)    do {\
     60                                    (reg) = ((reg) & ~(0x3f << 12)) | \
     61                                            ((v & 0x3f) << 12);\
     62                                } while (0)
     63#define GET_FP_ENABLE(reg)       (((reg) >>  7) & 0x1f)
     64#define UPDATE_FP_FLAGS(reg, v)   do {\
     65                                      (reg) |= ((v & 0x1f) << 2);\
     66                                  } while (0)
     67
     68/* Interrupt */
     69#define NR_IRQS  32
     70
     71/* Unit presece register */
     72enum {
     73    UPR_UP = (1 << 0),
     74    UPR_DCP = (1 << 1),
     75    UPR_ICP = (1 << 2),
     76    UPR_DMP = (1 << 3),
     77    UPR_IMP = (1 << 4),
     78    UPR_MP = (1 << 5),
     79    UPR_DUP = (1 << 6),
     80    UPR_PCUR = (1 << 7),
     81    UPR_PMP = (1 << 8),
     82    UPR_PICP = (1 << 9),
     83    UPR_TTP = (1 << 10),
     84    UPR_CUP = (255 << 24),
     85};
     86
     87/* CPU configure register */
     88enum {
     89    CPUCFGR_NSGF = (15 << 0),
     90    CPUCFGR_CGF = (1 << 4),
     91    CPUCFGR_OB32S = (1 << 5),
     92    CPUCFGR_OB64S = (1 << 6),
     93    CPUCFGR_OF32S = (1 << 7),
     94    CPUCFGR_OF64S = (1 << 8),
     95    CPUCFGR_OV64S = (1 << 9),
     96    CPUCFGR_ND = (1 << 10),
     97    CPUCFGR_AVRP = (1 << 11),
     98    CPUCFGR_EVBARP = (1 << 12),
     99    CPUCFGR_ISRP = (1 << 13),
    100    CPUCFGR_AECSRP = (1 << 14),
    101    CPUCFGR_OF64A32S = (1 << 15),
    102};
    103
    104/* DMMU configure register */
    105enum {
    106    DMMUCFGR_NTW = (3 << 0),
    107    DMMUCFGR_NTS = (7 << 2),
    108    DMMUCFGR_NAE = (7 << 5),
    109    DMMUCFGR_CRI = (1 << 8),
    110    DMMUCFGR_PRI = (1 << 9),
    111    DMMUCFGR_TEIRI = (1 << 10),
    112    DMMUCFGR_HTR = (1 << 11),
    113};
    114
    115/* IMMU configure register */
    116enum {
    117    IMMUCFGR_NTW = (3 << 0),
    118    IMMUCFGR_NTS = (7 << 2),
    119    IMMUCFGR_NAE = (7 << 5),
    120    IMMUCFGR_CRI = (1 << 8),
    121    IMMUCFGR_PRI = (1 << 9),
    122    IMMUCFGR_TEIRI = (1 << 10),
    123    IMMUCFGR_HTR = (1 << 11),
    124};
    125
    126/* Power management register */
    127enum {
    128    PMR_SDF = (15 << 0),
    129    PMR_DME = (1 << 4),
    130    PMR_SME = (1 << 5),
    131    PMR_DCGE = (1 << 6),
    132    PMR_SUME = (1 << 7),
    133};
    134
    135/* Float point control status register */
    136enum {
    137    FPCSR_FPEE = 1,
    138    FPCSR_RM = (3 << 1),
    139    FPCSR_OVF = (1 << 3),
    140    FPCSR_UNF = (1 << 4),
    141    FPCSR_SNF = (1 << 5),
    142    FPCSR_QNF = (1 << 6),
    143    FPCSR_ZF = (1 << 7),
    144    FPCSR_IXF = (1 << 8),
    145    FPCSR_IVF = (1 << 9),
    146    FPCSR_INF = (1 << 10),
    147    FPCSR_DZF = (1 << 11),
    148};
    149
    150/* Exceptions indices */
    151enum {
    152    EXCP_RESET    = 0x1,
    153    EXCP_BUSERR   = 0x2,
    154    EXCP_DPF      = 0x3,
    155    EXCP_IPF      = 0x4,
    156    EXCP_TICK     = 0x5,
    157    EXCP_ALIGN    = 0x6,
    158    EXCP_ILLEGAL  = 0x7,
    159    EXCP_INT      = 0x8,
    160    EXCP_DTLBMISS = 0x9,
    161    EXCP_ITLBMISS = 0xa,
    162    EXCP_RANGE    = 0xb,
    163    EXCP_SYSCALL  = 0xc,
    164    EXCP_FPE      = 0xd,
    165    EXCP_TRAP     = 0xe,
    166    EXCP_NR,
    167};
    168
    169/* Supervisor register */
    170enum {
    171    SR_SM = (1 << 0),
    172    SR_TEE = (1 << 1),
    173    SR_IEE = (1 << 2),
    174    SR_DCE = (1 << 3),
    175    SR_ICE = (1 << 4),
    176    SR_DME = (1 << 5),
    177    SR_IME = (1 << 6),
    178    SR_LEE = (1 << 7),
    179    SR_CE  = (1 << 8),
    180    SR_F   = (1 << 9),
    181    SR_CY  = (1 << 10),
    182    SR_OV  = (1 << 11),
    183    SR_OVE = (1 << 12),
    184    SR_DSX = (1 << 13),
    185    SR_EPH = (1 << 14),
    186    SR_FO  = (1 << 15),
    187    SR_SUMRA = (1 << 16),
    188    SR_SCE = (1 << 17),
    189};
    190
    191/* Tick Timer Mode Register */
    192enum {
    193    TTMR_TP = (0xfffffff),
    194    TTMR_IP = (1 << 28),
    195    TTMR_IE = (1 << 29),
    196    TTMR_M  = (3 << 30),
    197};
    198
    199/* Timer Mode */
    200enum {
    201    TIMER_NONE = (0 << 30),
    202    TIMER_INTR = (1 << 30),
    203    TIMER_SHOT = (2 << 30),
    204    TIMER_CONT = (3 << 30),
    205};
    206
    207/* TLB size */
    208enum {
    209    TLB_SIZE = 128,
    210    TLB_MASK = TLB_SIZE - 1,
    211};
    212
    213/* TLB prot */
    214enum {
    215    URE = (1 << 6),
    216    UWE = (1 << 7),
    217    SRE = (1 << 8),
    218    SWE = (1 << 9),
    219
    220    SXE = (1 << 6),
    221    UXE = (1 << 7),
    222};
    223
    224typedef struct OpenRISCTLBEntry {
    225    uint32_t mr;
    226    uint32_t tr;
    227} OpenRISCTLBEntry;
    228
    229#ifndef CONFIG_USER_ONLY
    230typedef struct CPUOpenRISCTLBContext {
    231    OpenRISCTLBEntry itlb[TLB_SIZE];
    232    OpenRISCTLBEntry dtlb[TLB_SIZE];
    233
    234    int (*cpu_openrisc_map_address_code)(struct OpenRISCCPU *cpu,
    235                                         hwaddr *physical,
    236                                         int *prot,
    237                                         target_ulong address, int rw);
    238    int (*cpu_openrisc_map_address_data)(struct OpenRISCCPU *cpu,
    239                                         hwaddr *physical,
    240                                         int *prot,
    241                                         target_ulong address, int rw);
    242} CPUOpenRISCTLBContext;
    243#endif
    244
    245typedef struct CPUOpenRISCState {
    246    target_ulong shadow_gpr[16][32]; /* Shadow registers */
    247
    248    target_ulong pc;          /* Program counter */
    249    target_ulong ppc;         /* Prev PC */
    250    target_ulong jmp_pc;      /* Jump PC */
    251
    252    uint64_t mac;             /* Multiply registers MACHI:MACLO */
    253
    254    target_ulong epcr;        /* Exception PC register */
    255    target_ulong eear;        /* Exception EA register */
    256
    257    target_ulong sr_f;        /* the SR_F bit, values 0, 1.  */
    258    target_ulong sr_cy;       /* the SR_CY bit, values 0, 1.  */
    259    target_long  sr_ov;       /* the SR_OV bit (in the sign bit only) */
    260    uint32_t sr;              /* Supervisor register, without SR_{F,CY,OV} */
    261    uint32_t esr;             /* Exception supervisor register */
    262    uint32_t evbar;           /* Exception vector base address register */
    263    uint32_t pmr;             /* Power Management Register */
    264    uint32_t fpcsr;           /* Float register */
    265    float_status fp_status;
    266
    267    target_ulong lock_addr;
    268    target_ulong lock_value;
    269
    270    uint32_t dflag;           /* In delay slot (boolean) */
    271
    272#ifndef CONFIG_USER_ONLY
    273    CPUOpenRISCTLBContext tlb;
    274#endif
    275
    276    /* Fields up to this point are cleared by a CPU reset */
    277    struct {} end_reset_fields;
    278
    279    /* Fields from here on are preserved across CPU reset. */
    280    uint32_t vr;              /* Version register */
    281    uint32_t vr2;             /* Version register 2 */
    282    uint32_t avr;             /* Architecture version register */
    283    uint32_t upr;             /* Unit presence register */
    284    uint32_t cpucfgr;         /* CPU configure register */
    285    uint32_t dmmucfgr;        /* DMMU configure register */
    286    uint32_t immucfgr;        /* IMMU configure register */
    287
    288#ifndef CONFIG_USER_ONLY
    289    QEMUTimer *timer;
    290    uint32_t ttmr;          /* Timer tick mode register */
    291    int is_counting;
    292
    293    uint32_t picmr;         /* Interrupt mask register */
    294    uint32_t picsr;         /* Interrupt contrl register*/
    295#endif
    296} CPUOpenRISCState;
    297
    298/**
    299 * OpenRISCCPU:
    300 * @env: #CPUOpenRISCState
    301 *
    302 * A OpenRISC CPU.
    303 */
    304struct OpenRISCCPU {
    305    /*< private >*/
    306    CPUState parent_obj;
    307    /*< public >*/
    308
    309    CPUNegativeOffsetState neg;
    310    CPUOpenRISCState env;
    311};
    312
    313
    314void cpu_openrisc_list(void);
    315void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
    316hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
    317int openrisc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
    318int openrisc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
    319void openrisc_translate_init(void);
    320bool openrisc_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
    321                           MMUAccessType access_type, int mmu_idx,
    322                           bool probe, uintptr_t retaddr);
    323int print_insn_or1k(bfd_vma addr, disassemble_info *info);
    324
    325#define cpu_list cpu_openrisc_list
    326
    327#ifndef CONFIG_USER_ONLY
    328extern const VMStateDescription vmstate_openrisc_cpu;
    329
    330void openrisc_cpu_do_interrupt(CPUState *cpu);
    331bool openrisc_cpu_exec_interrupt(CPUState *cpu, int int_req);
    332
    333/* hw/openrisc_pic.c */
    334void cpu_openrisc_pic_init(OpenRISCCPU *cpu);
    335
    336/* hw/openrisc_timer.c */
    337void cpu_openrisc_clock_init(OpenRISCCPU *cpu);
    338uint32_t cpu_openrisc_count_get(OpenRISCCPU *cpu);
    339void cpu_openrisc_count_set(OpenRISCCPU *cpu, uint32_t val);
    340void cpu_openrisc_count_update(OpenRISCCPU *cpu);
    341void cpu_openrisc_timer_update(OpenRISCCPU *cpu);
    342void cpu_openrisc_count_start(OpenRISCCPU *cpu);
    343void cpu_openrisc_count_stop(OpenRISCCPU *cpu);
    344#endif
    345
    346#define OPENRISC_CPU_TYPE_SUFFIX "-" TYPE_OPENRISC_CPU
    347#define OPENRISC_CPU_TYPE_NAME(model) model OPENRISC_CPU_TYPE_SUFFIX
    348#define CPU_RESOLVING_TYPE TYPE_OPENRISC_CPU
    349
    350typedef CPUOpenRISCState CPUArchState;
    351typedef OpenRISCCPU ArchCPU;
    352
    353#include "exec/cpu-all.h"
    354
    355#define TB_FLAGS_SM    SR_SM
    356#define TB_FLAGS_DME   SR_DME
    357#define TB_FLAGS_IME   SR_IME
    358#define TB_FLAGS_OVE   SR_OVE
    359#define TB_FLAGS_DFLAG 2      /* reuse SR_TEE */
    360#define TB_FLAGS_R0_0  4      /* reuse SR_IEE */
    361
    362static inline uint32_t cpu_get_gpr(const CPUOpenRISCState *env, int i)
    363{
    364    return env->shadow_gpr[0][i];
    365}
    366
    367static inline void cpu_set_gpr(CPUOpenRISCState *env, int i, uint32_t val)
    368{
    369    env->shadow_gpr[0][i] = val;
    370}
    371
    372static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env,
    373                                        target_ulong *pc,
    374                                        target_ulong *cs_base, uint32_t *flags)
    375{
    376    *pc = env->pc;
    377    *cs_base = 0;
    378    *flags = (env->dflag ? TB_FLAGS_DFLAG : 0)
    379           | (cpu_get_gpr(env, 0) ? 0 : TB_FLAGS_R0_0)
    380           | (env->sr & (SR_SM | SR_DME | SR_IME | SR_OVE));
    381}
    382
    383static inline int cpu_mmu_index(CPUOpenRISCState *env, bool ifetch)
    384{
    385    int ret = MMU_NOMMU_IDX;  /* mmu is disabled */
    386
    387    if (env->sr & (ifetch ? SR_IME : SR_DME)) {
    388        /* The mmu is enabled; test supervisor state.  */
    389        ret = env->sr & SR_SM ? MMU_SUPERVISOR_IDX : MMU_USER_IDX;
    390    }
    391
    392    return ret;
    393}
    394
    395static inline uint32_t cpu_get_sr(const CPUOpenRISCState *env)
    396{
    397    return (env->sr
    398            + env->sr_f * SR_F
    399            + env->sr_cy * SR_CY
    400            + (env->sr_ov < 0) * SR_OV);
    401}
    402
    403static inline void cpu_set_sr(CPUOpenRISCState *env, uint32_t val)
    404{
    405    env->sr_f = (val & SR_F) != 0;
    406    env->sr_cy = (val & SR_CY) != 0;
    407    env->sr_ov = (val & SR_OV ? -1 : 0);
    408    env->sr = (val & ~(SR_F | SR_CY | SR_OV)) | SR_FO;
    409}
    410
    411void cpu_set_fpcsr(CPUOpenRISCState *env, uint32_t val);
    412
    413#define CPU_INTERRUPT_TIMER   CPU_INTERRUPT_TGT_INT_0
    414
    415#endif /* OPENRISC_CPU_H */