qemu/target/alpha/cpu.h
<<
>>
Prefs
   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.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 <http://www.gnu.org/licenses/>.
  18 */
  19
  20#ifndef ALPHA_CPU_H
  21#define ALPHA_CPU_H
  22
  23#include "cpu-qom.h"
  24#include "exec/cpu-defs.h"
  25#include "qemu/cpu-float.h"
  26
  27/* Alpha processors have a weak memory model */
  28#define TCG_GUEST_DEFAULT_MO      (0)
  29
  30#define ICACHE_LINE_SIZE 32
  31#define DCACHE_LINE_SIZE 32
  32
  33/* Alpha major type */
  34enum {
  35    ALPHA_EV3  = 1,
  36    ALPHA_EV4  = 2,
  37    ALPHA_SIM  = 3,
  38    ALPHA_LCA  = 4,
  39    ALPHA_EV5  = 5, /* 21164 */
  40    ALPHA_EV45 = 6, /* 21064A */
  41    ALPHA_EV56 = 7, /* 21164A */
  42};
  43
  44/* EV4 minor type */
  45enum {
  46    ALPHA_EV4_2 = 0,
  47    ALPHA_EV4_3 = 1,
  48};
  49
  50/* LCA minor type */
  51enum {
  52    ALPHA_LCA_1 = 1, /* 21066 */
  53    ALPHA_LCA_2 = 2, /* 20166 */
  54    ALPHA_LCA_3 = 3, /* 21068 */
  55    ALPHA_LCA_4 = 4, /* 21068 */
  56    ALPHA_LCA_5 = 5, /* 21066A */
  57    ALPHA_LCA_6 = 6, /* 21068A */
  58};
  59
  60/* EV5 minor type */
  61enum {
  62    ALPHA_EV5_1 = 1, /* Rev BA, CA */
  63    ALPHA_EV5_2 = 2, /* Rev DA, EA */
  64    ALPHA_EV5_3 = 3, /* Pass 3 */
  65    ALPHA_EV5_4 = 4, /* Pass 3.2 */
  66    ALPHA_EV5_5 = 5, /* Pass 4 */
  67};
  68
  69/* EV45 minor type */
  70enum {
  71    ALPHA_EV45_1 = 1, /* Pass 1 */
  72    ALPHA_EV45_2 = 2, /* Pass 1.1 */
  73    ALPHA_EV45_3 = 3, /* Pass 2 */
  74};
  75
  76/* EV56 minor type */
  77enum {
  78    ALPHA_EV56_1 = 1, /* Pass 1 */
  79    ALPHA_EV56_2 = 2, /* Pass 2 */
  80};
  81
  82enum {
  83    IMPLVER_2106x = 0, /* EV4, EV45 & LCA45 */
  84    IMPLVER_21164 = 1, /* EV5, EV56 & PCA45 */
  85    IMPLVER_21264 = 2, /* EV6, EV67 & EV68x */
  86    IMPLVER_21364 = 3, /* EV7 & EV79 */
  87};
  88
  89enum {
  90    AMASK_BWX      = 0x00000001,
  91    AMASK_FIX      = 0x00000002,
  92    AMASK_CIX      = 0x00000004,
  93    AMASK_MVI      = 0x00000100,
  94    AMASK_TRAP     = 0x00000200,
  95    AMASK_PREFETCH = 0x00001000,
  96};
  97
  98enum {
  99    VAX_ROUND_NORMAL = 0,
 100    VAX_ROUND_CHOPPED,
 101};
 102
 103enum {
 104    IEEE_ROUND_NORMAL = 0,
 105    IEEE_ROUND_DYNAMIC,
 106    IEEE_ROUND_PLUS,
 107    IEEE_ROUND_MINUS,
 108    IEEE_ROUND_CHOPPED,
 109};
 110
 111/* IEEE floating-point operations encoding */
 112/* Trap mode */
 113enum {
 114    FP_TRAP_I   = 0x0,
 115    FP_TRAP_U   = 0x1,
 116    FP_TRAP_S  = 0x4,
 117    FP_TRAP_SU  = 0x5,
 118    FP_TRAP_SUI = 0x7,
 119};
 120
 121/* Rounding mode */
 122enum {
 123    FP_ROUND_CHOPPED = 0x0,
 124    FP_ROUND_MINUS   = 0x1,
 125    FP_ROUND_NORMAL  = 0x2,
 126    FP_ROUND_DYNAMIC = 0x3,
 127};
 128
 129/* FPCR bits -- right-shifted 32 so we can use a uint32_t.  */
 130#define FPCR_SUM                (1U << (63 - 32))
 131#define FPCR_INED               (1U << (62 - 32))
 132#define FPCR_UNFD               (1U << (61 - 32))
 133#define FPCR_UNDZ               (1U << (60 - 32))
 134#define FPCR_DYN_SHIFT          (58 - 32)
 135#define FPCR_DYN_CHOPPED        (0U << FPCR_DYN_SHIFT)
 136#define FPCR_DYN_MINUS          (1U << FPCR_DYN_SHIFT)
 137#define FPCR_DYN_NORMAL         (2U << FPCR_DYN_SHIFT)
 138#define FPCR_DYN_PLUS           (3U << FPCR_DYN_SHIFT)
 139#define FPCR_DYN_MASK           (3U << FPCR_DYN_SHIFT)
 140#define FPCR_IOV                (1U << (57 - 32))
 141#define FPCR_INE                (1U << (56 - 32))
 142#define FPCR_UNF                (1U << (55 - 32))
 143#define FPCR_OVF                (1U << (54 - 32))
 144#define FPCR_DZE                (1U << (53 - 32))
 145#define FPCR_INV                (1U << (52 - 32))
 146#define FPCR_OVFD               (1U << (51 - 32))
 147#define FPCR_DZED               (1U << (50 - 32))
 148#define FPCR_INVD               (1U << (49 - 32))
 149#define FPCR_DNZ                (1U << (48 - 32))
 150#define FPCR_DNOD               (1U << (47 - 32))
 151#define FPCR_STATUS_MASK        (FPCR_IOV | FPCR_INE | FPCR_UNF \
 152                                 | FPCR_OVF | FPCR_DZE | FPCR_INV)
 153
 154/* The silly software trap enables implemented by the kernel emulation.
 155   These are more or less architecturally required, since the real hardware
 156   has read-as-zero bits in the FPCR when the features aren't implemented.
 157   For the purposes of QEMU, we pretend the FPCR can hold everything.  */
 158#define SWCR_TRAP_ENABLE_INV    (1U << 1)
 159#define SWCR_TRAP_ENABLE_DZE    (1U << 2)
 160#define SWCR_TRAP_ENABLE_OVF    (1U << 3)
 161#define SWCR_TRAP_ENABLE_UNF    (1U << 4)
 162#define SWCR_TRAP_ENABLE_INE    (1U << 5)
 163#define SWCR_TRAP_ENABLE_DNO    (1U << 6)
 164#define SWCR_TRAP_ENABLE_MASK   ((1U << 7) - (1U << 1))
 165
 166#define SWCR_MAP_DMZ            (1U << 12)
 167#define SWCR_MAP_UMZ            (1U << 13)
 168#define SWCR_MAP_MASK           (SWCR_MAP_DMZ | SWCR_MAP_UMZ)
 169
 170#define SWCR_STATUS_INV         (1U << 17)
 171#define SWCR_STATUS_DZE         (1U << 18)
 172#define SWCR_STATUS_OVF         (1U << 19)
 173#define SWCR_STATUS_UNF         (1U << 20)
 174#define SWCR_STATUS_INE         (1U << 21)
 175#define SWCR_STATUS_DNO         (1U << 22)
 176#define SWCR_STATUS_MASK        ((1U << 23) - (1U << 17))
 177
 178#define SWCR_STATUS_TO_EXCSUM_SHIFT  16
 179
 180#define SWCR_MASK  (SWCR_TRAP_ENABLE_MASK | SWCR_MAP_MASK | SWCR_STATUS_MASK)
 181
 182/* MMU modes definitions */
 183
 184/* Alpha has 5 MMU modes: PALcode, Kernel, Executive, Supervisor, and User.
 185   The Unix PALcode only exposes the kernel and user modes; presumably
 186   executive and supervisor are used by VMS.
 187
 188   PALcode itself uses physical mode for code and kernel mode for data;
 189   there are PALmode instructions that can access data via physical mode
 190   or via an os-installed "alternate mode", which is one of the 4 above.
 191
 192   That said, we're only emulating Unix PALcode, and not attempting VMS,
 193   so we don't need to implement Executive and Supervisor.  QEMU's own
 194   PALcode cheats and usees the KSEG mapping for its code+data rather than
 195   physical addresses.  */
 196
 197#define MMU_KERNEL_IDX   0
 198#define MMU_USER_IDX     1
 199#define MMU_PHYS_IDX     2
 200
 201typedef struct CPUArchState {
 202    uint64_t ir[31];
 203    float64 fir[31];
 204    uint64_t pc;
 205    uint64_t unique;
 206    uint64_t lock_addr;
 207    uint64_t lock_value;
 208
 209    /* The FPCR, and disassembled portions thereof.  */
 210    uint32_t fpcr;
 211#ifdef CONFIG_USER_ONLY
 212    uint32_t swcr;
 213#endif
 214    uint32_t fpcr_exc_enable;
 215    float_status fp_status;
 216    uint8_t fpcr_dyn_round;
 217    uint8_t fpcr_flush_to_zero;
 218
 219    /* Mask of PALmode, Processor State et al.  Most of this gets copied
 220       into the TranslatorBlock flags and controls code generation.  */
 221    uint32_t flags;
 222
 223    /* The high 32-bits of the processor cycle counter.  */
 224    uint32_t pcc_ofs;
 225
 226    /* These pass data from the exception logic in the translator and
 227       helpers to the OS entry point.  This is used for both system
 228       emulation and user-mode.  */
 229    uint64_t trap_arg0;
 230    uint64_t trap_arg1;
 231    uint64_t trap_arg2;
 232
 233#if !defined(CONFIG_USER_ONLY)
 234    /* The internal data required by our emulation of the Unix PALcode.  */
 235    uint64_t exc_addr;
 236    uint64_t palbr;
 237    uint64_t ptbr;
 238    uint64_t vptptr;
 239    uint64_t sysval;
 240    uint64_t usp;
 241    uint64_t shadow[8];
 242    uint64_t scratch[24];
 243#endif
 244
 245    /* This alarm doesn't exist in real hardware; we wish it did.  */
 246    uint64_t alarm_expire;
 247
 248    int error_code;
 249
 250    uint32_t features;
 251    uint32_t amask;
 252    int implver;
 253} CPUAlphaState;
 254
 255/**
 256 * AlphaCPU:
 257 * @env: #CPUAlphaState
 258 *
 259 * An Alpha CPU.
 260 */
 261struct ArchCPU {
 262    /*< private >*/
 263    CPUState parent_obj;
 264    /*< public >*/
 265
 266    CPUNegativeOffsetState neg;
 267    CPUAlphaState env;
 268
 269    /* This alarm doesn't exist in real hardware; we wish it did.  */
 270    QEMUTimer *alarm_timer;
 271};
 272
 273
 274#ifndef CONFIG_USER_ONLY
 275extern const VMStateDescription vmstate_alpha_cpu;
 276
 277void alpha_cpu_do_interrupt(CPUState *cpu);
 278bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req);
 279#endif /* !CONFIG_USER_ONLY */
 280void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags);
 281hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 282int alpha_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 283int alpha_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 284
 285#define cpu_list alpha_cpu_list
 286
 287#include "exec/cpu-all.h"
 288
 289enum {
 290    FEATURE_ASN    = 0x00000001,
 291    FEATURE_SPS    = 0x00000002,
 292    FEATURE_VIRBND = 0x00000004,
 293    FEATURE_TBCHK  = 0x00000008,
 294};
 295
 296enum {
 297    EXCP_RESET,
 298    EXCP_MCHK,
 299    EXCP_SMP_INTERRUPT,
 300    EXCP_CLK_INTERRUPT,
 301    EXCP_DEV_INTERRUPT,
 302    EXCP_MMFAULT,
 303    EXCP_UNALIGN,
 304    EXCP_OPCDEC,
 305    EXCP_ARITH,
 306    EXCP_FEN,
 307    EXCP_CALL_PAL,
 308};
 309
 310/* Alpha-specific interrupt pending bits.  */
 311#define CPU_INTERRUPT_TIMER     CPU_INTERRUPT_TGT_EXT_0
 312#define CPU_INTERRUPT_SMP       CPU_INTERRUPT_TGT_EXT_1
 313#define CPU_INTERRUPT_MCHK      CPU_INTERRUPT_TGT_EXT_2
 314
 315/* OSF/1 Page table bits.  */
 316enum {
 317    PTE_VALID = 0x0001,
 318    PTE_FOR   = 0x0002,  /* used for page protection (fault on read) */
 319    PTE_FOW   = 0x0004,  /* used for page protection (fault on write) */
 320    PTE_FOE   = 0x0008,  /* used for page protection (fault on exec) */
 321    PTE_ASM   = 0x0010,
 322    PTE_KRE   = 0x0100,
 323    PTE_URE   = 0x0200,
 324    PTE_KWE   = 0x1000,
 325    PTE_UWE   = 0x2000
 326};
 327
 328/* Hardware interrupt (entInt) constants.  */
 329enum {
 330    INT_K_IP,
 331    INT_K_CLK,
 332    INT_K_MCHK,
 333    INT_K_DEV,
 334    INT_K_PERF,
 335};
 336
 337/* Memory management (entMM) constants.  */
 338enum {
 339    MM_K_TNV,
 340    MM_K_ACV,
 341    MM_K_FOR,
 342    MM_K_FOE,
 343    MM_K_FOW
 344};
 345
 346/* Arithmetic exception (entArith) constants.  */
 347enum {
 348    EXC_M_SWC = 1,      /* Software completion */
 349    EXC_M_INV = 2,      /* Invalid operation */
 350    EXC_M_DZE = 4,      /* Division by zero */
 351    EXC_M_FOV = 8,      /* Overflow */
 352    EXC_M_UNF = 16,     /* Underflow */
 353    EXC_M_INE = 32,     /* Inexact result */
 354    EXC_M_IOV = 64      /* Integer Overflow */
 355};
 356
 357/* Processor status constants.  */
 358/* Low 3 bits are interrupt mask level.  */
 359#define PS_INT_MASK   7u
 360
 361/* Bits 4 and 5 are the mmu mode.  The VMS PALcode uses all 4 modes;
 362   The Unix PALcode only uses bit 4.  */
 363#define PS_USER_MODE  8u
 364
 365/* CPUAlphaState->flags constants.  These are layed out so that we
 366   can set or reset the pieces individually by assigning to the byte,
 367   or manipulated as a whole.  */
 368
 369#define ENV_FLAG_PAL_SHIFT    0
 370#define ENV_FLAG_PS_SHIFT     8
 371#define ENV_FLAG_RX_SHIFT     16
 372#define ENV_FLAG_FEN_SHIFT    24
 373
 374#define ENV_FLAG_PAL_MODE     (1u << ENV_FLAG_PAL_SHIFT)
 375#define ENV_FLAG_PS_USER      (PS_USER_MODE << ENV_FLAG_PS_SHIFT)
 376#define ENV_FLAG_RX_FLAG      (1u << ENV_FLAG_RX_SHIFT)
 377#define ENV_FLAG_FEN          (1u << ENV_FLAG_FEN_SHIFT)
 378
 379#define ENV_FLAG_TB_MASK \
 380    (ENV_FLAG_PAL_MODE | ENV_FLAG_PS_USER | ENV_FLAG_FEN)
 381
 382#define TB_FLAG_UNALIGN       (1u << 1)
 383
 384static inline int cpu_mmu_index(CPUAlphaState *env, bool ifetch)
 385{
 386    int ret = env->flags & ENV_FLAG_PS_USER ? MMU_USER_IDX : MMU_KERNEL_IDX;
 387    if (env->flags & ENV_FLAG_PAL_MODE) {
 388        ret = MMU_KERNEL_IDX;
 389    }
 390    return ret;
 391}
 392
 393enum {
 394    IR_V0   = 0,
 395    IR_T0   = 1,
 396    IR_T1   = 2,
 397    IR_T2   = 3,
 398    IR_T3   = 4,
 399    IR_T4   = 5,
 400    IR_T5   = 6,
 401    IR_T6   = 7,
 402    IR_T7   = 8,
 403    IR_S0   = 9,
 404    IR_S1   = 10,
 405    IR_S2   = 11,
 406    IR_S3   = 12,
 407    IR_S4   = 13,
 408    IR_S5   = 14,
 409    IR_S6   = 15,
 410    IR_FP   = IR_S6,
 411    IR_A0   = 16,
 412    IR_A1   = 17,
 413    IR_A2   = 18,
 414    IR_A3   = 19,
 415    IR_A4   = 20,
 416    IR_A5   = 21,
 417    IR_T8   = 22,
 418    IR_T9   = 23,
 419    IR_T10  = 24,
 420    IR_T11  = 25,
 421    IR_RA   = 26,
 422    IR_T12  = 27,
 423    IR_PV   = IR_T12,
 424    IR_AT   = 28,
 425    IR_GP   = 29,
 426    IR_SP   = 30,
 427    IR_ZERO = 31,
 428};
 429
 430void alpha_translate_init(void);
 431
 432#define ALPHA_CPU_TYPE_SUFFIX "-" TYPE_ALPHA_CPU
 433#define ALPHA_CPU_TYPE_NAME(model) model ALPHA_CPU_TYPE_SUFFIX
 434#define CPU_RESOLVING_TYPE TYPE_ALPHA_CPU
 435
 436void alpha_cpu_list(void);
 437G_NORETURN void dynamic_excp(CPUAlphaState *, uintptr_t, int, int);
 438G_NORETURN void arith_excp(CPUAlphaState *, uintptr_t, int, uint64_t);
 439
 440uint64_t cpu_alpha_load_fpcr (CPUAlphaState *env);
 441void cpu_alpha_store_fpcr (CPUAlphaState *env, uint64_t val);
 442uint64_t cpu_alpha_load_gr(CPUAlphaState *env, unsigned reg);
 443void cpu_alpha_store_gr(CPUAlphaState *env, unsigned reg, uint64_t val);
 444
 445#ifdef CONFIG_USER_ONLY
 446void alpha_cpu_record_sigsegv(CPUState *cs, vaddr address,
 447                              MMUAccessType access_type,
 448                              bool maperr, uintptr_t retaddr);
 449void alpha_cpu_record_sigbus(CPUState *cs, vaddr address,
 450                             MMUAccessType access_type, uintptr_t retaddr);
 451#else
 452bool alpha_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 453                        MMUAccessType access_type, int mmu_idx,
 454                        bool probe, uintptr_t retaddr);
 455G_NORETURN void alpha_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
 456                                              MMUAccessType access_type, int mmu_idx,
 457                                              uintptr_t retaddr);
 458void alpha_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
 459                                     vaddr addr, unsigned size,
 460                                     MMUAccessType access_type,
 461                                     int mmu_idx, MemTxAttrs attrs,
 462                                     MemTxResult response, uintptr_t retaddr);
 463#endif
 464
 465static inline void cpu_get_tb_cpu_state(CPUAlphaState *env, target_ulong *pc,
 466                                        target_ulong *cs_base, uint32_t *pflags)
 467{
 468    *pc = env->pc;
 469    *cs_base = 0;
 470    *pflags = env->flags & ENV_FLAG_TB_MASK;
 471#ifdef CONFIG_USER_ONLY
 472    *pflags |= TB_FLAG_UNALIGN * !env_cpu(env)->prctl_unalign_sigbus;
 473#endif
 474}
 475
 476#ifdef CONFIG_USER_ONLY
 477/* Copied from linux ieee_swcr_to_fpcr.  */
 478static inline uint64_t alpha_ieee_swcr_to_fpcr(uint64_t swcr)
 479{
 480    uint64_t fpcr = 0;
 481
 482    fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
 483    fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
 484    fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
 485                      | SWCR_TRAP_ENABLE_DZE
 486                      | SWCR_TRAP_ENABLE_OVF)) << 48;
 487    fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
 488                      | SWCR_TRAP_ENABLE_INE)) << 57;
 489    fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
 490    fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
 491
 492    return fpcr;
 493}
 494
 495/* Copied from linux ieee_fpcr_to_swcr.  */
 496static inline uint64_t alpha_ieee_fpcr_to_swcr(uint64_t fpcr)
 497{
 498    uint64_t swcr = 0;
 499
 500    swcr |= (fpcr >> 35) & SWCR_STATUS_MASK;
 501    swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
 502    swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
 503                             | SWCR_TRAP_ENABLE_DZE
 504                             | SWCR_TRAP_ENABLE_OVF);
 505    swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF | SWCR_TRAP_ENABLE_INE);
 506    swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
 507    swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
 508
 509    return swcr;
 510}
 511#endif /* CONFIG_USER_ONLY */
 512
 513#endif /* ALPHA_CPU_H */
 514