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