|
|
1.1 root 1: /*
2: * Alpha emulation cpu definitions for qemu.
3: *
4: * Copyright (c) 2007 Jocelyn Mayer
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
1.1.1.3 root 17: * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1.1 root 18: */
19:
20: #if !defined (__CPU_ALPHA_H__)
21: #define __CPU_ALPHA_H__
22:
23: #include "config.h"
24:
25: #define TARGET_LONG_BITS 64
26:
1.1.1.3 root 27: #define CPUState struct CPUAlphaState
28:
1.1 root 29: #include "cpu-defs.h"
30:
31: #include <setjmp.h>
32:
33: #include "softfloat.h"
34:
35: #define TARGET_HAS_ICE 1
36:
37: #define ELF_MACHINE EM_ALPHA
38:
39: #define ICACHE_LINE_SIZE 32
40: #define DCACHE_LINE_SIZE 32
41:
1.1.1.3 root 42: #define TARGET_PAGE_BITS 13
1.1 root 43:
44: #define VA_BITS 43
45:
46: /* Alpha major type */
47: enum {
48: ALPHA_EV3 = 1,
49: ALPHA_EV4 = 2,
50: ALPHA_SIM = 3,
51: ALPHA_LCA = 4,
52: ALPHA_EV5 = 5, /* 21164 */
53: ALPHA_EV45 = 6, /* 21064A */
54: ALPHA_EV56 = 7, /* 21164A */
55: };
56:
57: /* EV4 minor type */
58: enum {
59: ALPHA_EV4_2 = 0,
60: ALPHA_EV4_3 = 1,
61: };
62:
63: /* LCA minor type */
64: enum {
65: ALPHA_LCA_1 = 1, /* 21066 */
66: ALPHA_LCA_2 = 2, /* 20166 */
67: ALPHA_LCA_3 = 3, /* 21068 */
68: ALPHA_LCA_4 = 4, /* 21068 */
69: ALPHA_LCA_5 = 5, /* 21066A */
70: ALPHA_LCA_6 = 6, /* 21068A */
71: };
72:
73: /* EV5 minor type */
74: enum {
75: ALPHA_EV5_1 = 1, /* Rev BA, CA */
76: ALPHA_EV5_2 = 2, /* Rev DA, EA */
77: ALPHA_EV5_3 = 3, /* Pass 3 */
78: ALPHA_EV5_4 = 4, /* Pass 3.2 */
79: ALPHA_EV5_5 = 5, /* Pass 4 */
80: };
81:
82: /* EV45 minor type */
83: enum {
84: ALPHA_EV45_1 = 1, /* Pass 1 */
85: ALPHA_EV45_2 = 2, /* Pass 1.1 */
86: ALPHA_EV45_3 = 3, /* Pass 2 */
87: };
88:
89: /* EV56 minor type */
90: enum {
91: ALPHA_EV56_1 = 1, /* Pass 1 */
92: ALPHA_EV56_2 = 2, /* Pass 2 */
93: };
94:
95: enum {
96: IMPLVER_2106x = 0, /* EV4, EV45 & LCA45 */
97: IMPLVER_21164 = 1, /* EV5, EV56 & PCA45 */
98: IMPLVER_21264 = 2, /* EV6, EV67 & EV68x */
99: IMPLVER_21364 = 3, /* EV7 & EV79 */
100: };
101:
102: enum {
103: AMASK_BWX = 0x00000001,
104: AMASK_FIX = 0x00000002,
105: AMASK_CIX = 0x00000004,
106: AMASK_MVI = 0x00000100,
107: AMASK_TRAP = 0x00000200,
108: AMASK_PREFETCH = 0x00001000,
109: };
110:
111: enum {
112: VAX_ROUND_NORMAL = 0,
113: VAX_ROUND_CHOPPED,
114: };
115:
116: enum {
117: IEEE_ROUND_NORMAL = 0,
118: IEEE_ROUND_DYNAMIC,
119: IEEE_ROUND_PLUS,
120: IEEE_ROUND_MINUS,
121: IEEE_ROUND_CHOPPED,
122: };
123:
124: /* IEEE floating-point operations encoding */
125: /* Trap mode */
126: enum {
127: FP_TRAP_I = 0x0,
128: FP_TRAP_U = 0x1,
129: FP_TRAP_S = 0x4,
130: FP_TRAP_SU = 0x5,
131: FP_TRAP_SUI = 0x7,
132: };
133:
134: /* Rounding mode */
135: enum {
136: FP_ROUND_CHOPPED = 0x0,
137: FP_ROUND_MINUS = 0x1,
138: FP_ROUND_NORMAL = 0x2,
139: FP_ROUND_DYNAMIC = 0x3,
140: };
141:
142: /* Internal processor registers */
143: /* XXX: TOFIX: most of those registers are implementation dependant */
144: enum {
145: /* Ebox IPRs */
1.1.1.3 root 146: IPR_CC = 0xC0, /* 21264 */
147: IPR_CC_CTL = 0xC1, /* 21264 */
148: #define IPR_CC_CTL_ENA_SHIFT 32
149: #define IPR_CC_CTL_COUNTER_MASK 0xfffffff0UL
150: IPR_VA = 0xC2, /* 21264 */
151: IPR_VA_CTL = 0xC4, /* 21264 */
152: #define IPR_VA_CTL_VA_48_SHIFT 1
153: #define IPR_VA_CTL_VPTB_SHIFT 30
154: IPR_VA_FORM = 0xC3, /* 21264 */
1.1 root 155: /* Ibox IPRs */
1.1.1.3 root 156: IPR_ITB_TAG = 0x00, /* 21264 */
157: IPR_ITB_PTE = 0x01, /* 21264 */
158: IPR_ITB_IAP = 0x02,
159: IPR_ITB_IA = 0x03, /* 21264 */
160: IPR_ITB_IS = 0x04, /* 21264 */
1.1 root 161: IPR_PMPC = 0x05,
1.1.1.3 root 162: IPR_EXC_ADDR = 0x06, /* 21264 */
163: IPR_IVA_FORM = 0x07, /* 21264 */
164: IPR_CM = 0x09, /* 21264 */
165: #define IPR_CM_SHIFT 3
166: #define IPR_CM_MASK (3ULL << IPR_CM_SHIFT) /* 21264 */
167: IPR_IER = 0x0A, /* 21264 */
168: #define IPR_IER_MASK 0x0000007fffffe000ULL
169: IPR_IER_CM = 0x0B, /* 21264: = CM | IER */
170: IPR_SIRR = 0x0C, /* 21264 */
171: #define IPR_SIRR_SHIFT 14
172: #define IPR_SIRR_MASK 0x7fff
173: IPR_ISUM = 0x0D, /* 21264 */
174: IPR_HW_INT_CLR = 0x0E, /* 21264 */
1.1 root 175: IPR_EXC_SUM = 0x0F,
176: IPR_PAL_BASE = 0x10,
177: IPR_I_CTL = 0x11,
1.1.1.3 root 178: #define IPR_I_CTL_CHIP_ID_SHIFT 24 /* 21264 */
179: #define IPR_I_CTL_BIST_FAIL (1 << 23) /* 21264 */
180: #define IPR_I_CTL_IC_EN_SHIFT 2 /* 21264 */
181: #define IPR_I_CTL_SDE1_SHIFT 7 /* 21264 */
182: #define IPR_I_CTL_HWE_SHIFT 12 /* 21264 */
183: #define IPR_I_CTL_VA_48_SHIFT 15 /* 21264 */
184: #define IPR_I_CTL_SPE_SHIFT 3 /* 21264 */
185: #define IPR_I_CTL_CALL_PAL_R23_SHIFT 20 /* 21264 */
186: IPR_I_STAT = 0x16, /* 21264 */
187: IPR_IC_FLUSH = 0x13, /* 21264 */
188: IPR_IC_FLUSH_ASM = 0x12, /* 21264 */
1.1 root 189: IPR_CLR_MAP = 0x15,
190: IPR_SLEEP = 0x17,
191: IPR_PCTX = 0x40,
1.1.1.3 root 192: IPR_PCTX_ASN = 0x01, /* field */
193: #define IPR_PCTX_ASN_SHIFT 39
194: IPR_PCTX_ASTER = 0x02, /* field */
195: #define IPR_PCTX_ASTER_SHIFT 5
196: IPR_PCTX_ASTRR = 0x04, /* field */
197: #define IPR_PCTX_ASTRR_SHIFT 9
198: IPR_PCTX_PPCE = 0x08, /* field */
199: #define IPR_PCTX_PPCE_SHIFT 1
200: IPR_PCTX_FPE = 0x10, /* field */
201: #define IPR_PCTX_FPE_SHIFT 2
202: IPR_PCTX_ALL = 0x5f, /* all fields */
203: IPR_PCTR_CTL = 0x14, /* 21264 */
1.1 root 204: /* Mbox IPRs */
1.1.1.3 root 205: IPR_DTB_TAG0 = 0x20, /* 21264 */
206: IPR_DTB_TAG1 = 0xA0, /* 21264 */
207: IPR_DTB_PTE0 = 0x21, /* 21264 */
208: IPR_DTB_PTE1 = 0xA1, /* 21264 */
1.1 root 209: IPR_DTB_ALTMODE = 0xA6,
1.1.1.3 root 210: IPR_DTB_ALTMODE0 = 0x26, /* 21264 */
211: #define IPR_DTB_ALTMODE_MASK 3
1.1 root 212: IPR_DTB_IAP = 0xA2,
1.1.1.3 root 213: IPR_DTB_IA = 0xA3, /* 21264 */
1.1 root 214: IPR_DTB_IS0 = 0x24,
215: IPR_DTB_IS1 = 0xA4,
1.1.1.3 root 216: IPR_DTB_ASN0 = 0x25, /* 21264 */
217: IPR_DTB_ASN1 = 0xA5, /* 21264 */
218: #define IPR_DTB_ASN_SHIFT 56
219: IPR_MM_STAT = 0x27, /* 21264 */
220: IPR_M_CTL = 0x28, /* 21264 */
221: #define IPR_M_CTL_SPE_SHIFT 1
222: #define IPR_M_CTL_SPE_MASK 7
223: IPR_DC_CTL = 0x29, /* 21264 */
224: IPR_DC_STAT = 0x2A, /* 21264 */
1.1 root 225: /* Cbox IPRs */
226: IPR_C_DATA = 0x2B,
227: IPR_C_SHIFT = 0x2C,
228:
229: IPR_ASN,
230: IPR_ASTEN,
231: IPR_ASTSR,
232: IPR_DATFX,
233: IPR_ESP,
234: IPR_FEN,
235: IPR_IPIR,
236: IPR_IPL,
237: IPR_KSP,
238: IPR_MCES,
239: IPR_PERFMON,
240: IPR_PCBB,
241: IPR_PRBR,
242: IPR_PTBR,
243: IPR_SCBB,
244: IPR_SISR,
245: IPR_SSP,
246: IPR_SYSPTBR,
247: IPR_TBCHK,
248: IPR_TBIA,
249: IPR_TBIAP,
250: IPR_TBIS,
251: IPR_TBISD,
252: IPR_TBISI,
253: IPR_USP,
254: IPR_VIRBND,
255: IPR_VPTB,
256: IPR_WHAMI,
257: IPR_ALT_MODE,
258: IPR_LAST,
259: };
260:
261: typedef struct CPUAlphaState CPUAlphaState;
262:
263: typedef struct pal_handler_t pal_handler_t;
264: struct pal_handler_t {
265: /* Reset */
266: void (*reset)(CPUAlphaState *env);
267: /* Uncorrectable hardware error */
268: void (*machine_check)(CPUAlphaState *env);
269: /* Arithmetic exception */
270: void (*arithmetic)(CPUAlphaState *env);
271: /* Interrupt / correctable hardware error */
272: void (*interrupt)(CPUAlphaState *env);
273: /* Data fault */
274: void (*dfault)(CPUAlphaState *env);
275: /* DTB miss pal */
276: void (*dtb_miss_pal)(CPUAlphaState *env);
277: /* DTB miss native */
278: void (*dtb_miss_native)(CPUAlphaState *env);
279: /* Unaligned access */
280: void (*unalign)(CPUAlphaState *env);
281: /* ITB miss */
282: void (*itb_miss)(CPUAlphaState *env);
283: /* Instruction stream access violation */
284: void (*itb_acv)(CPUAlphaState *env);
285: /* Reserved or privileged opcode */
286: void (*opcdec)(CPUAlphaState *env);
287: /* Floating point exception */
288: void (*fen)(CPUAlphaState *env);
289: /* Call pal instruction */
290: void (*call_pal)(CPUAlphaState *env, uint32_t palcode);
291: };
292:
293: #define NB_MMU_MODES 4
294:
295: struct CPUAlphaState {
296: uint64_t ir[31];
297: float64 fir[31];
298: float_status fp_status;
299: uint64_t fpcr;
300: uint64_t pc;
301: uint64_t lock;
302: uint32_t pcc[2];
303: uint64_t ipr[IPR_LAST];
304: uint64_t ps;
305: uint64_t unique;
306: int saved_mode; /* Used for HW_LD / HW_ST */
1.1.1.2 root 307: int intr_flag; /* For RC and RS */
1.1 root 308:
309: #if TARGET_LONG_BITS > HOST_LONG_BITS
310: /* temporary fixed-point registers
311: * used to emulate 64 bits target on 32 bits hosts
312: */
1.1.1.2 root 313: target_ulong t0, t1;
1.1 root 314: #endif
315:
316: /* Those resources are used only in Qemu core */
317: CPU_COMMON
318:
319: uint32_t hflags;
320:
321: int error_code;
322:
323: uint32_t features;
324: uint32_t amask;
325: int implver;
326: pal_handler_t *pal_handler;
327: };
328:
329: #define cpu_init cpu_alpha_init
330: #define cpu_exec cpu_alpha_exec
331: #define cpu_gen_code cpu_alpha_gen_code
332: #define cpu_signal_handler cpu_alpha_signal_handler
333:
334: /* MMU modes definitions */
335: #define MMU_MODE0_SUFFIX _kernel
336: #define MMU_MODE1_SUFFIX _executive
337: #define MMU_MODE2_SUFFIX _supervisor
338: #define MMU_MODE3_SUFFIX _user
339: #define MMU_USER_IDX 3
340: static inline int cpu_mmu_index (CPUState *env)
341: {
342: return (env->ps >> 3) & 3;
343: }
344:
1.1.1.2 root 345: #if defined(CONFIG_USER_ONLY)
346: static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
347: {
348: if (newsp)
349: env->ir[30] = newsp;
350: /* FIXME: Zero syscall return value. */
351: }
352: #endif
353:
1.1 root 354: #include "cpu-all.h"
1.1.1.2 root 355: #include "exec-all.h"
1.1 root 356:
357: enum {
358: FEATURE_ASN = 0x00000001,
359: FEATURE_SPS = 0x00000002,
360: FEATURE_VIRBND = 0x00000004,
361: FEATURE_TBCHK = 0x00000008,
362: };
363:
364: enum {
365: EXCP_RESET = 0x0000,
366: EXCP_MCHK = 0x0020,
367: EXCP_ARITH = 0x0060,
368: EXCP_HW_INTERRUPT = 0x00E0,
369: EXCP_DFAULT = 0x01E0,
370: EXCP_DTB_MISS_PAL = 0x09E0,
371: EXCP_ITB_MISS = 0x03E0,
372: EXCP_ITB_ACV = 0x07E0,
373: EXCP_DTB_MISS_NATIVE = 0x08E0,
374: EXCP_UNALIGN = 0x11E0,
375: EXCP_OPCDEC = 0x13E0,
376: EXCP_FEN = 0x17E0,
377: EXCP_CALL_PAL = 0x2000,
378: EXCP_CALL_PALP = 0x3000,
379: EXCP_CALL_PALE = 0x4000,
380: /* Pseudo exception for console */
381: EXCP_CONSOLE_DISPATCH = 0x4001,
382: EXCP_CONSOLE_FIXUP = 0x4002,
383: };
384:
385: /* Arithmetic exception */
386: enum {
387: EXCP_ARITH_OVERFLOW,
388: };
389:
390: enum {
391: IR_V0 = 0,
392: IR_T0 = 1,
393: IR_T1 = 2,
394: IR_T2 = 3,
395: IR_T3 = 4,
396: IR_T4 = 5,
397: IR_T5 = 6,
398: IR_T6 = 7,
399: IR_T7 = 8,
400: IR_S0 = 9,
401: IR_S1 = 10,
402: IR_S2 = 11,
403: IR_S3 = 12,
404: IR_S4 = 13,
405: IR_S5 = 14,
406: IR_S6 = 15,
407: #define IR_FP IR_S6
408: IR_A0 = 16,
409: IR_A1 = 17,
410: IR_A2 = 18,
411: IR_A3 = 19,
412: IR_A4 = 20,
413: IR_A5 = 21,
414: IR_T8 = 22,
415: IR_T9 = 23,
416: IR_T10 = 24,
417: IR_T11 = 25,
418: IR_RA = 26,
419: IR_T12 = 27,
420: #define IR_PV IR_T12
421: IR_AT = 28,
422: IR_GP = 29,
423: IR_SP = 30,
424: IR_ZERO = 31,
425: };
426:
427: CPUAlphaState * cpu_alpha_init (const char *cpu_model);
428: int cpu_alpha_exec(CPUAlphaState *s);
429: /* you can call this signal handler from your SIGBUS and SIGSEGV
430: signal handlers to inform the virtual CPU of exceptions. non zero
431: is returned if the signal was handled by the virtual CPU. */
432: int cpu_alpha_signal_handler(int host_signum, void *pinfo,
433: void *puc);
1.1.1.2 root 434: int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw,
435: int mmu_idx, int is_softmmu);
1.1.1.4 ! root 436: #define cpu_handle_mmu_fault cpu_alpha_handle_mmu_fault
1.1.1.2 root 437: void do_interrupt (CPUState *env);
438:
1.1 root 439: int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp);
440: int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp);
441: void pal_init (CPUState *env);
1.1.1.2 root 442: #if !defined (CONFIG_USER_ONLY)
443: void call_pal (CPUState *env);
444: #else
1.1 root 445: void call_pal (CPUState *env, int palcode);
1.1.1.2 root 446: #endif
447:
448: static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
449: {
450: env->pc = tb->pc;
451: }
452:
453: static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
454: target_ulong *cs_base, int *flags)
455: {
456: *pc = env->pc;
457: *cs_base = 0;
458: *flags = env->ps;
459: }
1.1 root 460:
461: #endif /* !defined (__CPU_ALPHA_H__) */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.