faults.cc revision 10417
12292SN/A/*
22329SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
32292SN/A * All rights reserved.
42292SN/A *
52292SN/A * Redistribution and use in source and binary forms, with or without
62292SN/A * modification, are permitted provided that the following conditions are
72292SN/A * met: redistributions of source code must retain the above copyright
82292SN/A * notice, this list of conditions and the following disclaimer;
92292SN/A * redistributions in binary form must reproduce the above copyright
102292SN/A * notice, this list of conditions and the following disclaimer in the
112292SN/A * documentation and/or other materials provided with the distribution;
122292SN/A * neither the name of the copyright holders nor the names of its
132292SN/A * contributors may be used to endorse or promote products derived from
142292SN/A * this software without specific prior written permission.
152292SN/A *
162292SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172292SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182292SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192292SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212292SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222292SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232292SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242292SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252292SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262292SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272689Sktlim@umich.edu *
282689Sktlim@umich.edu * Authors: Gabe Black
292292SN/A *          Kevin Lim
302292SN/A */
312292SN/A
322292SN/A#include "arch/alpha/ev5.hh"
332292SN/A#include "arch/alpha/faults.hh"
342292SN/A#include "arch/alpha/tlb.hh"
352292SN/A#include "base/trace.hh"
362292SN/A#include "cpu/base.hh"
372292SN/A#include "cpu/thread_context.hh"
382292SN/A#include "mem/page_table.hh"
392292SN/A#include "sim/process.hh"
402669Sktlim@umich.edu#include "sim/full_system.hh"
412292SN/A
422292SN/Anamespace AlphaISA {
432292SN/A
442292SN/AFaultName MachineCheckFault::_name = "mchk";
452292SN/AFaultVect MachineCheckFault::_vect = 0x0401;
462292SN/AFaultStat MachineCheckFault::_count;
472733Sktlim@umich.edu
482292SN/AFaultName AlignmentFault::_name = "unalign";
492292SN/AFaultVect AlignmentFault::_vect = 0x0301;
502292SN/AFaultStat AlignmentFault::_count;
512292SN/A
522348SN/AFaultName ResetFault::_name = "reset";
532292SN/AFaultVect ResetFault::_vect = 0x0001;
542292SN/AFaultStat ResetFault::_count;
552292SN/A
562292SN/AFaultName ArithmeticFault::_name = "arith";
572292SN/AFaultVect ArithmeticFault::_vect = 0x0501;
582292SN/AFaultStat ArithmeticFault::_count;
592292SN/A
604329Sktlim@umich.eduFaultName InterruptFault::_name = "interrupt";
612292SN/AFaultVect InterruptFault::_vect = 0x0101;
622292SN/AFaultStat InterruptFault::_count;
632292SN/A
642292SN/AFaultName NDtbMissFault::_name = "dtb_miss_single";
652727Sktlim@umich.eduFaultVect NDtbMissFault::_vect = 0x0201;
662727Sktlim@umich.eduFaultStat NDtbMissFault::_count;
672727Sktlim@umich.edu
682871Sktlim@umich.eduFaultName PDtbMissFault::_name = "dtb_miss_double";
692871Sktlim@umich.eduFaultVect PDtbMissFault::_vect = 0x0281;
702871Sktlim@umich.eduFaultStat PDtbMissFault::_count;
712871Sktlim@umich.edu
722871Sktlim@umich.eduFaultName DtbPageFault::_name = "dtb_page_fault";
732907Sktlim@umich.eduFaultVect DtbPageFault::_vect = 0x0381;
742871Sktlim@umich.eduFaultStat DtbPageFault::_count;
752292SN/A
762292SN/AFaultName DtbAcvFault::_name = "dtb_acv_fault";
772348SN/AFaultVect DtbAcvFault::_vect = 0x0381;
782307SN/AFaultStat DtbAcvFault::_count;
792348SN/A
802307SN/AFaultName DtbAlignmentFault::_name = "unalign";
812307SN/AFaultVect DtbAlignmentFault::_vect = 0x0301;
822292SN/AFaultStat DtbAlignmentFault::_count;
832292SN/A
842292SN/AFaultName ItbPageFault::_name = "itbmiss";
852292SN/AFaultVect ItbPageFault::_vect = 0x0181;
862292SN/AFaultStat ItbPageFault::_count;
872292SN/A
882292SN/AFaultName ItbAcvFault::_name = "iaccvio";
892292SN/AFaultVect ItbAcvFault::_vect = 0x0081;
902292SN/AFaultStat ItbAcvFault::_count;
912292SN/A
922292SN/AFaultName UnimplementedOpcodeFault::_name = "opdec";
932329SN/AFaultVect UnimplementedOpcodeFault::_vect = 0x0481;
942329SN/AFaultStat UnimplementedOpcodeFault::_count;
952292SN/A
962292SN/AFaultName FloatEnableFault::_name = "fen";
972292SN/AFaultVect FloatEnableFault::_vect = 0x0581;
982292SN/AFaultStat FloatEnableFault::_count;
992292SN/A
1002292SN/AFaultName PalFault::_name = "pal";
1012292SN/AFaultVect PalFault::_vect = 0x2001;
1022292SN/AFaultStat PalFault::_count;
1032292SN/A
1042292SN/AFaultName IntegerOverflowFault::_name = "intover";
1052292SN/AFaultVect IntegerOverflowFault::_vect = 0x0501;
1062292SN/AFaultStat IntegerOverflowFault::_count;
1072292SN/A
1082292SN/Avoid
1092292SN/AAlphaFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
1102329SN/A{
1112329SN/A    FaultBase::invoke(tc);
1122329SN/A    if (!FullSystem)
1132292SN/A        return;
1142292SN/A    countStat()++;
1152292SN/A
1162329SN/A    PCState pc = tc->pcState();
1172329SN/A
1182292SN/A    // exception restart address
1192292SN/A    if (setRestartAddress() || !(pc.pc() & 0x3))
1202292SN/A        tc->setMiscRegNoEffect(IPR_EXC_ADDR, pc.pc());
1212292SN/A
1222292SN/A    if (skipFaultingInstruction()) {
1232292SN/A        // traps...  skip faulting instruction.
1242292SN/A        tc->setMiscRegNoEffect(IPR_EXC_ADDR,
1252292SN/A                   tc->readMiscRegNoEffect(IPR_EXC_ADDR) + 4);
1262292SN/A    }
1272292SN/A
1282292SN/A    pc.set(tc->readMiscRegNoEffect(IPR_PAL_BASE) + vect());
1292292SN/A    tc->pcState(pc);
1302329SN/A}
1312329SN/A
1322292SN/Avoid
1332292SN/AArithmeticFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
1342292SN/A{
1352292SN/A    FaultBase::invoke(tc);
1362292SN/A    if (!FullSystem)
1372292SN/A        return;
1382292SN/A    panic("Arithmetic traps are unimplemented!");
1392329SN/A}
1402329SN/A
1412292SN/Avoid
1422292SN/ADtbFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
1432292SN/A{
1442292SN/A    if (FullSystem) {
1452329SN/A        // Set fault address and flags.  Even though we're modeling an
1462329SN/A        // EV5, we use the EV6 technique of not latching fault registers
1472292SN/A        // on VPTE loads (instead of locking the registers until IPR_VA is
1482292SN/A        // read, like the EV5).  The EV6 approach is cleaner and seems to
1492292SN/A        // work with EV5 PAL code, but not the other way around.
1502292SN/A        if (!tc->misspeculating() &&
1512292SN/A            reqFlags.noneSet(Request::VPTE | Request::PREFETCH)) {
1522292SN/A            // set VA register with faulting address
1532292SN/A            tc->setMiscRegNoEffect(IPR_VA, vaddr);
1542292SN/A
1552329SN/A            // set MM_STAT register flags
1562329SN/A            MachInst machInst = inst->machInst;
1572292SN/A            tc->setMiscRegNoEffect(IPR_MM_STAT,
1582292SN/A                (((Opcode(machInst) & 0x3f) << 11) |
1592329SN/A                 ((Ra(machInst) & 0x1f) << 6) |
1602329SN/A                 (flags & 0x3f)));
1612329SN/A
1622292SN/A            // set VA_FORM register with faulting formatted address
1632292SN/A            tc->setMiscRegNoEffect(IPR_VA_FORM,
1642292SN/A                tc->readMiscRegNoEffect(IPR_MVPTBR) | (vaddr.vpn() << 3));
1652292SN/A        }
1662292SN/A    }
1672292SN/A
1682292SN/A    AlphaFault::invoke(tc);
1692329SN/A}
1702329SN/A
1712329SN/Avoid
1722292SN/AItbFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
1732292SN/A{
1742292SN/A    if (FullSystem) {
1752292SN/A        if (!tc->misspeculating()) {
1762292SN/A            tc->setMiscRegNoEffect(IPR_ITB_TAG, pc);
1772292SN/A            tc->setMiscRegNoEffect(IPR_IFAULT_VA_FORM,
1782292SN/A                tc->readMiscRegNoEffect(IPR_IVPTBR) | (VAddr(pc).vpn() << 3));
1792292SN/A        }
1802292SN/A    }
1812329SN/A
1822329SN/A    AlphaFault::invoke(tc);
1832292SN/A}
1842292SN/A
1852292SN/Avoid
1862292SN/AItbPageFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
1872329SN/A{
1882329SN/A    if (FullSystem) {
1892292SN/A        ItbFault::invoke(tc);
1902292SN/A        return;
1912292SN/A    }
1922292SN/A
1932329SN/A    Process *p = tc->getProcessPtr();
1942329SN/A    TlbEntry entry;
1952292SN/A    bool success = p->pTable->lookup(pc, entry);
1962292SN/A    if (!success) {
1972292SN/A        panic("Tried to execute unmapped address %#x.\n", pc);
1982292SN/A    } else {
1992329SN/A        VAddr vaddr(pc);
2002329SN/A        tc->getITBPtr()->insert(vaddr.page(), entry);
2012292SN/A    }
2022292SN/A}
2032292SN/A
2042292SN/Avoid
2052292SN/ANDtbMissFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
2062292SN/A{
2072292SN/A    if (FullSystem) {
2082292SN/A        DtbFault::invoke(tc, inst);
2092292SN/A        return;
2102292SN/A    }
2112292SN/A
2122292SN/A    Process *p = tc->getProcessPtr();
2132292SN/A    TlbEntry entry;
2142292SN/A    bool success = p->pTable->lookup(vaddr, entry);
2152292SN/A    if (!success) {
2162292SN/A        if (p->fixupStackFault(vaddr))
2172292SN/A            success = p->pTable->lookup(vaddr, entry);
2182292SN/A    }
2192292SN/A    if (!success) {
2202292SN/A        panic("Tried to access unmapped address %#x.\n", (Addr)vaddr);
2212292SN/A    } else {
2222292SN/A        tc->getDTBPtr()->insert(vaddr.page(), entry);
2232292SN/A    }
2242292SN/A}
2252292SN/A
2262292SN/A} // namespace AlphaISA
2272292SN/A
2282292SN/A