xref: /qemu/target/alpha/cpu.h (revision 5ee4f3c2c750ce55f825116610beb3340daedeca)
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