|
|
1.1 root 1: /*
2: * SH4 emulation
1.1.1.4 root 3: *
1.1 root 4: * Copyright (c) 2005 Samuel Tardieu
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, write to the Free Software
1.1.1.5 ! root 18: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
1.1 root 19: */
20: #ifndef _CPU_SH4_H
21: #define _CPU_SH4_H
22:
23: #include "config.h"
24:
25: #define TARGET_LONG_BITS 32
26: #define TARGET_HAS_ICE 1
27:
1.1.1.3 root 28: #define ELF_MACHINE EM_SH
29:
1.1.1.5 ! root 30: /* CPU Subtypes */
! 31: #define SH_CPU_SH7750 (1 << 0)
! 32: #define SH_CPU_SH7750S (1 << 1)
! 33: #define SH_CPU_SH7750R (1 << 2)
! 34: #define SH_CPU_SH7751 (1 << 3)
! 35: #define SH_CPU_SH7751R (1 << 4)
! 36: #define SH_CPU_SH7785 (1 << 5)
! 37: #define SH_CPU_SH7750_ALL (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7750R)
! 38: #define SH_CPU_SH7751_ALL (SH_CPU_SH7751 | SH_CPU_SH7751R)
! 39:
1.1 root 40: #include "cpu-defs.h"
41:
1.1.1.2 root 42: #include "softfloat.h"
43:
1.1 root 44: #define TARGET_PAGE_BITS 12 /* 4k XXXXX */
45:
46: #define SR_MD (1 << 30)
47: #define SR_RB (1 << 29)
48: #define SR_BL (1 << 28)
49: #define SR_FD (1 << 15)
50: #define SR_M (1 << 9)
51: #define SR_Q (1 << 8)
1.1.1.5 ! root 52: #define SR_I3 (1 << 7)
! 53: #define SR_I2 (1 << 6)
! 54: #define SR_I1 (1 << 5)
! 55: #define SR_I0 (1 << 4)
1.1 root 56: #define SR_S (1 << 1)
57: #define SR_T (1 << 0)
58:
59: #define FPSCR_FR (1 << 21)
60: #define FPSCR_SZ (1 << 20)
61: #define FPSCR_PR (1 << 19)
62: #define FPSCR_DN (1 << 18)
1.1.1.4 root 63: #define DELAY_SLOT (1 << 0)
1.1 root 64: #define DELAY_SLOT_CONDITIONAL (1 << 1)
1.1.1.4 root 65: #define DELAY_SLOT_TRUE (1 << 2)
66: #define DELAY_SLOT_CLEARME (1 << 3)
67: /* The dynamic value of the DELAY_SLOT_TRUE flag determines whether the jump
68: * after the delay slot should be taken or not. It is calculated from SR_T.
69: *
70: * It is unclear if it is permitted to modify the SR_T flag in a delay slot.
71: * The use of DELAY_SLOT_TRUE flag makes us accept such SR_T modification.
72: */
1.1 root 73:
74: /* XXXXX The structure could be made more compact */
75: typedef struct tlb_t {
76: uint8_t asid; /* address space identifier */
77: uint32_t vpn; /* virtual page number */
78: uint8_t v; /* validity */
79: uint32_t ppn; /* physical page number */
80: uint8_t sz; /* page size */
81: uint32_t size; /* cached page size in bytes */
82: uint8_t sh; /* share status */
83: uint8_t c; /* cacheability */
84: uint8_t pr; /* protection key */
85: uint8_t d; /* dirty */
86: uint8_t wt; /* write through */
87: uint8_t sa; /* space attribute (PCMCIA) */
88: uint8_t tc; /* timing control */
89: } tlb_t;
90:
91: #define UTLB_SIZE 64
92: #define ITLB_SIZE 4
93:
1.1.1.4 root 94: #define NB_MMU_MODES 2
95:
1.1.1.5 ! root 96: enum sh_features {
! 97: SH_FEATURE_SH4A = 1,
! 98: SH_FEATURE_BCR3_AND_BCR4 = 2,
! 99: };
! 100:
1.1 root 101: typedef struct CPUSH4State {
1.1.1.5 ! root 102: int id; /* CPU model */
! 103:
1.1 root 104: uint32_t flags; /* general execution flags */
105: uint32_t gregs[24]; /* general registers */
1.1.1.4 root 106: float32 fregs[32]; /* floating point registers */
1.1 root 107: uint32_t sr; /* status register */
108: uint32_t ssr; /* saved status register */
109: uint32_t spc; /* saved program counter */
110: uint32_t gbr; /* global base register */
111: uint32_t vbr; /* vector base register */
112: uint32_t sgr; /* saved global register 15 */
113: uint32_t dbr; /* debug base register */
114: uint32_t pc; /* program counter */
115: uint32_t delayed_pc; /* target of delayed jump */
116: uint32_t mach; /* multiply and accumulate high */
117: uint32_t macl; /* multiply and accumulate low */
118: uint32_t pr; /* procedure register */
119: uint32_t fpscr; /* floating point status/control register */
120: uint32_t fpul; /* floating point communication register */
121:
1.1.1.5 ! root 122: /* float point status register */
1.1.1.4 root 123: float_status fp_status;
1.1.1.2 root 124:
1.1.1.5 ! root 125: /* The features that we should emulate. See sh_features above. */
! 126: uint32_t features;
! 127:
1.1 root 128: /* Those belong to the specific unit (SH7750) but are handled here */
129: uint32_t mmucr; /* MMU control register */
130: uint32_t pteh; /* page table entry high register */
131: uint32_t ptel; /* page table entry low register */
132: uint32_t ptea; /* page table entry assistance register */
133: uint32_t ttb; /* tranlation table base register */
134: uint32_t tea; /* TLB exception address register */
135: uint32_t tra; /* TRAPA exception register */
136: uint32_t expevt; /* exception event register */
137: uint32_t intevt; /* interrupt event register */
138:
1.1.1.5 ! root 139: uint32_t pvr; /* Processor Version Register */
! 140: uint32_t prr; /* Processor Revision Register */
! 141: uint32_t cvr; /* Cache Version Register */
! 142:
! 143: uint32_t ldst;
! 144:
1.1 root 145: CPU_COMMON tlb_t utlb[UTLB_SIZE]; /* unified translation table */
146: tlb_t itlb[ITLB_SIZE]; /* instruction translation table */
1.1.1.4 root 147: void *intc_handle;
1.1.1.5 ! root 148: int intr_at_halt; /* SR_BL ignored during sleep */
1.1 root 149: } CPUSH4State;
150:
1.1.1.4 root 151: CPUSH4State *cpu_sh4_init(const char *cpu_model);
1.1 root 152: int cpu_sh4_exec(CPUSH4State * s);
1.1.1.4 root 153: int cpu_sh4_signal_handler(int host_signum, void *pinfo,
1.1.1.3 root 154: void *puc);
1.1.1.5 ! root 155: int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw,
! 156: int mmu_idx, int is_softmmu);
! 157: void do_interrupt(CPUSH4State * env);
! 158:
! 159: void sh4_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
! 160: void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
! 161: uint32_t mem_value);
! 162:
! 163: static inline void cpu_set_tls(CPUSH4State *env, target_ulong newtls)
! 164: {
! 165: env->gbr = newtls;
! 166: }
! 167:
! 168: void cpu_load_tlb(CPUSH4State * env);
1.1 root 169:
170: #include "softfloat.h"
171:
1.1.1.4 root 172: #define CPUState CPUSH4State
173: #define cpu_init cpu_sh4_init
174: #define cpu_exec cpu_sh4_exec
175: #define cpu_gen_code cpu_sh4_gen_code
176: #define cpu_signal_handler cpu_sh4_signal_handler
1.1.1.5 ! root 177: #define cpu_list sh4_cpu_list
1.1.1.4 root 178:
179: /* MMU modes definitions */
180: #define MMU_MODE0_SUFFIX _kernel
181: #define MMU_MODE1_SUFFIX _user
182: #define MMU_USER_IDX 1
183: static inline int cpu_mmu_index (CPUState *env)
184: {
185: return (env->sr & SR_MD) == 0 ? 1 : 0;
186: }
187:
1.1.1.5 ! root 188: #if defined(CONFIG_USER_ONLY)
! 189: static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
! 190: {
! 191: if (newsp)
! 192: env->gregs[15] = newsp;
! 193: env->gregs[0] = 0;
! 194: }
! 195: #endif
! 196:
1.1 root 197: #include "cpu-all.h"
1.1.1.5 ! root 198: #include "exec-all.h"
1.1 root 199:
200: /* Memory access type */
201: enum {
202: /* Privilege */
203: ACCESS_PRIV = 0x01,
204: /* Direction */
205: ACCESS_WRITE = 0x02,
206: /* Type of instruction */
207: ACCESS_CODE = 0x10,
208: ACCESS_INT = 0x20
209: };
210:
211: /* MMU control register */
212: #define MMUCR 0x1F000010
213: #define MMUCR_AT (1<<0)
214: #define MMUCR_SV (1<<8)
1.1.1.5 ! root 215: #define MMUCR_URC_BITS (6)
! 216: #define MMUCR_URC_OFFSET (10)
! 217: #define MMUCR_URC_SIZE (1 << MMUCR_URC_BITS)
! 218: #define MMUCR_URC_MASK (((MMUCR_URC_SIZE) - 1) << MMUCR_URC_OFFSET)
! 219: static inline int cpu_mmucr_urc (uint32_t mmucr)
! 220: {
! 221: return ((mmucr & MMUCR_URC_MASK) >> MMUCR_URC_OFFSET);
! 222: }
! 223:
! 224: /* PTEH : Page Translation Entry High register */
! 225: #define PTEH_ASID_BITS (8)
! 226: #define PTEH_ASID_SIZE (1 << PTEH_ASID_BITS)
! 227: #define PTEH_ASID_MASK (PTEH_ASID_SIZE - 1)
! 228: #define cpu_pteh_asid(pteh) ((pteh) & PTEH_ASID_MASK)
! 229: #define PTEH_VPN_BITS (22)
! 230: #define PTEH_VPN_OFFSET (10)
! 231: #define PTEH_VPN_SIZE (1 << PTEH_VPN_BITS)
! 232: #define PTEH_VPN_MASK (((PTEH_VPN_SIZE) - 1) << PTEH_VPN_OFFSET)
! 233: static inline int cpu_pteh_vpn (uint32_t pteh)
! 234: {
! 235: return ((pteh & PTEH_VPN_MASK) >> PTEH_VPN_OFFSET);
! 236: }
! 237:
! 238: /* PTEL : Page Translation Entry Low register */
! 239: #define PTEL_V (1 << 8)
! 240: #define cpu_ptel_v(ptel) (((ptel) & PTEL_V) >> 8)
! 241: #define PTEL_C (1 << 3)
! 242: #define cpu_ptel_c(ptel) (((ptel) & PTEL_C) >> 3)
! 243: #define PTEL_D (1 << 2)
! 244: #define cpu_ptel_d(ptel) (((ptel) & PTEL_D) >> 2)
! 245: #define PTEL_SH (1 << 1)
! 246: #define cpu_ptel_sh(ptel)(((ptel) & PTEL_SH) >> 1)
! 247: #define PTEL_WT (1 << 0)
! 248: #define cpu_ptel_wt(ptel) ((ptel) & PTEL_WT)
! 249:
! 250: #define PTEL_SZ_HIGH_OFFSET (7)
! 251: #define PTEL_SZ_HIGH (1 << PTEL_SZ_HIGH_OFFSET)
! 252: #define PTEL_SZ_LOW_OFFSET (4)
! 253: #define PTEL_SZ_LOW (1 << PTEL_SZ_LOW_OFFSET)
! 254: static inline int cpu_ptel_sz (uint32_t ptel)
! 255: {
! 256: int sz;
! 257: sz = (ptel & PTEL_SZ_HIGH) >> PTEL_SZ_HIGH_OFFSET;
! 258: sz <<= 1;
! 259: sz |= (ptel & PTEL_SZ_LOW) >> PTEL_SZ_LOW_OFFSET;
! 260: return sz;
! 261: }
! 262:
! 263: #define PTEL_PPN_BITS (19)
! 264: #define PTEL_PPN_OFFSET (10)
! 265: #define PTEL_PPN_SIZE (1 << PTEL_PPN_BITS)
! 266: #define PTEL_PPN_MASK (((PTEL_PPN_SIZE) - 1) << PTEL_PPN_OFFSET)
! 267: static inline int cpu_ptel_ppn (uint32_t ptel)
! 268: {
! 269: return ((ptel & PTEL_PPN_MASK) >> PTEL_PPN_OFFSET);
! 270: }
! 271:
! 272: #define PTEL_PR_BITS (2)
! 273: #define PTEL_PR_OFFSET (5)
! 274: #define PTEL_PR_SIZE (1 << PTEL_PR_BITS)
! 275: #define PTEL_PR_MASK (((PTEL_PR_SIZE) - 1) << PTEL_PR_OFFSET)
! 276: static inline int cpu_ptel_pr (uint32_t ptel)
! 277: {
! 278: return ((ptel & PTEL_PR_MASK) >> PTEL_PR_OFFSET);
! 279: }
! 280:
! 281: /* PTEA : Page Translation Entry Assistance register */
! 282: #define PTEA_SA_BITS (3)
! 283: #define PTEA_SA_SIZE (1 << PTEA_SA_BITS)
! 284: #define PTEA_SA_MASK (PTEA_SA_SIZE - 1)
! 285: #define cpu_ptea_sa(ptea) ((ptea) & PTEA_SA_MASK)
! 286: #define PTEA_TC (1 << 3)
! 287: #define cpu_ptea_tc(ptea) (((ptea) & PTEA_TC) >> 3)
! 288:
! 289: static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
! 290: {
! 291: env->pc = tb->pc;
! 292: env->flags = tb->flags;
! 293: }
! 294:
! 295: static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
! 296: target_ulong *cs_base, int *flags)
! 297: {
! 298: *pc = env->pc;
! 299: *cs_base = 0;
! 300: *flags = (env->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL
! 301: | DELAY_SLOT_TRUE | DELAY_SLOT_CLEARME)) /* Bits 0- 3 */
! 302: | (env->fpscr & (FPSCR_FR | FPSCR_SZ | FPSCR_PR)) /* Bits 19-21 */
! 303: | (env->sr & (SR_MD | SR_RB)) /* Bits 29-30 */
! 304: | (env->sr & SR_FD); /* Bit 15 */
! 305: }
1.1 root 306:
307: #endif /* _CPU_SH4_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.