* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
POWERPC_EXCP_SYSCALL_VECTORED = 102, /* scv exception */
/* EOL */
POWERPC_EXCP_NB = 103,
- /* QEMU exceptions: used internally during code translation */
- POWERPC_EXCP_STOP = 0x200, /* stop translation */
- POWERPC_EXCP_BRANCH = 0x201, /* branch instruction */
/* QEMU exceptions: special cases we want to stop translation */
- POWERPC_EXCP_SYNC = 0x202, /* context synchronizing instruction */
POWERPC_EXCP_SYSCALL_USER = 0x203, /* System call in user mode only */
};
/* SPR access micro-ops generations callbacks */
struct ppc_spr_t {
+ const char *name;
+ target_ulong default_value;
+#ifndef CONFIG_USER_ONLY
+ unsigned int gdb_id;
+#endif
+#ifdef CONFIG_TCG
void (*uea_read)(DisasContext *ctx, int gpr_num, int spr_num);
void (*uea_write)(DisasContext *ctx, int spr_num, int gpr_num);
-#if !defined(CONFIG_USER_ONLY)
+# ifndef CONFIG_USER_ONLY
void (*oea_read)(DisasContext *ctx, int gpr_num, int spr_num);
void (*oea_write)(DisasContext *ctx, int spr_num, int gpr_num);
void (*hea_read)(DisasContext *ctx, int gpr_num, int spr_num);
void (*hea_write)(DisasContext *ctx, int spr_num, int gpr_num);
- unsigned int gdb_id;
+# endif
#endif
- const char *name;
- target_ulong default_value;
#ifdef CONFIG_KVM
/*
* We (ab)use the fact that all the SPRs will have ids for the
#define MSR_PR 14 /* Problem state hflags */
#define MSR_FP 13 /* Floating point available hflags */
#define MSR_ME 12 /* Machine check interrupt enable */
-#define MSR_FE0 11 /* Floating point exception mode 0 hflags */
+#define MSR_FE0 11 /* Floating point exception mode 0 */
#define MSR_SE 10 /* Single-step trace enable x hflags */
#define MSR_DWE 10 /* Debug wait enable on 405 x */
#define MSR_UBLE 10 /* User BTB lock enable on e500 x */
#define MSR_BE 9 /* Branch trace enable x hflags */
#define MSR_DE 9 /* Debug interrupts enable on embedded PowerPC x */
-#define MSR_FE1 8 /* Floating point exception mode 1 hflags */
+#define MSR_FE1 8 /* Floating point exception mode 1 */
#define MSR_AL 7 /* AL bit on POWER */
#define MSR_EP 6 /* Exception prefix on 601 */
#define MSR_IR 5 /* Instruction relocate */
#define LPCR_PECE_U_SHIFT (63 - 19)
#define LPCR_PECE_U_MASK (0x7ull << LPCR_PECE_U_SHIFT)
#define LPCR_HVEE PPC_BIT(17) /* Hypervisor Virt Exit Enable */
-#define LPCR_RMLS_SHIFT (63 - 37)
+#define LPCR_RMLS_SHIFT (63 - 37) /* RMLS (removed in ISA v3.0) */
#define LPCR_RMLS (0xfull << LPCR_RMLS_SHIFT)
+#define LPCR_HAIL PPC_BIT(37) /* ISA v3.1 HV AIL=3 equivalent */
#define LPCR_ILE PPC_BIT(38)
-#define LPCR_AIL_SHIFT (63 - 40) /* Alternate interrupt location */
+#define LPCR_AIL_SHIFT (63 - 40) /* Alternate interrupt location */
#define LPCR_AIL (3ull << LPCR_AIL_SHIFT)
#define LPCR_UPRT PPC_BIT(41) /* Use Process Table */
#define LPCR_EVIRT PPC_BIT(42) /* Enhanced Virtualisation */
POWERPC_FLAG_TM = 0x00100000,
/* Has SCV (ISA 3.00) */
POWERPC_FLAG_SCV = 0x00200000,
+ /* Has HID0 for LE bit (601) */
+ POWERPC_FLAG_HID0_LE = 0x00400000,
+};
+
+/*
+ * Bits for env->hflags.
+ *
+ * Most of these bits overlap with corresponding bits in MSR,
+ * but some come from other sources. Those that do come from
+ * the MSR are validated in hreg_compute_hflags.
+ */
+enum {
+ HFLAGS_LE = 0, /* MSR_LE -- comes from elsewhere on 601 */
+ HFLAGS_HV = 1, /* computed from MSR_HV and other state */
+ HFLAGS_64 = 2, /* computed from MSR_CE and MSR_SF */
+ HFLAGS_GTSE = 3, /* computed from SPR_LPCR[GTSE] */
+ HFLAGS_DR = 4, /* MSR_DR */
+ HFLAGS_SPE = 6, /* from MSR_SPE if cpu has SPE; avoid overlap w/ MSR_VR */
+ HFLAGS_TM = 8, /* computed from MSR_TM */
+ HFLAGS_BE = 9, /* MSR_BE -- from elsewhere on embedded ppc */
+ HFLAGS_SE = 10, /* MSR_SE -- from elsewhere on embedded ppc */
+ HFLAGS_FP = 13, /* MSR_FP */
+ HFLAGS_PR = 14, /* MSR_PR */
+ HFLAGS_VSX = 23, /* MSR_VSX if cpu has VSX */
+ HFLAGS_VR = 25, /* MSR_VR if cpu has VRE */
+
+ HFLAGS_IMMU_IDX = 26, /* 26..28 -- the composite immu_idx */
+ HFLAGS_DMMU_IDX = 29, /* 29..31 -- the composite dmmu_idx */
};
/*****************************************************************************/
#define fpscr_ni (((env->fpscr) >> FPSCR_NI) & 0x1)
#define fpscr_rn (((env->fpscr) >> FPSCR_RN0) & 0x3)
/* Invalid operation exception summary */
-#define fpscr_ix ((env->fpscr) & ((1 << FPSCR_VXSNAN) | (1 << FPSCR_VXISI) | \
- (1 << FPSCR_VXIDI) | (1 << FPSCR_VXZDZ) | \
- (1 << FPSCR_VXIMZ) | (1 << FPSCR_VXVC) | \
- (1 << FPSCR_VXSOFT) | (1 << FPSCR_VXSQRT) | \
- (1 << FPSCR_VXCVI)))
+#define FPSCR_IX ((1 << FPSCR_VXSNAN) | (1 << FPSCR_VXISI) | \
+ (1 << FPSCR_VXIDI) | (1 << FPSCR_VXZDZ) | \
+ (1 << FPSCR_VXIMZ) | (1 << FPSCR_VXVC) | \
+ (1 << FPSCR_VXSOFT) | (1 << FPSCR_VXSQRT) | \
+ (1 << FPSCR_VXCVI))
/* exception summary */
#define fpscr_ex (((env->fpscr) >> FPSCR_XX) & 0x1F)
/* enabled exception summary */
bool resume_as_sreset;
#endif
- /* These resources are used only in QEMU core */
- target_ulong hflags; /* hflags is MSR & HFLAGS_MASK */
- target_ulong hflags_nmsr; /* specific hflags, not coming from MSR */
- int immu_idx; /* precomputed MMU index to speed up insn accesses */
- int dmmu_idx; /* precomputed MMU index to speed up data accesses */
+ /* These resources are used only in TCG */
+ uint32_t hflags;
+ target_ulong hflags_compat_nmsr; /* for migration compatibility */
/* Power management */
int (*check_pow)(CPUPPCState *env);
void ppc_cpu_do_interrupt(CPUState *cpu);
bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
void ppc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
-void ppc_cpu_dump_statistics(CPUState *cpu, int flags);
hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
int ppc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
int ppc_cpu_gdb_read_register_apple(CPUState *cpu, GByteArray *buf, int reg);
#if !defined(CONFIG_USER_ONLY)
void ppc_store_sdr1(CPUPPCState *env, target_ulong value);
-void ppc_store_ptcr(CPUPPCState *env, target_ulong value);
#endif /* !defined(CONFIG_USER_ONLY) */
void ppc_store_msr(CPUPPCState *env, target_ulong value);
+void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val);
void ppc_cpu_list(void);
#endif
#endif
-void store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask);
+void ppc_store_fpscr(CPUPPCState *env, target_ulong val);
void helper_hfscr_facility_check(CPUPPCState *env, uint32_t bit,
const char *caller, uint32_t cause);
#define MMU_USER_IDX 0
static inline int cpu_mmu_index(CPUPPCState *env, bool ifetch)
{
- return ifetch ? env->immu_idx : env->dmmu_idx;
+#ifdef CONFIG_USER_ONLY
+ return MMU_USER_IDX;
+#else
+ return (env->hflags >> (ifetch ? HFLAGS_IMMU_IDX : HFLAGS_DMMU_IDX)) & 7;
+#endif
}
/* Compatibility modes */
#define SPR_MPC_BAR (0x09F)
#define SPR_PSPB (0x09F)
#define SPR_DPDES (0x0B0)
-#define SPR_DAWR (0x0B4)
+#define SPR_DAWR0 (0x0B4)
#define SPR_RPR (0x0BA)
#define SPR_CIABR (0x0BB)
-#define SPR_DAWRX (0x0BC)
+#define SPR_DAWRX0 (0x0BC)
#define SPR_HFSCR (0x0BE)
#define SPR_VRSAVE (0x100)
#define SPR_USPRG0 (0x100)
#define SPR_750FX_HID2 (0x3F8)
#define SPR_Exxx_L1FINV0 (0x3F8)
#define SPR_L2CR (0x3F9)
+#define SPR_Exxx_L2CSR0 (0x3F9)
#define SPR_L3CR (0x3FA)
#define SPR_750_TDCH (0x3FA)
#define SPR_IABR2 (0x3FA)
#define L1CSR1_ICFI 0x00000002 /* Instruction Cache Flash Invalidate */
#define L1CSR1_ICE 0x00000001 /* Instruction Cache Enable */
+/* E500 L2CSR0 */
+#define E500_L2CSR0_L2FI (1 << 21) /* L2 cache flash invalidate */
+#define E500_L2CSR0_L2FL (1 << 11) /* L2 cache flush */
+#define E500_L2CSR0_L2LFC (1 << 10) /* L2 cache lock flash clear */
+
/* HID0 bits */
#define HID0_DEEPNAP (1 << 24) /* pre-2.06 */
#define HID0_DOZE (1 << 23) /* pre-2.06 */
* may be needed for precise access rights control and precise exceptions.
*/
enum {
- /* 1 bit to define user level / supervisor access */
- ACCESS_USER = 0x00,
- ACCESS_SUPER = 0x01,
/* Type of instruction that generated the access */
ACCESS_CODE = 0x10, /* Code fetch access */
ACCESS_INT = 0x20, /* Integer load/store access */
HMER_XSCOM_STATUS_MASK = PPC_BITMASK(21, 23),
};
-/* Alternate Interrupt Location (AIL) */
-enum {
- AIL_NONE = 0,
- AIL_RESERVED = 1,
- AIL_0001_8000 = 2,
- AIL_C000_0000_0000_4000 = 3,
-};
-
/*****************************************************************************/
#define is_isa300(ctx) (!!(ctx->insns_flags2 & PPC2_ISA300))
*/
#define is_book3s_arch2x(ctx) (!!((ctx)->insns_flags & PPC_SEGMENT_64B))
+#ifdef CONFIG_DEBUG_TCG
+void cpu_get_tb_cpu_state(CPUPPCState *env, target_ulong *pc,
+ target_ulong *cs_base, uint32_t *flags);
+#else
static inline void cpu_get_tb_cpu_state(CPUPPCState *env, target_ulong *pc,
target_ulong *cs_base, uint32_t *flags)
{
*cs_base = 0;
*flags = env->hflags;
}
+#endif
void QEMU_NORETURN raise_exception(CPUPPCState *env, uint32_t exception);
void QEMU_NORETURN raise_exception_ra(CPUPPCState *env, uint32_t exception,
return (ppc_avr_t *)((uintptr_t)env + avr_full_offset(i));
}
+static inline bool ppc_has_spr(PowerPCCPU *cpu, int spr)
+{
+ /* We can test whether the SPR is defined by checking for a valid name */
+ return cpu->env.spr_cb[spr].name != NULL;
+}
+
void dump_mmu(CPUPPCState *env);
void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len);
+void ppc_store_vscr(CPUPPCState *env, uint32_t vscr);
+uint32_t ppc_get_vscr(CPUPPCState *env);
#endif /* PPC_CPU_H */