faults.cc revision 4172:141705d83494
12292SN/A/*
22689Sktlim@umich.edu * 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/faults.hh"
332292SN/A#include "cpu/thread_context.hh"
342292SN/A#include "cpu/base.hh"
352292SN/A#include "base/trace.hh"
362292SN/A#if FULL_SYSTEM
372292SN/A#include "arch/alpha/ev5.hh"
382292SN/A#else
392292SN/A#include "sim/process.hh"
402669Sktlim@umich.edu#include "mem/page_table.hh"
415034Smilesck@eecs.umich.edu#endif
422292SN/A
432292SN/Anamespace AlphaISA
442292SN/A{
452292SN/A
462292SN/AFaultName MachineCheckFault::_name = "mchk";
472292SN/AFaultVect MachineCheckFault::_vect = 0x0401;
482292SN/AFaultStat MachineCheckFault::_count;
492292SN/A
502292SN/AFaultName AlignmentFault::_name = "unalign";
512292SN/AFaultVect AlignmentFault::_vect = 0x0301;
522292SN/AFaultStat AlignmentFault::_count;
532292SN/A
542292SN/AFaultName ResetFault::_name = "reset";
552292SN/AFaultVect ResetFault::_vect = 0x0001;
562292SN/AFaultStat ResetFault::_count;
572292SN/A
582292SN/AFaultName ArithmeticFault::_name = "arith";
592292SN/AFaultVect ArithmeticFault::_vect = 0x0501;
602292SN/AFaultStat ArithmeticFault::_count;
612292SN/A
622292SN/A#if !FULL_SYSTEM
632292SN/AFaultName PageTableFault::_name = "page_table_fault";
642292SN/AFaultVect PageTableFault::_vect = 0x0000;
652292SN/AFaultStat PageTableFault::_count;
662292SN/A#endif
672292SN/A
682292SN/AFaultName InterruptFault::_name = "interrupt";
692292SN/AFaultVect InterruptFault::_vect = 0x0101;
702292SN/AFaultStat InterruptFault::_count;
712292SN/A
722292SN/AFaultName NDtbMissFault::_name = "dtb_miss_single";
732292SN/AFaultVect NDtbMissFault::_vect = 0x0201;
742292SN/AFaultStat NDtbMissFault::_count;
752292SN/A
762292SN/AFaultName PDtbMissFault::_name = "dtb_miss_double";
772292SN/AFaultVect PDtbMissFault::_vect = 0x0281;
782292SN/AFaultStat PDtbMissFault::_count;
792292SN/A
802292SN/AFaultName DtbPageFault::_name = "dfault";
812292SN/AFaultVect DtbPageFault::_vect = 0x0381;
822292SN/AFaultStat DtbPageFault::_count;
832292SN/A
842292SN/AFaultName DtbAcvFault::_name = "dfault";
852292SN/AFaultVect DtbAcvFault::_vect = 0x0381;
862292SN/AFaultStat DtbAcvFault::_count;
872292SN/A
882292SN/AFaultName DtbAlignmentFault::_name = "unalign";
892292SN/AFaultVect DtbAlignmentFault::_vect = 0x0301;
902292SN/AFaultStat DtbAlignmentFault::_count;
912292SN/A
922292SN/AFaultName ItbMissFault::_name = "itbmiss";
932292SN/AFaultVect ItbMissFault::_vect = 0x0181;
942292SN/AFaultStat ItbMissFault::_count;
952292SN/A
962292SN/AFaultName ItbPageFault::_name = "itbmiss";
972292SN/AFaultVect ItbPageFault::_vect = 0x0181;
982292SN/AFaultStat ItbPageFault::_count;
992292SN/A
1002292SN/AFaultName ItbAcvFault::_name = "iaccvio";
1012292SN/AFaultVect ItbAcvFault::_vect = 0x0081;
1022292SN/AFaultStat ItbAcvFault::_count;
1032292SN/A
1042292SN/AFaultName UnimplementedOpcodeFault::_name = "opdec";
1052292SN/AFaultVect UnimplementedOpcodeFault::_vect = 0x0481;
1062292SN/AFaultStat UnimplementedOpcodeFault::_count;
1072292SN/A
1082292SN/AFaultName FloatEnableFault::_name = "fen";
1092292SN/AFaultVect FloatEnableFault::_vect = 0x0581;
1102292SN/AFaultStat FloatEnableFault::_count;
1112292SN/A
1122292SN/AFaultName PalFault::_name = "pal";
1132292SN/AFaultVect PalFault::_vect = 0x2001;
1142292SN/AFaultStat PalFault::_count;
1152292SN/A
1162292SN/AFaultName IntegerOverflowFault::_name = "intover";
1172292SN/AFaultVect IntegerOverflowFault::_vect = 0x0501;
1182292SN/AFaultStat IntegerOverflowFault::_count;
1192292SN/A
1205034Smilesck@eecs.umich.edu#if FULL_SYSTEM
1212292SN/A
1225034Smilesck@eecs.umich.eduvoid AlphaFault::invoke(ThreadContext * tc)
1232292SN/A{
1242292SN/A    FaultBase::invoke(tc);
1252292SN/A    countStat()++;
1262292SN/A
1272292SN/A    // exception restart address
1282292SN/A    if (setRestartAddress() || !(tc->readPC() & 0x3))
1292292SN/A        tc->setMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR, tc->readPC());
1302292SN/A
1312292SN/A    if (skipFaultingInstruction()) {
1322292SN/A        // traps...  skip faulting instruction.
1332292SN/A        tc->setMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR,
1342292SN/A                   tc->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR) + 4);
1352292SN/A    }
1362292SN/A
1372292SN/A    tc->setPC(tc->readMiscRegNoEffect(AlphaISA::IPR_PAL_BASE) + vect());
1382292SN/A    tc->setNextPC(tc->readPC() + sizeof(MachInst));
1392292SN/A}
1402327SN/A
1412292SN/Avoid ArithmeticFault::invoke(ThreadContext * tc)
1422292SN/A{
1432292SN/A    FaultBase::invoke(tc);
1442292SN/A    panic("Arithmetic traps are unimplemented!");
1452292SN/A}
1462292SN/A
1472292SN/Avoid DtbFault::invoke(ThreadContext * tc)
1482292SN/A{
1492292SN/A    // Set fault address and flags.  Even though we're modeling an
1502292SN/A    // EV5, we use the EV6 technique of not latching fault registers
1512292SN/A    // on VPTE loads (instead of locking the registers until IPR_VA is
1522292SN/A    // read, like the EV5).  The EV6 approach is cleaner and seems to
1532292SN/A    // work with EV5 PAL code, but not the other way around.
1542292SN/A    if (!tc->misspeculating()
1552292SN/A        && !(reqFlags & VPTE) && !(reqFlags & NO_FAULT)) {
1562292SN/A        // set VA register with faulting address
1572292SN/A        tc->setMiscRegNoEffect(AlphaISA::IPR_VA, vaddr);
1582292SN/A
1592292SN/A        // set MM_STAT register flags
1602307SN/A        tc->setMiscRegNoEffect(AlphaISA::IPR_MM_STAT,
1612348SN/A            (((EV5::Opcode(tc->getInst()) & 0x3f) << 11)
1622307SN/A             | ((EV5::Ra(tc->getInst()) & 0x1f) << 6)
1632348SN/A             | (flags & 0x3f)));
1642348SN/A
1652307SN/A        // set VA_FORM register with faulting formatted address
1662292SN/A        tc->setMiscRegNoEffect(AlphaISA::IPR_VA_FORM,
1672292SN/A            tc->readMiscRegNoEffect(AlphaISA::IPR_MVPTBR) | (vaddr.vpn() << 3));
1682292SN/A    }
169
170    AlphaFault::invoke(tc);
171}
172
173void ItbFault::invoke(ThreadContext * tc)
174{
175    if (!tc->misspeculating()) {
176        tc->setMiscRegNoEffect(AlphaISA::IPR_ITB_TAG, pc);
177        tc->setMiscRegNoEffect(AlphaISA::IPR_IFAULT_VA_FORM,
178                       tc->readMiscRegNoEffect(AlphaISA::IPR_IVPTBR) |
179                       (AlphaISA::VAddr(pc).vpn() << 3));
180    }
181
182    AlphaFault::invoke(tc);
183}
184
185#else //!FULL_SYSTEM
186
187void PageTableFault::invoke(ThreadContext *tc)
188{
189    Process *p = tc->getProcessPtr();
190
191    // address is higher than the stack region or in the current stack region
192    if (vaddr > p->stack_base || vaddr > p->stack_min)
193        FaultBase::invoke(tc);
194
195    // We've accessed the next page
196    if (vaddr > p->stack_min - PageBytes) {
197        DPRINTF(Stack,
198                "Increasing stack %#x:%#x to %#x:%#x because of access to %#x",
199                p->stack_min, p->stack_base, p->stack_min - PageBytes,
200                p->stack_base, vaddr);
201        p->stack_min -= PageBytes;
202        if (p->stack_base - p->stack_min > 8*1024*1024)
203            fatal("Over max stack size for one thread\n");
204        p->pTable->allocate(p->stack_min, PageBytes);
205    } else {
206        warn("Page fault on address %#x\n", vaddr);
207        FaultBase::invoke(tc);
208    }
209}
210
211#endif
212
213} // namespace AlphaISA
214
215