14c9649a9Sj_mayer /* 24c9649a9Sj_mayer * Alpha emulation cpu definitions for qemu. 34c9649a9Sj_mayer * 44c9649a9Sj_mayer * Copyright (c) 2007 Jocelyn Mayer 54c9649a9Sj_mayer * 64c9649a9Sj_mayer * This library is free software; you can redistribute it and/or 74c9649a9Sj_mayer * modify it under the terms of the GNU Lesser General Public 84c9649a9Sj_mayer * License as published by the Free Software Foundation; either 94c9649a9Sj_mayer * version 2 of the License, or (at your option) any later version. 104c9649a9Sj_mayer * 114c9649a9Sj_mayer * This library is distributed in the hope that it will be useful, 124c9649a9Sj_mayer * but WITHOUT ANY WARRANTY; without even the implied warranty of 134c9649a9Sj_mayer * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 144c9649a9Sj_mayer * Lesser General Public License for more details. 154c9649a9Sj_mayer * 164c9649a9Sj_mayer * You should have received a copy of the GNU Lesser General Public 178167ee88SBlue Swirl * License along with this library; if not, see <http://www.gnu.org/licenses/>. 184c9649a9Sj_mayer */ 194c9649a9Sj_mayer 2007f5a258SMarkus Armbruster #ifndef ALPHA_CPU_H 2107f5a258SMarkus Armbruster #define ALPHA_CPU_H 224c9649a9Sj_mayer 232c976297SStefan Weil #include "qemu-common.h" 241dc8e6b7SPaolo Bonzini #include "cpu-qom.h" 254c9649a9Sj_mayer 264c9649a9Sj_mayer #define TARGET_LONG_BITS 64 27d94f0a8eSPaolo Bonzini #define ALIGNED_ONLY 284c9649a9Sj_mayer 299349b4f9SAndreas Färber #define CPUArchState struct CPUAlphaState 30c2764719Spbrook 31*5ee4f3c2SRichard Henderson /* Alpha processors have a weak memory model */ 32*5ee4f3c2SRichard Henderson #define TCG_GUEST_DEFAULT_MO (0) 33*5ee4f3c2SRichard Henderson 34022c62cbSPaolo Bonzini #include "exec/cpu-defs.h" 354c9649a9Sj_mayer 366b4c305cSPaolo Bonzini #include "fpu/softfloat.h" 374c9649a9Sj_mayer 384c9649a9Sj_mayer #define ICACHE_LINE_SIZE 32 394c9649a9Sj_mayer #define DCACHE_LINE_SIZE 32 404c9649a9Sj_mayer 41b09d9d46Saurel32 #define TARGET_PAGE_BITS 13 424c9649a9Sj_mayer 4376393642SRichard Henderson #ifdef CONFIG_USER_ONLY 4476393642SRichard Henderson /* ??? The kernel likes to give addresses in high memory. If the host has 4576393642SRichard Henderson more virtual address space than the guest, this can lead to impossible 4676393642SRichard Henderson allocations. Honor the long-standing assumption that only kernel addrs 4776393642SRichard Henderson are negative, but otherwise allow allocations anywhere. This could lead 4876393642SRichard Henderson to tricky emulation problems for programs doing tagged addressing, but 4976393642SRichard Henderson that's far fewer than encounter the impossible allocation problem. */ 5076393642SRichard Henderson #define TARGET_PHYS_ADDR_SPACE_BITS 63 5176393642SRichard Henderson #define TARGET_VIRT_ADDR_SPACE_BITS 63 5276393642SRichard Henderson #else 5352705890SRichard Henderson /* ??? EV4 has 34 phys addr bits, EV5 has 40, EV6 has 44. */ 5452705890SRichard Henderson #define TARGET_PHYS_ADDR_SPACE_BITS 44 5552705890SRichard Henderson #define TARGET_VIRT_ADDR_SPACE_BITS (30 + TARGET_PAGE_BITS) 5676393642SRichard Henderson #endif 574c9649a9Sj_mayer 584c9649a9Sj_mayer /* Alpha major type */ 594c9649a9Sj_mayer enum { 604c9649a9Sj_mayer ALPHA_EV3 = 1, 614c9649a9Sj_mayer ALPHA_EV4 = 2, 624c9649a9Sj_mayer ALPHA_SIM = 3, 634c9649a9Sj_mayer ALPHA_LCA = 4, 644c9649a9Sj_mayer ALPHA_EV5 = 5, /* 21164 */ 654c9649a9Sj_mayer ALPHA_EV45 = 6, /* 21064A */ 664c9649a9Sj_mayer ALPHA_EV56 = 7, /* 21164A */ 674c9649a9Sj_mayer }; 684c9649a9Sj_mayer 694c9649a9Sj_mayer /* EV4 minor type */ 704c9649a9Sj_mayer enum { 714c9649a9Sj_mayer ALPHA_EV4_2 = 0, 724c9649a9Sj_mayer ALPHA_EV4_3 = 1, 734c9649a9Sj_mayer }; 744c9649a9Sj_mayer 754c9649a9Sj_mayer /* LCA minor type */ 764c9649a9Sj_mayer enum { 774c9649a9Sj_mayer ALPHA_LCA_1 = 1, /* 21066 */ 784c9649a9Sj_mayer ALPHA_LCA_2 = 2, /* 20166 */ 794c9649a9Sj_mayer ALPHA_LCA_3 = 3, /* 21068 */ 804c9649a9Sj_mayer ALPHA_LCA_4 = 4, /* 21068 */ 814c9649a9Sj_mayer ALPHA_LCA_5 = 5, /* 21066A */ 824c9649a9Sj_mayer ALPHA_LCA_6 = 6, /* 21068A */ 834c9649a9Sj_mayer }; 844c9649a9Sj_mayer 854c9649a9Sj_mayer /* EV5 minor type */ 864c9649a9Sj_mayer enum { 874c9649a9Sj_mayer ALPHA_EV5_1 = 1, /* Rev BA, CA */ 884c9649a9Sj_mayer ALPHA_EV5_2 = 2, /* Rev DA, EA */ 894c9649a9Sj_mayer ALPHA_EV5_3 = 3, /* Pass 3 */ 904c9649a9Sj_mayer ALPHA_EV5_4 = 4, /* Pass 3.2 */ 914c9649a9Sj_mayer ALPHA_EV5_5 = 5, /* Pass 4 */ 924c9649a9Sj_mayer }; 934c9649a9Sj_mayer 944c9649a9Sj_mayer /* EV45 minor type */ 954c9649a9Sj_mayer enum { 964c9649a9Sj_mayer ALPHA_EV45_1 = 1, /* Pass 1 */ 974c9649a9Sj_mayer ALPHA_EV45_2 = 2, /* Pass 1.1 */ 984c9649a9Sj_mayer ALPHA_EV45_3 = 3, /* Pass 2 */ 994c9649a9Sj_mayer }; 1004c9649a9Sj_mayer 1014c9649a9Sj_mayer /* EV56 minor type */ 1024c9649a9Sj_mayer enum { 1034c9649a9Sj_mayer ALPHA_EV56_1 = 1, /* Pass 1 */ 1044c9649a9Sj_mayer ALPHA_EV56_2 = 2, /* Pass 2 */ 1054c9649a9Sj_mayer }; 1064c9649a9Sj_mayer 1074c9649a9Sj_mayer enum { 1084c9649a9Sj_mayer IMPLVER_2106x = 0, /* EV4, EV45 & LCA45 */ 1094c9649a9Sj_mayer IMPLVER_21164 = 1, /* EV5, EV56 & PCA45 */ 1104c9649a9Sj_mayer IMPLVER_21264 = 2, /* EV6, EV67 & EV68x */ 1114c9649a9Sj_mayer IMPLVER_21364 = 3, /* EV7 & EV79 */ 1124c9649a9Sj_mayer }; 1134c9649a9Sj_mayer 1144c9649a9Sj_mayer enum { 1154c9649a9Sj_mayer AMASK_BWX = 0x00000001, 1164c9649a9Sj_mayer AMASK_FIX = 0x00000002, 1174c9649a9Sj_mayer AMASK_CIX = 0x00000004, 1184c9649a9Sj_mayer AMASK_MVI = 0x00000100, 1194c9649a9Sj_mayer AMASK_TRAP = 0x00000200, 1204c9649a9Sj_mayer AMASK_PREFETCH = 0x00001000, 1214c9649a9Sj_mayer }; 1224c9649a9Sj_mayer 1234c9649a9Sj_mayer enum { 1244c9649a9Sj_mayer VAX_ROUND_NORMAL = 0, 1254c9649a9Sj_mayer VAX_ROUND_CHOPPED, 1264c9649a9Sj_mayer }; 1274c9649a9Sj_mayer 1284c9649a9Sj_mayer enum { 1294c9649a9Sj_mayer IEEE_ROUND_NORMAL = 0, 1304c9649a9Sj_mayer IEEE_ROUND_DYNAMIC, 1314c9649a9Sj_mayer IEEE_ROUND_PLUS, 1324c9649a9Sj_mayer IEEE_ROUND_MINUS, 1334c9649a9Sj_mayer IEEE_ROUND_CHOPPED, 1344c9649a9Sj_mayer }; 1354c9649a9Sj_mayer 1364c9649a9Sj_mayer /* IEEE floating-point operations encoding */ 1374c9649a9Sj_mayer /* Trap mode */ 1384c9649a9Sj_mayer enum { 1394c9649a9Sj_mayer FP_TRAP_I = 0x0, 1404c9649a9Sj_mayer FP_TRAP_U = 0x1, 1414c9649a9Sj_mayer FP_TRAP_S = 0x4, 1424c9649a9Sj_mayer FP_TRAP_SU = 0x5, 1434c9649a9Sj_mayer FP_TRAP_SUI = 0x7, 1444c9649a9Sj_mayer }; 1454c9649a9Sj_mayer 1464c9649a9Sj_mayer /* Rounding mode */ 1474c9649a9Sj_mayer enum { 1484c9649a9Sj_mayer FP_ROUND_CHOPPED = 0x0, 1494c9649a9Sj_mayer FP_ROUND_MINUS = 0x1, 1504c9649a9Sj_mayer FP_ROUND_NORMAL = 0x2, 1514c9649a9Sj_mayer FP_ROUND_DYNAMIC = 0x3, 1524c9649a9Sj_mayer }; 1534c9649a9Sj_mayer 154f3d3aad4SRichard Henderson /* FPCR bits -- right-shifted 32 so we can use a uint32_t. */ 155f3d3aad4SRichard Henderson #define FPCR_SUM (1U << (63 - 32)) 156f3d3aad4SRichard Henderson #define FPCR_INED (1U << (62 - 32)) 157f3d3aad4SRichard Henderson #define FPCR_UNFD (1U << (61 - 32)) 158f3d3aad4SRichard Henderson #define FPCR_UNDZ (1U << (60 - 32)) 159f3d3aad4SRichard Henderson #define FPCR_DYN_SHIFT (58 - 32) 160f3d3aad4SRichard Henderson #define FPCR_DYN_CHOPPED (0U << FPCR_DYN_SHIFT) 161f3d3aad4SRichard Henderson #define FPCR_DYN_MINUS (1U << FPCR_DYN_SHIFT) 162f3d3aad4SRichard Henderson #define FPCR_DYN_NORMAL (2U << FPCR_DYN_SHIFT) 163f3d3aad4SRichard Henderson #define FPCR_DYN_PLUS (3U << FPCR_DYN_SHIFT) 164f3d3aad4SRichard Henderson #define FPCR_DYN_MASK (3U << FPCR_DYN_SHIFT) 165f3d3aad4SRichard Henderson #define FPCR_IOV (1U << (57 - 32)) 166f3d3aad4SRichard Henderson #define FPCR_INE (1U << (56 - 32)) 167f3d3aad4SRichard Henderson #define FPCR_UNF (1U << (55 - 32)) 168f3d3aad4SRichard Henderson #define FPCR_OVF (1U << (54 - 32)) 169f3d3aad4SRichard Henderson #define FPCR_DZE (1U << (53 - 32)) 170f3d3aad4SRichard Henderson #define FPCR_INV (1U << (52 - 32)) 171f3d3aad4SRichard Henderson #define FPCR_OVFD (1U << (51 - 32)) 172f3d3aad4SRichard Henderson #define FPCR_DZED (1U << (50 - 32)) 173f3d3aad4SRichard Henderson #define FPCR_INVD (1U << (49 - 32)) 174f3d3aad4SRichard Henderson #define FPCR_DNZ (1U << (48 - 32)) 175f3d3aad4SRichard Henderson #define FPCR_DNOD (1U << (47 - 32)) 176ba0e276dSRichard Henderson #define FPCR_STATUS_MASK (FPCR_IOV | FPCR_INE | FPCR_UNF \ 177ba0e276dSRichard Henderson | FPCR_OVF | FPCR_DZE | FPCR_INV) 178ba0e276dSRichard Henderson 179ba0e276dSRichard Henderson /* The silly software trap enables implemented by the kernel emulation. 180ba0e276dSRichard Henderson These are more or less architecturally required, since the real hardware 181ba0e276dSRichard Henderson has read-as-zero bits in the FPCR when the features aren't implemented. 182ba0e276dSRichard Henderson For the purposes of QEMU, we pretend the FPCR can hold everything. */ 183f3d3aad4SRichard Henderson #define SWCR_TRAP_ENABLE_INV (1U << 1) 184f3d3aad4SRichard Henderson #define SWCR_TRAP_ENABLE_DZE (1U << 2) 185f3d3aad4SRichard Henderson #define SWCR_TRAP_ENABLE_OVF (1U << 3) 186f3d3aad4SRichard Henderson #define SWCR_TRAP_ENABLE_UNF (1U << 4) 187f3d3aad4SRichard Henderson #define SWCR_TRAP_ENABLE_INE (1U << 5) 188f3d3aad4SRichard Henderson #define SWCR_TRAP_ENABLE_DNO (1U << 6) 189f3d3aad4SRichard Henderson #define SWCR_TRAP_ENABLE_MASK ((1U << 7) - (1U << 1)) 190ba0e276dSRichard Henderson 191f3d3aad4SRichard Henderson #define SWCR_MAP_DMZ (1U << 12) 192f3d3aad4SRichard Henderson #define SWCR_MAP_UMZ (1U << 13) 193ba0e276dSRichard Henderson #define SWCR_MAP_MASK (SWCR_MAP_DMZ | SWCR_MAP_UMZ) 194ba0e276dSRichard Henderson 195f3d3aad4SRichard Henderson #define SWCR_STATUS_INV (1U << 17) 196f3d3aad4SRichard Henderson #define SWCR_STATUS_DZE (1U << 18) 197f3d3aad4SRichard Henderson #define SWCR_STATUS_OVF (1U << 19) 198f3d3aad4SRichard Henderson #define SWCR_STATUS_UNF (1U << 20) 199f3d3aad4SRichard Henderson #define SWCR_STATUS_INE (1U << 21) 200f3d3aad4SRichard Henderson #define SWCR_STATUS_DNO (1U << 22) 201f3d3aad4SRichard Henderson #define SWCR_STATUS_MASK ((1U << 23) - (1U << 17)) 202ba0e276dSRichard Henderson 203ba0e276dSRichard Henderson #define SWCR_MASK (SWCR_TRAP_ENABLE_MASK | SWCR_MAP_MASK | SWCR_STATUS_MASK) 204ba0e276dSRichard Henderson 2058417845eSRichard Henderson /* MMU modes definitions */ 2064c9649a9Sj_mayer 2076a73ecf5SRichard Henderson /* Alpha has 5 MMU modes: PALcode, Kernel, Executive, Supervisor, and User. 2088417845eSRichard Henderson The Unix PALcode only exposes the kernel and user modes; presumably 2098417845eSRichard Henderson executive and supervisor are used by VMS. 2108417845eSRichard Henderson 2118417845eSRichard Henderson PALcode itself uses physical mode for code and kernel mode for data; 2128417845eSRichard Henderson there are PALmode instructions that can access data via physical mode 2138417845eSRichard Henderson or via an os-installed "alternate mode", which is one of the 4 above. 2148417845eSRichard Henderson 2156a73ecf5SRichard Henderson That said, we're only emulating Unix PALcode, and not attempting VMS, 2166a73ecf5SRichard Henderson so we don't need to implement Executive and Supervisor. QEMU's own 2176a73ecf5SRichard Henderson PALcode cheats and usees the KSEG mapping for its code+data rather than 2186a73ecf5SRichard Henderson physical addresses. */ 2198417845eSRichard Henderson 2206a73ecf5SRichard Henderson #define NB_MMU_MODES 3 2218417845eSRichard Henderson 2228417845eSRichard Henderson #define MMU_MODE0_SUFFIX _kernel 2238417845eSRichard Henderson #define MMU_MODE1_SUFFIX _user 2248417845eSRichard Henderson #define MMU_KERNEL_IDX 0 2258417845eSRichard Henderson #define MMU_USER_IDX 1 2266a73ecf5SRichard Henderson #define MMU_PHYS_IDX 2 2278417845eSRichard Henderson 2288417845eSRichard Henderson typedef struct CPUAlphaState CPUAlphaState; 2296ebbf390Sj_mayer 2304c9649a9Sj_mayer struct CPUAlphaState { 2314c9649a9Sj_mayer uint64_t ir[31]; 2324c9649a9Sj_mayer float64 fir[31]; 2334c9649a9Sj_mayer uint64_t pc; 2344c9649a9Sj_mayer uint64_t unique; 2356910b8f6SRichard Henderson uint64_t lock_addr; 2366910b8f6SRichard Henderson uint64_t lock_value; 237f3d3aad4SRichard Henderson 238f3d3aad4SRichard Henderson /* The FPCR, and disassembled portions thereof. */ 239f3d3aad4SRichard Henderson uint32_t fpcr; 240f3d3aad4SRichard Henderson uint32_t fpcr_exc_enable; 2418443effbSRichard Henderson float_status fp_status; 2428443effbSRichard Henderson uint8_t fpcr_dyn_round; 2438443effbSRichard Henderson uint8_t fpcr_flush_to_zero; 2448443effbSRichard Henderson 245129d8aa5SRichard Henderson /* The Internal Processor Registers. Some of these we assume always 246129d8aa5SRichard Henderson exist for use in user-mode. */ 247129d8aa5SRichard Henderson uint8_t ps; 2488443effbSRichard Henderson uint8_t intr_flag; 249129d8aa5SRichard Henderson uint8_t pal_mode; 25026b46094SRichard Henderson uint8_t fen; 25126b46094SRichard Henderson 25226b46094SRichard Henderson uint32_t pcc_ofs; 253129d8aa5SRichard Henderson 254129d8aa5SRichard Henderson /* These pass data from the exception logic in the translator and 255129d8aa5SRichard Henderson helpers to the OS entry point. This is used for both system 256129d8aa5SRichard Henderson emulation and user-mode. */ 257129d8aa5SRichard Henderson uint64_t trap_arg0; 258129d8aa5SRichard Henderson uint64_t trap_arg1; 259129d8aa5SRichard Henderson uint64_t trap_arg2; 2604c9649a9Sj_mayer 26126b46094SRichard Henderson #if !defined(CONFIG_USER_ONLY) 26226b46094SRichard Henderson /* The internal data required by our emulation of the Unix PALcode. */ 26326b46094SRichard Henderson uint64_t exc_addr; 26426b46094SRichard Henderson uint64_t palbr; 26526b46094SRichard Henderson uint64_t ptbr; 26626b46094SRichard Henderson uint64_t vptptr; 26726b46094SRichard Henderson uint64_t sysval; 26826b46094SRichard Henderson uint64_t usp; 26926b46094SRichard Henderson uint64_t shadow[8]; 27026b46094SRichard Henderson uint64_t scratch[24]; 27126b46094SRichard Henderson #endif 27226b46094SRichard Henderson 273c781cf96SRichard Henderson /* This alarm doesn't exist in real hardware; we wish it did. */ 274c781cf96SRichard Henderson uint64_t alarm_expire; 275c781cf96SRichard Henderson 2765cbdb3a3SStefan Weil /* Those resources are used only in QEMU core */ 2774c9649a9Sj_mayer CPU_COMMON 2784c9649a9Sj_mayer 2794c9649a9Sj_mayer int error_code; 2804c9649a9Sj_mayer 2814c9649a9Sj_mayer uint32_t features; 2824c9649a9Sj_mayer uint32_t amask; 2834c9649a9Sj_mayer int implver; 2844c9649a9Sj_mayer }; 2854c9649a9Sj_mayer 2861dc8e6b7SPaolo Bonzini /** 2871dc8e6b7SPaolo Bonzini * AlphaCPU: 2881dc8e6b7SPaolo Bonzini * @env: #CPUAlphaState 2891dc8e6b7SPaolo Bonzini * 2901dc8e6b7SPaolo Bonzini * An Alpha CPU. 2911dc8e6b7SPaolo Bonzini */ 2921dc8e6b7SPaolo Bonzini struct AlphaCPU { 2931dc8e6b7SPaolo Bonzini /*< private >*/ 2941dc8e6b7SPaolo Bonzini CPUState parent_obj; 2951dc8e6b7SPaolo Bonzini /*< public >*/ 2961dc8e6b7SPaolo Bonzini 2971dc8e6b7SPaolo Bonzini CPUAlphaState env; 2981dc8e6b7SPaolo Bonzini 2991dc8e6b7SPaolo Bonzini /* This alarm doesn't exist in real hardware; we wish it did. */ 3001dc8e6b7SPaolo Bonzini QEMUTimer *alarm_timer; 3011dc8e6b7SPaolo Bonzini }; 3021dc8e6b7SPaolo Bonzini 3031dc8e6b7SPaolo Bonzini static inline AlphaCPU *alpha_env_get_cpu(CPUAlphaState *env) 3041dc8e6b7SPaolo Bonzini { 3051dc8e6b7SPaolo Bonzini return container_of(env, AlphaCPU, env); 3061dc8e6b7SPaolo Bonzini } 3071dc8e6b7SPaolo Bonzini 3081dc8e6b7SPaolo Bonzini #define ENV_GET_CPU(e) CPU(alpha_env_get_cpu(e)) 3091dc8e6b7SPaolo Bonzini 3101dc8e6b7SPaolo Bonzini #define ENV_OFFSET offsetof(AlphaCPU, env) 3111dc8e6b7SPaolo Bonzini 3121dc8e6b7SPaolo Bonzini #ifndef CONFIG_USER_ONLY 3131dc8e6b7SPaolo Bonzini extern const struct VMStateDescription vmstate_alpha_cpu; 3141dc8e6b7SPaolo Bonzini #endif 3151dc8e6b7SPaolo Bonzini 3161dc8e6b7SPaolo Bonzini void alpha_cpu_do_interrupt(CPUState *cpu); 3171dc8e6b7SPaolo Bonzini bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req); 3181dc8e6b7SPaolo Bonzini void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, 3191dc8e6b7SPaolo Bonzini int flags); 3201dc8e6b7SPaolo Bonzini hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); 3211dc8e6b7SPaolo Bonzini int alpha_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); 3221dc8e6b7SPaolo Bonzini int alpha_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); 3231dc8e6b7SPaolo Bonzini void alpha_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, 324b35399bbSSergey Sorokin MMUAccessType access_type, 325b35399bbSSergey Sorokin int mmu_idx, uintptr_t retaddr); 3261dc8e6b7SPaolo Bonzini 327494342b3SAndreas Färber #define cpu_list alpha_cpu_list 3289467d44cSths #define cpu_signal_handler cpu_alpha_signal_handler 3299467d44cSths 330022c62cbSPaolo Bonzini #include "exec/cpu-all.h" 3314c9649a9Sj_mayer 3324c9649a9Sj_mayer enum { 3334c9649a9Sj_mayer FEATURE_ASN = 0x00000001, 3344c9649a9Sj_mayer FEATURE_SPS = 0x00000002, 3354c9649a9Sj_mayer FEATURE_VIRBND = 0x00000004, 3364c9649a9Sj_mayer FEATURE_TBCHK = 0x00000008, 3374c9649a9Sj_mayer }; 3384c9649a9Sj_mayer 3394c9649a9Sj_mayer enum { 34007b6c13bSRichard Henderson EXCP_RESET, 34107b6c13bSRichard Henderson EXCP_MCHK, 34207b6c13bSRichard Henderson EXCP_SMP_INTERRUPT, 34307b6c13bSRichard Henderson EXCP_CLK_INTERRUPT, 34407b6c13bSRichard Henderson EXCP_DEV_INTERRUPT, 34507b6c13bSRichard Henderson EXCP_MMFAULT, 34607b6c13bSRichard Henderson EXCP_UNALIGN, 34707b6c13bSRichard Henderson EXCP_OPCDEC, 34807b6c13bSRichard Henderson EXCP_ARITH, 34907b6c13bSRichard Henderson EXCP_FEN, 35007b6c13bSRichard Henderson EXCP_CALL_PAL, 3514c9649a9Sj_mayer }; 3524c9649a9Sj_mayer 3536a80e088SRichard Henderson /* Alpha-specific interrupt pending bits. */ 3546a80e088SRichard Henderson #define CPU_INTERRUPT_TIMER CPU_INTERRUPT_TGT_EXT_0 3556a80e088SRichard Henderson #define CPU_INTERRUPT_SMP CPU_INTERRUPT_TGT_EXT_1 3566a80e088SRichard Henderson #define CPU_INTERRUPT_MCHK CPU_INTERRUPT_TGT_EXT_2 3576a80e088SRichard Henderson 358a3b9af16SRichard Henderson /* OSF/1 Page table bits. */ 359a3b9af16SRichard Henderson enum { 360a3b9af16SRichard Henderson PTE_VALID = 0x0001, 361a3b9af16SRichard Henderson PTE_FOR = 0x0002, /* used for page protection (fault on read) */ 362a3b9af16SRichard Henderson PTE_FOW = 0x0004, /* used for page protection (fault on write) */ 363a3b9af16SRichard Henderson PTE_FOE = 0x0008, /* used for page protection (fault on exec) */ 364a3b9af16SRichard Henderson PTE_ASM = 0x0010, 365a3b9af16SRichard Henderson PTE_KRE = 0x0100, 366a3b9af16SRichard Henderson PTE_URE = 0x0200, 367a3b9af16SRichard Henderson PTE_KWE = 0x1000, 368a3b9af16SRichard Henderson PTE_UWE = 0x2000 369a3b9af16SRichard Henderson }; 370a3b9af16SRichard Henderson 371ea879fc7SRichard Henderson /* Hardware interrupt (entInt) constants. */ 372ea879fc7SRichard Henderson enum { 373ea879fc7SRichard Henderson INT_K_IP, 374ea879fc7SRichard Henderson INT_K_CLK, 375ea879fc7SRichard Henderson INT_K_MCHK, 376ea879fc7SRichard Henderson INT_K_DEV, 377ea879fc7SRichard Henderson INT_K_PERF, 378ea879fc7SRichard Henderson }; 379ea879fc7SRichard Henderson 380ea879fc7SRichard Henderson /* Memory management (entMM) constants. */ 381ea879fc7SRichard Henderson enum { 382ea879fc7SRichard Henderson MM_K_TNV, 383ea879fc7SRichard Henderson MM_K_ACV, 384ea879fc7SRichard Henderson MM_K_FOR, 385ea879fc7SRichard Henderson MM_K_FOE, 386ea879fc7SRichard Henderson MM_K_FOW 387ea879fc7SRichard Henderson }; 388ea879fc7SRichard Henderson 389ea879fc7SRichard Henderson /* Arithmetic exception (entArith) constants. */ 390ea879fc7SRichard Henderson enum { 391ea879fc7SRichard Henderson EXC_M_SWC = 1, /* Software completion */ 392ea879fc7SRichard Henderson EXC_M_INV = 2, /* Invalid operation */ 393ea879fc7SRichard Henderson EXC_M_DZE = 4, /* Division by zero */ 394ea879fc7SRichard Henderson EXC_M_FOV = 8, /* Overflow */ 395ea879fc7SRichard Henderson EXC_M_UNF = 16, /* Underflow */ 396ea879fc7SRichard Henderson EXC_M_INE = 32, /* Inexact result */ 397ea879fc7SRichard Henderson EXC_M_IOV = 64 /* Integer Overflow */ 398ea879fc7SRichard Henderson }; 399ea879fc7SRichard Henderson 400ea879fc7SRichard Henderson /* Processor status constants. */ 401ea879fc7SRichard Henderson enum { 402ea879fc7SRichard Henderson /* Low 3 bits are interrupt mask level. */ 403ea879fc7SRichard Henderson PS_INT_MASK = 7, 404ea879fc7SRichard Henderson 405ea879fc7SRichard Henderson /* Bits 4 and 5 are the mmu mode. The VMS PALcode uses all 4 modes; 406ea879fc7SRichard Henderson The Unix PALcode only uses bit 4. */ 407ea879fc7SRichard Henderson PS_USER_MODE = 8 408ea879fc7SRichard Henderson }; 409ea879fc7SRichard Henderson 41097ed5ccdSBenjamin Herrenschmidt static inline int cpu_mmu_index(CPUAlphaState *env, bool ifetch) 411ea879fc7SRichard Henderson { 412bba9bdceSRichard Henderson if (env->pal_mode) { 413bba9bdceSRichard Henderson return MMU_KERNEL_IDX; 414bba9bdceSRichard Henderson } else if (env->ps & PS_USER_MODE) { 415bba9bdceSRichard Henderson return MMU_USER_IDX; 416bba9bdceSRichard Henderson } else { 417bba9bdceSRichard Henderson return MMU_KERNEL_IDX; 418bba9bdceSRichard Henderson } 419ea879fc7SRichard Henderson } 4204c9649a9Sj_mayer 4214c9649a9Sj_mayer enum { 4224c9649a9Sj_mayer IR_V0 = 0, 4234c9649a9Sj_mayer IR_T0 = 1, 4244c9649a9Sj_mayer IR_T1 = 2, 4254c9649a9Sj_mayer IR_T2 = 3, 4264c9649a9Sj_mayer IR_T3 = 4, 4274c9649a9Sj_mayer IR_T4 = 5, 4284c9649a9Sj_mayer IR_T5 = 6, 4294c9649a9Sj_mayer IR_T6 = 7, 4304c9649a9Sj_mayer IR_T7 = 8, 4314c9649a9Sj_mayer IR_S0 = 9, 4324c9649a9Sj_mayer IR_S1 = 10, 4334c9649a9Sj_mayer IR_S2 = 11, 4344c9649a9Sj_mayer IR_S3 = 12, 4354c9649a9Sj_mayer IR_S4 = 13, 4364c9649a9Sj_mayer IR_S5 = 14, 4374c9649a9Sj_mayer IR_S6 = 15, 438a4b388ffSRichard Henderson IR_FP = IR_S6, 4394c9649a9Sj_mayer IR_A0 = 16, 4404c9649a9Sj_mayer IR_A1 = 17, 4414c9649a9Sj_mayer IR_A2 = 18, 4424c9649a9Sj_mayer IR_A3 = 19, 4434c9649a9Sj_mayer IR_A4 = 20, 4444c9649a9Sj_mayer IR_A5 = 21, 4454c9649a9Sj_mayer IR_T8 = 22, 4464c9649a9Sj_mayer IR_T9 = 23, 4474c9649a9Sj_mayer IR_T10 = 24, 4484c9649a9Sj_mayer IR_T11 = 25, 4494c9649a9Sj_mayer IR_RA = 26, 4504c9649a9Sj_mayer IR_T12 = 27, 451a4b388ffSRichard Henderson IR_PV = IR_T12, 4524c9649a9Sj_mayer IR_AT = 28, 4534c9649a9Sj_mayer IR_GP = 29, 4544c9649a9Sj_mayer IR_SP = 30, 4554c9649a9Sj_mayer IR_ZERO = 31, 4564c9649a9Sj_mayer }; 4574c9649a9Sj_mayer 4580c28246fSAndreas Färber void alpha_translate_init(void); 4590c28246fSAndreas Färber 4605f5e3350SAndreas Färber AlphaCPU *cpu_alpha_init(const char *cpu_model); 4615f5e3350SAndreas Färber 4622994fd96SEduardo Habkost #define cpu_init(cpu_model) CPU(cpu_alpha_init(cpu_model)) 4635f5e3350SAndreas Färber 464494342b3SAndreas Färber void alpha_cpu_list(FILE *f, fprintf_function cpu_fprintf); 465e96efcfcSj_mayer /* you can call this signal handler from your SIGBUS and SIGSEGV 466e96efcfcSj_mayer signal handlers to inform the virtual CPU of exceptions. non zero 467e96efcfcSj_mayer is returned if the signal was handled by the virtual CPU. */ 468e96efcfcSj_mayer int cpu_alpha_signal_handler(int host_signum, void *pinfo, 469e96efcfcSj_mayer void *puc); 4707510454eSAndreas Färber int alpha_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, 47197b348e7SBlue Swirl int mmu_idx); 47220503968SBlue Swirl void QEMU_NORETURN dynamic_excp(CPUAlphaState *, uintptr_t, int, int); 47320503968SBlue Swirl void QEMU_NORETURN arith_excp(CPUAlphaState *, uintptr_t, int, uint64_t); 47495870356Saurel32 4754d5712f1SAndreas Färber uint64_t cpu_alpha_load_fpcr (CPUAlphaState *env); 4764d5712f1SAndreas Färber void cpu_alpha_store_fpcr (CPUAlphaState *env, uint64_t val); 47759124384SRichard Henderson uint64_t cpu_alpha_load_gr(CPUAlphaState *env, unsigned reg); 47859124384SRichard Henderson void cpu_alpha_store_gr(CPUAlphaState *env, unsigned reg, uint64_t val); 4795b450407SRichard Henderson #ifndef CONFIG_USER_ONLY 480c658b94fSAndreas Färber QEMU_NORETURN void alpha_cpu_unassigned_access(CPUState *cpu, hwaddr addr, 481c658b94fSAndreas Färber bool is_write, bool is_exec, 482c658b94fSAndreas Färber int unused, unsigned size); 4835b450407SRichard Henderson #endif 4844c9649a9Sj_mayer 485a18ad893SRichard Henderson /* Bits in TB->FLAGS that control how translation is processed. */ 486a18ad893SRichard Henderson enum { 487a18ad893SRichard Henderson TB_FLAGS_PAL_MODE = 1, 488a18ad893SRichard Henderson TB_FLAGS_FEN = 2, 489a18ad893SRichard Henderson TB_FLAGS_USER_MODE = 8, 490a18ad893SRichard Henderson 491a18ad893SRichard Henderson TB_FLAGS_AMASK_SHIFT = 4, 492a18ad893SRichard Henderson TB_FLAGS_AMASK_BWX = AMASK_BWX << TB_FLAGS_AMASK_SHIFT, 493a18ad893SRichard Henderson TB_FLAGS_AMASK_FIX = AMASK_FIX << TB_FLAGS_AMASK_SHIFT, 494a18ad893SRichard Henderson TB_FLAGS_AMASK_CIX = AMASK_CIX << TB_FLAGS_AMASK_SHIFT, 495a18ad893SRichard Henderson TB_FLAGS_AMASK_MVI = AMASK_MVI << TB_FLAGS_AMASK_SHIFT, 496a18ad893SRichard Henderson TB_FLAGS_AMASK_TRAP = AMASK_TRAP << TB_FLAGS_AMASK_SHIFT, 497a18ad893SRichard Henderson TB_FLAGS_AMASK_PREFETCH = AMASK_PREFETCH << TB_FLAGS_AMASK_SHIFT, 498a18ad893SRichard Henderson }; 499a18ad893SRichard Henderson 5004d5712f1SAndreas Färber static inline void cpu_get_tb_cpu_state(CPUAlphaState *env, target_ulong *pc, 50189fee74aSEmilio G. Cota target_ulong *cs_base, uint32_t *pflags) 5026b917547Saliguori { 503a18ad893SRichard Henderson int flags = 0; 504a18ad893SRichard Henderson 5056b917547Saliguori *pc = env->pc; 5066b917547Saliguori *cs_base = 0; 507a18ad893SRichard Henderson 508a18ad893SRichard Henderson if (env->pal_mode) { 509a18ad893SRichard Henderson flags = TB_FLAGS_PAL_MODE; 510a18ad893SRichard Henderson } else { 511a18ad893SRichard Henderson flags = env->ps & PS_USER_MODE; 512a18ad893SRichard Henderson } 513a18ad893SRichard Henderson if (env->fen) { 514a18ad893SRichard Henderson flags |= TB_FLAGS_FEN; 515a18ad893SRichard Henderson } 516a18ad893SRichard Henderson flags |= env->amask << TB_FLAGS_AMASK_SHIFT; 517a18ad893SRichard Henderson 518a18ad893SRichard Henderson *pflags = flags; 5196b917547Saliguori } 5206b917547Saliguori 52107f5a258SMarkus Armbruster #endif /* ALPHA_CPU_H */ 522