aboutsummaryrefslogtreecommitdiff
path: root/target-sparc/op_helper.c
diff options
context:
space:
mode:
authorIgor V. Kovalenko <igor.v.kovalenko@gmail.com>2010-05-04 23:15:41 +0400
committerBlue Swirl <blauwirbel@gmail.com>2010-05-06 20:13:36 +0000
commit299b520cd4092be3c53f8380b81315c33927d9d3 (patch)
tree3c37f5188ec41e70558cb18b9f940fbd81a782cd /target-sparc/op_helper.c
parent788686ec59bb8277ff70ae3853a0720c8b2b865d (diff)
downloadqemu-299b520cd4092be3c53f8380b81315c33927d9d3.zip
qemu-299b520cd4092be3c53f8380b81315c33927d9d3.tar.gz
qemu-299b520cd4092be3c53f8380b81315c33927d9d3.tar.bz2
sparc64: implement global translation table entries v1
- match global tte against any context - show global tte in MMU dump v0->v1: added default case to switch statement in demap_tlb - should fix gcc warning about uninitialized context variable Signed-off-by: Igor V. Kovalenko <igor.v.kovalenko@gmail.com> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'target-sparc/op_helper.c')
-rw-r--r--target-sparc/op_helper.c53
1 files changed, 44 insertions, 9 deletions
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index b27778b..245eba7 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -129,24 +129,59 @@ static void demap_tlb(SparcTLBEntry *tlb, target_ulong demap_addr,
{
unsigned int i;
target_ulong mask;
+ uint64_t context;
+
+ int is_demap_context = (demap_addr >> 6) & 1;
+
+ // demap context
+ switch ((demap_addr >> 4) & 3) {
+ case 0: // primary
+ context = env1->dmmu.mmu_primary_context;
+ break;
+ case 1: // secondary
+ context = env1->dmmu.mmu_secondary_context;
+ break;
+ case 2: // nucleus
+ context = 0;
+ break;
+ case 3: // reserved
+ default:
+ return;
+ }
for (i = 0; i < 64; i++) {
if (TTE_IS_VALID(tlb[i].tte)) {
- mask = 0xffffffffffffe000ULL;
- mask <<= 3 * ((tlb[i].tte >> 61) & 3);
+ if (is_demap_context) {
+ // will remove non-global entries matching context value
+ if (TTE_IS_GLOBAL(tlb[i].tte) ||
+ !tlb_compare_context(&tlb[i], context)) {
+ continue;
+ }
+ } else {
+ // demap page
+ // will remove any entry matching VA
+ mask = 0xffffffffffffe000ULL;
+ mask <<= 3 * ((tlb[i].tte >> 61) & 3);
- if ((demap_addr & mask) == (tlb[i].tag & mask)) {
- replace_tlb_entry(&tlb[i], 0, 0, env1);
+ if (!compare_masked(demap_addr, tlb[i].tag, mask)) {
+ continue;
+ }
+
+ // entry should be global or matching context value
+ if (!TTE_IS_GLOBAL(tlb[i].tte) &&
+ !tlb_compare_context(&tlb[i], context)) {
+ continue;
+ }
+ }
+
+ replace_tlb_entry(&tlb[i], 0, 0, env1);
#ifdef DEBUG_MMU
- DPRINTF_MMU("%s demap invalidated entry [%02u]\n", strmmu, i);
- dump_mmu(env1);
+ DPRINTF_MMU("%s demap invalidated entry [%02u]\n", strmmu, i);
+ dump_mmu(env1);
#endif
- }
- //return;
}
}
-
}
static void replace_tlb_1bit_lru(SparcTLBEntry *tlb,