summaryrefslogtreecommitdiff
path: root/target-tricore
diff options
context:
space:
mode:
authorBastian Koppelmann <kbastian@mail.uni-paderborn.de>2014-09-01 12:59:48 +0100
committerPeter Maydell <peter.maydell@linaro.org>2014-09-01 14:49:20 +0100
commit2d30267e8e8ea61a8ee7cf48392d993699cbb114 (patch)
treecba80401be9466954259fd470d4f5bb57fad9687 /target-tricore
parente2d05011030d99fa0db1eeab1ca3c8fc497a6c95 (diff)
downloadqemu-2d30267e8e8ea61a8ee7cf48392d993699cbb114.tar.gz
target-tricore: Add softmmu support
Add basic softmmu support for TriCore Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de> Message-id: 1409572800-4116-4-git-send-email-kbastian@mail.uni-paderborn.de Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-tricore')
-rw-r--r--target-tricore/helper.c54
-rw-r--r--target-tricore/op_helper.c33
2 files changed, 85 insertions, 2 deletions
diff --git a/target-tricore/helper.c b/target-tricore/helper.c
index ee7f0076c0..e4af6f1ac2 100644
--- a/target-tricore/helper.c
+++ b/target-tricore/helper.c
@@ -24,10 +24,62 @@
#include "cpu.h"
+enum {
+ TLBRET_DIRTY = -4,
+ TLBRET_INVALID = -3,
+ TLBRET_NOMATCH = -2,
+ TLBRET_BADADDR = -1,
+ TLBRET_MATCH = 0
+};
+
+#if defined(CONFIG_SOFTMMU)
+static int get_physical_address(CPUTriCoreState *env, hwaddr *physical,
+ int *prot, target_ulong address,
+ int rw, int access_type)
+{
+ int ret = TLBRET_MATCH;
+
+ *physical = address & 0xFFFFFFFF;
+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+
+ return ret;
+}
+#endif
+
+/* TODO: Add exeption support*/
+static void raise_mmu_exception(CPUTriCoreState *env, target_ulong address,
+ int rw, int tlb_error)
+{
+}
+
int cpu_tricore_handle_mmu_fault(CPUState *cs, target_ulong address,
int rw, int mmu_idx)
{
- return 0;
+ TriCoreCPU *cpu = TRICORE_CPU(cs);
+ CPUTriCoreState *env = &cpu->env;
+ hwaddr physical;
+ int prot;
+ int access_type;
+ int ret = 0;
+
+ rw &= 1;
+ access_type = ACCESS_INT;
+ ret = get_physical_address(env, &physical, &prot,
+ address, rw, access_type);
+ qemu_log("%s address=" TARGET_FMT_lx " ret %d physical " TARGET_FMT_plx
+ " prot %d\n", __func__, address, ret, physical, prot);
+
+ if (ret == TLBRET_MATCH) {
+ tlb_set_page(cs, address & TARGET_PAGE_MASK,
+ physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
+ mmu_idx, TARGET_PAGE_SIZE);
+ ret = 0;
+ } else if (ret < 0) {
+ raise_mmu_exception(env, address, rw, ret);
+ ret = 1;
+ }
+
+ return ret;
}
void tricore_cpu_do_interrupt(CPUState *cs)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 275790b10a..c1342e9da5 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -20,8 +20,39 @@
#include "exec/helper-proto.h"
#include "exec/cpu_ldst.h"
+static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
+ uint32_t exception,
+ int error_code,
+ uintptr_t pc)
+{
+ CPUState *cs = CPU(tricore_env_get_cpu(env));
+ cs->exception_index = exception;
+ env->error_code = error_code;
+
+ if (pc) {
+ /* now we have a real cpu fault */
+ cpu_restore_state(cs, pc);
+ }
+
+ cpu_loop_exit(cs);
+}
+
+static inline void QEMU_NORETURN do_raise_exception(CPUTriCoreState *env,
+ uint32_t exception,
+ uintptr_t pc)
+{
+ do_raise_exception_err(env, exception, 0, pc);
+}
+
void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
uintptr_t retaddr)
{
+ int ret;
+ ret = cpu_tricore_handle_mmu_fault(cs, addr, is_write, mmu_idx);
+ if (ret) {
+ TriCoreCPU *cpu = TRICORE_CPU(cs);
+ CPUTriCoreState *env = &cpu->env;
+ do_raise_exception_err(env, cs->exception_index,
+ env->error_code, retaddr);
+ }
}
-