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