qemu/target/lm32/cpu.h
<<
>>
Prefs
   1/*
   2 *  LatticeMico32 virtual CPU header.
   3 *
   4 *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
   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 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 LM32_CPU_H
  21#define LM32_CPU_H
  22
  23#define TARGET_LONG_BITS 32
  24
  25#define CPUArchState struct CPULM32State
  26
  27#include "qemu-common.h"
  28#include "cpu-qom.h"
  29#include "exec/cpu-defs.h"
  30struct CPULM32State;
  31typedef struct CPULM32State CPULM32State;
  32
  33#define NB_MMU_MODES 1
  34#define TARGET_PAGE_BITS 12
  35static inline int cpu_mmu_index(CPULM32State *env, bool ifetch)
  36{
  37    return 0;
  38}
  39
  40#define TARGET_PHYS_ADDR_SPACE_BITS 32
  41#define TARGET_VIRT_ADDR_SPACE_BITS 32
  42
  43/* Exceptions indices */
  44enum {
  45    EXCP_RESET = 0,
  46    EXCP_BREAKPOINT,
  47    EXCP_INSN_BUS_ERROR,
  48    EXCP_WATCHPOINT,
  49    EXCP_DATA_BUS_ERROR,
  50    EXCP_DIVIDE_BY_ZERO,
  51    EXCP_IRQ,
  52    EXCP_SYSTEMCALL
  53};
  54
  55/* Registers */
  56enum {
  57    R_R0 = 0, R_R1, R_R2, R_R3, R_R4, R_R5, R_R6, R_R7, R_R8, R_R9, R_R10,
  58    R_R11, R_R12, R_R13, R_R14, R_R15, R_R16, R_R17, R_R18, R_R19, R_R20,
  59    R_R21, R_R22, R_R23, R_R24, R_R25, R_R26, R_R27, R_R28, R_R29, R_R30,
  60    R_R31
  61};
  62
  63/* Register aliases */
  64enum {
  65    R_GP = R_R26,
  66    R_FP = R_R27,
  67    R_SP = R_R28,
  68    R_RA = R_R29,
  69    R_EA = R_R30,
  70    R_BA = R_R31
  71};
  72
  73/* IE flags */
  74enum {
  75    IE_IE  = (1<<0),
  76    IE_EIE = (1<<1),
  77    IE_BIE = (1<<2),
  78};
  79
  80/* DC flags */
  81enum {
  82    DC_SS  = (1<<0),
  83    DC_RE  = (1<<1),
  84    DC_C0  = (1<<2),
  85    DC_C1  = (1<<3),
  86    DC_C2  = (1<<4),
  87    DC_C3  = (1<<5),
  88};
  89
  90/* CFG mask */
  91enum {
  92    CFG_M         = (1<<0),
  93    CFG_D         = (1<<1),
  94    CFG_S         = (1<<2),
  95    CFG_U         = (1<<3),
  96    CFG_X         = (1<<4),
  97    CFG_CC        = (1<<5),
  98    CFG_IC        = (1<<6),
  99    CFG_DC        = (1<<7),
 100    CFG_G         = (1<<8),
 101    CFG_H         = (1<<9),
 102    CFG_R         = (1<<10),
 103    CFG_J         = (1<<11),
 104    CFG_INT_SHIFT = 12,
 105    CFG_BP_SHIFT  = 18,
 106    CFG_WP_SHIFT  = 22,
 107    CFG_REV_SHIFT = 26,
 108};
 109
 110/* CSRs */
 111enum {
 112    CSR_IE   = 0x00,
 113    CSR_IM   = 0x01,
 114    CSR_IP   = 0x02,
 115    CSR_ICC  = 0x03,
 116    CSR_DCC  = 0x04,
 117    CSR_CC   = 0x05,
 118    CSR_CFG  = 0x06,
 119    CSR_EBA  = 0x07,
 120    CSR_DC   = 0x08,
 121    CSR_DEBA = 0x09,
 122    CSR_JTX  = 0x0e,
 123    CSR_JRX  = 0x0f,
 124    CSR_BP0  = 0x10,
 125    CSR_BP1  = 0x11,
 126    CSR_BP2  = 0x12,
 127    CSR_BP3  = 0x13,
 128    CSR_WP0  = 0x18,
 129    CSR_WP1  = 0x19,
 130    CSR_WP2  = 0x1a,
 131    CSR_WP3  = 0x1b,
 132};
 133
 134enum {
 135    LM32_FEATURE_MULTIPLY     =  1,
 136    LM32_FEATURE_DIVIDE       =  2,
 137    LM32_FEATURE_SHIFT        =  4,
 138    LM32_FEATURE_SIGN_EXTEND  =  8,
 139    LM32_FEATURE_I_CACHE      = 16,
 140    LM32_FEATURE_D_CACHE      = 32,
 141    LM32_FEATURE_CYCLE_COUNT  = 64,
 142};
 143
 144enum {
 145    LM32_FLAG_IGNORE_MSB = 1,
 146};
 147
 148struct CPULM32State {
 149    /* general registers */
 150    uint32_t regs[32];
 151
 152    /* special registers */
 153    uint32_t pc;        /* program counter */
 154    uint32_t ie;        /* interrupt enable */
 155    uint32_t icc;       /* instruction cache control */
 156    uint32_t dcc;       /* data cache control */
 157    uint32_t cc;        /* cycle counter */
 158    uint32_t cfg;       /* configuration */
 159
 160    /* debug registers */
 161    uint32_t dc;        /* debug control */
 162    uint32_t bp[4];     /* breakpoints */
 163    uint32_t wp[4];     /* watchpoints */
 164
 165    struct CPUBreakpoint *cpu_breakpoint[4];
 166    struct CPUWatchpoint *cpu_watchpoint[4];
 167
 168    /* Fields up to this point are cleared by a CPU reset */
 169    struct {} end_reset_fields;
 170
 171    CPU_COMMON
 172
 173    /* Fields from here on are preserved across CPU reset. */
 174    uint32_t eba;       /* exception base address */
 175    uint32_t deba;      /* debug exception base address */
 176
 177    /* interrupt controller handle for callbacks */
 178    DeviceState *pic_state;
 179    /* JTAG UART handle for callbacks */
 180    DeviceState *juart_state;
 181
 182    /* processor core features */
 183    uint32_t flags;
 184
 185};
 186
 187/**
 188 * LM32CPU:
 189 * @env: #CPULM32State
 190 *
 191 * A LatticeMico32 CPU.
 192 */
 193struct LM32CPU {
 194    /*< private >*/
 195    CPUState parent_obj;
 196    /*< public >*/
 197
 198    CPULM32State env;
 199
 200    uint32_t revision;
 201    uint8_t num_interrupts;
 202    uint8_t num_breakpoints;
 203    uint8_t num_watchpoints;
 204    uint32_t features;
 205};
 206
 207static inline LM32CPU *lm32_env_get_cpu(CPULM32State *env)
 208{
 209    return container_of(env, LM32CPU, env);
 210}
 211
 212#define ENV_GET_CPU(e) CPU(lm32_env_get_cpu(e))
 213
 214#define ENV_OFFSET offsetof(LM32CPU, env)
 215
 216#ifndef CONFIG_USER_ONLY
 217extern const struct VMStateDescription vmstate_lm32_cpu;
 218#endif
 219
 220void lm32_cpu_do_interrupt(CPUState *cpu);
 221bool lm32_cpu_exec_interrupt(CPUState *cs, int int_req);
 222void lm32_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
 223                         int flags);
 224hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 225int lm32_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
 226int lm32_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 227
 228typedef enum {
 229    LM32_WP_DISABLED = 0,
 230    LM32_WP_READ,
 231    LM32_WP_WRITE,
 232    LM32_WP_READ_WRITE,
 233} lm32_wp_t;
 234
 235static inline lm32_wp_t lm32_wp_type(uint32_t dc, int idx)
 236{
 237    assert(idx < 4);
 238    return (dc >> (idx+1)*2) & 0x3;
 239}
 240
 241/* you can call this signal handler from your SIGBUS and SIGSEGV
 242   signal handlers to inform the virtual CPU of exceptions. non zero
 243   is returned if the signal was handled by the virtual CPU.  */
 244int cpu_lm32_signal_handler(int host_signum, void *pinfo,
 245                          void *puc);
 246void lm32_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 247void lm32_translate_init(void);
 248void cpu_lm32_set_phys_msb_ignore(CPULM32State *env, int value);
 249void QEMU_NORETURN raise_exception(CPULM32State *env, int index);
 250void lm32_debug_excp_handler(CPUState *cs);
 251void lm32_breakpoint_insert(CPULM32State *env, int index, target_ulong address);
 252void lm32_breakpoint_remove(CPULM32State *env, int index);
 253void lm32_watchpoint_insert(CPULM32State *env, int index, target_ulong address,
 254        lm32_wp_t wp_type);
 255void lm32_watchpoint_remove(CPULM32State *env, int index);
 256bool lm32_cpu_do_semihosting(CPUState *cs);
 257
 258#define LM32_CPU_TYPE_SUFFIX "-" TYPE_LM32_CPU
 259#define LM32_CPU_TYPE_NAME(model) model LM32_CPU_TYPE_SUFFIX
 260#define CPU_RESOLVING_TYPE TYPE_LM32_CPU
 261
 262#define cpu_list lm32_cpu_list
 263#define cpu_signal_handler cpu_lm32_signal_handler
 264
 265int lm32_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size, int rw,
 266                              int mmu_idx);
 267
 268#include "exec/cpu-all.h"
 269
 270static inline void cpu_get_tb_cpu_state(CPULM32State *env, target_ulong *pc,
 271                                        target_ulong *cs_base, uint32_t *flags)
 272{
 273    *pc = env->pc;
 274    *cs_base = 0;
 275    *flags = 0;
 276}
 277
 278#endif
 279