diff options
author | Bastian Koppelmann <kbastian@mail.uni-paderborn.de> | 2014-09-01 12:59:48 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2014-09-01 14:49:20 +0100 |
commit | 2d30267e8e8ea61a8ee7cf48392d993699cbb114 (patch) | |
tree | cba80401be9466954259fd470d4f5bb57fad9687 /target-tricore/helper.c | |
parent | e2d05011030d99fa0db1eeab1ca3c8fc497a6c95 (diff) |
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/helper.c')
-rw-r--r-- | target-tricore/helper.c | 54 |
1 files changed, 53 insertions, 1 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) |