* 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__)
#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 {
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,
IPR_VPTB,
IPR_WHAMI,
IPR_ALT_MODE,
+#endif
IPR_LAST,
};
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
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
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,
/* 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,
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,
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,
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)
{
*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__) */