From: Igor Kovalenko <igor.v.kovalenko@gmail.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] sparc64: unify mmu tag matching code
Date: Sun, 12 Jul 2009 02:45:41 +0400 [thread overview]
Message-ID: <b2fa41d60907111545k247f587fw2f88a035e66902a6@mail.gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 172 bytes --]
This patch extracts common part of sparc64 tag
matching code used by IMMU and DMMU lookups.
Signed-off-by: igor.v.kovalenko@gmail.com
--
Kind regards,
Igor V. Kovalenko
[-- Attachment #2: sparc64-compare-masked --]
[-- Type: application/octet-stream, Size: 5925 bytes --]
Index: qemu-trunk/target-sparc/helper.c
===================================================================
--- qemu-trunk.orig/target-sparc/helper.c
+++ qemu-trunk/target-sparc/helper.c
@@ -379,12 +379,55 @@ static inline target_phys_addr_t ultrasp
/*
* UltraSparc IIi I/DMMUs
*/
+
+static inline int compare_masked(uint64_t x, uint64_t y, uint64_t mask)
+{
+ return (x & mask) == (y & mask);
+}
+
+// Returns true if TTE tag is valid and matches virtual address value in context
+// requires virtual address mask value calculated from TTE entry size
+static inline int ultrasparc_tag_match(uint64_t tlb_tag, uint64_t tlb_tte,
+ uint64_t address, uint64_t context,
+ target_phys_addr_t *physical)
+{
+ uint64_t mask;
+
+ switch ((tlb_tte >> 61) & 3) {
+ default:
+ case 0x0: // 8k
+ mask = 0xffffffffffffe000ULL;
+ break;
+ case 0x1: // 64k
+ mask = 0xffffffffffff0000ULL;
+ break;
+ case 0x2: // 512k
+ mask = 0xfffffffffff80000ULL;
+ break;
+ case 0x3: // 4M
+ mask = 0xffffffffffc00000ULL;
+ break;
+ }
+
+ // valid, context match, virtual address match?
+ if ((tlb_tte & 0x8000000000000000ULL) &&
+ compare_masked(context, tlb_tag, 0x1fff) &&
+ compare_masked(address, tlb_tag, mask))
+ {
+ // decode physical address
+ *physical = ((tlb_tte & mask) | (address & ~mask)) & 0x1ffffffe000ULL;
+ return 1;
+ }
+
+ return 0;
+}
+
static int get_physical_address_data(CPUState *env,
target_phys_addr_t *physical, int *prot,
target_ulong address, int rw, int is_user)
{
- target_ulong mask;
unsigned int i;
+ uint64_t context;
if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
*physical = ultrasparc_truncate_physical(address);
@@ -392,26 +435,13 @@ static int get_physical_address_data(CPU
return 0;
}
+ context = env->dmmuregs[1] & 0x1fff;
+
for (i = 0; i < 64; i++) {
- switch ((env->dtlb_tte[i] >> 61) & 3) {
- default:
- case 0x0: // 8k
- mask = 0xffffffffffffe000ULL;
- break;
- case 0x1: // 64k
- mask = 0xffffffffffff0000ULL;
- break;
- case 0x2: // 512k
- mask = 0xfffffffffff80000ULL;
- break;
- case 0x3: // 4M
- mask = 0xffffffffffc00000ULL;
- break;
- }
// ctx match, vaddr match, valid?
- if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
- (address & mask) == (env->dtlb_tag[i] & mask) &&
- (env->dtlb_tte[i] & 0x8000000000000000ULL)) {
+ if (ultrasparc_tag_match(env->dtlb_tag[i], env->dtlb_tte[i],
+ address, context, physical)
+ ) {
// access ok?
if (((env->dtlb_tte[i] & 0x4) && is_user) ||
(!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {
@@ -426,8 +456,6 @@ static int get_physical_address_data(CPU
#endif
return 1;
}
- *physical = ((env->dtlb_tte[i] & mask) | (address & ~mask)) &
- 0x1ffffffe000ULL;
*prot = PAGE_READ;
if (env->dtlb_tte[i] & 0x2)
*prot |= PAGE_WRITE;
@@ -437,7 +465,7 @@ static int get_physical_address_data(CPU
#ifdef DEBUG_MMU
printf("DMISS at 0x%" PRIx64 "\n", address);
#endif
- env->dmmuregs[6] = (address & ~0x1fffULL) | (env->dmmuregs[1] & 0x1fff);
+ env->dmmuregs[6] = (address & ~0x1fffULL) | context;
env->exception_index = TT_DMISS;
return 1;
}
@@ -446,8 +474,8 @@ static int get_physical_address_code(CPU
target_phys_addr_t *physical, int *prot,
target_ulong address, int is_user)
{
- target_ulong mask;
unsigned int i;
+ uint64_t context;
if ((env->lsu & IMMU_E) == 0 || (env->pstate & PS_RED) != 0) {
/* IMMU disabled */
@@ -456,26 +484,13 @@ static int get_physical_address_code(CPU
return 0;
}
+ context = env->dmmuregs[1] & 0x1fff;
+
for (i = 0; i < 64; i++) {
- switch ((env->itlb_tte[i] >> 61) & 3) {
- default:
- case 0x0: // 8k
- mask = 0xffffffffffffe000ULL;
- break;
- case 0x1: // 64k
- mask = 0xffffffffffff0000ULL;
- break;
- case 0x2: // 512k
- mask = 0xfffffffffff80000ULL;
- break;
- case 0x3: // 4M
- mask = 0xffffffffffc00000ULL;
- break;
- }
// ctx match, vaddr match, valid?
- if (env->dmmuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
- (address & mask) == (env->itlb_tag[i] & mask) &&
- (env->itlb_tte[i] & 0x8000000000000000ULL)) {
+ if (ultrasparc_tag_match(env->itlb_tag[i], env->itlb_tte[i],
+ address, context, physical)
+ ) {
// access ok?
if ((env->itlb_tte[i] & 0x4) && is_user) {
if (env->immuregs[3]) /* Fault status register */
@@ -488,8 +503,6 @@ static int get_physical_address_code(CPU
#endif
return 1;
}
- *physical = ((env->itlb_tte[i] & mask) | (address & ~mask)) &
- 0x1ffffffe000ULL;
*prot = PAGE_EXEC;
return 0;
}
@@ -498,7 +511,7 @@ static int get_physical_address_code(CPU
printf("TMISS at 0x%" PRIx64 "\n", address);
#endif
/* Context is stored in DMMU (dmmuregs[1]) also for IMMU */
- env->immuregs[6] = (address & ~0x1fffULL) | (env->dmmuregs[1] & 0x1fff);
+ env->immuregs[6] = (address & ~0x1fffULL) | context;
env->exception_index = TT_TMISS;
return 1;
}
reply other threads:[~2009-07-11 22:45 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=b2fa41d60907111545k247f587fw2f88a035e66902a6@mail.gmail.com \
--to=igor.v.kovalenko@gmail.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).