]> Git Repo - qemu.git/blobdiff - target-alpha/cpu.h
Merge branch 'ppc-next' of git://repo.or.cz/qemu/agraf
[qemu.git] / target-alpha / cpu.h
index 710a6021fa452762a6b32637daf8a3b1f95f0ae4..686fb4a6a7c84e6afc6ed1bb276d2b105b6ac78c 100644 (file)
@@ -14,8 +14,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #if !defined (__CPU_ALPHA_H__)
@@ -25,6 +24,8 @@
 
 #define TARGET_LONG_BITS 64
 
+#define CPUState struct CPUAlphaState
+
 #include "cpu-defs.h"
 
 #include <setjmp.h>
 #define ICACHE_LINE_SIZE 32
 #define DCACHE_LINE_SIZE 32
 
-#define TARGET_PAGE_BITS 12
+#define TARGET_PAGE_BITS 13
 
-#define VA_BITS 43
+/* ??? EV4 has 34 phys addr bits, EV5 has 40, EV6 has 44.  */
+#define TARGET_PHYS_ADDR_SPACE_BITS    44
+#define TARGET_VIRT_ADDR_SPACE_BITS    (30 + TARGET_PAGE_BITS)
 
 /* Alpha major type */
 enum {
@@ -138,55 +141,145 @@ enum {
     FP_ROUND_DYNAMIC = 0x3,
 };
 
+/* FPCR bits */
+#define FPCR_SUM               (1ULL << 63)
+#define FPCR_INED              (1ULL << 62)
+#define FPCR_UNFD              (1ULL << 61)
+#define FPCR_UNDZ              (1ULL << 60)
+#define FPCR_DYN_SHIFT         58
+#define FPCR_DYN_CHOPPED       (0ULL << FPCR_DYN_SHIFT)
+#define FPCR_DYN_MINUS         (1ULL << FPCR_DYN_SHIFT)
+#define FPCR_DYN_NORMAL                (2ULL << FPCR_DYN_SHIFT)
+#define FPCR_DYN_PLUS          (3ULL << FPCR_DYN_SHIFT)
+#define FPCR_DYN_MASK          (3ULL << FPCR_DYN_SHIFT)
+#define FPCR_IOV               (1ULL << 57)
+#define FPCR_INE               (1ULL << 56)
+#define FPCR_UNF               (1ULL << 55)
+#define FPCR_OVF               (1ULL << 54)
+#define FPCR_DZE               (1ULL << 53)
+#define FPCR_INV               (1ULL << 52)
+#define FPCR_OVFD              (1ULL << 51)
+#define FPCR_DZED              (1ULL << 50)
+#define FPCR_INVD              (1ULL << 49)
+#define FPCR_DNZ               (1ULL << 48)
+#define FPCR_DNOD              (1ULL << 47)
+#define FPCR_STATUS_MASK       (FPCR_IOV | FPCR_INE | FPCR_UNF \
+                                | FPCR_OVF | FPCR_DZE | FPCR_INV)
+
+/* The silly software trap enables implemented by the kernel emulation.
+   These are more or less architecturally required, since the real hardware
+   has read-as-zero bits in the FPCR when the features aren't implemented.
+   For the purposes of QEMU, we pretend the FPCR can hold everything.  */
+#define SWCR_TRAP_ENABLE_INV   (1ULL << 1)
+#define SWCR_TRAP_ENABLE_DZE   (1ULL << 2)
+#define SWCR_TRAP_ENABLE_OVF   (1ULL << 3)
+#define SWCR_TRAP_ENABLE_UNF   (1ULL << 4)
+#define SWCR_TRAP_ENABLE_INE   (1ULL << 5)
+#define SWCR_TRAP_ENABLE_DNO   (1ULL << 6)
+#define SWCR_TRAP_ENABLE_MASK  ((1ULL << 7) - (1ULL << 1))
+
+#define SWCR_MAP_DMZ           (1ULL << 12)
+#define SWCR_MAP_UMZ           (1ULL << 13)
+#define SWCR_MAP_MASK          (SWCR_MAP_DMZ | SWCR_MAP_UMZ)
+
+#define SWCR_STATUS_INV                (1ULL << 17)
+#define SWCR_STATUS_DZE                (1ULL << 18)
+#define SWCR_STATUS_OVF                (1ULL << 19)
+#define SWCR_STATUS_UNF                (1ULL << 20)
+#define SWCR_STATUS_INE                (1ULL << 21)
+#define SWCR_STATUS_DNO                (1ULL << 22)
+#define SWCR_STATUS_MASK       ((1ULL << 23) - (1ULL << 17))
+
+#define SWCR_MASK  (SWCR_TRAP_ENABLE_MASK | SWCR_MAP_MASK | SWCR_STATUS_MASK)
+
 /* Internal processor registers */
 /* XXX: TOFIX: most of those registers are implementation dependant */
 enum {
+#if defined(CONFIG_USER_ONLY)
+    IPR_EXC_ADDR,
+    IPR_EXC_SUM,
+    IPR_EXC_MASK,
+#else
     /* Ebox IPRs */
-    IPR_CC           = 0xC0,
-    IPR_CC_CTL       = 0xC1,
-    IPR_VA           = 0xC2,
-    IPR_VA_CTL       = 0xC4,
-    IPR_VA_FORM      = 0xC3,
+    IPR_CC           = 0xC0,            /* 21264 */
+    IPR_CC_CTL       = 0xC1,            /* 21264 */
+#define IPR_CC_CTL_ENA_SHIFT 32
+#define IPR_CC_CTL_COUNTER_MASK 0xfffffff0UL
+    IPR_VA           = 0xC2,            /* 21264 */
+    IPR_VA_CTL       = 0xC4,            /* 21264 */
+#define IPR_VA_CTL_VA_48_SHIFT 1
+#define IPR_VA_CTL_VPTB_SHIFT 30
+    IPR_VA_FORM      = 0xC3,            /* 21264 */
     /* Ibox IPRs */
-    IPR_ITB_TAG      = 0x00,
-    IPR_ITB_PTE      = 0x01,
-    IPT_ITB_IAP      = 0x02,
-    IPT_ITB_IA       = 0x03,
-    IPT_ITB_IS       = 0x04,
+    IPR_ITB_TAG      = 0x00,            /* 21264 */
+    IPR_ITB_PTE      = 0x01,            /* 21264 */
+    IPR_ITB_IAP      = 0x02,
+    IPR_ITB_IA       = 0x03,            /* 21264 */
+    IPR_ITB_IS       = 0x04,            /* 21264 */
     IPR_PMPC         = 0x05,
-    IPR_EXC_ADDR     = 0x06,
-    IPR_IVA_FORM     = 0x07,
-    IPR_CM           = 0x09,
-    IPR_IER          = 0x0A,
-    IPR_SIRR         = 0x0C,
-    IPR_ISUM         = 0x0D,
-    IPR_HW_INT_CLR   = 0x0E,
+    IPR_EXC_ADDR     = 0x06,            /* 21264 */
+    IPR_IVA_FORM     = 0x07,            /* 21264 */
+    IPR_CM           = 0x09,            /* 21264 */
+#define IPR_CM_SHIFT 3
+#define IPR_CM_MASK (3ULL << IPR_CM_SHIFT)      /* 21264 */
+    IPR_IER          = 0x0A,            /* 21264 */
+#define IPR_IER_MASK 0x0000007fffffe000ULL
+    IPR_IER_CM       = 0x0B,            /* 21264: = CM | IER */
+    IPR_SIRR         = 0x0C,            /* 21264 */
+#define IPR_SIRR_SHIFT 14
+#define IPR_SIRR_MASK 0x7fff
+    IPR_ISUM         = 0x0D,            /* 21264 */
+    IPR_HW_INT_CLR   = 0x0E,            /* 21264 */
     IPR_EXC_SUM      = 0x0F,
     IPR_PAL_BASE     = 0x10,
     IPR_I_CTL        = 0x11,
-    IPR_I_STAT       = 0x16,
-    IPR_IC_FLUSH     = 0x13,
-    IPR_IC_FLUSH_ASM = 0x12,
+#define IPR_I_CTL_CHIP_ID_SHIFT 24      /* 21264 */
+#define IPR_I_CTL_BIST_FAIL (1 << 23)   /* 21264 */
+#define IPR_I_CTL_IC_EN_SHIFT 2         /* 21264 */
+#define IPR_I_CTL_SDE1_SHIFT 7          /* 21264 */
+#define IPR_I_CTL_HWE_SHIFT 12          /* 21264 */
+#define IPR_I_CTL_VA_48_SHIFT 15        /* 21264 */
+#define IPR_I_CTL_SPE_SHIFT 3           /* 21264 */
+#define IPR_I_CTL_CALL_PAL_R23_SHIFT 20 /* 21264 */
+    IPR_I_STAT       = 0x16,            /* 21264 */
+    IPR_IC_FLUSH     = 0x13,            /* 21264 */
+    IPR_IC_FLUSH_ASM = 0x12,            /* 21264 */
     IPR_CLR_MAP      = 0x15,
     IPR_SLEEP        = 0x17,
     IPR_PCTX         = 0x40,
-    IPR_PCTR_CTL     = 0x14,
+    IPR_PCTX_ASN       = 0x01,  /* field */
+#define IPR_PCTX_ASN_SHIFT 39
+    IPR_PCTX_ASTER     = 0x02,  /* field */
+#define IPR_PCTX_ASTER_SHIFT 5
+    IPR_PCTX_ASTRR     = 0x04,  /* field */
+#define IPR_PCTX_ASTRR_SHIFT 9
+    IPR_PCTX_PPCE      = 0x08,  /* field */
+#define IPR_PCTX_PPCE_SHIFT 1
+    IPR_PCTX_FPE       = 0x10,  /* field */
+#define IPR_PCTX_FPE_SHIFT 2
+    IPR_PCTX_ALL       = 0x5f,  /* all fields */
+    IPR_PCTR_CTL     = 0x14,            /* 21264 */
     /* Mbox IPRs */
-    IPR_DTB_TAG0     = 0x20,
-    IPR_DTB_TAG1     = 0xA0,
-    IPR_DTB_PTE0     = 0x21,
-    IPR_DTB_PTE1     = 0xA1,
+    IPR_DTB_TAG0     = 0x20,            /* 21264 */
+    IPR_DTB_TAG1     = 0xA0,            /* 21264 */
+    IPR_DTB_PTE0     = 0x21,            /* 21264 */
+    IPR_DTB_PTE1     = 0xA1,            /* 21264 */
     IPR_DTB_ALTMODE  = 0xA6,
+    IPR_DTB_ALTMODE0 = 0x26,            /* 21264 */
+#define IPR_DTB_ALTMODE_MASK 3
     IPR_DTB_IAP      = 0xA2,
-    IPR_DTB_IA       = 0xA3,
+    IPR_DTB_IA       = 0xA3,            /* 21264 */
     IPR_DTB_IS0      = 0x24,
     IPR_DTB_IS1      = 0xA4,
-    IPR_DTB_ASN0     = 0x25,
-    IPR_DTB_ASN1     = 0xA5,
-    IPR_MM_STAT      = 0x27,
-    IPR_M_CTL        = 0x28,
-    IPR_DC_CTL       = 0x29,
-    IPR_DC_STAT      = 0x2A,
+    IPR_DTB_ASN0     = 0x25,            /* 21264 */
+    IPR_DTB_ASN1     = 0xA5,            /* 21264 */
+#define IPR_DTB_ASN_SHIFT 56
+    IPR_MM_STAT      = 0x27,            /* 21264 */
+    IPR_M_CTL        = 0x28,            /* 21264 */
+#define IPR_M_CTL_SPE_SHIFT 1
+#define IPR_M_CTL_SPE_MASK 7
+    IPR_DC_CTL       = 0x29,            /* 21264 */
+    IPR_DC_STAT      = 0x2A,            /* 21264 */
     /* Cbox IPRs */
     IPR_C_DATA       = 0x2B,
     IPR_C_SHIFT      = 0x2C,
@@ -220,6 +313,7 @@ enum {
     IPR_VPTB,
     IPR_WHAMI,
     IPR_ALT_MODE,
+#endif
     IPR_LAST,
 };
 
@@ -259,17 +353,28 @@ struct pal_handler_t {
 
 struct CPUAlphaState {
     uint64_t ir[31];
-    float64  fir[31];
-    float_status fp_status;
-    uint64_t fpcr;
+    float64 fir[31];
     uint64_t pc;
-    uint64_t lock;
-    uint32_t pcc[2];
     uint64_t ipr[IPR_LAST];
     uint64_t ps;
     uint64_t unique;
-    int saved_mode; /* Used for HW_LD / HW_ST */
-    int intr_flag; /* For RC and RS */
+    uint64_t lock_addr;
+    uint64_t lock_st_addr;
+    uint64_t lock_value;
+    float_status fp_status;
+    /* The following fields make up the FPCR, but in FP_STATUS format.  */
+    uint8_t fpcr_exc_status;
+    uint8_t fpcr_exc_mask;
+    uint8_t fpcr_dyn_round;
+    uint8_t fpcr_flush_to_zero;
+    uint8_t fpcr_dnz;
+    uint8_t fpcr_dnod;
+    uint8_t fpcr_undz;
+
+    /* Used for HW_LD / HW_ST */
+    uint8_t saved_mode;
+    /* For RC and RS */
+    uint8_t intr_flag;
 
 #if TARGET_LONG_BITS > HOST_LONG_BITS
     /* temporary fixed-point registers
@@ -291,7 +396,6 @@ struct CPUAlphaState {
     pal_handler_t *pal_handler;
 };
 
-#define CPUState CPUAlphaState
 #define cpu_init cpu_alpha_init
 #define cpu_exec cpu_alpha_exec
 #define cpu_gen_code cpu_alpha_gen_code
@@ -308,17 +412,7 @@ static inline int cpu_mmu_index (CPUState *env)
     return (env->ps >> 3) & 3;
 }
 
-#if defined(CONFIG_USER_ONLY)
-static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
-{
-    if (newsp)
-        env->ir[30] = newsp;
-    /* FIXME: Zero syscall return value.  */
-}
-#endif
-
 #include "cpu-all.h"
-#include "exec-all.h"
 
 enum {
     FEATURE_ASN    = 0x00000001,
@@ -346,22 +440,18 @@ enum {
     /* Pseudo exception for console */
     EXCP_CONSOLE_DISPATCH = 0x4001,
     EXCP_CONSOLE_FIXUP    = 0x4002,
+    EXCP_STL_C            = 0x4003,
+    EXCP_STQ_C            = 0x4004,
 };
 
 /* Arithmetic exception */
-enum {
-    EXCP_ARITH_OVERFLOW,
-};
-
-enum {
-    PALCODE_CALL = 0x00000000,
-    PALCODE_LD   = 0x01000000,
-    PALCODE_ST   = 0x02000000,
-    PALCODE_MFPR = 0x03000000,
-    PALCODE_MTPR = 0x04000000,
-    PALCODE_REI  = 0x05000000,
-    PALCODE_INIT = 0xF0000000,
-};
+#define EXC_M_IOV       (1<<16)         /* Integer Overflow */
+#define EXC_M_INE       (1<<15)         /* Inexact result */
+#define EXC_M_UNF       (1<<14)         /* Underflow */
+#define EXC_M_FOV       (1<<13)         /* Overflow */
+#define EXC_M_DZE       (1<<12)         /* Division by zero */
+#define EXC_M_INV       (1<<11)         /* Invalid operation */
+#define EXC_M_SWC       (1<<10)         /* Software completion */
 
 enum {
     IR_V0   = 0,
@@ -380,7 +470,7 @@ enum {
     IR_S4   = 13,
     IR_S5   = 14,
     IR_S6   = 15,
-#define IR_FP IR_S6
+    IR_FP   = IR_S6,
     IR_A0   = 16,
     IR_A1   = 17,
     IR_A2   = 18,
@@ -393,7 +483,7 @@ enum {
     IR_T11  = 25,
     IR_RA   = 26,
     IR_T12  = 27,
-#define IR_PV IR_T12
+    IR_PV   = IR_T12,
     IR_AT   = 28,
     IR_GP   = 29,
     IR_SP   = 30,
@@ -409,22 +499,18 @@ int cpu_alpha_signal_handler(int host_signum, void *pinfo,
                              void *puc);
 int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw,
                                 int mmu_idx, int is_softmmu);
+#define cpu_handle_mmu_fault cpu_alpha_handle_mmu_fault
 void do_interrupt (CPUState *env);
 
+uint64_t cpu_alpha_load_fpcr (CPUState *env);
+void cpu_alpha_store_fpcr (CPUState *env, uint64_t val);
 int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp);
 int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp);
-void pal_init (CPUState *env);
 #if !defined (CONFIG_USER_ONLY)
+void pal_init (CPUState *env);
 void call_pal (CPUState *env);
-#else
-void call_pal (CPUState *env, int palcode);
 #endif
 
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
-    env->pc = tb->pc;
-}
-
 static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
                                         target_ulong *cs_base, int *flags)
 {
@@ -433,4 +519,20 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
     *flags = env->ps;
 }
 
+#if defined(CONFIG_USER_ONLY)
+static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
+{
+    if (newsp) {
+        env->ir[IR_SP] = newsp;
+    }
+    env->ir[IR_V0] = 0;
+    env->ir[IR_A3] = 0;
+}
+
+static inline void cpu_set_tls(CPUState *env, target_ulong newtls)
+{
+    env->unique = newtls;
+}
+#endif
+
 #endif /* !defined (__CPU_ALPHA_H__) */
This page took 0.033359 seconds and 4 git commands to generate.