fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 484 lines 16 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/cpu/arm/arm.h * 7 * Created: 2004-11-03 by Hampa Hug <hampa@hampa.ch> * 8 * Copyright: (C) 2004-2009 Hampa Hug <hampa@hampa.ch> * 9 * Copyright: (C) 2004-2006 Lukas Ruf <ruf@lpr.ch> * 10 *****************************************************************************/ 11 12/***************************************************************************** 13 * This program is free software. You can redistribute it and / or modify it * 14 * under the terms of the GNU General Public License version 2 as published * 15 * by the Free Software Foundation. * 16 * * 17 * This program is distributed in the hope that it will be useful, but * 18 * WITHOUT ANY WARRANTY, without even the implied warranty of * 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * 20 * Public License for more details. * 21 *****************************************************************************/ 22 23/***************************************************************************** 24 * This software was developed at the Computer Engineering and Networks * 25 * Laboratory (TIK), Swiss Federal Institute of Technology (ETH) Zurich. * 26 *****************************************************************************/ 27 28 29#ifndef ARM_H 30#define ARM_H 1 31 32 33#include <stdint.h> 34 35 36/***************************************************************************** 37 * ARM 38 *****************************************************************************/ 39 40/* PSR fields */ 41#define ARM_PSR_N (1UL << 31) 42#define ARM_PSR_Z (1UL << 30) 43#define ARM_PSR_C (1UL << 29) 44#define ARM_PSR_V (1UL << 28) 45#define ARM_PSR_CC 0xf0000000UL 46#define ARM_PSR_Q (1UL << 27) 47#define ARM_PSR_I (1UL << 7) 48#define ARM_PSR_F (1UL << 6) 49#define ARM_PSR_T (1UL << 5) 50#define ARM_PSR_M 0x1fUL 51 52 53#define ARM_MODE_USR 0x10 54#define ARM_MODE_FIQ 0x11 55#define ARM_MODE_IRQ 0x12 56#define ARM_MODE_SVC 0x13 57#define ARM_MODE_ABT 0x17 58#define ARM_MODE_UND 0x1b 59#define ARM_MODE_SYS 0x1f 60 61 62/* enable big endian mode */ 63#define ARM_FLAG_BIGENDIAN 1 64#define ARM_FLAG_T 2 /* thumb mode */ 65#define ARM_FLAG_M 4 /* multiply instructions */ 66#define ARM_FLAG_E 8 /* enhanced dsp instructions */ 67#define ARM_FLAG_CPAR 16 /* coprocessor access register */ 68#define ARM_FLAG_XSCALE (ARM_FLAG_T | ARM_FLAG_M | ARM_FLAG_E | ARM_FLAG_CPAR) 69#define ARM_FLAG_ALL 0xffff 70 71 72#define ARM_C15_ID_XSCALE_V5TE 0x69052000UL 73#define ARM_C15_ID_IXP2400 0x69054190UL 74 75#define ARM_C15_ID 0x69052000UL 76#define ARM_C15_CR_M 0x00000001UL 77#define ARM_C15_CR_A 0x00000002UL 78#define ARM_C15_CR_C 0x00000004UL 79#define ARM_C15_CR_W 0x00000008UL 80#define ARM_C15_CR_P 0x00000010UL 81#define ARM_C15_CR_D 0x00000020UL 82#define ARM_C15_CR_L 0x00000040UL 83#define ARM_C15_CR_B 0x00000080UL 84#define ARM_C15_CR_S 0x00000100UL 85#define ARM_C15_CR_R 0x00000200UL 86#define ARM_C15_CR_F 0x00000400UL 87#define ARM_C15_CR_Z 0x00000800UL 88#define ARM_C15_CR_I 0x00001000UL 89#define ARM_C15_CR_V 0x00002000UL 90 91 92#define ARM_XLAT_CPU 0 93#define ARM_XLAT_REAL 1 94#define ARM_XLAT_VIRTUAL 2 95 96 97#define ARM_REG_ALT_CNT 24 98#define ARM_SPSR_CNT 6 99 100#define arm_set_bits(var, bits, val) do { \ 101 if (val) (var) |= (bits); else (var) &= ~(bits); \ 102 } while (0) 103 104#define arm_get_gpr(c, n) ((c)->reg[(n)]) 105#define arm_get_pc(c) ((c)->reg[15]) 106#define arm_get_lr(c) ((c)->reg[14]) 107#define arm_get_cpsr(c) ((c)->cpsr) 108#define arm_get_spsr(c) ((c)->spsr) 109#define arm_get_last_pc(c) ((c)->lastpc[1]) 110 111#define arm_set_gpr(c, n, v) do { (c)->reg[(n)] = (v); } while (0) 112#define arm_set_pc(c, v) do { (c)->reg[15] = (v); } while (0) 113#define arm_set_lr(c, v) do { (c)->reg[14] = (v); } while (0) 114#define arm_set_cpsr(c, v) do { (c)->cpsr = (v); } while (0) 115#define arm_set_spsr(c, v) do { (c)->spsr = (v); } while (0) 116 117#define arm_get_cc_n(c) (((c)->cpsr & ARM_PSR_N) != 0) 118#define arm_get_cc_z(c) (((c)->cpsr & ARM_PSR_Z) != 0) 119#define arm_get_cc_c(c) (((c)->cpsr & ARM_PSR_C) != 0) 120#define arm_get_cc_v(c) (((c)->cpsr & ARM_PSR_V) != 0) 121#define arm_get_cc_q(c) (((c)->cpsr & ARM_PSR_Q) != 0) 122 123#define arm_get_cpsr_i(c) (((c)->cpsr & ARM_PSR_I) != 0) 124#define arm_get_cpsr_f(c) (((c)->cpsr & ARM_PSR_F) != 0) 125#define arm_get_cpsr_t(c) (((c)->cpsr & ARM_PSR_T) != 0) 126#define arm_get_cpsr_m(c) ((c)->cpsr & ARM_PSR_M) 127 128#define arm_set_cc_n(c, v) arm_set_bits ((c)->cpsr, ARM_PSR_N, (v)) 129#define arm_set_cc_z(c, v) arm_set_bits ((c)->cpsr, ARM_PSR_Z, (v)) 130#define arm_set_cc_c(c, v) arm_set_bits ((c)->cpsr, ARM_PSR_C, (v)) 131#define arm_set_cc_v(c, v) arm_set_bits ((c)->cpsr, ARM_PSR_V, (v)) 132#define arm_set_cc_q(c, v) arm_set_bits ((c)->cpsr, ARM_PSR_Q, (v)) 133 134#define arm_set_cpsr_i(c, v) arm_set_bits ((c)->cpsr, ARM_PSR_I, (v)) 135#define arm_set_cpsr_f(c, v) arm_set_bits ((c)->cpsr, ARM_PSR_F, (v)) 136#define arm_set_cpsr_t(c, v) arm_set_bits ((c)->cpsr, ARM_PSR_T, (v)) 137#define arm_set_cpsr_m(c, v) do { \ 138 (c)->cpsr &= ~0x1fUL; \ 139 (c)->cpsr |= (v) & 0x1f; \ 140 } while (0) 141 142#define arm_get_mmu(c) (&(c)->copr15) 143 144 145struct arm_s; 146struct arm_copr_s; 147 148 149typedef unsigned char (*arm_get_uint8_f) (void *ext, unsigned long addr); 150typedef unsigned short (*arm_get_uint16_f) (void *ext, unsigned long addr); 151typedef unsigned long (*arm_get_uint32_f) (void *ext, unsigned long addr); 152 153typedef void (*arm_set_uint8_f) (void *ext, unsigned long addr, unsigned char val); 154typedef void (*arm_set_uint16_f) (void *ext, unsigned long addr, unsigned short val); 155typedef void (*arm_set_uint32_f) (void *ext, unsigned long addr, unsigned long val); 156 157typedef void (*arm_opcode_f) (struct arm_s *c); 158 159 160/***************************************************************************** 161 * @short The ARM coprocessor context 162 *****************************************************************************/ 163typedef struct arm_copr_s { 164 unsigned copr_idx; 165 166 int (*reset) (struct arm_s *c, struct arm_copr_s *p); 167 int (*exec) (struct arm_s *c, struct arm_copr_s *p); 168 169 void *ext; 170} arm_copr_t; 171 172 173typedef struct { 174 int valid; 175 176 uint32_t vaddr; 177 uint32_t vmask; 178 179 uint32_t raddr; 180 uint32_t rmask; 181} arm_tbuf_t; 182 183 184typedef struct { 185 arm_copr_t copr; 186 187 arm_tbuf_t tbuf_exec; 188 arm_tbuf_t tbuf_read; 189 arm_tbuf_t tbuf_write; 190 191 uint32_t reg[16]; 192 193 uint32_t cache_type; 194 uint32_t auxiliary_control; 195} arm_copr15_t; 196 197 198typedef struct { 199 arm_copr_t copr; 200 201 uint32_t cclkcfg; 202 uint32_t pwrmode; 203} arm_copr14_t; 204 205 206/***************************************************************************** 207 * @short The ARM CPU context 208 *****************************************************************************/ 209typedef struct arm_s { 210 unsigned flags; 211 212 void *mem_ext; 213 214 arm_get_uint8_f get_uint8; 215 arm_get_uint16_f get_uint16; 216 arm_get_uint32_f get_uint32; 217 218 arm_set_uint8_f set_uint8; 219 arm_set_uint16_f set_uint16; 220 arm_set_uint32_f set_uint32; 221 222 unsigned char *ram; 223 unsigned long ram_cnt; 224 225 void *log_ext; 226 int (*log_opcode) (void *ext, unsigned long ir); 227 void (*log_undef) (void *ext, unsigned long ir); 228 void (*log_exception) (void *ext, unsigned long addr); 229 230 uint32_t cpsr; 231 232 uint32_t spsr; 233 uint32_t spsr_alt[ARM_SPSR_CNT]; 234 235 uint32_t reg[16]; 236 uint32_t reg_alt[ARM_REG_ALT_CNT]; 237 238 uint32_t lastpc[2]; 239 240 /* the current register mapping */ 241 unsigned reg_map; 242 243 arm_copr_t *copr[16]; 244 245 arm_copr14_t copr14; 246 247 /* system control coprocessor */ 248 arm_copr15_t copr15; 249 250 uint32_t ir; 251 252 uint32_t exception_base; 253 254 /* this reflects the B bit in copr15 reg 1 */ 255 int bigendian; 256 257 /* cpu is in a privileged mode */ 258 int privileged; 259 260 unsigned char irq; 261 unsigned char fiq; 262 unsigned char irq_or_fiq; 263 264 unsigned long delay; 265 266 unsigned long long oprcnt; 267 unsigned long long clkcnt; 268 269 arm_opcode_f opcodes[256]; 270} arm_t; 271 272 273 274/***************************************************************************** 275 * MMU 276 *****************************************************************************/ 277 278int arm_translate_extern (arm_t *c, uint32_t *addr, unsigned xlat, 279 unsigned *domn, unsigned *perm 280); 281 282int arm_get_mem8 (arm_t *c, uint32_t addr, unsigned xlat, uint8_t *val); 283int arm_get_mem16 (arm_t *c, uint32_t addr, unsigned xlat, uint16_t *val); 284int arm_get_mem32 (arm_t *c, uint32_t addr, unsigned xlat, uint32_t *val); 285 286int arm_set_mem8 (arm_t *c, uint32_t addr, unsigned xlat, uint8_t val); 287int arm_set_mem16 (arm_t *c, uint32_t addr, unsigned xlat, uint16_t val); 288int arm_set_mem32 (arm_t *c, uint32_t addr, unsigned xlat, uint32_t val); 289 290 291/*!*************************************************************************** 292 * @short Initialize an ARM context 293 *****************************************************************************/ 294void arm_init (arm_t *c); 295 296/*!*************************************************************************** 297 * @short Create and initialize an ARM context 298 * @return The ARM context or NULL on error 299 *****************************************************************************/ 300arm_t *arm_new (void); 301 302/*!*************************************************************************** 303 * @short Free the resources used by an ARM context 304 *****************************************************************************/ 305void arm_free (arm_t *c); 306 307/*!*************************************************************************** 308 * @short Delete an ARM context 309 *****************************************************************************/ 310void arm_del (arm_t *c); 311 312/*!*************************************************************************** 313 * @short Set the memory access functions 314 *****************************************************************************/ 315void arm_set_mem_fct (arm_t *c, void *ext, 316 void *get8, void *get16, void *get32, 317 void *set8, void *set16, void *set32 318); 319 320void arm_set_ram (arm_t *c, unsigned char *ram, unsigned long cnt); 321 322 323/*!*************************************************************************** 324 * @short Get CPU flags 325 * @short c The cpu context 326 * @short flags The flags to get 327 * @return The current cpu flags masked by flags. 328 *****************************************************************************/ 329unsigned arm_get_flags (const arm_t *c, unsigned flags); 330 331/*!*************************************************************************** 332 * @short Set CPU flags 333 * @short c The cpu context 334 * @short flags The flags to set (ARM_FLAG_*) 335 * @short val Set the flags if non-zero, clear them otherwise 336 * 337 * Flags must be set before arm_reset() is called. 338 *****************************************************************************/ 339void arm_set_flags (arm_t *c, unsigned flags, int val); 340 341unsigned long arm_get_id (arm_t *c); 342void arm_set_id (arm_t *c, unsigned long id); 343 344 345int arm_get_reg (arm_t *c, const char *reg, unsigned long *val); 346int arm_set_reg (arm_t *c, const char *reg, unsigned long val); 347 348 349/*!*************************************************************************** 350 * @short Get the number of executed instructions 351 *****************************************************************************/ 352unsigned long long arm_get_opcnt (arm_t *c); 353 354/*!*************************************************************************** 355 * @short Get the number of clock cycles 356 *****************************************************************************/ 357unsigned long long arm_get_clkcnt (arm_t *c); 358 359/*!*************************************************************************** 360 * @short Get the previous instruction delay 361 *****************************************************************************/ 362unsigned long arm_get_delay (arm_t *c); 363 364 365/*!*************************************************************************** 366 * @short Initialize a coprocessor context 367 *****************************************************************************/ 368void arm_copr_init (arm_copr_t *p); 369 370/*!*************************************************************************** 371 * @short Free a coprocessor context 372 *****************************************************************************/ 373void arm_copr_free (arm_copr_t *p); 374 375/*!*************************************************************************** 376 * @short Check if coprocessor is present and enabled 377 * @param i The coprocessor index 378 * @return Zero if coprocessor i is present and enabled, non-zero otherwise. 379 *****************************************************************************/ 380int arm_copr_check (arm_t *c, unsigned i); 381 382/*!*************************************************************************** 383 * @short Set a coprocessor 384 * @param c The ARM CPU context 385 * @param i The coprocessor index 386 * @param p The coprocessor context 387 * 388 * The coprocessor context p is owned by the caller. 389 *****************************************************************************/ 390void arm_set_copr (arm_t *c, unsigned i, arm_copr_t *p); 391 392 393void cp14_init (arm_copr14_t *c); 394void cp14_free (arm_copr14_t *p); 395arm_copr_t *cp14_new (void); 396void cp14_del (arm_copr14_t *p); 397 398 399/*!*************************************************************************** 400 * @short Initialize a system control coprocessor context 401 *****************************************************************************/ 402void cp15_init (arm_copr15_t *c); 403void cp15_free (arm_copr15_t *p); 404arm_copr_t *cp15_new (void); 405void cp15_del (arm_copr15_t *p); 406 407 408void arm_set_reg_map (arm_t *arm, unsigned mode); 409 410 411/*!*************************************************************************** 412 * @short Reset an arm cpu core 413 *****************************************************************************/ 414void arm_reset (arm_t *c); 415 416/*!*************************************************************************** 417 * @short Execute an exception 418 *****************************************************************************/ 419void arm_exception (arm_t *c, uint32_t addr, uint32_t ret, unsigned mode); 420 421void arm_exception_reset (arm_t *c); 422 423void arm_exception_undefined (arm_t *c); 424 425void arm_exception_swi (arm_t *c); 426 427void arm_exception_prefetch_abort (arm_t *c); 428 429void arm_exception_data_abort (arm_t *c); 430 431void arm_exception_irq (arm_t *c); 432 433void arm_exception_fiq (arm_t *c); 434 435/*!*************************************************************************** 436 * @short The external interrupt input signal 437 *****************************************************************************/ 438void arm_set_irq (arm_t *c, unsigned char val); 439 440/*!*************************************************************************** 441 * @short The external fast interrupt input signal 442 *****************************************************************************/ 443void arm_set_fiq (arm_t *c, unsigned char val); 444 445/*!*************************************************************************** 446 * @short Execute one instruction 447 *****************************************************************************/ 448void arm_execute (arm_t *c); 449 450/*!*************************************************************************** 451 * @short Clock an ARM cpu core 452 *****************************************************************************/ 453void arm_clock (arm_t *c, unsigned long n); 454 455 456/***************************************************************************** 457 * disasm 458 *****************************************************************************/ 459 460#define ARM_DFLAG_PRIV 0x0001 461#define ARM_DFLAG_TLBM 0x0002 462#define ARM_DFLAG_CALL 0x0100 463 464typedef struct { 465 unsigned flags; 466 467 uint32_t pc; 468 uint32_t ir; 469 470 unsigned argn; 471 472 char op[64]; 473 char arg[8][64]; 474} arm_dasm_t; 475 476 477typedef void (*arm_dasm_f) (arm_dasm_t *da); 478 479 480void arm_dasm (arm_dasm_t *dis, uint32_t pc, uint32_t ir); 481void arm_dasm_mem (arm_t *c, arm_dasm_t *da, uint32_t pc, unsigned xlat); 482 483 484#endif