summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorAndrew Schultz <alschult@umich.edu>2004-02-16 21:56:38 -0500
committerAndrew Schultz <alschult@umich.edu>2004-02-16 21:56:38 -0500
commita73e263f94b9c6a512abb88d5b047125c57cf115 (patch)
treee6211ef95388432b4ca4353c43b60a6b735c31c0 /arch
parentb797f992132b1192df4f580a32fa3254b6e48a1d (diff)
downloadgem5-a73e263f94b9c6a512abb88d5b047125c57cf115.tar.xz
Change logic for translating a memory addresses, extra checks for invalid
physical addresses. --HG-- extra : convert_revision : efb4a5229d88cb3c024e0b24f5916048bd42d589
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/alpha_memory.cc93
1 files changed, 49 insertions, 44 deletions
diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/alpha_memory.cc
index 00e97250f..7bdbea6c1 100644
--- a/arch/alpha/alpha_memory.cc
+++ b/arch/alpha/alpha_memory.cc
@@ -280,17 +280,13 @@ AlphaItb::translate(MemReqPtr &req) const
return No_Fault;
}
- // verify that this is a good virtual address
- if (!validVirtualAddress(req->vaddr)) {
- fault(req->vaddr, req->xc);
- acv++;
- return Itb_Acv_Fault;
- }
+ if (req->flags & PHYSICAL) {
+ req->paddr = req->vaddr;
+ } else if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) &&
+ VA_SPACE(req->vaddr) == 2) {
+ // Check for "superpage" mapping: when SP<1> is set, and
+ // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>.
- // Check for "superpage" mapping: when SP<1> is set, and
- // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>.
- if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) &&
- VA_SPACE(req->vaddr) == 2) {
// only valid in kernel mode
if (ICM_CM(ipr[AlphaISA::IPR_ICM]) != AlphaISA::mode_kernel) {
fault(req->vaddr, req->xc);
@@ -298,16 +294,18 @@ AlphaItb::translate(MemReqPtr &req) const
return Itb_Acv_Fault;
}
- req->flags |= PHYSICAL;
- }
-
- if (req->flags & PHYSICAL) {
req->paddr = req->vaddr & PA_IMPL_MASK;
} else {
- // not a physical address: need to look up pte
+ // verify that this is a good virtual address
+ if (!validVirtualAddress(req->vaddr)) {
+ fault(req->vaddr, req->xc);
+ acv++;
+ return Itb_Acv_Fault;
+ }
+ // not a physical address: need to look up pte
AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr),
- DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]));
+ DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]));
if (!pte) {
fault(req->vaddr, req->xc);
@@ -326,6 +324,10 @@ AlphaItb::translate(MemReqPtr &req) const
}
}
+ // check that the physical address is ok (catch bad physical addresses)
+ if (req->paddr & ~PA_IMPL_MASK)
+ return Machine_Check_Fault;
+
checkCacheability(req);
hits++;
@@ -440,11 +442,6 @@ AlphaDtb::translate(MemReqPtr &req, bool write) const
Addr pc = regs->pc;
InternalProcReg *ipr = regs->ipr;
- if (write)
- write_accesses++;
- else
- read_accesses++;
-
AlphaISA::mode_type mode =
(AlphaISA::mode_type)DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]);
@@ -454,20 +451,13 @@ AlphaDtb::translate(MemReqPtr &req, bool write) const
: AlphaISA::mode_kernel;
}
- // verify that this is a good virtual address
- if (!validVirtualAddress(req->vaddr)) {
- fault(req->vaddr,
- ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK |
- MM_STAT_ACV_MASK),
- req->xc);
-
- if (write) { write_acv++; } else { read_acv++; }
- return Dtb_Fault_Fault;
- }
+ if (req->flags & PHYSICAL) {
+ req->paddr = req->vaddr;
+ } else if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) &&
+ VA_SPACE(req->vaddr) == 2) {
+ // Check for "superpage" mapping: when SP<1> is set, and
+ // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>.
- // Check for "superpage" mapping: when SP<1> is set, and
- // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13>.
- if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && VA_SPACE(req->vaddr) == 2) {
// only valid in kernel mode
if (DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]) != AlphaISA::mode_kernel) {
fault(req->vaddr,
@@ -477,14 +467,25 @@ AlphaDtb::translate(MemReqPtr &req, bool write) const
return Dtb_Acv_Fault;
}
- req->flags |= PHYSICAL;
- }
-
- if (req->flags & PHYSICAL) {
req->paddr = req->vaddr & PA_IMPL_MASK;
} else {
- // not a physical address: need to look up pte
+ if (write)
+ write_accesses++;
+ else
+ read_accesses++;
+
+ // verify that this is a good virtual address
+ if (!validVirtualAddress(req->vaddr)) {
+ fault(req->vaddr,
+ ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK |
+ MM_STAT_ACV_MASK),
+ req->xc);
+
+ if (write) { write_acv++; } else { read_acv++; }
+ return Dtb_Fault_Fault;
+ }
+ // not a physical address: need to look up pte
AlphaISA::PTE *pte = lookup(VA_VPN(req->vaddr),
DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]));
@@ -528,14 +529,18 @@ AlphaDtb::translate(MemReqPtr &req, bool write) const
return Dtb_Fault_Fault;
}
}
+
+ if (write)
+ write_hits++;
+ else
+ read_hits++;
}
- checkCacheability(req);
+ // check that the physical address is ok (catch bad physical addresses)
+ if (req->paddr & ~PA_IMPL_MASK)
+ return Machine_Check_Fault;
- if (write)
- write_hits++;
- else
- read_hits++;
+ checkCacheability(req);
return No_Fault;
}