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 9d6ea4236SChetan Pant * version 2.1 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 231dc8e6b7SPaolo Bonzini #include "cpu-qom.h" 2474433bf0SRichard Henderson #include "exec/cpu-defs.h" 2569242e7eSMarc-André Lureau #include "qemu/cpu-float.h" 264c9649a9Sj_mayer 274c9649a9Sj_mayer #define ICACHE_LINE_SIZE 32 284c9649a9Sj_mayer #define DCACHE_LINE_SIZE 32 294c9649a9Sj_mayer 304c9649a9Sj_mayer /* Alpha major type */ 314c9649a9Sj_mayer enum { 324c9649a9Sj_mayer ALPHA_EV3 = 1, 334c9649a9Sj_mayer ALPHA_EV4 = 2, 344c9649a9Sj_mayer ALPHA_SIM = 3, 354c9649a9Sj_mayer ALPHA_LCA = 4, 364c9649a9Sj_mayer ALPHA_EV5 = 5, /* 21164 */ 374c9649a9Sj_mayer ALPHA_EV45 = 6, /* 21064A */ 384c9649a9Sj_mayer ALPHA_EV56 = 7, /* 21164A */ 394c9649a9Sj_mayer }; 404c9649a9Sj_mayer 414c9649a9Sj_mayer /* EV4 minor type */ 424c9649a9Sj_mayer enum { 434c9649a9Sj_mayer ALPHA_EV4_2 = 0, 444c9649a9Sj_mayer ALPHA_EV4_3 = 1, 454c9649a9Sj_mayer }; 464c9649a9Sj_mayer 474c9649a9Sj_mayer /* LCA minor type */ 484c9649a9Sj_mayer enum { 494c9649a9Sj_mayer ALPHA_LCA_1 = 1, /* 21066 */ 504c9649a9Sj_mayer ALPHA_LCA_2 = 2, /* 20166 */ 514c9649a9Sj_mayer ALPHA_LCA_3 = 3, /* 21068 */ 524c9649a9Sj_mayer ALPHA_LCA_4 = 4, /* 21068 */ 534c9649a9Sj_mayer ALPHA_LCA_5 = 5, /* 21066A */ 544c9649a9Sj_mayer ALPHA_LCA_6 = 6, /* 21068A */ 554c9649a9Sj_mayer }; 564c9649a9Sj_mayer 574c9649a9Sj_mayer /* EV5 minor type */ 584c9649a9Sj_mayer enum { 594c9649a9Sj_mayer ALPHA_EV5_1 = 1, /* Rev BA, CA */ 604c9649a9Sj_mayer ALPHA_EV5_2 = 2, /* Rev DA, EA */ 614c9649a9Sj_mayer ALPHA_EV5_3 = 3, /* Pass 3 */ 624c9649a9Sj_mayer ALPHA_EV5_4 = 4, /* Pass 3.2 */ 634c9649a9Sj_mayer ALPHA_EV5_5 = 5, /* Pass 4 */ 644c9649a9Sj_mayer }; 654c9649a9Sj_mayer 664c9649a9Sj_mayer /* EV45 minor type */ 674c9649a9Sj_mayer enum { 684c9649a9Sj_mayer ALPHA_EV45_1 = 1, /* Pass 1 */ 694c9649a9Sj_mayer ALPHA_EV45_2 = 2, /* Pass 1.1 */ 704c9649a9Sj_mayer ALPHA_EV45_3 = 3, /* Pass 2 */ 714c9649a9Sj_mayer }; 724c9649a9Sj_mayer 734c9649a9Sj_mayer /* EV56 minor type */ 744c9649a9Sj_mayer enum { 754c9649a9Sj_mayer ALPHA_EV56_1 = 1, /* Pass 1 */ 764c9649a9Sj_mayer ALPHA_EV56_2 = 2, /* Pass 2 */ 774c9649a9Sj_mayer }; 784c9649a9Sj_mayer 794c9649a9Sj_mayer enum { 804c9649a9Sj_mayer IMPLVER_2106x = 0, /* EV4, EV45 & LCA45 */ 814c9649a9Sj_mayer IMPLVER_21164 = 1, /* EV5, EV56 & PCA45 */ 824c9649a9Sj_mayer IMPLVER_21264 = 2, /* EV6, EV67 & EV68x */ 834c9649a9Sj_mayer IMPLVER_21364 = 3, /* EV7 & EV79 */ 844c9649a9Sj_mayer }; 854c9649a9Sj_mayer 864c9649a9Sj_mayer enum { 874c9649a9Sj_mayer AMASK_BWX = 0x00000001, 884c9649a9Sj_mayer AMASK_FIX = 0x00000002, 894c9649a9Sj_mayer AMASK_CIX = 0x00000004, 904c9649a9Sj_mayer AMASK_MVI = 0x00000100, 914c9649a9Sj_mayer AMASK_TRAP = 0x00000200, 924c9649a9Sj_mayer AMASK_PREFETCH = 0x00001000, 934c9649a9Sj_mayer }; 944c9649a9Sj_mayer 954c9649a9Sj_mayer enum { 964c9649a9Sj_mayer VAX_ROUND_NORMAL = 0, 974c9649a9Sj_mayer VAX_ROUND_CHOPPED, 984c9649a9Sj_mayer }; 994c9649a9Sj_mayer 1004c9649a9Sj_mayer enum { 1014c9649a9Sj_mayer IEEE_ROUND_NORMAL = 0, 1024c9649a9Sj_mayer IEEE_ROUND_DYNAMIC, 1034c9649a9Sj_mayer IEEE_ROUND_PLUS, 1044c9649a9Sj_mayer IEEE_ROUND_MINUS, 1054c9649a9Sj_mayer IEEE_ROUND_CHOPPED, 1064c9649a9Sj_mayer }; 1074c9649a9Sj_mayer 1084c9649a9Sj_mayer /* IEEE floating-point operations encoding */ 1094c9649a9Sj_mayer /* Trap mode */ 1104c9649a9Sj_mayer enum { 1114c9649a9Sj_mayer FP_TRAP_I = 0x0, 1124c9649a9Sj_mayer FP_TRAP_U = 0x1, 1134c9649a9Sj_mayer FP_TRAP_S = 0x4, 1144c9649a9Sj_mayer FP_TRAP_SU = 0x5, 1154c9649a9Sj_mayer FP_TRAP_SUI = 0x7, 1164c9649a9Sj_mayer }; 1174c9649a9Sj_mayer 1184c9649a9Sj_mayer /* Rounding mode */ 1194c9649a9Sj_mayer enum { 1204c9649a9Sj_mayer FP_ROUND_CHOPPED = 0x0, 1214c9649a9Sj_mayer FP_ROUND_MINUS = 0x1, 1224c9649a9Sj_mayer FP_ROUND_NORMAL = 0x2, 1234c9649a9Sj_mayer FP_ROUND_DYNAMIC = 0x3, 1244c9649a9Sj_mayer }; 1254c9649a9Sj_mayer 126f3d3aad4SRichard Henderson /* FPCR bits -- right-shifted 32 so we can use a uint32_t. */ 127f3d3aad4SRichard Henderson #define FPCR_SUM (1U << (63 - 32)) 128f3d3aad4SRichard Henderson #define FPCR_INED (1U << (62 - 32)) 129f3d3aad4SRichard Henderson #define FPCR_UNFD (1U << (61 - 32)) 130f3d3aad4SRichard Henderson #define FPCR_UNDZ (1U << (60 - 32)) 131f3d3aad4SRichard Henderson #define FPCR_DYN_SHIFT (58 - 32) 132f3d3aad4SRichard Henderson #define FPCR_DYN_CHOPPED (0U << FPCR_DYN_SHIFT) 133f3d3aad4SRichard Henderson #define FPCR_DYN_MINUS (1U << FPCR_DYN_SHIFT) 134f3d3aad4SRichard Henderson #define FPCR_DYN_NORMAL (2U << FPCR_DYN_SHIFT) 135f3d3aad4SRichard Henderson #define FPCR_DYN_PLUS (3U << FPCR_DYN_SHIFT) 136f3d3aad4SRichard Henderson #define FPCR_DYN_MASK (3U << FPCR_DYN_SHIFT) 137f3d3aad4SRichard Henderson #define FPCR_IOV (1U << (57 - 32)) 138f3d3aad4SRichard Henderson #define FPCR_INE (1U << (56 - 32)) 139f3d3aad4SRichard Henderson #define FPCR_UNF (1U << (55 - 32)) 140f3d3aad4SRichard Henderson #define FPCR_OVF (1U << (54 - 32)) 141f3d3aad4SRichard Henderson #define FPCR_DZE (1U << (53 - 32)) 142f3d3aad4SRichard Henderson #define FPCR_INV (1U << (52 - 32)) 143f3d3aad4SRichard Henderson #define FPCR_OVFD (1U << (51 - 32)) 144f3d3aad4SRichard Henderson #define FPCR_DZED (1U << (50 - 32)) 145f3d3aad4SRichard Henderson #define FPCR_INVD (1U << (49 - 32)) 146f3d3aad4SRichard Henderson #define FPCR_DNZ (1U << (48 - 32)) 147f3d3aad4SRichard Henderson #define FPCR_DNOD (1U << (47 - 32)) 148ba0e276dSRichard Henderson #define FPCR_STATUS_MASK (FPCR_IOV | FPCR_INE | FPCR_UNF \ 149ba0e276dSRichard Henderson | FPCR_OVF | FPCR_DZE | FPCR_INV) 150ba0e276dSRichard Henderson 151ba0e276dSRichard Henderson /* The silly software trap enables implemented by the kernel emulation. 152ba0e276dSRichard Henderson These are more or less architecturally required, since the real hardware 153ba0e276dSRichard Henderson has read-as-zero bits in the FPCR when the features aren't implemented. 154ba0e276dSRichard Henderson For the purposes of QEMU, we pretend the FPCR can hold everything. */ 155f3d3aad4SRichard Henderson #define SWCR_TRAP_ENABLE_INV (1U << 1) 156f3d3aad4SRichard Henderson #define SWCR_TRAP_ENABLE_DZE (1U << 2) 157f3d3aad4SRichard Henderson #define SWCR_TRAP_ENABLE_OVF (1U << 3) 158f3d3aad4SRichard Henderson #define SWCR_TRAP_ENABLE_UNF (1U << 4) 159f3d3aad4SRichard Henderson #define SWCR_TRAP_ENABLE_INE (1U << 5) 160f3d3aad4SRichard Henderson #define SWCR_TRAP_ENABLE_DNO (1U << 6) 161f3d3aad4SRichard Henderson #define SWCR_TRAP_ENABLE_MASK ((1U << 7) - (1U << 1)) 162ba0e276dSRichard Henderson 163f3d3aad4SRichard Henderson #define SWCR_MAP_DMZ (1U << 12) 164f3d3aad4SRichard Henderson #define SWCR_MAP_UMZ (1U << 13) 165ba0e276dSRichard Henderson #define SWCR_MAP_MASK (SWCR_MAP_DMZ | SWCR_MAP_UMZ) 166ba0e276dSRichard Henderson 167f3d3aad4SRichard Henderson #define SWCR_STATUS_INV (1U << 17) 168f3d3aad4SRichard Henderson #define SWCR_STATUS_DZE (1U << 18) 169f3d3aad4SRichard Henderson #define SWCR_STATUS_OVF (1U << 19) 170f3d3aad4SRichard Henderson #define SWCR_STATUS_UNF (1U << 20) 171f3d3aad4SRichard Henderson #define SWCR_STATUS_INE (1U << 21) 172f3d3aad4SRichard Henderson #define SWCR_STATUS_DNO (1U << 22) 173f3d3aad4SRichard Henderson #define SWCR_STATUS_MASK ((1U << 23) - (1U << 17)) 174ba0e276dSRichard Henderson 17521ba8564SRichard Henderson #define SWCR_STATUS_TO_EXCSUM_SHIFT 16 17621ba8564SRichard Henderson 177ba0e276dSRichard Henderson #define SWCR_MASK (SWCR_TRAP_ENABLE_MASK | SWCR_MAP_MASK | SWCR_STATUS_MASK) 178ba0e276dSRichard Henderson 1798417845eSRichard Henderson /* MMU modes definitions */ 1804c9649a9Sj_mayer 1816a73ecf5SRichard Henderson /* Alpha has 5 MMU modes: PALcode, Kernel, Executive, Supervisor, and User. 1828417845eSRichard Henderson The Unix PALcode only exposes the kernel and user modes; presumably 1838417845eSRichard Henderson executive and supervisor are used by VMS. 1848417845eSRichard Henderson 1858417845eSRichard Henderson PALcode itself uses physical mode for code and kernel mode for data; 1868417845eSRichard Henderson there are PALmode instructions that can access data via physical mode 1878417845eSRichard Henderson or via an os-installed "alternate mode", which is one of the 4 above. 1888417845eSRichard Henderson 1896a73ecf5SRichard Henderson That said, we're only emulating Unix PALcode, and not attempting VMS, 1906a73ecf5SRichard Henderson so we don't need to implement Executive and Supervisor. QEMU's own 1918b81968cSMichael Tokarev PALcode cheats and uses the KSEG mapping for its code+data rather than 1926a73ecf5SRichard Henderson physical addresses. */ 1938417845eSRichard Henderson 1948417845eSRichard Henderson #define MMU_KERNEL_IDX 0 1958417845eSRichard Henderson #define MMU_USER_IDX 1 1966a73ecf5SRichard Henderson #define MMU_PHYS_IDX 2 1978417845eSRichard Henderson 1981ea4a06aSPhilippe Mathieu-Daudé typedef struct CPUArchState { 1994c9649a9Sj_mayer uint64_t ir[31]; 2004c9649a9Sj_mayer float64 fir[31]; 2014c9649a9Sj_mayer uint64_t pc; 2024c9649a9Sj_mayer uint64_t unique; 2036910b8f6SRichard Henderson uint64_t lock_addr; 2046910b8f6SRichard Henderson uint64_t lock_value; 205f3d3aad4SRichard Henderson 206f3d3aad4SRichard Henderson /* The FPCR, and disassembled portions thereof. */ 207f3d3aad4SRichard Henderson uint32_t fpcr; 20821ba8564SRichard Henderson #ifdef CONFIG_USER_ONLY 20921ba8564SRichard Henderson uint32_t swcr; 21021ba8564SRichard Henderson #endif 211f3d3aad4SRichard Henderson uint32_t fpcr_exc_enable; 2128443effbSRichard Henderson float_status fp_status; 2138443effbSRichard Henderson uint8_t fpcr_dyn_round; 2148443effbSRichard Henderson uint8_t fpcr_flush_to_zero; 2158443effbSRichard Henderson 216bcd2625dSRichard Henderson /* Mask of PALmode, Processor State et al. Most of this gets copied 217bcd2625dSRichard Henderson into the TranslatorBlock flags and controls code generation. */ 218bcd2625dSRichard Henderson uint32_t flags; 21926b46094SRichard Henderson 220bcd2625dSRichard Henderson /* The high 32-bits of the processor cycle counter. */ 22126b46094SRichard Henderson uint32_t pcc_ofs; 222129d8aa5SRichard Henderson 223129d8aa5SRichard Henderson /* These pass data from the exception logic in the translator and 224129d8aa5SRichard Henderson helpers to the OS entry point. This is used for both system 225129d8aa5SRichard Henderson emulation and user-mode. */ 226129d8aa5SRichard Henderson uint64_t trap_arg0; 227129d8aa5SRichard Henderson uint64_t trap_arg1; 228129d8aa5SRichard Henderson uint64_t trap_arg2; 2294c9649a9Sj_mayer 23026b46094SRichard Henderson #if !defined(CONFIG_USER_ONLY) 23126b46094SRichard Henderson /* The internal data required by our emulation of the Unix PALcode. */ 23226b46094SRichard Henderson uint64_t exc_addr; 23326b46094SRichard Henderson uint64_t palbr; 23426b46094SRichard Henderson uint64_t ptbr; 23526b46094SRichard Henderson uint64_t vptptr; 23626b46094SRichard Henderson uint64_t sysval; 23726b46094SRichard Henderson uint64_t usp; 23826b46094SRichard Henderson uint64_t shadow[8]; 23926b46094SRichard Henderson uint64_t scratch[24]; 24026b46094SRichard Henderson #endif 24126b46094SRichard Henderson 242c781cf96SRichard Henderson /* This alarm doesn't exist in real hardware; we wish it did. */ 243c781cf96SRichard Henderson uint64_t alarm_expire; 244c781cf96SRichard Henderson 2454c9649a9Sj_mayer int error_code; 2464c9649a9Sj_mayer 2474c9649a9Sj_mayer uint32_t features; 2484c9649a9Sj_mayer uint32_t amask; 2494c9649a9Sj_mayer int implver; 2501ea4a06aSPhilippe Mathieu-Daudé } CPUAlphaState; 2514c9649a9Sj_mayer 2521dc8e6b7SPaolo Bonzini /** 2531dc8e6b7SPaolo Bonzini * AlphaCPU: 2541dc8e6b7SPaolo Bonzini * @env: #CPUAlphaState 2551dc8e6b7SPaolo Bonzini * 2561dc8e6b7SPaolo Bonzini * An Alpha CPU. 2571dc8e6b7SPaolo Bonzini */ 258b36e239eSPhilippe Mathieu-Daudé struct ArchCPU { 2591dc8e6b7SPaolo Bonzini CPUState parent_obj; 2601dc8e6b7SPaolo Bonzini 2611dc8e6b7SPaolo Bonzini CPUAlphaState env; 2621dc8e6b7SPaolo Bonzini 2631dc8e6b7SPaolo Bonzini /* This alarm doesn't exist in real hardware; we wish it did. */ 2641dc8e6b7SPaolo Bonzini QEMUTimer *alarm_timer; 2651dc8e6b7SPaolo Bonzini }; 2661dc8e6b7SPaolo Bonzini 2679348028eSPhilippe Mathieu-Daudé /** 2689348028eSPhilippe Mathieu-Daudé * AlphaCPUClass: 2699348028eSPhilippe Mathieu-Daudé * @parent_realize: The parent class' realize handler. 2709348028eSPhilippe Mathieu-Daudé * 2719348028eSPhilippe Mathieu-Daudé * An Alpha CPU model. 2729348028eSPhilippe Mathieu-Daudé */ 2739348028eSPhilippe Mathieu-Daudé struct AlphaCPUClass { 2749348028eSPhilippe Mathieu-Daudé CPUClass parent_class; 2759348028eSPhilippe Mathieu-Daudé 2769348028eSPhilippe Mathieu-Daudé DeviceRealize parent_realize; 2779348028eSPhilippe Mathieu-Daudé }; 2781dc8e6b7SPaolo Bonzini 2791dc8e6b7SPaolo Bonzini #ifndef CONFIG_USER_ONLY 2808a9358ccSMarkus Armbruster extern const VMStateDescription vmstate_alpha_cpu; 2811dc8e6b7SPaolo Bonzini 2821dc8e6b7SPaolo Bonzini void alpha_cpu_do_interrupt(CPUState *cpu); 2831dc8e6b7SPaolo Bonzini bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req); 2846d2d454aSPhilippe Mathieu-Daudé hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); 2859354e694SPhilippe Mathieu-Daudé #endif /* !CONFIG_USER_ONLY */ 28690c84c56SMarkus Armbruster void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags); 287a010bdbeSAlex Bennée int alpha_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); 2881dc8e6b7SPaolo Bonzini int alpha_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); 2891dc8e6b7SPaolo Bonzini 290022c62cbSPaolo Bonzini #include "exec/cpu-all.h" 2914c9649a9Sj_mayer 2924c9649a9Sj_mayer enum { 2934c9649a9Sj_mayer FEATURE_ASN = 0x00000001, 2944c9649a9Sj_mayer FEATURE_SPS = 0x00000002, 2954c9649a9Sj_mayer FEATURE_VIRBND = 0x00000004, 2964c9649a9Sj_mayer FEATURE_TBCHK = 0x00000008, 2974c9649a9Sj_mayer }; 2984c9649a9Sj_mayer 2994c9649a9Sj_mayer enum { 30007b6c13bSRichard Henderson EXCP_RESET, 30107b6c13bSRichard Henderson EXCP_MCHK, 30207b6c13bSRichard Henderson EXCP_SMP_INTERRUPT, 30307b6c13bSRichard Henderson EXCP_CLK_INTERRUPT, 30407b6c13bSRichard Henderson EXCP_DEV_INTERRUPT, 30507b6c13bSRichard Henderson EXCP_MMFAULT, 30607b6c13bSRichard Henderson EXCP_UNALIGN, 30707b6c13bSRichard Henderson EXCP_OPCDEC, 30807b6c13bSRichard Henderson EXCP_ARITH, 30907b6c13bSRichard Henderson EXCP_FEN, 31007b6c13bSRichard Henderson EXCP_CALL_PAL, 3114c9649a9Sj_mayer }; 3124c9649a9Sj_mayer 3136a80e088SRichard Henderson /* Alpha-specific interrupt pending bits. */ 3146a80e088SRichard Henderson #define CPU_INTERRUPT_TIMER CPU_INTERRUPT_TGT_EXT_0 3156a80e088SRichard Henderson #define CPU_INTERRUPT_SMP CPU_INTERRUPT_TGT_EXT_1 3166a80e088SRichard Henderson #define CPU_INTERRUPT_MCHK CPU_INTERRUPT_TGT_EXT_2 3176a80e088SRichard Henderson 318a3b9af16SRichard Henderson /* OSF/1 Page table bits. */ 319a3b9af16SRichard Henderson enum { 320a3b9af16SRichard Henderson PTE_VALID = 0x0001, 321a3b9af16SRichard Henderson PTE_FOR = 0x0002, /* used for page protection (fault on read) */ 322a3b9af16SRichard Henderson PTE_FOW = 0x0004, /* used for page protection (fault on write) */ 323a3b9af16SRichard Henderson PTE_FOE = 0x0008, /* used for page protection (fault on exec) */ 324a3b9af16SRichard Henderson PTE_ASM = 0x0010, 325a3b9af16SRichard Henderson PTE_KRE = 0x0100, 326a3b9af16SRichard Henderson PTE_URE = 0x0200, 327a3b9af16SRichard Henderson PTE_KWE = 0x1000, 328a3b9af16SRichard Henderson PTE_UWE = 0x2000 329a3b9af16SRichard Henderson }; 330a3b9af16SRichard Henderson 331ea879fc7SRichard Henderson /* Hardware interrupt (entInt) constants. */ 332ea879fc7SRichard Henderson enum { 333ea879fc7SRichard Henderson INT_K_IP, 334ea879fc7SRichard Henderson INT_K_CLK, 335ea879fc7SRichard Henderson INT_K_MCHK, 336ea879fc7SRichard Henderson INT_K_DEV, 337ea879fc7SRichard Henderson INT_K_PERF, 338ea879fc7SRichard Henderson }; 339ea879fc7SRichard Henderson 340ea879fc7SRichard Henderson /* Memory management (entMM) constants. */ 341ea879fc7SRichard Henderson enum { 342ea879fc7SRichard Henderson MM_K_TNV, 343ea879fc7SRichard Henderson MM_K_ACV, 344ea879fc7SRichard Henderson MM_K_FOR, 345ea879fc7SRichard Henderson MM_K_FOE, 346ea879fc7SRichard Henderson MM_K_FOW 347ea879fc7SRichard Henderson }; 348ea879fc7SRichard Henderson 349ea879fc7SRichard Henderson /* Arithmetic exception (entArith) constants. */ 350ea879fc7SRichard Henderson enum { 351ea879fc7SRichard Henderson EXC_M_SWC = 1, /* Software completion */ 352ea879fc7SRichard Henderson EXC_M_INV = 2, /* Invalid operation */ 353ea879fc7SRichard Henderson EXC_M_DZE = 4, /* Division by zero */ 354ea879fc7SRichard Henderson EXC_M_FOV = 8, /* Overflow */ 355ea879fc7SRichard Henderson EXC_M_UNF = 16, /* Underflow */ 356ea879fc7SRichard Henderson EXC_M_INE = 32, /* Inexact result */ 357ea879fc7SRichard Henderson EXC_M_IOV = 64 /* Integer Overflow */ 358ea879fc7SRichard Henderson }; 359ea879fc7SRichard Henderson 360ea879fc7SRichard Henderson /* Processor status constants. */ 361ea879fc7SRichard Henderson /* Low 3 bits are interrupt mask level. */ 362bcd2625dSRichard Henderson #define PS_INT_MASK 7u 363ea879fc7SRichard Henderson 364ea879fc7SRichard Henderson /* Bits 4 and 5 are the mmu mode. The VMS PALcode uses all 4 modes; 365ea879fc7SRichard Henderson The Unix PALcode only uses bit 4. */ 366bcd2625dSRichard Henderson #define PS_USER_MODE 8u 367bcd2625dSRichard Henderson 3688b81968cSMichael Tokarev /* CPUAlphaState->flags constants. These are laid out so that we 369bcd2625dSRichard Henderson can set or reset the pieces individually by assigning to the byte, 370bcd2625dSRichard Henderson or manipulated as a whole. */ 371bcd2625dSRichard Henderson 372bcd2625dSRichard Henderson #define ENV_FLAG_PAL_SHIFT 0 373bcd2625dSRichard Henderson #define ENV_FLAG_PS_SHIFT 8 374bcd2625dSRichard Henderson #define ENV_FLAG_RX_SHIFT 16 375bcd2625dSRichard Henderson #define ENV_FLAG_FEN_SHIFT 24 376bcd2625dSRichard Henderson 377bcd2625dSRichard Henderson #define ENV_FLAG_PAL_MODE (1u << ENV_FLAG_PAL_SHIFT) 378bcd2625dSRichard Henderson #define ENV_FLAG_PS_USER (PS_USER_MODE << ENV_FLAG_PS_SHIFT) 379bcd2625dSRichard Henderson #define ENV_FLAG_RX_FLAG (1u << ENV_FLAG_RX_SHIFT) 380bcd2625dSRichard Henderson #define ENV_FLAG_FEN (1u << ENV_FLAG_FEN_SHIFT) 381bcd2625dSRichard Henderson 382bcd2625dSRichard Henderson #define ENV_FLAG_TB_MASK \ 383bcd2625dSRichard Henderson (ENV_FLAG_PAL_MODE | ENV_FLAG_PS_USER | ENV_FLAG_FEN) 384ea879fc7SRichard Henderson 385fed14246SRichard Henderson #define TB_FLAG_UNALIGN (1u << 1) 386fed14246SRichard Henderson 38732a8ea12SRichard Henderson static inline int alpha_env_mmu_index(CPUAlphaState *env) 388ea879fc7SRichard Henderson { 389bcd2625dSRichard Henderson int ret = env->flags & ENV_FLAG_PS_USER ? MMU_USER_IDX : MMU_KERNEL_IDX; 390bcd2625dSRichard Henderson if (env->flags & ENV_FLAG_PAL_MODE) { 391bcd2625dSRichard Henderson ret = MMU_KERNEL_IDX; 392bba9bdceSRichard Henderson } 393bcd2625dSRichard Henderson return ret; 394ea879fc7SRichard Henderson } 3954c9649a9Sj_mayer 3964c9649a9Sj_mayer enum { 3974c9649a9Sj_mayer IR_V0 = 0, 3984c9649a9Sj_mayer IR_T0 = 1, 3994c9649a9Sj_mayer IR_T1 = 2, 4004c9649a9Sj_mayer IR_T2 = 3, 4014c9649a9Sj_mayer IR_T3 = 4, 4024c9649a9Sj_mayer IR_T4 = 5, 4034c9649a9Sj_mayer IR_T5 = 6, 4044c9649a9Sj_mayer IR_T6 = 7, 4054c9649a9Sj_mayer IR_T7 = 8, 4064c9649a9Sj_mayer IR_S0 = 9, 4074c9649a9Sj_mayer IR_S1 = 10, 4084c9649a9Sj_mayer IR_S2 = 11, 4094c9649a9Sj_mayer IR_S3 = 12, 4104c9649a9Sj_mayer IR_S4 = 13, 4114c9649a9Sj_mayer IR_S5 = 14, 4124c9649a9Sj_mayer IR_S6 = 15, 413a4b388ffSRichard Henderson IR_FP = IR_S6, 4144c9649a9Sj_mayer IR_A0 = 16, 4154c9649a9Sj_mayer IR_A1 = 17, 4164c9649a9Sj_mayer IR_A2 = 18, 4174c9649a9Sj_mayer IR_A3 = 19, 4184c9649a9Sj_mayer IR_A4 = 20, 4194c9649a9Sj_mayer IR_A5 = 21, 4204c9649a9Sj_mayer IR_T8 = 22, 4214c9649a9Sj_mayer IR_T9 = 23, 4224c9649a9Sj_mayer IR_T10 = 24, 4234c9649a9Sj_mayer IR_T11 = 25, 4244c9649a9Sj_mayer IR_RA = 26, 4254c9649a9Sj_mayer IR_T12 = 27, 426a4b388ffSRichard Henderson IR_PV = IR_T12, 4274c9649a9Sj_mayer IR_AT = 28, 4284c9649a9Sj_mayer IR_GP = 29, 4294c9649a9Sj_mayer IR_SP = 30, 4304c9649a9Sj_mayer IR_ZERO = 31, 4314c9649a9Sj_mayer }; 4324c9649a9Sj_mayer 4330c28246fSAndreas Färber void alpha_translate_init(void); 434*e4a8e093SRichard Henderson void alpha_translate_code(CPUState *cs, TranslationBlock *tb, 435*e4a8e093SRichard Henderson int *max_insns, vaddr pc, void *host_pc); 4360c28246fSAndreas Färber 4370dacec87SIgor Mammedov #define CPU_RESOLVING_TYPE TYPE_ALPHA_CPU 43873a25e83SIgor Mammedov 4398905770bSMarc-André Lureau G_NORETURN void dynamic_excp(CPUAlphaState *, uintptr_t, int, int); 4408905770bSMarc-André Lureau G_NORETURN void arith_excp(CPUAlphaState *, uintptr_t, int, uint64_t); 44195870356Saurel32 4424d5712f1SAndreas Färber uint64_t cpu_alpha_load_fpcr (CPUAlphaState *env); 4434d5712f1SAndreas Färber void cpu_alpha_store_fpcr (CPUAlphaState *env, uint64_t val); 44459124384SRichard Henderson uint64_t cpu_alpha_load_gr(CPUAlphaState *env, unsigned reg); 44559124384SRichard Henderson void cpu_alpha_store_gr(CPUAlphaState *env, unsigned reg, uint64_t val); 44690113883SRichard Henderson 44790113883SRichard Henderson #ifdef CONFIG_USER_ONLY 44890113883SRichard Henderson void alpha_cpu_record_sigsegv(CPUState *cs, vaddr address, 44990113883SRichard Henderson MMUAccessType access_type, 45090113883SRichard Henderson bool maperr, uintptr_t retaddr); 451e7424abcSRichard Henderson void alpha_cpu_record_sigbus(CPUState *cs, vaddr address, 452e7424abcSRichard Henderson MMUAccessType access_type, uintptr_t retaddr); 45390113883SRichard Henderson #else 45490113883SRichard Henderson bool alpha_cpu_tlb_fill(CPUState *cs, vaddr address, int size, 45590113883SRichard Henderson MMUAccessType access_type, int mmu_idx, 45690113883SRichard Henderson bool probe, uintptr_t retaddr); 4578905770bSMarc-André Lureau G_NORETURN void alpha_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, 458e7424abcSRichard Henderson MMUAccessType access_type, int mmu_idx, 4598905770bSMarc-André Lureau uintptr_t retaddr); 4606ad4d7eeSPeter Maydell void alpha_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, 4616ad4d7eeSPeter Maydell vaddr addr, unsigned size, 4626ad4d7eeSPeter Maydell MMUAccessType access_type, 4636ad4d7eeSPeter Maydell int mmu_idx, MemTxAttrs attrs, 4646ad4d7eeSPeter Maydell MemTxResult response, uintptr_t retaddr); 4655b450407SRichard Henderson #endif 4664c9649a9Sj_mayer 467bb5de525SAnton Johansson static inline void cpu_get_tb_cpu_state(CPUAlphaState *env, vaddr *pc, 468bb5de525SAnton Johansson uint64_t *cs_base, uint32_t *pflags) 4696b917547Saliguori { 4706b917547Saliguori *pc = env->pc; 4716b917547Saliguori *cs_base = 0; 472bcd2625dSRichard Henderson *pflags = env->flags & ENV_FLAG_TB_MASK; 473fed14246SRichard Henderson #ifdef CONFIG_USER_ONLY 474fed14246SRichard Henderson *pflags |= TB_FLAG_UNALIGN * !env_cpu(env)->prctl_unalign_sigbus; 475fed14246SRichard Henderson #endif 4766b917547Saliguori } 4776b917547Saliguori 47821ba8564SRichard Henderson #ifdef CONFIG_USER_ONLY 47921ba8564SRichard Henderson /* Copied from linux ieee_swcr_to_fpcr. */ 48021ba8564SRichard Henderson static inline uint64_t alpha_ieee_swcr_to_fpcr(uint64_t swcr) 48121ba8564SRichard Henderson { 48221ba8564SRichard Henderson uint64_t fpcr = 0; 48321ba8564SRichard Henderson 48421ba8564SRichard Henderson fpcr |= (swcr & SWCR_STATUS_MASK) << 35; 48521ba8564SRichard Henderson fpcr |= (swcr & SWCR_MAP_DMZ) << 36; 48621ba8564SRichard Henderson fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV 48721ba8564SRichard Henderson | SWCR_TRAP_ENABLE_DZE 48821ba8564SRichard Henderson | SWCR_TRAP_ENABLE_OVF)) << 48; 48921ba8564SRichard Henderson fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF 49021ba8564SRichard Henderson | SWCR_TRAP_ENABLE_INE)) << 57; 49121ba8564SRichard Henderson fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0); 49221ba8564SRichard Henderson fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41; 49321ba8564SRichard Henderson 49421ba8564SRichard Henderson return fpcr; 49521ba8564SRichard Henderson } 49621ba8564SRichard Henderson 49721ba8564SRichard Henderson /* Copied from linux ieee_fpcr_to_swcr. */ 49821ba8564SRichard Henderson static inline uint64_t alpha_ieee_fpcr_to_swcr(uint64_t fpcr) 49921ba8564SRichard Henderson { 50021ba8564SRichard Henderson uint64_t swcr = 0; 50121ba8564SRichard Henderson 50221ba8564SRichard Henderson swcr |= (fpcr >> 35) & SWCR_STATUS_MASK; 50321ba8564SRichard Henderson swcr |= (fpcr >> 36) & SWCR_MAP_DMZ; 50421ba8564SRichard Henderson swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV 50521ba8564SRichard Henderson | SWCR_TRAP_ENABLE_DZE 50621ba8564SRichard Henderson | SWCR_TRAP_ENABLE_OVF); 50721ba8564SRichard Henderson swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF | SWCR_TRAP_ENABLE_INE); 50821ba8564SRichard Henderson swcr |= (fpcr >> 47) & SWCR_MAP_UMZ; 50921ba8564SRichard Henderson swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO; 51021ba8564SRichard Henderson 51121ba8564SRichard Henderson return swcr; 51221ba8564SRichard Henderson } 51321ba8564SRichard Henderson #endif /* CONFIG_USER_ONLY */ 51421ba8564SRichard Henderson 51507f5a258SMarkus Armbruster #endif /* ALPHA_CPU_H */ 516