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