Revision 4c9649a9

b/target-alpha/cpu.h
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
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20

  
21
#if !defined (__CPU_ALPHA_H__)
22
#define __CPU_ALPHA_H__
23

  
24
#include "config.h"
25

  
26
#define TARGET_LONG_BITS 64
27

  
28
#include "cpu-defs.h"
29

  
30

  
31
#include <setjmp.h>
32

  
33
#include "softfloat.h"
34

  
35
/* XXX: put this in a common place */
36
#define likely(x)   __builtin_expect(!!(x), 1)
37
#define unlikely(x)   __builtin_expect(!!(x), 0)
38

  
39
#define TARGET_HAS_ICE 1
40

  
41
#define ELF_MACHINE	EM_ALPHA
42

  
43
#define ICACHE_LINE_SIZE 32
44
#define DCACHE_LINE_SIZE 32
45

  
46
#define TARGET_PAGE_BITS 12
47

  
48
#define VA_BITS 43
49

  
50
/* Alpha major type */
51
enum {
52
    ALPHA_EV3  = 1,
53
    ALPHA_EV4  = 2,
54
    ALPHA_SIM  = 3,
55
    ALPHA_LCA  = 4,
56
    ALPHA_EV5  = 5, /* 21164 */
57
    ALPHA_EV45 = 6, /* 21064A */
58
    ALPHA_EV56 = 7, /* 21164A */
59
};
60

  
61
/* EV4 minor type */
62
enum {
63
    ALPHA_EV4_2 = 0,
64
    ALPHA_EV4_3 = 1,
65
};
66

  
67
/* LCA minor type */
68
enum {
69
    ALPHA_LCA_1 = 1, /* 21066 */
70
    ALPHA_LCA_2 = 2, /* 20166 */
71
    ALPHA_LCA_3 = 3, /* 21068 */
72
    ALPHA_LCA_4 = 4, /* 21068 */
73
    ALPHA_LCA_5 = 5, /* 21066A */
74
    ALPHA_LCA_6 = 6, /* 21068A */
75
};
76

  
77
/* EV5 minor type */
78
enum {
79
    ALPHA_EV5_1 = 1, /* Rev BA, CA */
80
    ALPHA_EV5_2 = 2, /* Rev DA, EA */
81
    ALPHA_EV5_3 = 3, /* Pass 3 */
82
    ALPHA_EV5_4 = 4, /* Pass 3.2 */
83
    ALPHA_EV5_5 = 5, /* Pass 4 */
84
};
85

  
86
/* EV45 minor type */
87
enum {
88
    ALPHA_EV45_1 = 1, /* Pass 1 */
89
    ALPHA_EV45_2 = 2, /* Pass 1.1 */
90
    ALPHA_EV45_3 = 3, /* Pass 2 */
91
};
92

  
93
/* EV56 minor type */
94
enum {
95
    ALPHA_EV56_1 = 1, /* Pass 1 */
96
    ALPHA_EV56_2 = 2, /* Pass 2 */
97
};
98

  
99
enum {
100
    IMPLVER_2106x = 0, /* EV4, EV45 & LCA45 */
101
    IMPLVER_21164 = 1, /* EV5, EV56 & PCA45 */
102
    IMPLVER_21264 = 2, /* EV6, EV67 & EV68x */
103
    IMPLVER_21364 = 3, /* EV7 & EV79 */
104
};
105

  
106
enum {
107
    AMASK_BWX      = 0x00000001,
108
    AMASK_FIX      = 0x00000002,
109
    AMASK_CIX      = 0x00000004,
110
    AMASK_MVI      = 0x00000100,
111
    AMASK_TRAP     = 0x00000200,
112
    AMASK_PREFETCH = 0x00001000,
113
};
114

  
115
enum {
116
    VAX_ROUND_NORMAL = 0,
117
    VAX_ROUND_CHOPPED,
118
};
119

  
120
enum {
121
    IEEE_ROUND_NORMAL = 0,
122
    IEEE_ROUND_DYNAMIC,
123
    IEEE_ROUND_PLUS,
124
    IEEE_ROUND_MINUS,
125
    IEEE_ROUND_CHOPPED,
126
};
127

  
128
/* IEEE floating-point operations encoding */
129
/* Trap mode */
130
enum {
131
    FP_TRAP_I   = 0x0,
132
    FP_TRAP_U   = 0x1,
133
    FP_TRAP_S  = 0x4,
134
    FP_TRAP_SU  = 0x5,
135
    FP_TRAP_SUI = 0x7,
136
};
137

  
138
/* Rounding mode */
139
enum {
140
    FP_ROUND_CHOPPED = 0x0,
141
    FP_ROUND_MINUS   = 0x1,
142
    FP_ROUND_NORMAL  = 0x2,
143
    FP_ROUND_DYNAMIC = 0x3,
144
};
145

  
146
/* Internal processor registers */
147
/* XXX: TOFIX: most of those registers are implementation dependant */
148
enum {
149
    /* Ebox IPRs */
150
    IPR_CC           = 0xC0,
151
    IPR_CC_CTL       = 0xC1,
152
    IPR_VA           = 0xC2,
153
    IPR_VA_CTL       = 0xC4,
154
    IPR_VA_FORM      = 0xC3,
155
    /* Ibox IPRs */
156
    IPR_ITB_TAG      = 0x00,
157
    IPR_ITB_PTE      = 0x01,
158
    IPT_ITB_IAP      = 0x02,
159
    IPT_ITB_IA       = 0x03,
160
    IPT_ITB_IS       = 0x04,
161
    IPR_PMPC         = 0x05,
162
    IPR_EXC_ADDR     = 0x06,
163
    IPR_IVA_FORM     = 0x07,
164
    IPR_CM           = 0x09,
165
    IPR_IER          = 0x0A,
166
    IPR_SIRR         = 0x0C,
167
    IPR_ISUM         = 0x0D,
168
    IPR_HW_INT_CLR   = 0x0E,
169
    IPR_EXC_SUM      = 0x0F,
170
    IPR_PAL_BASE     = 0x10,
171
    IPR_I_CTL        = 0x11,
172
    IPR_I_STAT       = 0x16,
173
    IPR_IC_FLUSH     = 0x13,
174
    IPR_IC_FLUSH_ASM = 0x12,
175
    IPR_CLR_MAP      = 0x15,
176
    IPR_SLEEP        = 0x17,
177
    IPR_PCTX         = 0x40,
178
    IPR_PCTR_CTL     = 0x14,
179
    /* Mbox IPRs */
180
    IPR_DTB_TAG0     = 0x20,
181
    IPR_DTB_TAG1     = 0xA0,
182
    IPR_DTB_PTE0     = 0x21,
183
    IPR_DTB_PTE1     = 0xA1,
184
    IPR_DTB_ALTMODE  = 0xA6,
185
    IPR_DTB_IAP      = 0xA2,
186
    IPR_DTB_IA       = 0xA3,
187
    IPR_DTB_IS0      = 0x24,
188
    IPR_DTB_IS1      = 0xA4,
189
    IPR_DTB_ASN0     = 0x25,
190
    IPR_DTB_ASN1     = 0xA5,
191
    IPR_MM_STAT      = 0x27,
192
    IPR_M_CTL        = 0x28,
193
    IPR_DC_CTL       = 0x29,
194
    IPR_DC_STAT      = 0x2A,
195
    /* Cbox IPRs */
196
    IPR_C_DATA       = 0x2B,
197
    IPR_C_SHIFT      = 0x2C,
198

  
199
    IPR_ASN,
200
    IPR_ASTEN,
201
    IPR_ASTSR,
202
    IPR_DATFX,
203
    IPR_ESP,
204
    IPR_FEN,
205
    IPR_IPIR,
206
    IPR_IPL,
207
    IPR_KSP,
208
    IPR_MCES,
209
    IPR_PERFMON,
210
    IPR_PCBB,
211
    IPR_PRBR,
212
    IPR_PTBR,
213
    IPR_SCBB,
214
    IPR_SISR,
215
    IPR_SSP,
216
    IPR_SYSPTBR,
217
    IPR_TBCHK,
218
    IPR_TBIA,
219
    IPR_TBIAP,
220
    IPR_TBIS,
221
    IPR_TBISD,
222
    IPR_TBISI,
223
    IPR_USP,
224
    IPR_VIRBND,
225
    IPR_VPTB,
226
    IPR_WHAMI,
227
    IPR_ALT_MODE,
228
    IPR_LAST,
229
};
230

  
231
typedef struct CPUAlphaState CPUAlphaState;
232

  
233
typedef struct pal_handler_t pal_handler_t;
234
struct pal_handler_t {
235
    /* Reset */
236
    void (*reset)(CPUAlphaState *env);
237
    /* Uncorrectable hardware error */
238
    void (*machine_check)(CPUAlphaState *env);
239
    /* Arithmetic exception */
240
    void (*arithmetic)(CPUAlphaState *env);
241
    /* Interrupt / correctable hardware error */
242
    void (*interrupt)(CPUAlphaState *env);
243
    /* Data fault */
244
    void (*dfault)(CPUAlphaState *env);
245
    /* DTB miss pal */
246
    void (*dtb_miss_pal)(CPUAlphaState *env);
247
    /* DTB miss native */
248
    void (*dtb_miss_native)(CPUAlphaState *env);
249
    /* Unaligned access */
250
    void (*unalign)(CPUAlphaState *env);
251
    /* ITB miss */
252
    void (*itb_miss)(CPUAlphaState *env);
253
    /* Instruction stream access violation */
254
    void (*itb_acv)(CPUAlphaState *env);
255
    /* Reserved or privileged opcode */
256
    void (*opcdec)(CPUAlphaState *env);
257
    /* Floating point exception */
258
    void (*fen)(CPUAlphaState *env);
259
    /* Call pal instruction */
260
    void (*call_pal)(CPUAlphaState *env, uint32_t palcode);
261
};
262

  
263
struct CPUAlphaState {
264
    uint64_t ir[31];
265
    float64  fir[31];
266
    float_status fp_status;
267
    uint64_t fpcr;
268
    uint64_t pc;
269
    uint64_t lock;
270
    uint32_t pcc[2];
271
    uint64_t ipr[IPR_LAST];
272
    uint64_t ps;
273
    uint64_t unique;
274
    int saved_mode; /* Used for HW_LD / HW_ST */
275

  
276
    /* */
277
    double ft0, ft1, ft2;
278

  
279
    /* Those resources are used only in Qemu core */
280
    CPU_COMMON
281

  
282
    jmp_buf jmp_env;
283
    int user_mode_only; /* user mode only simulation */
284
    uint32_t hflags;
285
    int halted;
286

  
287
    int exception_index;
288
    int error_code;
289
    int interrupt_request;
290

  
291
    uint32_t features;
292
    uint32_t amask;
293
    int implver;
294
    pal_handler_t *pal_handler;
295
};
296

  
297
#include "cpu-all.h"
298

  
299
enum {
300
    FEATURE_ASN    = 0x00000001,
301
    FEATURE_SPS    = 0x00000002,
302
    FEATURE_VIRBND = 0x00000004,
303
    FEATURE_TBCHK  = 0x00000008,
304
};
305

  
306
enum {
307
    EXCP_RESET            = 0x0000,
308
    EXCP_MCHK             = 0x0020,
309
    EXCP_ARITH            = 0x0060,
310
    EXCP_HW_INTERRUPT     = 0x00E0,
311
    EXCP_DFAULT           = 0x01E0,
312
    EXCP_DTB_MISS_PAL     = 0x09E0,
313
    EXCP_ITB_MISS         = 0x03E0,
314
    EXCP_ITB_ACV          = 0x07E0,
315
    EXCP_DTB_MISS_NATIVE  = 0x08E0,
316
    EXCP_UNALIGN          = 0x11E0,
317
    EXCP_OPCDEC           = 0x13E0,
318
    EXCP_FEN              = 0x17E0,
319
    EXCP_CALL_PAL         = 0x2000,
320
    EXCP_CALL_PALP        = 0x3000,
321
    EXCP_CALL_PALE        = 0x4000,
322
    /* Pseudo exception for console */
323
    EXCP_CONSOLE_DISPATCH = 0x4001,
324
    EXCP_CONSOLE_FIXUP    = 0x4002,
325
};
326

  
327
/* Arithmetic exception */
328
enum {
329
    EXCP_ARITH_OVERFLOW,
330
};
331

  
332
enum {
333
    PALCODE_CALL = 0x00000000,
334
    PALCODE_LD   = 0x01000000,
335
    PALCODE_ST   = 0x02000000,
336
    PALCODE_MFPR = 0x03000000,
337
    PALCODE_MTPR = 0x04000000,
338
    PALCODE_REI  = 0x05000000,
339
    PALCODE_INIT = 0xF0000000,
340
};
341

  
342
enum {
343
    IR_V0   = 0,
344
    IR_T0   = 1,
345
    IR_T1   = 2,
346
    IR_T2   = 3,
347
    IR_T3   = 4,
348
    IR_T4   = 5,
349
    IR_T5   = 6,
350
    IR_T6   = 7,
351
    IR_T7   = 8,
352
    IR_S0   = 9,
353
    IR_S1   = 10,
354
    IR_S2   = 11,
355
    IR_S3   = 12,
356
    IR_S4   = 13,
357
    IR_S5   = 14,
358
    IR_S6   = 15,
359
#define IR_FP IR_S6
360
    IR_A0   = 16,
361
    IR_A1   = 17,
362
    IR_A2   = 18,
363
    IR_A3   = 19,
364
    IR_A4   = 20,
365
    IR_A5   = 21,
366
    IR_T8   = 22,
367
    IR_T9   = 23,
368
    IR_T10  = 24,
369
    IR_T11  = 25,
370
    IR_RA   = 26,
371
    IR_T12  = 27,
372
#define IR_PV IR_T12
373
    IR_AT   = 28,
374
    IR_GP   = 29,
375
    IR_SP   = 30,
376
    IR_ZERO = 31,
377
};
378

  
379
int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp);
380
int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp);
381
void cpu_loop_exit (void);
382
void pal_init (CPUState *env);
383
void call_pal (CPUState *env, int palcode);
384

  
385
#endif /* !defined (__CPU_ALPHA_H__) */
b/target-alpha/exec.h
1
/*
2
 *  Alpha emulation cpu run-time 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
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20

  
21
#if !defined (__ALPHA_EXEC_H__)
22
#define __ALPHA_EXEC_H__
23

  
24
#include "config.h"
25

  
26
#include "dyngen-exec.h"
27

  
28
#define TARGET_LONG_BITS 64
29

  
30
register struct CPUAlphaState *env asm(AREG0);
31

  
32
#if TARGET_LONG_BITS > HOST_LONG_BITS
33

  
34
/* no registers can be used */
35
#define T0 (env->t0)
36
#define T1 (env->t1)
37
#define T2 (env->t2)
38

  
39
#else
40

  
41
register uint64_t T0 asm(AREG1);
42
register uint64_t T1 asm(AREG2);
43
register uint64_t T2 asm(AREG3);
44

  
45
#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
46

  
47
#define PARAM(n) ((uint64_t)PARAM##n)
48
#define SPARAM(n) ((int32_t)PARAM##n)
49
#define FT0 (env->ft0)
50
#define FT1 (env->ft1)
51
#define FT2 (env->ft2)
52
#define FP_STATUS (env->fp_status)
53

  
54
#if defined (DEBUG_OP)
55
#define RETURN() __asm__ __volatile__("nop" : : : "memory");
56
#else
57
#define RETURN() __asm__ __volatile__("" : : : "memory");
58
#endif
59

  
60
#include "cpu.h"
61
#include "exec-all.h"
62

  
63
#if !defined(CONFIG_USER_ONLY)
64
#include "softmmu_exec.h"
65
#endif /* !defined(CONFIG_USER_ONLY) */
66

  
67
static inline void env_to_regs(void)
68
{
69
}
70

  
71
static inline void regs_to_env(void)
72
{
73
}
74

  
75
int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw,
76
                                int is_user, int is_softmmu);
77
int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp);
78
int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp);
79

  
80
void do_interrupt (CPUState *env);
81

  
82
#endif /* !defined (__ALPHA_EXEC_H__) */
b/target-alpha/helper.c
1
/*
2
 *  Alpha emulation cpu helpers 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
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20

  
21
#include <stdint.h>
22
#include <stdlib.h>
23
#include <stdio.h>
24

  
25
#include "cpu.h"
26
#include "exec-all.h"
27

  
28
#if defined(CONFIG_USER_ONLY) 
29

  
30
int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
31
                                int is_user, int is_softmmu)
32
{
33
    if (rw == 2)
34
        env->exception_index = EXCP_ITB_MISS;
35
    else
36
        env->exception_index = EXCP_DFAULT;
37
    env->ipr[IPR_EXC_ADDR] = address;
38
    
39
    return 1;
40
}
41

  
42
target_ulong cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
43
{
44
    return addr;
45
}
46

  
47
void do_interrupt (CPUState *env)
48
{
49
    env->exception_index = -1;
50
}
51

  
52
#else
53

  
54
target_ulong cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
55
{
56
    return -1;
57
}
58

  
59
int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
60
                                int is_user, int is_softmmu)
61
{
62
    uint32_t opc;
63

  
64
    if (rw == 2) {
65
        /* Instruction translation buffer miss */
66
        env->exception_index = EXCP_ITB_MISS;
67
    } else {
68
        if (env->ipr[IPR_EXC_ADDR] & 1)
69
            env->exception_index = EXCP_DTB_MISS_PAL;
70
        else
71
            env->exception_index = EXCP_DTB_MISS_NATIVE;
72
        opc = (ldl_code(env->pc) >> 21) << 4;
73
        if (rw) {
74
            opc |= 0x9;
75
        } else {
76
            opc |= 0x4;
77
        }
78
        env->ipr[IPR_MM_STAT] = opc;
79
    }
80

  
81
    return 1;
82
}
83

  
84
int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp)
85
{
86
    uint64_t hwpcb;
87
    int ret = 0;
88

  
89
    hwpcb = env->ipr[IPR_PCBB];
90
    switch (iprn) {
91
    case IPR_ASN:
92
        if (env->features & FEATURE_ASN)
93
            *valp = env->ipr[IPR_ASN];
94
        else
95
            *valp = 0;
96
        break;
97
    case IPR_ASTEN:
98
        *valp = ((int64_t)(env->ipr[IPR_ASTEN] << 60)) >> 60;
99
        break;
100
    case IPR_ASTSR:
101
        *valp = ((int64_t)(env->ipr[IPR_ASTSR] << 60)) >> 60;
102
        break;
103
    case IPR_DATFX:
104
        /* Write only */
105
        ret = -1;
106
        break;
107
    case IPR_ESP:
108
        if (env->features & FEATURE_SPS)
109
            *valp = env->ipr[IPR_ESP];
110
        else
111
            *valp = ldq_raw(hwpcb + 8);
112
        break;
113
    case IPR_FEN:
114
        *valp = ((int64_t)(env->ipr[IPR_FEN] << 63)) >> 63;
115
        break;
116
    case IPR_IPIR:
117
        /* Write-only */
118
        ret = -1;
119
        break;
120
    case IPR_IPL:
121
        *valp = ((int64_t)(env->ipr[IPR_IPL] << 59)) >> 59;
122
        break;
123
    case IPR_KSP:
124
        if (!(env->ipr[IPR_EXC_ADDR] & 1)) {
125
            ret = -1;
126
        } else {
127
            if (env->features & FEATURE_SPS)
128
                *valp = env->ipr[IPR_KSP];
129
            else
130
                *valp = ldq_raw(hwpcb + 0);
131
        }
132
        break;
133
    case IPR_MCES:
134
        *valp = ((int64_t)(env->ipr[IPR_MCES] << 59)) >> 59;
135
        break;
136
    case IPR_PERFMON:
137
        /* Implementation specific */
138
        *valp = 0;
139
        break;
140
    case IPR_PCBB:
141
        *valp = ((int64_t)env->ipr[IPR_PCBB] << 16) >> 16;
142
        break;
143
    case IPR_PRBR:
144
        *valp = env->ipr[IPR_PRBR];
145
        break;
146
    case IPR_PTBR:
147
        *valp = env->ipr[IPR_PTBR];
148
        break;
149
    case IPR_SCBB:
150
        *valp = (int64_t)((int32_t)env->ipr[IPR_SCBB]);
151
        break;
152
    case IPR_SIRR:
153
        /* Write-only */
154
        ret = -1;
155
        break;
156
    case IPR_SISR:
157
        *valp = (int64_t)((int16_t)env->ipr[IPR_SISR]);
158
    case IPR_SSP:
159
        if (env->features & FEATURE_SPS)
160
            *valp = env->ipr[IPR_SSP];
161
        else
162
            *valp = ldq_raw(hwpcb + 16);
163
        break;
164
    case IPR_SYSPTBR:
165
        if (env->features & FEATURE_VIRBND)
166
            *valp = env->ipr[IPR_SYSPTBR];
167
        else
168
            ret = -1;
169
        break;
170
    case IPR_TBCHK:
171
        if ((env->features & FEATURE_TBCHK)) {
172
            /* XXX: TODO */
173
            *valp = 0;
174
            ret = -1;
175
        } else {
176
            ret = -1;
177
        }
178
        break;
179
    case IPR_TBIA:
180
        /* Write-only */
181
        ret = -1;
182
        break;
183
    case IPR_TBIAP:
184
        /* Write-only */
185
        ret = -1;
186
        break;
187
    case IPR_TBIS:
188
        /* Write-only */
189
        ret = -1;
190
        break;
191
    case IPR_TBISD:
192
        /* Write-only */
193
        ret = -1;
194
        break;
195
    case IPR_TBISI:
196
        /* Write-only */
197
        ret = -1;
198
        break;
199
    case IPR_USP:
200
        if (env->features & FEATURE_SPS)
201
            *valp = env->ipr[IPR_USP];
202
        else
203
            *valp = ldq_raw(hwpcb + 24);
204
        break;
205
    case IPR_VIRBND:
206
        if (env->features & FEATURE_VIRBND)
207
            *valp = env->ipr[IPR_VIRBND];
208
        else
209
            ret = -1;
210
        break;
211
    case IPR_VPTB:
212
        *valp = env->ipr[IPR_VPTB];
213
        break;
214
    case IPR_WHAMI:
215
        *valp = env->ipr[IPR_WHAMI];
216
        break;
217
    default:
218
        /* Invalid */
219
        ret = -1;
220
        break;
221
    }
222

  
223
    return ret;
224
}
225

  
226
int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp)
227
{
228
    uint64_t hwpcb, tmp64;
229
    uint8_t tmp8;
230
    int ret = 0;
231

  
232
    hwpcb = env->ipr[IPR_PCBB];
233
    switch (iprn) {
234
    case IPR_ASN:
235
        /* Read-only */
236
        ret = -1;
237
        break;
238
    case IPR_ASTEN:
239
        tmp8 = ((int8_t)(env->ipr[IPR_ASTEN] << 4)) >> 4;
240
        *oldvalp = tmp8;
241
        tmp8 &= val & 0xF;
242
        tmp8 |= (val >> 4) & 0xF;
243
        env->ipr[IPR_ASTEN] &= ~0xF;
244
        env->ipr[IPR_ASTEN] |= tmp8;
245
        ret = 1;
246
        break;
247
    case IPR_ASTSR:
248
        tmp8 = ((int8_t)(env->ipr[IPR_ASTSR] << 4)) >> 4;
249
        *oldvalp = tmp8;
250
        tmp8 &= val & 0xF;
251
        tmp8 |= (val >> 4) & 0xF;
252
        env->ipr[IPR_ASTSR] &= ~0xF;
253
        env->ipr[IPR_ASTSR] |= tmp8;
254
        ret = 1;
255
    case IPR_DATFX:
256
        env->ipr[IPR_DATFX] &= ~0x1;
257
        env->ipr[IPR_DATFX] |= val & 1;
258
        tmp64 = ldq_raw(hwpcb + 56);
259
        tmp64 &= ~0x8000000000000000ULL;
260
        tmp64 |= (val & 1) << 63;
261
        stq_raw(hwpcb + 56, tmp64);
262
        break;
263
    case IPR_ESP:
264
        if (env->features & FEATURE_SPS)
265
            env->ipr[IPR_ESP] = val;
266
        else
267
            stq_raw(hwpcb + 8, val);
268
        break;
269
    case IPR_FEN:
270
        env->ipr[IPR_FEN] = val & 1;
271
        tmp64 = ldq_raw(hwpcb + 56);
272
        tmp64 &= ~1;
273
        tmp64 |= val & 1;
274
        stq_raw(hwpcb + 56, tmp64);
275
        break;
276
    case IPR_IPIR:
277
        /* XXX: TODO: Send IRQ to CPU #ir[16] */
278
        break;
279
    case IPR_IPL:
280
        *oldvalp = ((int64_t)(env->ipr[IPR_IPL] << 59)) >> 59;
281
        env->ipr[IPR_IPL] &= ~0x1F;
282
        env->ipr[IPR_IPL] |= val & 0x1F;
283
        /* XXX: may issue an interrupt or ASR _now_ */
284
        ret = 1;
285
        break;
286
    case IPR_KSP:
287
        if (!(env->ipr[IPR_EXC_ADDR] & 1)) {
288
            ret = -1;
289
        } else {
290
            if (env->features & FEATURE_SPS)
291
                env->ipr[IPR_KSP] = val;
292
            else
293
                stq_raw(hwpcb + 0, val);
294
        }
295
        break;
296
    case IPR_MCES:
297
        env->ipr[IPR_MCES] &= ~((val & 0x7) | 0x18);
298
        env->ipr[IPR_MCES] |= val & 0x18;
299
        break;
300
    case IPR_PERFMON:
301
        /* Implementation specific */
302
        *oldvalp = 0;
303
        ret = 1;
304
        break;
305
    case IPR_PCBB:
306
        /* Read-only */
307
        ret = -1;
308
        break;
309
    case IPR_PRBR:
310
        env->ipr[IPR_PRBR] = val;
311
        break;
312
    case IPR_PTBR:
313
        /* Read-only */
314
        ret = -1;
315
        break;
316
    case IPR_SCBB:
317
        env->ipr[IPR_SCBB] = (uint32_t)val;
318
        break;
319
    case IPR_SIRR:
320
        if (val & 0xF) {
321
            env->ipr[IPR_SISR] |= 1 << (val & 0xF);
322
            /* XXX: request a software interrupt _now_ */
323
        }
324
        break;
325
    case IPR_SISR:
326
        /* Read-only */
327
        ret = -1;
328
        break;
329
    case IPR_SSP:
330
        if (env->features & FEATURE_SPS)
331
            env->ipr[IPR_SSP] = val;
332
        else
333
            stq_raw(hwpcb + 16, val);
334
        break;
335
    case IPR_SYSPTBR:
336
        if (env->features & FEATURE_VIRBND)
337
            env->ipr[IPR_SYSPTBR] = val;
338
        else
339
            ret = -1;
340
    case IPR_TBCHK:
341
        /* Read-only */
342
        ret = -1;
343
        break;
344
    case IPR_TBIA:
345
        tlb_flush(env, 1);
346
        break;
347
    case IPR_TBIAP:
348
        tlb_flush(env, 1);
349
        break;
350
    case IPR_TBIS:
351
        tlb_flush_page(env, val);
352
        break;
353
    case IPR_TBISD:
354
        tlb_flush_page(env, val);
355
        break;
356
    case IPR_TBISI:
357
        tlb_flush_page(env, val);
358
        break;
359
    case IPR_USP:
360
        if (env->features & FEATURE_SPS)
361
            env->ipr[IPR_USP] = val;
362
        else
363
            stq_raw(hwpcb + 24, val);
364
        break;
365
    case IPR_VIRBND:
366
        if (env->features & FEATURE_VIRBND)
367
            env->ipr[IPR_VIRBND] = val;
368
        else
369
            ret = -1;
370
        break;
371
    case IPR_VPTB:
372
        env->ipr[IPR_VPTB] = val;
373
        break;
374
    case IPR_WHAMI:
375
        /* Read-only */
376
        ret = -1;
377
        break;
378
    default:
379
        /* Invalid */
380
        ret = -1;
381
        break;
382
    }
383

  
384
    return ret;
385
}
386

  
387
void do_interrupt (CPUState *env)
388
{
389
    int excp;
390

  
391
    env->ipr[IPR_EXC_ADDR] = env->pc | 1;
392
    excp = env->exception_index;
393
    env->exception_index = 0;
394
    env->error_code = 0;
395
    /* XXX: disable interrupts and memory mapping */
396
    if (env->ipr[IPR_PAL_BASE] != -1ULL) {
397
        /* We use native PALcode */
398
        env->pc = env->ipr[IPR_PAL_BASE] + excp;
399
    } else {
400
        /* We use emulated PALcode */
401
        call_pal(env);
402
        /* Emulate REI */
403
        env->pc = env->ipr[IPR_EXC_ADDR] & ~7;
404
        env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1;
405
        /* XXX: re-enable interrupts and memory mapping */
406
    }
407
}
408
#endif
409

  
410
void cpu_dump_state (CPUState *env, FILE *f, 
411
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
412
                     int flags)
413
{
414
    static unsigned char *linux_reg_names[] = {
415
        "v0 ", "t0 ", "t1 ", "t2 ", "t3 ", "t4 ", "t5 ", "t6 ",
416
        "t7 ", "s0 ", "s1 ", "s2 ", "s3 ", "s4 ", "s5 ", "fp ",
417
        "a0 ", "a1 ", "a2 ", "a3 ", "a4 ", "a5 ", "t8 ", "t9 ",
418
        "t10", "t11", "ra ", "t12", "at ", "gp ", "sp ", "zero",
419
    };
420
    int i;
421

  
422
    cpu_fprintf(f, "     PC  " TARGET_FMT_lx "      PS  " TARGET_FMT_lx "\n",
423
                env->pc, env->ps);
424
    for (i = 0; i < 31; i++) {
425
        cpu_fprintf(f, "IR%02d %s " TARGET_FMT_lx " ", i,
426
                    linux_reg_names[i], env->ir[i]);
427
        if ((i % 3) == 2)
428
            cpu_fprintf(f, "\n");
429
    }
430
    cpu_fprintf(f, "\n");
431
    for (i = 0; i < 31; i++) {
432
        cpu_fprintf(f, "FIR%02d    " TARGET_FMT_lx " ", i,
433
                    *((uint64_t *)(&env->fir[i])));
434
        if ((i % 3) == 2)
435
            cpu_fprintf(f, "\n");
436
    }
437
    cpu_fprintf(f, "FT " TARGET_FMT_lx " " TARGET_FMT_lx " " TARGET_FMT_lx,
438
                *((uint64_t *)(&env->ft0)), *((uint64_t *)(&env->ft1)),
439
                *((uint64_t *)(&env->ft2)));
440
    cpu_fprintf(f, "\nMEM " TARGET_FMT_lx " %d %d\n",
441
                ldq_raw(0x000000004007df60ULL),
442
                (uint8_t *)(&env->ft0), (uint8_t *)(&env->fir[0]));
443
}
444

  
445
void cpu_dump_EA (target_ulong EA)
446
{
447
    FILE *f;
448

  
449
    if (logfile)
450
        f = logfile;
451
    else
452
        f = stdout;
453
    fprintf(f, "Memory access at address " TARGET_FMT_lx "\n", EA);
454
}
b/target-alpha/op.c
1
/*
2
 *  Alpha emulation cpu micro-operations 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
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20

  
21
#define DEBUG_OP
22

  
23
#include "config.h"
24
#include "exec.h"
25

  
26
#include "op_helper.h"
27

  
28
#define REG 0
29
#include "op_template.h"
30

  
31
#define REG 1
32
#include "op_template.h"
33

  
34
#define REG 2
35
#include "op_template.h"
36

  
37
#define REG 3
38
#include "op_template.h"
39

  
40
#define REG 4
41
#include "op_template.h"
42

  
43
#define REG 5
44
#include "op_template.h"
45

  
46
#define REG 6
47
#include "op_template.h"
48

  
49
#define REG 7
50
#include "op_template.h"
51

  
52
#define REG 8
53
#include "op_template.h"
54

  
55
#define REG 9
56
#include "op_template.h"
57

  
58
#define REG 10
59
#include "op_template.h"
60

  
61
#define REG 11
62
#include "op_template.h"
63

  
64
#define REG 12
65
#include "op_template.h"
66

  
67
#define REG 13
68
#include "op_template.h"
69

  
70
#define REG 14
71
#include "op_template.h"
72

  
73
#define REG 15
74
#include "op_template.h"
75

  
76
#define REG 16
77
#include "op_template.h"
78

  
79
#define REG 17
80
#include "op_template.h"
81

  
82
#define REG 18
83
#include "op_template.h"
84

  
85
#define REG 19
86
#include "op_template.h"
87

  
88
#define REG 20
89
#include "op_template.h"
90

  
91
#define REG 21
92
#include "op_template.h"
93

  
94
#define REG 22
95
#include "op_template.h"
96

  
97
#define REG 23
98
#include "op_template.h"
99

  
100
#define REG 24
101
#include "op_template.h"
102

  
103
#define REG 25
104
#include "op_template.h"
105

  
106
#define REG 26
107
#include "op_template.h"
108

  
109
#define REG 27
110
#include "op_template.h"
111

  
112
#define REG 28
113
#include "op_template.h"
114

  
115
#define REG 29
116
#include "op_template.h"
117

  
118
#define REG 30
119
#include "op_template.h"
120

  
121
#define REG 31
122
#include "op_template.h"
123

  
124
/* Debug stuff */
125
void OPPROTO op_no_op (void)
126
{
127
#if !defined (DEBUG_OP)
128
    __asm__ __volatile__("nop" : : : "memory");
129
#endif
130
    RETURN();
131
}
132

  
133
void OPPROTO op_tb_flush (void)
134
{
135
    helper_tb_flush();
136
    RETURN();
137
}
138

  
139
/* Load and stores */
140
#define MEMSUFFIX _raw
141
#include "op_mem.h"
142
#if !defined(CONFIG_USER_ONLY)
143
#define MEMSUFFIX _user
144
#include "op_mem.h"
145
#define MEMSUFFIX _kernel
146
#include "op_mem.h"
147
/* Those are used for supervisor, executive and pal modes */
148
#define MEMSUFFIX _data
149
#include "op_mem.h"
150
#endif
151

  
152
/* Special operation for load and store */
153
void OPPROTO op_n7 (void)
154
{
155
    T0 &= ~(uint64_t)0x7;
156
    RETURN();
157
}
158

  
159
/* Misc */
160
void OPPROTO op_excp (void)
161
{
162
    helper_excp(PARAM(1), PARAM(2));
163
    RETURN();
164
}
165

  
166
void OPPROTO op_load_amask (void)
167
{
168
    helper_amask();
169
    RETURN();
170
}
171

  
172
void OPPROTO op_load_pcc (void)
173
{
174
    helper_load_pcc();
175
    RETURN();
176
}
177

  
178
void OPPROTO op_load_implver (void)
179
{
180
    helper_load_implver();
181
    RETURN();
182
}
183

  
184
void OPPROTO op_load_fpcr (void)
185
{
186
    helper_load_fpcr();
187
    RETURN();
188
}
189

  
190
void OPPROTO op_store_fpcr (void)
191
{
192
    helper_store_fpcr();
193
    RETURN();
194
}
195

  
196
void OPPROTO op_load_irf (void)
197
{
198
    helper_load_irf();
199
    RETURN();
200
}
201

  
202
void OPPROTO op_set_irf (void)
203
{
204
    helper_set_irf();
205
    RETURN();
206
}
207

  
208
void OPPROTO op_clear_irf (void)
209
{
210
    helper_clear_irf();
211
    RETURN();
212
}
213

  
214
void OPPROTO op_exit_tb (void)
215
{
216
    EXIT_TB();
217
}
218

  
219
/* Arithmetic */
220
void OPPROTO op_addq (void)
221
{
222
    T0 += T1;
223
    RETURN();
224
}
225

  
226
void OPPROTO op_addqv (void)
227
{
228
    helper_addqv();
229
    RETURN();
230
}
231

  
232
void OPPROTO op_addl (void)
233
{
234
    T0 = (int64_t)((int32_t)(T0 + T1));
235
    RETURN();
236
}
237

  
238
void OPPROTO op_addlv (void)
239
{
240
    helper_addlv();
241
    RETURN();
242
}
243

  
244
void OPPROTO op_subq (void)
245
{
246
    T0 -= T1;
247
    RETURN();
248
}
249

  
250
void OPPROTO op_subqv (void)
251
{
252
    helper_subqv();
253
    RETURN();
254
}
255

  
256
void OPPROTO op_subl (void)
257
{
258
    T0 = (int64_t)((int32_t)(T0 - T1));
259
    RETURN();
260
}
261

  
262
void OPPROTO op_sublv (void)
263
{
264
    helper_sublv();
265
    RETURN();
266
}
267

  
268
void OPPROTO op_s4 (void)
269
{
270
    T0 <<= 2;
271
    RETURN();
272
}
273

  
274
void OPPROTO op_s8 (void)
275
{
276
    T0 <<= 3;
277
    RETURN();
278
}
279

  
280
void OPPROTO op_mull (void)
281
{
282
    T0 = (int64_t)((int32_t)T0 * (int32_t)T1);
283
    RETURN();
284
}
285

  
286
void OPPROTO op_mullv (void)
287
{
288
    helper_mullv();
289
    RETURN();
290
}
291

  
292
void OPPROTO op_mulq (void)
293
{
294
    T0 *= T1;
295
    RETURN();
296
}
297

  
298
void OPPROTO op_mulqv (void)
299
{
300
    helper_mulqv();
301
    RETURN();
302
}
303

  
304
void OPPROTO op_umulh (void)
305
{
306
    helper_umulh();
307
    RETURN();
308
}
309

  
310
/* Logical */
311
void OPPROTO op_and (void)
312
{
313
    T0 &= T1;
314
    RETURN();
315
}
316

  
317
void OPPROTO op_bic (void)
318
{
319
    T0 &= ~T1;
320
    RETURN();
321
}
322

  
323
void OPPROTO op_bis (void)
324
{
325
    T0 |= T1;
326
    RETURN();
327
}
328

  
329
void OPPROTO op_eqv (void)
330
{
331
    T0 ^= ~T1;
332
    RETURN();
333
}
334

  
335
void OPPROTO op_ornot (void)
336
{
337
    T0 |= ~T1;
338
    RETURN();
339
}
340

  
341
void OPPROTO op_xor (void)
342
{
343
    T0 ^= T1;
344
    RETURN();
345
}
346

  
347
void OPPROTO op_sll (void)
348
{
349
    T0 <<= T1;
350
    RETURN();
351
}
352

  
353
void OPPROTO op_srl (void)
354
{
355
    T0 >>= T1;
356
    RETURN();
357
}
358

  
359
void OPPROTO op_sra (void)
360
{
361
    T0 = (int64_t)T0 >> T1;
362
    RETURN();
363
}
364

  
365
void OPPROTO op_sextb (void)
366
{
367
    T0 = (int64_t)((int8_t)T0);
368
    RETURN();
369
}
370

  
371
void OPPROTO op_sextw (void)
372
{
373
    T0 = (int64_t)((int16_t)T0);
374
    RETURN();
375

  
376
}
377

  
378
void OPPROTO op_ctpop (void)
379
{
380
    helper_ctpop();
381
    RETURN();
382
}
383

  
384
void OPPROTO op_ctlz (void)
385
{
386
    helper_ctlz();
387
    RETURN();
388
}
389

  
390
void OPPROTO op_cttz (void)
391
{
392
    helper_cttz();
393
    RETURN();
394
}
395

  
396
void OPPROTO op_mskbl (void)
397
{
398
    helper_mskbl();
399
    RETURN();
400
}
401

  
402
void OPPROTO op_extbl (void)
403
{
404
    helper_extbl();
405
    RETURN();
406
}
407

  
408
void OPPROTO op_insbl (void)
409
{
410
    helper_insbl();
411
    RETURN();
412
}
413

  
414
void OPPROTO op_mskwl (void)
415
{
416
    helper_mskwl();
417
    RETURN();
418
}
419

  
420
void OPPROTO op_extwl (void)
421
{
422
    helper_extwl();
423
    RETURN();
424
}
425

  
426
void OPPROTO op_inswl (void)
427
{
428
    helper_inswl();
429
    RETURN();
430
}
431

  
432
void OPPROTO op_mskll (void)
433
{
434
    helper_mskll();
435
    RETURN();
436
}
437

  
438
void OPPROTO op_extll (void)
439
{
440
    helper_extll();
441
    RETURN();
442
}
443

  
444
void OPPROTO op_insll (void)
445
{
446
    helper_insll();
447
    RETURN();
448
}
449

  
450
void OPPROTO op_zap (void)
451
{
452
    helper_zap();
453
    RETURN();
454
}
455

  
456
void OPPROTO op_zapnot (void)
457
{
458
    helper_zapnot();
459
    RETURN();
460
}
461

  
462
void OPPROTO op_mskql (void)
463
{
464
    helper_mskql();
465
    RETURN();
466
}
467

  
468
void OPPROTO op_extql (void)
469
{
470
    helper_extql();
471
    RETURN();
472
}
473

  
474
void OPPROTO op_insql (void)
475
{
476
    helper_insql();
477
    RETURN();
478
}
479

  
480
void OPPROTO op_mskwh (void)
481
{
482
    helper_mskwh();
483
    RETURN();
484
}
485

  
486
void OPPROTO op_inswh (void)
487
{
488
    helper_inswh();
489
    RETURN();
490
}
491

  
492
void OPPROTO op_extwh (void)
493
{
494
    helper_extwh();
495
    RETURN();
496
}
497

  
498
void OPPROTO op_msklh (void)
499
{
500
    helper_msklh();
501
    RETURN();
502
}
503

  
504
void OPPROTO op_inslh (void)
505
{
506
    helper_inslh();
507
    RETURN();
508
}
509

  
510
void OPPROTO op_extlh (void)
511
{
512
    helper_extlh();
513
    RETURN();
514
}
515

  
516
void OPPROTO op_mskqh (void)
517
{
518
    helper_mskqh();
519
    RETURN();
520
}
521

  
522
void OPPROTO op_insqh (void)
523
{
524
    helper_insqh();
525
    RETURN();
526
}
527

  
528
void OPPROTO op_extqh (void)
529
{
530
    helper_extqh();
531
    RETURN();
532
}
533

  
534
/* Tests */
535
void OPPROTO op_cmpult (void)
536
{
537
    if (T0 < T1)
538
        T0 = 1;
539
    else
540
        T0 = 0;
541
    RETURN();
542
}
543

  
544
void OPPROTO op_cmpule (void)
545
{
546
    if (T0 <= T1)
547
        T0 = 1;
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff