faults.cc revision 12461
17090SN/A/*
27090SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
37090SN/A * All rights reserved.
47090SN/A *
57090SN/A * Redistribution and use in source and binary forms, with or without
67090SN/A * modification, are permitted provided that the following conditions are
77090SN/A * met: redistributions of source code must retain the above copyright
87090SN/A * notice, this list of conditions and the following disclaimer;
97090SN/A * redistributions in binary form must reproduce the above copyright
107090SN/A * notice, this list of conditions and the following disclaimer in the
117090SN/A * documentation and/or other materials provided with the distribution;
127090SN/A * neither the name of the copyright holders nor the names of its
134486SN/A * contributors may be used to endorse or promote products derived from
144486SN/A * this software without specific prior written permission.
154486SN/A *
164486SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
174486SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
184486SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
194486SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
204486SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
214486SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
224486SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
234486SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
244486SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
254486SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
264486SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
274486SN/A *
284486SN/A * Authors: Gabe Black
294486SN/A *          Kevin Lim
304486SN/A */
314486SN/A
324486SN/A#include "arch/alpha/faults.hh"
334486SN/A
344486SN/A#include "arch/alpha/ev5.hh"
354486SN/A#include "arch/alpha/tlb.hh"
364486SN/A#include "base/trace.hh"
374486SN/A#include "cpu/base.hh"
384486SN/A#include "cpu/thread_context.hh"
397584SAli.Saidi@arm.com#include "mem/page_table.hh"
407584SAli.Saidi@arm.com#include "sim/full_system.hh"
417754SWilliam.Wang@arm.com#include "sim/process.hh"
424486SN/A
433630SN/Anamespace AlphaISA {
443630SN/A
457587SAli.Saidi@arm.comFaultName MachineCheckFault::_name = "mchk";
468212SAli.Saidi@ARM.comFaultVect MachineCheckFault::_vect = 0x0401;
475478SN/AFaultStat MachineCheckFault::_count;
485478SN/A
497584SAli.Saidi@arm.comFaultName AlignmentFault::_name = "unalign";
503630SN/AFaultVect AlignmentFault::_vect = 0x0301;
517584SAli.Saidi@arm.comFaultStat AlignmentFault::_count;
527584SAli.Saidi@arm.com
537584SAli.Saidi@arm.comFaultName ResetFault::_name = "reset";
547584SAli.Saidi@arm.comFaultVect ResetFault::_vect = 0x0001;
553898SN/AFaultStat ResetFault::_count;
567950SAli.Saidi@ARM.com
577950SAli.Saidi@ARM.comFaultName ArithmeticFault::_name = "arith";
587950SAli.Saidi@ARM.comFaultVect ArithmeticFault::_vect = 0x0501;
597950SAli.Saidi@ARM.comFaultStat ArithmeticFault::_count;
607950SAli.Saidi@ARM.com
617950SAli.Saidi@ARM.comFaultName InterruptFault::_name = "interrupt";
627950SAli.Saidi@ARM.comFaultVect InterruptFault::_vect = 0x0101;
637950SAli.Saidi@ARM.comFaultStat InterruptFault::_count;
647587SAli.Saidi@arm.com
657587SAli.Saidi@arm.comFaultName NDtbMissFault::_name = "dtb_miss_single";
667587SAli.Saidi@arm.comFaultVect NDtbMissFault::_vect = 0x0201;
677753SWilliam.Wang@arm.comFaultStat NDtbMissFault::_count;
687753SWilliam.Wang@arm.com
697753SWilliam.Wang@arm.comFaultName PDtbMissFault::_name = "dtb_miss_double";
707753SWilliam.Wang@arm.comFaultVect PDtbMissFault::_vect = 0x0281;
717587SAli.Saidi@arm.comFaultStat PDtbMissFault::_count;
727587SAli.Saidi@arm.com
737584SAli.Saidi@arm.comFaultName DtbPageFault::_name = "dtb_page_fault";
747584SAli.Saidi@arm.comFaultVect DtbPageFault::_vect = 0x0381;
757584SAli.Saidi@arm.comFaultStat DtbPageFault::_count;
767584SAli.Saidi@arm.com
777584SAli.Saidi@arm.comFaultName DtbAcvFault::_name = "dtb_acv_fault";
787584SAli.Saidi@arm.comFaultVect DtbAcvFault::_vect = 0x0381;
797584SAli.Saidi@arm.comFaultStat DtbAcvFault::_count;
807584SAli.Saidi@arm.com
817584SAli.Saidi@arm.comFaultName DtbAlignmentFault::_name = "unalign";
827584SAli.Saidi@arm.comFaultVect DtbAlignmentFault::_vect = 0x0301;
837584SAli.Saidi@arm.comFaultStat DtbAlignmentFault::_count;
847584SAli.Saidi@arm.com
857584SAli.Saidi@arm.comFaultName ItbPageFault::_name = "itbmiss";
867584SAli.Saidi@arm.comFaultVect ItbPageFault::_vect = 0x0181;
877584SAli.Saidi@arm.comFaultStat ItbPageFault::_count;
887584SAli.Saidi@arm.com
897584SAli.Saidi@arm.comFaultName ItbAcvFault::_name = "iaccvio";
907584SAli.Saidi@arm.comFaultVect ItbAcvFault::_vect = 0x0081;
917584SAli.Saidi@arm.comFaultStat ItbAcvFault::_count;
927584SAli.Saidi@arm.com
937584SAli.Saidi@arm.comFaultName UnimplementedOpcodeFault::_name = "opdec";
947584SAli.Saidi@arm.comFaultVect UnimplementedOpcodeFault::_vect = 0x0481;
957584SAli.Saidi@arm.comFaultStat UnimplementedOpcodeFault::_count;
967584SAli.Saidi@arm.com
977584SAli.Saidi@arm.comFaultName FloatEnableFault::_name = "fen";
987584SAli.Saidi@arm.comFaultVect FloatEnableFault::_vect = 0x0581;
997584SAli.Saidi@arm.comFaultStat FloatEnableFault::_count;
1007584SAli.Saidi@arm.com
1017584SAli.Saidi@arm.com/* We use the same fault vector, as for the guest system these should be the
1027584SAli.Saidi@arm.com * same, but for host purposes, having differentiation is helpful for
1037584SAli.Saidi@arm.com * debug/monitorization purposes. */
1047584SAli.Saidi@arm.comFaultName VectorEnableFault::_name = "ven";
1057584SAli.Saidi@arm.comFaultVect VectorEnableFault::_vect = 0x0581;
1067950SAli.Saidi@ARM.comFaultStat VectorEnableFault::_count;
1077754SWilliam.Wang@arm.com
1087950SAli.Saidi@ARM.comFaultName PalFault::_name = "pal";
1097950SAli.Saidi@ARM.comFaultVect PalFault::_vect = 0x2001;
1107950SAli.Saidi@ARM.comFaultStat PalFault::_count;
1117754SWilliam.Wang@arm.com
1127754SWilliam.Wang@arm.comFaultName IntegerOverflowFault::_name = "intover";
1137753SWilliam.Wang@arm.comFaultVect IntegerOverflowFault::_vect = 0x0501;
1147753SWilliam.Wang@arm.comFaultStat IntegerOverflowFault::_count;
1157753SWilliam.Wang@arm.com
1167950SAli.Saidi@ARM.comvoid
1177753SWilliam.Wang@arm.comAlphaFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
1187753SWilliam.Wang@arm.com{
1197584SAli.Saidi@arm.com    FaultBase::invoke(tc);
1207584SAli.Saidi@arm.com    if (!FullSystem)
1213630SN/A        return;
1223630SN/A    countStat()++;
1237753SWilliam.Wang@arm.com
1247753SWilliam.Wang@arm.com    PCState pc = tc->pcState();
1257753SWilliam.Wang@arm.com
1267584SAli.Saidi@arm.com    // exception restart address
1277584SAli.Saidi@arm.com    if (setRestartAddress() || !(pc.pc() & 0x3))
1287584SAli.Saidi@arm.com        tc->setMiscRegNoEffect(IPR_EXC_ADDR, pc.pc());
1297584SAli.Saidi@arm.com
1307584SAli.Saidi@arm.com    if (skipFaultingInstruction()) {
1317584SAli.Saidi@arm.com        // traps...  skip faulting instruction.
1327753SWilliam.Wang@arm.com        tc->setMiscRegNoEffect(IPR_EXC_ADDR,
1337754SWilliam.Wang@arm.com                   tc->readMiscRegNoEffect(IPR_EXC_ADDR) + 4);
1347950SAli.Saidi@ARM.com    }
1358212SAli.Saidi@ARM.com
1368212SAli.Saidi@ARM.com    pc.set(tc->readMiscRegNoEffect(IPR_PAL_BASE) + vect());
1378212SAli.Saidi@ARM.com    tc->pcState(pc);
1388212SAli.Saidi@ARM.com}
1398212SAli.Saidi@ARM.com
1408212SAli.Saidi@ARM.comvoid
1417584SAli.Saidi@arm.comArithmeticFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
1427731SAli.Saidi@ARM.com{
1437696SAli.Saidi@ARM.com    FaultBase::invoke(tc);
1447696SAli.Saidi@ARM.com    if (!FullSystem)
1457696SAli.Saidi@ARM.com        return;
1467696SAli.Saidi@ARM.com    panic("Arithmetic traps are unimplemented!");
1477696SAli.Saidi@ARM.com}
1487696SAli.Saidi@ARM.com
1497696SAli.Saidi@ARM.comvoid
1507696SAli.Saidi@ARM.comDtbFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
1517696SAli.Saidi@ARM.com{
1527696SAli.Saidi@ARM.com    if (FullSystem) {
1537696SAli.Saidi@ARM.com        // Set fault address and flags.  Even though we're modeling an
1547696SAli.Saidi@ARM.com        // EV5, we use the EV6 technique of not latching fault registers
1557696SAli.Saidi@ARM.com        // on VPTE loads (instead of locking the registers until IPR_VA is
1567696SAli.Saidi@ARM.com        // read, like the EV5).  The EV6 approach is cleaner and seems to
1577696SAli.Saidi@ARM.com        // work with EV5 PAL code, but not the other way around.
1587696SAli.Saidi@ARM.com        if (reqFlags.noneSet(AlphaRequestFlags::VPTE | Request::PREFETCH)) {
1597696SAli.Saidi@ARM.com            // set VA register with faulting address
1607696SAli.Saidi@ARM.com            tc->setMiscRegNoEffect(IPR_VA, vaddr);
1617696SAli.Saidi@ARM.com
1627696SAli.Saidi@ARM.com            // set MM_STAT register flags
1637696SAli.Saidi@ARM.com            MachInst machInst = inst->machInst;
1647696SAli.Saidi@ARM.com            tc->setMiscRegNoEffect(IPR_MM_STAT,
1657696SAli.Saidi@ARM.com                (((Opcode(machInst) & 0x3f) << 11) |
1667696SAli.Saidi@ARM.com                 ((Ra(machInst) & 0x1f) << 6) |
1677696SAli.Saidi@ARM.com                 (flags & 0x3f)));
1687696SAli.Saidi@ARM.com
1697696SAli.Saidi@ARM.com            // set VA_FORM register with faulting formatted address
1707696SAli.Saidi@ARM.com            tc->setMiscRegNoEffect(IPR_VA_FORM,
1717696SAli.Saidi@ARM.com                tc->readMiscRegNoEffect(IPR_MVPTBR) | (vaddr.vpn() << 3));
1727696SAli.Saidi@ARM.com        }
1737696SAli.Saidi@ARM.com    }
1747753SWilliam.Wang@arm.com
1757754SWilliam.Wang@arm.com    AlphaFault::invoke(tc);
1767754SWilliam.Wang@arm.com}
1778212SAli.Saidi@ARM.com
1787696SAli.Saidi@ARM.comvoid
1797696SAli.Saidi@ARM.comItbFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
1807696SAli.Saidi@ARM.com{
1817696SAli.Saidi@ARM.com    if (FullSystem) {
1827696SAli.Saidi@ARM.com        tc->setMiscRegNoEffect(IPR_ITB_TAG, pc);
1837696SAli.Saidi@ARM.com        tc->setMiscRegNoEffect(IPR_IFAULT_VA_FORM,
1847696SAli.Saidi@ARM.com            tc->readMiscRegNoEffect(IPR_IVPTBR) | (VAddr(pc).vpn() << 3));
1857696SAli.Saidi@ARM.com    }
1867696SAli.Saidi@ARM.com
1877696SAli.Saidi@ARM.com    AlphaFault::invoke(tc);
1887696SAli.Saidi@ARM.com}
1897696SAli.Saidi@ARM.com
1907696SAli.Saidi@ARM.comvoid
1917696SAli.Saidi@ARM.comItbPageFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
1927696SAli.Saidi@ARM.com{
1937696SAli.Saidi@ARM.com    if (FullSystem) {
1947696SAli.Saidi@ARM.com        ItbFault::invoke(tc);
1957754SWilliam.Wang@arm.com        return;
1967754SWilliam.Wang@arm.com    }
1977754SWilliam.Wang@arm.com
1987696SAli.Saidi@ARM.com    Process *p = tc->getProcessPtr();
1997696SAli.Saidi@ARM.com    const EmulationPageTable::Entry *pte = p->pTable->lookup(pc);
2007696SAli.Saidi@ARM.com    panic_if(!pte, "Tried to execute unmapped address %#x.\n", pc);
2017696SAli.Saidi@ARM.com
2027696SAli.Saidi@ARM.com    VAddr vaddr(pc);
2037696SAli.Saidi@ARM.com    TlbEntry entry(p->pTable->pid(), vaddr.page(), pte->paddr,
2047754SWilliam.Wang@arm.com                   pte->flags & EmulationPageTable::Uncacheable,
2057754SWilliam.Wang@arm.com                   pte->flags & EmulationPageTable::ReadOnly);
2067950SAli.Saidi@ARM.com    dynamic_cast<TLB *>(tc->getITBPtr())->insert(vaddr.page(), entry);
2077696SAli.Saidi@ARM.com}
2087696SAli.Saidi@ARM.com
2097584SAli.Saidi@arm.comvoid
2107584SAli.Saidi@arm.comNDtbMissFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
2117584SAli.Saidi@arm.com{
2127584SAli.Saidi@arm.com    if (FullSystem) {
2137584SAli.Saidi@arm.com        DtbFault::invoke(tc, inst);
2147584SAli.Saidi@arm.com        return;
2157584SAli.Saidi@arm.com    }
2167584SAli.Saidi@arm.com
2177584SAli.Saidi@arm.com    Process *p = tc->getProcessPtr();
2187584SAli.Saidi@arm.com    const EmulationPageTable::Entry *pte = p->pTable->lookup(vaddr);
2197584SAli.Saidi@arm.com    if (!pte && p->fixupStackFault(vaddr))
2207584SAli.Saidi@arm.com        pte = p->pTable->lookup(vaddr);
2217584SAli.Saidi@arm.com    panic_if(!pte, "Tried to access unmapped address %#x.\n", (Addr)vaddr);
2227584SAli.Saidi@arm.com    TlbEntry entry(p->pTable->pid(), vaddr.page(), pte->paddr,
2237584SAli.Saidi@arm.com                   pte->flags & EmulationPageTable::Uncacheable,
2247584SAli.Saidi@arm.com                   pte->flags & EmulationPageTable::ReadOnly);
2257584SAli.Saidi@arm.com    dynamic_cast<TLB *>(tc->getDTBPtr())->insert(vaddr.page(), entry);
2267584SAli.Saidi@arm.com}
2274104SN/A
2284104SN/A} // namespace AlphaISA
2297584SAli.Saidi@arm.com
2307584SAli.Saidi@arm.com