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