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