aboutsummaryrefslogtreecommitdiff
path: root/target-xtensa/cpu.h
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2011-09-06 03:55:40 +0400
committerBlue Swirl <blauwirbel@gmail.com>2011-09-10 16:57:38 +0000
commitf0a548b93da07b6546e4f8178a93c47284a27d05 (patch)
treee8d2301c3cfeb02d2b608058994f9e77f4d8e5ad /target-xtensa/cpu.h
parent8ffc2d0d97a59b25b48d023838906d5850e73184 (diff)
target-xtensa: add PS register and access control
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'target-xtensa/cpu.h')
-rw-r--r--target-xtensa/cpu.h53
1 files changed, 52 insertions, 1 deletions
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index ac9bbb4cdc..939222ca8c 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -108,8 +108,27 @@ enum {
enum {
SAR = 3,
SCOMPARE1 = 12,
+ PS = 230,
};
+#define PS_INTLEVEL 0xf
+#define PS_INTLEVEL_SHIFT 0
+
+#define PS_EXCM 0x10
+#define PS_UM 0x20
+
+#define PS_RING 0xc0
+#define PS_RING_SHIFT 6
+
+#define PS_OWB 0xf00
+#define PS_OWB_SHIFT 8
+
+#define PS_CALLINC 0x30000
+#define PS_CALLINC_SHIFT 16
+#define PS_CALLINC_LEN 2
+
+#define PS_WOE 0x40000
+
typedef struct XtensaConfig {
const char *name;
uint64_t options;
@@ -145,17 +164,49 @@ static inline bool xtensa_option_enabled(const XtensaConfig *config, int opt)
return (config->options & XTENSA_OPTION_BIT(opt)) != 0;
}
+static inline int xtensa_get_ring(const CPUState *env)
+{
+ if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
+ return (env->sregs[PS] & PS_RING) >> PS_RING_SHIFT;
+ } else {
+ return 0;
+ }
+}
+
+static inline int xtensa_get_cring(const CPUState *env)
+{
+ if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU) &&
+ (env->sregs[PS] & PS_EXCM) == 0) {
+ return (env->sregs[PS] & PS_RING) >> PS_RING_SHIFT;
+ } else {
+ return 0;
+ }
+}
+
+/* MMU modes definitions */
+#define MMU_MODE0_SUFFIX _ring0
+#define MMU_MODE1_SUFFIX _ring1
+#define MMU_MODE2_SUFFIX _ring2
+#define MMU_MODE3_SUFFIX _ring3
+
static inline int cpu_mmu_index(CPUState *env)
{
- return 0;
+ return xtensa_get_cring(env);
}
+#define XTENSA_TBFLAG_RING_MASK 0x3
+#define XTENSA_TBFLAG_EXCM 0x4
+
static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
target_ulong *cs_base, int *flags)
{
*pc = env->pc;
*cs_base = 0;
*flags = 0;
+ *flags |= xtensa_get_ring(env);
+ if (env->sregs[PS] & PS_EXCM) {
+ *flags |= XTENSA_TBFLAG_EXCM;
+ }
}
#include "cpu-all.h"