summaryrefslogtreecommitdiff
path: root/target-xtensa/helper.c
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2011-09-06 03:55:41 +0400
committerBlue Swirl <blauwirbel@gmail.com>2011-09-10 16:57:38 +0000
commit40643d7c0fe4dc967ebc2f75e6758a4649776949 (patch)
tree6fae13c6f2190389f1c0c78288f3037dc0d65d26 /target-xtensa/helper.c
parentf0a548b93da07b6546e4f8178a93c47284a27d05 (diff)
downloadqemu-40643d7c0fe4dc967ebc2f75e6758a4649776949.tar.gz
target-xtensa: implement exceptions
- mark privileged opcodes with ring check; - make debug exception on exception handler entry. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'target-xtensa/helper.c')
-rw-r--r--target-xtensa/helper.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c
index 83b8a041c1..44ebb9f29d 100644
--- a/target-xtensa/helper.c
+++ b/target-xtensa/helper.c
@@ -36,7 +36,8 @@
void cpu_reset(CPUXtensaState *env)
{
- env->pc = 0;
+ env->exception_taken = 0;
+ env->pc = env->config->exception_vector[EXC_RESET];
env->sregs[PS] = 0x1f;
}
@@ -44,6 +45,20 @@ static const XtensaConfig core_config[] = {
{
.name = "sample-xtensa-core",
.options = -1,
+ .ndepc = 1,
+ .excm_level = 16,
+ .exception_vector = {
+ [EXC_RESET] = 0x5fff8000,
+ [EXC_WINDOW_OVERFLOW4] = 0x5fff8400,
+ [EXC_WINDOW_UNDERFLOW4] = 0x5fff8440,
+ [EXC_WINDOW_OVERFLOW8] = 0x5fff8480,
+ [EXC_WINDOW_UNDERFLOW8] = 0x5fff84c0,
+ [EXC_WINDOW_OVERFLOW12] = 0x5fff8500,
+ [EXC_WINDOW_UNDERFLOW12] = 0x5fff8540,
+ [EXC_KERNEL] = 0x5fff861c,
+ [EXC_USER] = 0x5fff863c,
+ [EXC_DOUBLE] = 0x5fff865c,
+ },
},
};
@@ -94,4 +109,24 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
void do_interrupt(CPUState *env)
{
+ switch (env->exception_index) {
+ case EXC_WINDOW_OVERFLOW4:
+ case EXC_WINDOW_UNDERFLOW4:
+ case EXC_WINDOW_OVERFLOW8:
+ case EXC_WINDOW_UNDERFLOW8:
+ case EXC_WINDOW_OVERFLOW12:
+ case EXC_WINDOW_UNDERFLOW12:
+ case EXC_KERNEL:
+ case EXC_USER:
+ case EXC_DOUBLE:
+ if (env->config->exception_vector[env->exception_index]) {
+ env->pc = env->config->exception_vector[env->exception_index];
+ env->exception_taken = 1;
+ } else {
+ qemu_log("%s(pc = %08x) bad exception_index: %d\n",
+ __func__, env->pc, env->exception_index);
+ }
+ break;
+
+ }
}