summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/mips/isa/decoder.isa14
-rw-r--r--src/arch/mips/tlb.cc66
2 files changed, 43 insertions, 37 deletions
diff --git a/src/arch/mips/isa/decoder.isa b/src/arch/mips/isa/decoder.isa
index 36533e076..9832937b5 100644
--- a/src/arch/mips/isa/decoder.isa
+++ b/src/arch/mips/isa/decoder.isa
@@ -2491,12 +2491,11 @@ decode OPCODE_HI default Unknown::unknown() {
0x4: decode OPCODE_LO {
format LoadMemory {
- 0x0: lb({{ Rt.sw = Mem.sb; }}, mem_flags = NO_ALIGN_FAULT);
- 0x1: lh({{ Rt.sw = Mem.sh; }}, mem_flags = NO_HALF_WORD_ALIGN_FAULT);
+ 0x0: lb({{ Rt.sw = Mem.sb; }});
+ 0x1: lh({{ Rt.sw = Mem.sh; }});
0x3: lw({{ Rt.sw = Mem.sw; }});
- 0x4: lbu({{ Rt.uw = Mem.ub;}}, mem_flags = NO_ALIGN_FAULT);
- 0x5: lhu({{ Rt.uw = Mem.uh; }},
- mem_flags = NO_HALF_WORD_ALIGN_FAULT);
+ 0x4: lbu({{ Rt.uw = Mem.ub;}});
+ 0x5: lhu({{ Rt.uw = Mem.uh; }});
}
format LoadUnalignedMemory {
@@ -2514,9 +2513,8 @@ decode OPCODE_HI default Unknown::unknown() {
0x5: decode OPCODE_LO {
format StoreMemory {
- 0x0: sb({{ Mem.ub = Rt<7:0>; }}, mem_flags = NO_ALIGN_FAULT);
- 0x1: sh({{ Mem.uh = Rt<15:0>; }},
- mem_flags = NO_HALF_WORD_ALIGN_FAULT);
+ 0x0: sb({{ Mem.ub = Rt<7:0>; }});
+ 0x1: sh({{ Mem.uh = Rt<15:0>; }});
0x3: sw({{ Mem.uw = Rt<31:0>; }});
}
diff --git a/src/arch/mips/tlb.cc b/src/arch/mips/tlb.cc
index e104b0bd2..288c8e88e 100644
--- a/src/arch/mips/tlb.cc
+++ b/src/arch/mips/tlb.cc
@@ -302,19 +302,23 @@ TLB::translateInst(RequestPtr req, ThreadContext *tc)
return NoFault;
#else
- if (IsKSeg0(req->getVaddr())) {
+ Addr vaddr = req->getVaddr();
+
+ bool misaligned = (req->getSize() - 1) & vaddr;
+
+ if (IsKSeg0(vaddr)) {
// Address will not be translated through TLB, set response, and go!
- req->setPaddr(KSeg02Phys(req->getVaddr()));
+ req->setPaddr(KSeg02Phys(vaddr));
if (getOperatingMode(tc->readMiscReg(MISCREG_STATUS)) != mode_kernel ||
- req->isMisaligned()) {
+ misaligned) {
AddressErrorFault *Flt = new AddressErrorFault();
/* BadVAddr must be set */
- Flt->badVAddr = req->getVaddr();
+ Flt->badVAddr = vaddr;
return Flt;
}
- } else if(IsKSeg1(req->getVaddr())) {
+ } else if(IsKSeg1(vaddr)) {
// Address will not be translated through TLB, set response, and go!
- req->setPaddr(KSeg02Phys(req->getVaddr()));
+ req->setPaddr(KSeg02Phys(vaddr));
} else {
/*
* This is an optimization - smallPages is updated every time a TLB
@@ -323,16 +327,16 @@ TLB::translateInst(RequestPtr req, ThreadContext *tc)
*/
Addr VPN;
if (smallPages == 1) {
- VPN = ((req->getVaddr() >> 11));
+ VPN = (vaddr >> 11);
} else {
- VPN = ((req->getVaddr() >> 11) & 0xFFFFFFFC);
+ VPN = ((vaddr >> 11) & 0xFFFFFFFC);
}
uint8_t Asid = req->getAsid();
- if (req->isMisaligned()) {
+ if (misaligned) {
// Unaligned address!
AddressErrorFault *Flt = new AddressErrorFault();
/* BadVAddr must be set */
- Flt->badVAddr = req->getVaddr();
+ Flt->badVAddr = vaddr;
return Flt;
}
PTE *pte = lookup(VPN,Asid);
@@ -341,7 +345,7 @@ TLB::translateInst(RequestPtr req, ThreadContext *tc)
/* Check for valid bits */
int EvenOdd;
bool Valid;
- if ((((req->getVaddr()) >> pte->AddrShiftAmount) & 1) == 0) {
+ if ((((vaddr) >> pte->AddrShiftAmount) & 1) == 0) {
// Check even bits
Valid = pte->V0;
EvenOdd = 0;
@@ -360,7 +364,7 @@ TLB::translateInst(RequestPtr req, ThreadContext *tc)
Flt->entryHiVPN2X = (VPN & 0x3);
/* BadVAddr must be set */
- Flt->badVAddr = req->getVaddr();
+ Flt->badVAddr = vaddr;
/* Context must be set */
Flt->contextBadVPN2 = (VPN >> 2);
@@ -375,7 +379,7 @@ TLB::translateInst(RequestPtr req, ThreadContext *tc)
}
PAddr >>= (pte->AddrShiftAmount - 12);
PAddr <<= pte->AddrShiftAmount;
- PAddr |= ((req->getVaddr()) & pte->OffsetMask);
+ PAddr |= (vaddr & pte->OffsetMask);
req->setPaddr(PAddr);
}
} else {
@@ -387,7 +391,7 @@ TLB::translateInst(RequestPtr req, ThreadContext *tc)
Flt->entryHiVPN2X = (VPN & 0x3);
/* BadVAddr must be set */
- Flt->badVAddr = req->getVaddr();
+ Flt->badVAddr = vaddr;
/* Context must be set */
Flt->contextBadVPN2 = (VPN >> 2);
@@ -422,37 +426,41 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
return NoFault;
#else
- if (IsKSeg0(req->getVaddr())) {
+ Addr vaddr = req->getVaddr();
+
+ bool misaligned = (req->getSize() - 1) & vaddr;
+
+ if (IsKSeg0(vaddr)) {
// Address will not be translated through TLB, set response, and go!
- req->setPaddr(KSeg02Phys(req->getVaddr()));
+ req->setPaddr(KSeg02Phys(vaddr));
if (getOperatingMode(tc->readMiscReg(MISCREG_STATUS)) != mode_kernel ||
- req->isMisaligned()) {
+ misaligned) {
StoreAddressErrorFault *Flt = new StoreAddressErrorFault();
/* BadVAddr must be set */
- Flt->badVAddr = req->getVaddr();
+ Flt->badVAddr = vaddr;
return Flt;
}
- } else if(IsKSeg1(req->getVaddr())) {
+ } else if(IsKSeg1(vaddr)) {
// Address will not be translated through TLB, set response, and go!
- req->setPaddr(KSeg02Phys(req->getVaddr()));
+ req->setPaddr(KSeg02Phys(vaddr));
} else {
/*
* This is an optimization - smallPages is updated every time a TLB
* operation is performed. That way, we don't need to look at
* Config3 _ SP and PageGrain _ ESP every time we do a TLB lookup
*/
- Addr VPN = ((req->getVaddr() >> 11) & 0xFFFFFFFC);
+ Addr VPN = (vaddr >> 11) & 0xFFFFFFFC;
if (smallPages == 1) {
- VPN = ((req->getVaddr() >> 11));
+ VPN = vaddr >> 11;
}
uint8_t Asid = req->getAsid();
PTE *pte = lookup(VPN, Asid);
- if (req->isMisaligned()) {
+ if (misaligned) {
// Unaligned address!
StoreAddressErrorFault *Flt = new StoreAddressErrorFault();
/* BadVAddr must be set */
- Flt->badVAddr = req->getVaddr();
+ Flt->badVAddr = vaddr;
return Flt;
}
if (pte != NULL) {
@@ -461,7 +469,7 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
int EvenOdd;
bool Valid;
bool Dirty;
- if (((((req->getVaddr()) >> pte->AddrShiftAmount) & 1)) == 0) {
+ if ((((vaddr >> pte->AddrShiftAmount) & 1)) == 0) {
// Check even bits
Valid = pte->V0;
Dirty = pte->D0;
@@ -482,7 +490,7 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
Flt->entryHiVPN2X = (VPN & 0x3);
/* BadVAddr must be set */
- Flt->badVAddr = req->getVaddr();
+ Flt->badVAddr = vaddr;
/* Context must be set */
Flt->contextBadVPN2 = (VPN >> 2);
@@ -498,7 +506,7 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
Flt->entryHiVPN2X = (VPN & 0x3);
/* BadVAddr must be set */
- Flt->badVAddr = req->getVaddr();
+ Flt->badVAddr = vaddr;
/* Context must be set */
Flt->contextBadVPN2 = (VPN >> 2);
@@ -512,7 +520,7 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
}
PAddr >>= (pte->AddrShiftAmount - 12);
PAddr <<= pte->AddrShiftAmount;
- PAddr |= ((req->getVaddr()) & pte->OffsetMask);
+ PAddr |= (vaddr & pte->OffsetMask);
req->setPaddr(PAddr);
}
} else {
@@ -524,7 +532,7 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
Flt->entryHiVPN2X = (VPN & 0x3);
/* BadVAddr must be set */
- Flt->badVAddr = req->getVaddr();
+ Flt->badVAddr = vaddr;
/* Context must be set */
Flt->contextBadVPN2 = (VPN >> 2);