diff options
author | blueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-09-27 19:43:18 +0000 |
---|---|---|
committer | blueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-09-27 19:43:18 +0000 |
commit | cc6747f4c94de5ebe9605f3592633928934f6295 (patch) | |
tree | 27862605ae19587c04c186b007f820fa6a5a811a /target-sparc/op_helper.c | |
parent | 06e67a82da7b0d2bb2bdada0ec7122032a330312 (diff) | |
download | hqemu-cc6747f4c94de5ebe9605f3592633928934f6295.zip hqemu-cc6747f4c94de5ebe9605f3592633928934f6295.tar.gz |
Add mmu tlb demap support (Igor Kovalenko)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5332 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-sparc/op_helper.c')
-rw-r--r-- | target-sparc/op_helper.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c index fb24fc8..d01d9da 100644 --- a/target-sparc/op_helper.c +++ b/target-sparc/op_helper.c @@ -1941,6 +1941,8 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size) } case 0x55: // I-MMU data access { + // TODO: auto demap + unsigned int i = (addr >> 3) & 0x3f; env->itlb_tag[i] = env->immuregs[6]; @@ -1948,7 +1950,22 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size) return; } case 0x57: // I-MMU demap - // XXX + { + unsigned int i; + + for (i = 0; i < 64; i++) { + if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) { + target_ulong mask = 0xffffffffffffe000ULL; + + mask <<= 3 * ((env->itlb_tte[i] >> 61) & 3); + if ((val & mask) == (env->itlb_tag[i] & mask)) { + env->itlb_tag[i] = 0; + env->itlb_tte[i] = 0; + } + return; + } + } + } return; case 0x58: // D-MMU regs { @@ -2018,6 +2035,23 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size) return; } case 0x5f: // D-MMU demap + { + unsigned int i; + + for (i = 0; i < 64; i++) { + if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) { + target_ulong mask = 0xffffffffffffe000ULL; + + mask <<= 3 * ((env->dtlb_tte[i] >> 61) & 3); + if ((val & mask) == (env->dtlb_tag[i] & mask)) { + env->dtlb_tag[i] = 0; + env->dtlb_tte[i] = 0; + } + return; + } + } + } + return; case 0x49: // Interrupt data receive // XXX return; |