Move the magic m5 PageTableFault into sim/faults.[hh,cc] since it's the same across all architectures.
--HG-- extra : convert_revision : 18d441eb7ac44df4df41771bfe3dec69f7fa70ec
This commit is contained in:
parent
8edc9d79ce
commit
54fc750924
|
@ -59,12 +59,6 @@ FaultName ArithmeticFault::_name = "arith";
|
||||||
FaultVect ArithmeticFault::_vect = 0x0501;
|
FaultVect ArithmeticFault::_vect = 0x0501;
|
||||||
FaultStat ArithmeticFault::_count;
|
FaultStat ArithmeticFault::_count;
|
||||||
|
|
||||||
#if !FULL_SYSTEM
|
|
||||||
FaultName PageTableFault::_name = "page_table_fault";
|
|
||||||
FaultVect PageTableFault::_vect = 0x0000;
|
|
||||||
FaultStat PageTableFault::_count;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
FaultName InterruptFault::_name = "interrupt";
|
FaultName InterruptFault::_name = "interrupt";
|
||||||
FaultVect InterruptFault::_vect = 0x0101;
|
FaultVect InterruptFault::_vect = 0x0101;
|
||||||
FaultStat InterruptFault::_count;
|
FaultStat InterruptFault::_count;
|
||||||
|
@ -182,32 +176,6 @@ void ItbFault::invoke(ThreadContext * tc)
|
||||||
AlphaFault::invoke(tc);
|
AlphaFault::invoke(tc);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else //!FULL_SYSTEM
|
|
||||||
|
|
||||||
void PageTableFault::invoke(ThreadContext *tc)
|
|
||||||
{
|
|
||||||
Process *p = tc->getProcessPtr();
|
|
||||||
|
|
||||||
// address is higher than the stack region or in the current stack region
|
|
||||||
if (vaddr > p->stack_base || vaddr > p->stack_min)
|
|
||||||
FaultBase::invoke(tc);
|
|
||||||
|
|
||||||
// We've accessed the next page
|
|
||||||
if (vaddr > p->stack_min - PageBytes) {
|
|
||||||
DPRINTF(Stack,
|
|
||||||
"Increasing stack %#x:%#x to %#x:%#x because of access to %#x",
|
|
||||||
p->stack_min, p->stack_base, p->stack_min - PageBytes,
|
|
||||||
p->stack_base, vaddr);
|
|
||||||
p->stack_min -= PageBytes;
|
|
||||||
if (p->stack_base - p->stack_min > 8*1024*1024)
|
|
||||||
fatal("Over max stack size for one thread\n");
|
|
||||||
p->pTable->allocate(p->stack_min, PageBytes);
|
|
||||||
} else {
|
|
||||||
warn("Page fault on address %#x\n", vaddr);
|
|
||||||
FaultBase::invoke(tc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace AlphaISA
|
} // namespace AlphaISA
|
||||||
|
|
|
@ -85,29 +85,6 @@ class AlignmentFault : public AlphaFault
|
||||||
bool isAlignmentFault() {return true;}
|
bool isAlignmentFault() {return true;}
|
||||||
};
|
};
|
||||||
|
|
||||||
#if !FULL_SYSTEM
|
|
||||||
class PageTableFault : public AlphaFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
Addr vaddr;
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
PageTableFault(Addr va)
|
|
||||||
: vaddr(va) {}
|
|
||||||
FaultName name() {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline Fault genPageTableFault(Addr va)
|
|
||||||
{
|
|
||||||
return new PageTableFault(va);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline Fault genMachineCheckFault()
|
static inline Fault genMachineCheckFault()
|
||||||
{
|
{
|
||||||
return new MachineCheckFault;
|
return new MachineCheckFault;
|
||||||
|
|
|
@ -58,12 +58,6 @@ FaultName ArithmeticFault::_name = "arith";
|
||||||
FaultVect ArithmeticFault::_vect = 0x0501;
|
FaultVect ArithmeticFault::_vect = 0x0501;
|
||||||
FaultStat ArithmeticFault::_count;
|
FaultStat ArithmeticFault::_count;
|
||||||
|
|
||||||
#if !FULL_SYSTEM
|
|
||||||
FaultName PageTableFault::_name = "page_table_fault";
|
|
||||||
FaultVect PageTableFault::_vect = 0x0000;
|
|
||||||
FaultStat PageTableFault::_count;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
FaultName InterruptFault::_name = "interrupt";
|
FaultName InterruptFault::_name = "interrupt";
|
||||||
FaultVect InterruptFault::_vect = 0x0101;
|
FaultVect InterruptFault::_vect = 0x0101;
|
||||||
FaultStat InterruptFault::_count;
|
FaultStat InterruptFault::_count;
|
||||||
|
@ -112,25 +106,5 @@ FaultName IntegerOverflowFault::_name = "intover";
|
||||||
FaultVect IntegerOverflowFault::_vect = 0x0501;
|
FaultVect IntegerOverflowFault::_vect = 0x0501;
|
||||||
FaultStat IntegerOverflowFault::_count;
|
FaultStat IntegerOverflowFault::_count;
|
||||||
|
|
||||||
void PageTableFault::invoke(ThreadContext *tc)
|
|
||||||
{
|
|
||||||
Process *p = tc->getProcessPtr();
|
|
||||||
|
|
||||||
// address is higher than the stack region or in the current stack region
|
|
||||||
if (vaddr > p->stack_base || vaddr > p->stack_min)
|
|
||||||
FaultBase::invoke(tc);
|
|
||||||
|
|
||||||
// We've accessed the next page
|
|
||||||
if (vaddr > p->stack_min - PageBytes) {
|
|
||||||
p->stack_min -= PageBytes;
|
|
||||||
if (p->stack_base - p->stack_min > 8*1024*1024)
|
|
||||||
fatal("Over max stack size for one thread\n");
|
|
||||||
p->pTable->allocate(p->stack_min, PageBytes);
|
|
||||||
warn("Increasing stack size by one page.");
|
|
||||||
} else {
|
|
||||||
FaultBase::invoke(tc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace MipsISA
|
} // namespace MipsISA
|
||||||
|
|
||||||
|
|
|
@ -80,30 +80,6 @@ class AlignmentFault : public MipsFault
|
||||||
bool isAlignmentFault() {return true;}
|
bool isAlignmentFault() {return true;}
|
||||||
};
|
};
|
||||||
|
|
||||||
#if !FULL_SYSTEM
|
|
||||||
class PageTableFault : public MipsFault
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
Addr vaddr;
|
|
||||||
static FaultName _name;
|
|
||||||
static FaultVect _vect;
|
|
||||||
static FaultStat _count;
|
|
||||||
public:
|
|
||||||
PageTableFault(Addr va)
|
|
||||||
: vaddr(va) {}
|
|
||||||
FaultName name() {return _name;}
|
|
||||||
FaultVect vect() {return _vect;}
|
|
||||||
FaultStat & countStat() {return _count;}
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline Fault genPageTableFault(Addr va)
|
|
||||||
{
|
|
||||||
return new PageTableFault(va);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static inline Fault genMachineCheckFault()
|
static inline Fault genMachineCheckFault()
|
||||||
{
|
{
|
||||||
return new MachineCheckFault;
|
return new MachineCheckFault;
|
||||||
|
|
|
@ -267,12 +267,6 @@ template<> SparcFaultBase::FaultVals
|
||||||
SparcFault<TrapInstruction>::vals =
|
SparcFault<TrapInstruction>::vals =
|
||||||
{"trap_instruction", 0x100, 1602, {P, P, H}};
|
{"trap_instruction", 0x100, 1602, {P, P, H}};
|
||||||
|
|
||||||
#if !FULL_SYSTEM
|
|
||||||
template<> SparcFaultBase::FaultVals
|
|
||||||
SparcFault<PageTableFault>::vals =
|
|
||||||
{"page_table_fault", 0x0000, 0, {SH, SH, SH}};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This causes the thread context to enter RED state. This causes the side
|
* This causes the thread context to enter RED state. This causes the side
|
||||||
* effects which go with entering RED state because of a trap.
|
* effects which go with entering RED state because of a trap.
|
||||||
|
@ -680,28 +674,6 @@ void TrapInstruction::invoke(ThreadContext *tc)
|
||||||
tc->setNextNPC(tc->readNextNPC() + sizeof(MachInst));
|
tc->setNextNPC(tc->readNextNPC() + sizeof(MachInst));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageTableFault::invoke(ThreadContext *tc)
|
|
||||||
{
|
|
||||||
Process *p = tc->getProcessPtr();
|
|
||||||
|
|
||||||
// We've accessed the next page of the stack, so extend the stack
|
|
||||||
// to cover it.
|
|
||||||
if(vaddr < p->stack_min && vaddr >= p->stack_min - PageBytes)
|
|
||||||
{
|
|
||||||
p->stack_min -= PageBytes;
|
|
||||||
if(p->stack_base - p->stack_min > 8*1024*1024)
|
|
||||||
fatal("Over max stack size for one thread\n");
|
|
||||||
p->pTable->allocate(p->stack_min, PageBytes);
|
|
||||||
warn("Increasing stack size by one page.");
|
|
||||||
}
|
|
||||||
// Otherwise, we have an unexpected page fault. Report that fact,
|
|
||||||
// and what address was accessed to cause the fault.
|
|
||||||
else
|
|
||||||
{
|
|
||||||
panic("Page table fault when accessing virtual address %#x\n", vaddr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace SparcISA
|
} // namespace SparcISA
|
||||||
|
|
|
@ -256,22 +256,6 @@ class TrapInstruction : public EnumeratedFault<TrapInstruction>
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#if !FULL_SYSTEM
|
|
||||||
class PageTableFault : public SparcFault<PageTableFault>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
Addr vaddr;
|
|
||||||
public:
|
|
||||||
PageTableFault(Addr va) : vaddr(va) {}
|
|
||||||
void invoke(ThreadContext * tc);
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline Fault genPageTableFault(Addr va)
|
|
||||||
{
|
|
||||||
return new PageTableFault(va);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline Fault genMachineCheckFault()
|
static inline Fault genMachineCheckFault()
|
||||||
{
|
{
|
||||||
return new InternalProcessorError;
|
return new InternalProcessorError;
|
||||||
|
|
|
@ -157,7 +157,7 @@ PageTable::translate(RequestPtr &req)
|
||||||
assert(pageAlign(req->getVaddr() + req->getSize() - 1)
|
assert(pageAlign(req->getVaddr() + req->getSize() - 1)
|
||||||
== pageAlign(req->getVaddr()));
|
== pageAlign(req->getVaddr()));
|
||||||
if (!translate(req->getVaddr(), paddr)) {
|
if (!translate(req->getVaddr(), paddr)) {
|
||||||
return genPageTableFault(req->getVaddr());
|
return Fault(new PageTableFault(req->getVaddr()));
|
||||||
}
|
}
|
||||||
req->setPaddr(paddr);
|
req->setPaddr(paddr);
|
||||||
return page_check(req->getPaddr(), req->getSize());
|
return page_check(req->getPaddr(), req->getSize());
|
||||||
|
|
|
@ -29,10 +29,13 @@
|
||||||
* Gabe Black
|
* Gabe Black
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "arch/isa_traits.hh"
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
#include "sim/faults.hh"
|
|
||||||
#include "cpu/thread_context.hh"
|
#include "cpu/thread_context.hh"
|
||||||
#include "cpu/base.hh"
|
#include "cpu/base.hh"
|
||||||
|
#include "sim/faults.hh"
|
||||||
|
#include "sim/process.hh"
|
||||||
|
#include "mem/page_table.hh"
|
||||||
|
|
||||||
#if !FULL_SYSTEM
|
#if !FULL_SYSTEM
|
||||||
void FaultBase::invoke(ThreadContext * tc)
|
void FaultBase::invoke(ThreadContext * tc)
|
||||||
|
@ -53,3 +56,25 @@ void UnimpFault::invoke(ThreadContext * tc)
|
||||||
{
|
{
|
||||||
panic("Unimpfault: %s\n", panicStr.c_str());
|
panic("Unimpfault: %s\n", panicStr.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PageTableFault::invoke(ThreadContext *tc)
|
||||||
|
{
|
||||||
|
Process *p = tc->getProcessPtr();
|
||||||
|
|
||||||
|
// We've accessed the next page of the stack, so extend the stack
|
||||||
|
// to cover it.
|
||||||
|
if(vaddr < p->stack_min && vaddr >= p->stack_min - TheISA::PageBytes)
|
||||||
|
{
|
||||||
|
p->stack_min -= TheISA::PageBytes;
|
||||||
|
if(p->stack_base - p->stack_min > 8*1024*1024)
|
||||||
|
fatal("Over max stack size for one thread\n");
|
||||||
|
p->pTable->allocate(p->stack_min, TheISA::PageBytes);
|
||||||
|
warn("Increasing stack size by one page.");
|
||||||
|
}
|
||||||
|
// Otherwise, we have an unexpected page fault. Report that fact,
|
||||||
|
// and what address was accessed to cause the fault.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
panic("Page table fault when accessing virtual address %#x\n", vaddr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -76,4 +76,16 @@ class UnimpFault : public FaultBase
|
||||||
void invoke(ThreadContext * tc);
|
void invoke(ThreadContext * tc);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if !FULL_SYSTEM
|
||||||
|
class PageTableFault : public FaultBase
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Addr vaddr;
|
||||||
|
public:
|
||||||
|
FaultName name() {return "M5 page table fault";}
|
||||||
|
PageTableFault(Addr va) : vaddr(va) {}
|
||||||
|
void invoke(ThreadContext * tc);
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // __FAULTS_HH__
|
#endif // __FAULTS_HH__
|
||||||
|
|
Loading…
Reference in a new issue