faults.cc

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· CC 代码 · 共 210 行

CC
210
字号
/* * Copyright (c) 2003, 2004, 2005 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. * * Authors: Gabe M. Black *          Kevin T. Lim */#include "arch/alpha/ev5.hh"#include "arch/alpha/faults.hh"#include "arch/alpha/tlb.hh"#include "cpu/thread_context.hh"#include "cpu/base.hh"#include "base/trace.hh"#if !FULL_SYSTEM#include "sim/process.hh"#include "mem/page_table.hh"#endifnamespace AlphaISA{FaultName MachineCheckFault::_name = "mchk";FaultVect MachineCheckFault::_vect = 0x0401;FaultStat MachineCheckFault::_count;FaultName AlignmentFault::_name = "unalign";FaultVect AlignmentFault::_vect = 0x0301;FaultStat AlignmentFault::_count;FaultName ResetFault::_name = "reset";FaultVect ResetFault::_vect = 0x0001;FaultStat ResetFault::_count;FaultName ArithmeticFault::_name = "arith";FaultVect ArithmeticFault::_vect = 0x0501;FaultStat ArithmeticFault::_count;FaultName InterruptFault::_name = "interrupt";FaultVect InterruptFault::_vect = 0x0101;FaultStat InterruptFault::_count;FaultName NDtbMissFault::_name = "dtb_miss_single";FaultVect NDtbMissFault::_vect = 0x0201;FaultStat NDtbMissFault::_count;FaultName PDtbMissFault::_name = "dtb_miss_double";FaultVect PDtbMissFault::_vect = 0x0281;FaultStat PDtbMissFault::_count;FaultName DtbPageFault::_name = "dfault";FaultVect DtbPageFault::_vect = 0x0381;FaultStat DtbPageFault::_count;FaultName DtbAcvFault::_name = "dfault";FaultVect DtbAcvFault::_vect = 0x0381;FaultStat DtbAcvFault::_count;FaultName DtbAlignmentFault::_name = "unalign";FaultVect DtbAlignmentFault::_vect = 0x0301;FaultStat DtbAlignmentFault::_count;FaultName ItbPageFault::_name = "itbmiss";FaultVect ItbPageFault::_vect = 0x0181;FaultStat ItbPageFault::_count;FaultName ItbAcvFault::_name = "iaccvio";FaultVect ItbAcvFault::_vect = 0x0081;FaultStat ItbAcvFault::_count;FaultName UnimplementedOpcodeFault::_name = "opdec";FaultVect UnimplementedOpcodeFault::_vect = 0x0481;FaultStat UnimplementedOpcodeFault::_count;FaultName FloatEnableFault::_name = "fen";FaultVect FloatEnableFault::_vect = 0x0581;FaultStat FloatEnableFault::_count;FaultName PalFault::_name = "pal";FaultVect PalFault::_vect = 0x2001;FaultStat PalFault::_count;FaultName IntegerOverflowFault::_name = "intover";FaultVect IntegerOverflowFault::_vect = 0x0501;FaultStat IntegerOverflowFault::_count;#if FULL_SYSTEMvoid AlphaFault::invoke(ThreadContext * tc){    FaultBase::invoke(tc);    countStat()++;    // exception restart address    if (setRestartAddress() || !(tc->readPC() & 0x3))        tc->setMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR, tc->readPC());    if (skipFaultingInstruction()) {        // traps...  skip faulting instruction.        tc->setMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR,                   tc->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR) + 4);    }    tc->setPC(tc->readMiscRegNoEffect(AlphaISA::IPR_PAL_BASE) + vect());    tc->setNextPC(tc->readPC() + sizeof(MachInst));}void ArithmeticFault::invoke(ThreadContext * tc){    FaultBase::invoke(tc);    panic("Arithmetic traps are unimplemented!");}void DtbFault::invoke(ThreadContext * tc){    // Set fault address and flags.  Even though we're modeling an    // EV5, we use the EV6 technique of not latching fault registers    // on VPTE loads (instead of locking the registers until IPR_VA is    // read, like the EV5).  The EV6 approach is cleaner and seems to    // work with EV5 PAL code, but not the other way around.    if (!tc->misspeculating()        && !(reqFlags & VPTE) && !(reqFlags & NO_FAULT)) {        // set VA register with faulting address        tc->setMiscRegNoEffect(AlphaISA::IPR_VA, vaddr);        // set MM_STAT register flags        tc->setMiscRegNoEffect(AlphaISA::IPR_MM_STAT,            (((EV5::Opcode(tc->getInst()) & 0x3f) << 11)             | ((EV5::Ra(tc->getInst()) & 0x1f) << 6)             | (flags & 0x3f)));        // set VA_FORM register with faulting formatted address        tc->setMiscRegNoEffect(AlphaISA::IPR_VA_FORM,            tc->readMiscRegNoEffect(AlphaISA::IPR_MVPTBR) | (vaddr.vpn() << 3));    }    AlphaFault::invoke(tc);}void ItbFault::invoke(ThreadContext * tc){    if (!tc->misspeculating()) {        tc->setMiscRegNoEffect(AlphaISA::IPR_ITB_TAG, pc);        tc->setMiscRegNoEffect(AlphaISA::IPR_IFAULT_VA_FORM,                       tc->readMiscRegNoEffect(AlphaISA::IPR_IVPTBR) |                       (AlphaISA::VAddr(pc).vpn() << 3));    }    AlphaFault::invoke(tc);}#elsevoid ItbPageFault::invoke(ThreadContext * tc){    Process *p = tc->getProcessPtr();    TlbEntry entry;    bool success = p->pTable->lookup(pc, entry);    if(!success) {        panic("Tried to execute unmapped address %#x.\n", pc);    } else {        VAddr vaddr(pc);        tc->getITBPtr()->insert(vaddr.page(), entry);    }}void NDtbMissFault::invoke(ThreadContext * tc){    Process *p = tc->getProcessPtr();    TlbEntry entry;    bool success = p->pTable->lookup(vaddr, entry);    if(!success) {        p->checkAndAllocNextPage(vaddr);        success = p->pTable->lookup(vaddr, entry);    }    if(!success) {        panic("Tried to access unmapped address %#x.\n", (Addr)vaddr);    } else {        tc->getDTBPtr()->insert(vaddr.page(), entry);    }}#endif} // namespace AlphaISA

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?