1 /* 2 * Altera Nios II virtual CPU header 3 * 4 * Copyright (c) 2012 Chris Wulff <crwulff@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 18 * <http://www.gnu.org/licenses/lgpl-2.1.html> 19 */ 20 21 #ifndef NIOS2_CPU_H 22 #define NIOS2_CPU_H 23 24 #include "cpu-qom.h" 25 #include "exec/cpu-defs.h" 26 #include "hw/registerfields.h" 27 28 typedef struct CPUArchState CPUNios2State; 29 #if !defined(CONFIG_USER_ONLY) 30 #include "mmu.h" 31 #endif 32 33 /** 34 * Nios2CPUClass: 35 * @parent_phases: The parent class' reset phase handlers. 36 * 37 * A Nios2 CPU model. 38 */ 39 struct Nios2CPUClass { 40 CPUClass parent_class; 41 42 DeviceRealize parent_realize; 43 ResettablePhases parent_phases; 44 }; 45 46 #define TARGET_HAS_ICE 1 47 48 /* Configuration options for Nios II */ 49 #define RESET_ADDRESS 0x00000000 50 #define EXCEPTION_ADDRESS 0x00000004 51 #define FAST_TLB_MISS_ADDRESS 0x00000008 52 53 #define NUM_GP_REGS 32 54 #define NUM_CR_REGS 32 55 56 #ifndef CONFIG_USER_ONLY 57 /* 63 shadow register sets; index 0 is the primary register set. */ 58 #define NUM_REG_SETS 64 59 #endif 60 61 /* General purpose register aliases */ 62 enum { 63 R_ZERO = 0, 64 R_AT = 1, 65 R_RET0 = 2, 66 R_RET1 = 3, 67 R_ARG0 = 4, 68 R_ARG1 = 5, 69 R_ARG2 = 6, 70 R_ARG3 = 7, 71 R_ET = 24, 72 R_BT = 25, 73 R_GP = 26, 74 R_SP = 27, 75 R_FP = 28, 76 R_EA = 29, 77 R_BA = 30, 78 R_SSTATUS = 30, 79 R_RA = 31, 80 }; 81 82 /* Control register aliases */ 83 enum { 84 CR_STATUS = 0, 85 CR_ESTATUS = 1, 86 CR_BSTATUS = 2, 87 CR_IENABLE = 3, 88 CR_IPENDING = 4, 89 CR_CPUID = 5, 90 CR_EXCEPTION = 7, 91 CR_PTEADDR = 8, 92 CR_TLBACC = 9, 93 CR_TLBMISC = 10, 94 CR_ENCINJ = 11, 95 CR_BADADDR = 12, 96 CR_CONFIG = 13, 97 CR_MPUBASE = 14, 98 CR_MPUACC = 15, 99 }; 100 101 FIELD(CR_STATUS, PIE, 0, 1) 102 FIELD(CR_STATUS, U, 1, 1) 103 FIELD(CR_STATUS, EH, 2, 1) 104 FIELD(CR_STATUS, IH, 3, 1) 105 FIELD(CR_STATUS, IL, 4, 6) 106 FIELD(CR_STATUS, CRS, 10, 6) 107 FIELD(CR_STATUS, PRS, 16, 6) 108 FIELD(CR_STATUS, NMI, 22, 1) 109 FIELD(CR_STATUS, RSIE, 23, 1) 110 FIELD(CR_STATUS, SRS, 31, 1) /* only in sstatus */ 111 112 #define CR_STATUS_PIE R_CR_STATUS_PIE_MASK 113 #define CR_STATUS_U R_CR_STATUS_U_MASK 114 #define CR_STATUS_EH R_CR_STATUS_EH_MASK 115 #define CR_STATUS_IH R_CR_STATUS_IH_MASK 116 #define CR_STATUS_NMI R_CR_STATUS_NMI_MASK 117 #define CR_STATUS_RSIE R_CR_STATUS_RSIE_MASK 118 #define CR_STATUS_SRS R_CR_STATUS_SRS_MASK 119 120 FIELD(CR_EXCEPTION, CAUSE, 2, 5) 121 FIELD(CR_EXCEPTION, ECCFTL, 31, 1) 122 123 FIELD(CR_PTEADDR, VPN, 2, 20) 124 FIELD(CR_PTEADDR, PTBASE, 22, 10) 125 126 FIELD(CR_TLBACC, PFN, 0, 20) 127 FIELD(CR_TLBACC, G, 20, 1) 128 FIELD(CR_TLBACC, X, 21, 1) 129 FIELD(CR_TLBACC, W, 22, 1) 130 FIELD(CR_TLBACC, R, 23, 1) 131 FIELD(CR_TLBACC, C, 24, 1) 132 FIELD(CR_TLBACC, IG, 25, 7) 133 134 #define CR_TLBACC_C R_CR_TLBACC_C_MASK 135 #define CR_TLBACC_R R_CR_TLBACC_R_MASK 136 #define CR_TLBACC_W R_CR_TLBACC_W_MASK 137 #define CR_TLBACC_X R_CR_TLBACC_X_MASK 138 #define CR_TLBACC_G R_CR_TLBACC_G_MASK 139 140 FIELD(CR_TLBMISC, D, 0, 1) 141 FIELD(CR_TLBMISC, PERM, 1, 1) 142 FIELD(CR_TLBMISC, BAD, 2, 1) 143 FIELD(CR_TLBMISC, DBL, 3, 1) 144 FIELD(CR_TLBMISC, PID, 4, 14) 145 FIELD(CR_TLBMISC, WE, 18, 1) 146 FIELD(CR_TLBMISC, RD, 19, 1) 147 FIELD(CR_TLBMISC, WAY, 20, 4) 148 FIELD(CR_TLBMISC, EE, 24, 1) 149 150 #define CR_TLBMISC_EE R_CR_TLBMISC_EE_MASK 151 #define CR_TLBMISC_RD R_CR_TLBMISC_RD_MASK 152 #define CR_TLBMISC_WE R_CR_TLBMISC_WE_MASK 153 #define CR_TLBMISC_DBL R_CR_TLBMISC_DBL_MASK 154 #define CR_TLBMISC_BAD R_CR_TLBMISC_BAD_MASK 155 #define CR_TLBMISC_PERM R_CR_TLBMISC_PERM_MASK 156 #define CR_TLBMISC_D R_CR_TLBMISC_D_MASK 157 158 /* Exceptions */ 159 #define EXCP_BREAK 0x1000 160 #define EXCP_SEMIHOST 0x1001 161 #define EXCP_RESET 0 162 #define EXCP_PRESET 1 163 #define EXCP_IRQ 2 164 #define EXCP_TRAP 3 165 #define EXCP_UNIMPL 4 166 #define EXCP_ILLEGAL 5 167 #define EXCP_UNALIGN 6 168 #define EXCP_UNALIGND 7 169 #define EXCP_DIV 8 170 #define EXCP_SUPERA_X 9 171 #define EXCP_SUPERI 10 172 #define EXCP_SUPERA_D 11 173 #define EXCP_TLB_X 12 174 #define EXCP_TLB_D (0x1000 | EXCP_TLB_X) 175 #define EXCP_PERM_X 13 176 #define EXCP_PERM_R 14 177 #define EXCP_PERM_W 15 178 #define EXCP_MPUI 16 179 #define EXCP_MPUD 17 180 181 struct CPUArchState { 182 #ifdef CONFIG_USER_ONLY 183 uint32_t regs[NUM_GP_REGS]; 184 #else 185 uint32_t shadow_regs[NUM_REG_SETS][NUM_GP_REGS]; 186 /* Pointer into shadow_regs for the current register set. */ 187 uint32_t *regs; 188 #endif 189 uint32_t ctrl[NUM_CR_REGS]; 190 uint32_t pc; 191 192 #if !defined(CONFIG_USER_ONLY) 193 Nios2MMU mmu; 194 #endif 195 int error_code; 196 }; 197 198 typedef struct { 199 uint32_t writable; 200 uint32_t readonly; 201 } ControlRegState; 202 203 /** 204 * Nios2CPU: 205 * @env: #CPUNios2State 206 * 207 * A Nios2 CPU. 208 */ 209 struct ArchCPU { 210 CPUState parent_obj; 211 212 CPUNios2State env; 213 214 bool diverr_present; 215 bool mmu_present; 216 bool eic_present; 217 218 uint32_t pid_num_bits; 219 uint32_t tlb_num_ways; 220 uint32_t tlb_num_entries; 221 222 /* Addresses that are hard-coded in the FPGA build settings */ 223 uint32_t reset_addr; 224 uint32_t exception_addr; 225 uint32_t fast_tlb_miss_addr; 226 227 /* Bits within each control register which are reserved or readonly. */ 228 ControlRegState cr_state[NUM_CR_REGS]; 229 230 /* External Interrupt Controller Interface */ 231 uint32_t rha; /* Requested handler address */ 232 uint32_t ril; /* Requested interrupt level */ 233 uint32_t rrs; /* Requested register set */ 234 bool rnmi; /* Requested nonmaskable interrupt */ 235 }; 236 237 238 static inline bool nios2_cr_reserved(const ControlRegState *s) 239 { 240 return (s->writable | s->readonly) == 0; 241 } 242 243 static inline void nios2_update_crs(CPUNios2State *env) 244 { 245 #ifndef CONFIG_USER_ONLY 246 unsigned crs = FIELD_EX32(env->ctrl[CR_STATUS], CR_STATUS, CRS); 247 env->regs = env->shadow_regs[crs]; 248 #endif 249 } 250 251 void nios2_tcg_init(void); 252 void nios2_cpu_do_interrupt(CPUState *cs); 253 void dump_mmu(CPUNios2State *env); 254 void nios2_cpu_dump_state(CPUState *cpu, FILE *f, int flags); 255 G_NORETURN void nios2_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, 256 MMUAccessType access_type, int mmu_idx, 257 uintptr_t retaddr); 258 G_NORETURN void nios2_cpu_loop_exit_advance(CPUNios2State *env, 259 uintptr_t retaddr); 260 261 void do_nios2_semihosting(CPUNios2State *env); 262 263 #define CPU_RESOLVING_TYPE TYPE_NIOS2_CPU 264 265 #define cpu_gen_code cpu_nios2_gen_code 266 267 #define CPU_SAVE_VERSION 1 268 269 /* MMU modes definitions */ 270 #define MMU_SUPERVISOR_IDX 0 271 #define MMU_USER_IDX 1 272 273 static inline int cpu_mmu_index(CPUNios2State *env, bool ifetch) 274 { 275 return (env->ctrl[CR_STATUS] & CR_STATUS_U) ? MMU_USER_IDX : 276 MMU_SUPERVISOR_IDX; 277 } 278 279 #ifndef CONFIG_USER_ONLY 280 hwaddr nios2_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); 281 bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size, 282 MMUAccessType access_type, int mmu_idx, 283 bool probe, uintptr_t retaddr); 284 #endif 285 286 typedef CPUNios2State CPUArchState; 287 typedef Nios2CPU ArchCPU; 288 289 #include "exec/cpu-all.h" 290 291 FIELD(TBFLAGS, CRS0, 0, 1) /* Set if CRS == 0. */ 292 FIELD(TBFLAGS, U, 1, 1) /* Overlaps CR_STATUS_U */ 293 FIELD(TBFLAGS, R0_0, 2, 1) /* Set if R0 == 0. */ 294 295 static inline void cpu_get_tb_cpu_state(CPUNios2State *env, vaddr *pc, 296 uint64_t *cs_base, uint32_t *flags) 297 { 298 unsigned crs = FIELD_EX32(env->ctrl[CR_STATUS], CR_STATUS, CRS); 299 300 *pc = env->pc; 301 *cs_base = 0; 302 *flags = (env->ctrl[CR_STATUS] & CR_STATUS_U) 303 | (crs ? 0 : R_TBFLAGS_CRS0_MASK) 304 | (env->regs[0] ? 0 : R_TBFLAGS_R0_0_MASK); 305 } 306 307 #endif /* NIOS2_CPU_H */ 308