diff options
Diffstat (limited to 'arch/alpha')
35 files changed, 2171 insertions, 337 deletions
diff --git a/arch/alpha/SConscript b/arch/alpha/SConscript index 050dfb9cf..03d73eef7 100644 --- a/arch/alpha/SConscript +++ b/arch/alpha/SConscript @@ -50,7 +50,7 @@ base_sources = Split(''' # Full-system sources full_system_sources = Split(''' - alpha_memory.cc + tlb.cc arguments.cc ev5.cc osfpal.cc @@ -61,9 +61,10 @@ full_system_sources = Split(''' # Syscall emulation (non-full-system) sources syscall_emulation_sources = Split(''' - alpha_common_syscall_emul.cc - alpha_linux_process.cc - alpha_tru64_process.cc + common_syscall_emul.cc + linux_process.cc + tru64_process.cc + process.cc ''') # Set up complete list of sources based on configuration. diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 9d2ff4db7..11faf1850 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -26,7 +26,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "arch/alpha/alpha_memory.hh" +#include "arch/alpha/tlb.hh" #include "arch/alpha/isa_traits.hh" #include "arch/alpha/osfpal.hh" #include "base/kgdb.h" @@ -47,66 +47,22 @@ using namespace EV5; //////////////////////////////////////////////////////////////////////// // -// -// -void -AlphaISA::swap_palshadow(RegFile *regs, bool use_shadow) -{ - if (regs->pal_shadow == use_shadow) - panic("swap_palshadow: wrong PAL shadow state"); - - regs->pal_shadow = use_shadow; - - for (int i = 0; i < NumIntRegs; i++) { - if (reg_redir[i]) { - IntReg temp = regs->intRegFile[i]; - regs->intRegFile[i] = regs->palregs[i]; - regs->palregs[i] = temp; - } - } -} - -//////////////////////////////////////////////////////////////////////// -// // Machine dependent functions // void AlphaISA::initCPU(ExecContext *xc, int cpuId) { initIPRs(xc, cpuId); - // CPU comes up with PAL regs enabled - swap_palshadow(regs, true); xc->setIntReg(16, cpuId); xc->setIntReg(0, cpuId); - xc->setPC(xc->readMiscReg(IPR_PAL_BASE) + fault_addr(ResetFault)); + xc->setPC(xc->readMiscReg(IPR_PAL_BASE) + (new ResetFault)->vect()); xc->setNextPC(xc->readPC() + sizeof(MachInst)); } //////////////////////////////////////////////////////////////////////// // -// alpha exceptions - value equals trap address, update with MD_FAULT_TYPE -// -const Addr -AlphaISA::fault_addr(Fault fault) -{ - //Check for the system wide faults - if(fault == NoFault) return 0x0000; - else if(fault == MachineCheckFault) return 0x0401; - else if(fault == AlignmentFault) return 0x0301; - //Deal with the alpha specific faults - return ((AlphaFault*)fault)->vect; -}; - -const int AlphaISA::reg_redir[AlphaISA::NumIntRegs] = { - /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, - /* 8 */ 1, 1, 1, 1, 1, 1, 1, 0, - /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, - /* 24 */ 0, 1, 0, 0, 0, 0, 0, 0 }; - -//////////////////////////////////////////////////////////////////////// -// // // void @@ -163,7 +119,7 @@ AlphaISA::processInterrupts(CPU *cpu) if (ipl && ipl > cpu->readMiscReg(IPR_IPLR)) { cpu->setMiscReg(IPR_ISR, summary); cpu->setMiscReg(IPR_INTID, ipl); - cpu->trap(InterruptFault); + cpu->trap(new InterruptFault); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", cpu->readMiscReg(IPR_IPLR), ipl, summary); } @@ -181,78 +137,17 @@ AlphaISA::zeroRegisters(CPU *cpu) cpu->cpuXC->setFloatRegDouble(ZeroReg, 0.0); } -void -CPUExecContext::ev5_trap(Fault fault) -{ - DPRINTF(Fault, "Fault %s at PC: %#x\n", fault->name, regs.pc); - cpu->recordEvent(csprintf("Fault %s", fault->name)); - - assert(!misspeculating()); - cpu->kernelStats->fault(fault); - - if (fault == ArithmeticFault) - panic("Arithmetic traps are unimplemented!"); - - // exception restart address - if (fault != InterruptFault || !inPalMode()) - setMiscReg(AlphaISA::IPR_EXC_ADDR, regs.pc); - - if (fault == PalFault || fault == ArithmeticFault /* || - fault == InterruptFault && !inPalMode() */) { - // traps... skip faulting instruction - setMiscReg(AlphaISA::IPR_EXC_ADDR, - readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4); - } - - if (!inPalMode()) - AlphaISA::swap_palshadow(®s, true); - - regs.pc = readMiscReg(AlphaISA::IPR_PAL_BASE) + AlphaISA::fault_addr(fault); - regs.npc = regs.pc + sizeof(MachInst); -} - - -void -AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) -{ - bool use_pc = (fault == NoFault); - - if (fault == ArithmeticFault) - panic("arithmetic faults NYI..."); - - // compute exception restart address - if (use_pc || fault == PalFault || fault == ArithmeticFault) { - // traps... skip faulting instruction - regs->miscRegs.setReg(IPR_EXC_ADDR, regs->pc + 4); - } else { - // fault, post fault at excepting instruction - regs->miscRegs.setReg(IPR_EXC_ADDR, regs->pc); - } - - // jump to expection address (PAL PC bit set here as well...) - if (!use_pc) - regs->npc = regs->miscRegs.readReg(IPR_PAL_BASE) + - fault_addr(fault); - else - regs->npc = regs->miscRegs.readReg(IPR_PAL_BASE) + pc; - - // that's it! (orders of magnitude less painful than x86) -} - Fault CPUExecContext::hwrei() { if (!inPalMode()) - return UnimplementedOpcodeFault; + return new UnimplementedOpcodeFault; setNextPC(readMiscReg(AlphaISA::IPR_EXC_ADDR)); if (!misspeculating()) { cpu->kernelStats->hwrei(); - if ((readMiscReg(AlphaISA::IPR_EXC_ADDR) & 1) == 0) - AlphaISA::swap_palshadow(®s, false); - cpu->checkInterrupts = true; } @@ -354,12 +249,12 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc) case AlphaISA::IPR_DTB_IAP: case AlphaISA::IPR_ITB_IA: case AlphaISA::IPR_ITB_IAP: - fault = UnimplementedOpcodeFault; + fault = new UnimplementedOpcodeFault; break; default: // invalid IPR - fault = UnimplementedOpcodeFault; + fault = new UnimplementedOpcodeFault; break; } @@ -523,7 +418,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) case AlphaISA::IPR_ITB_PTE_TEMP: case AlphaISA::IPR_DTB_PTE_TEMP: // read-only registers - return UnimplementedOpcodeFault; + return new UnimplementedOpcodeFault; case AlphaISA::IPR_HWINT_CLR: case AlphaISA::IPR_SL_XMIT: @@ -627,7 +522,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) default: // invalid IPR - return UnimplementedOpcodeFault; + return new UnimplementedOpcodeFault; } // no error... diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index fa4950198..84f785c0a 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -27,37 +27,124 @@ */ #include "arch/alpha/faults.hh" +#include "cpu/exec_context.hh" +#include "cpu/base.hh" +#include "base/trace.hh" +#include "kern/kernel_stats.hh" -ResetFaultType * const ResetFault = - new ResetFaultType("reset", 1, 0x0001); -ArithmeticFaultType * const ArithmeticFault = - new ArithmeticFaultType("arith", 3, 0x0501); -InterruptFaultType * const InterruptFault = - new InterruptFaultType("interrupt", 4, 0x0101); -NDtbMissFaultType * const NDtbMissFault = - new NDtbMissFaultType("dtb_miss_single", 5, 0x0201); -PDtbMissFaultType * const PDtbMissFault = - new PDtbMissFaultType("dtb_miss_double", 6, 0x0281); -DtbPageFaultType * const DtbPageFault = - new DtbPageFaultType("dfault", 8, 0x0381); -DtbAcvFaultType * const DtbAcvFault = - new DtbAcvFaultType("dfault", 9, 0x0381); -ItbMissFaultType * const ItbMissFault = - new ItbMissFaultType("itbmiss", 10, 0x0181); -ItbPageFaultType * const ItbPageFault = - new ItbPageFaultType("itbmiss", 11, 0x0181); -ItbAcvFaultType * const ItbAcvFault = - new ItbAcvFaultType("iaccvio", 12, 0x0081); -UnimplementedOpcodeFaultType * const UnimplementedOpcodeFault = - new UnimplementedOpcodeFaultType("opdec", 13, 0x0481); -FloatEnableFaultType * const FloatEnableFault = - new FloatEnableFaultType("fen", 14, 0x0581); -PalFaultType * const PalFault = - new PalFaultType("pal", 15, 0x2001); -IntegerOverflowFaultType * const IntegerOverflowFault = - new IntegerOverflowFaultType("intover", 16, 0x0501); - -Fault * ListOfFaults[] = { +namespace AlphaISA +{ + +FaultName MachineCheckFault::_name = "mchk"; +FaultVect MachineCheckFault::_vect = 0x0401; +FaultStat MachineCheckFault::_stat; + +FaultName AlignmentFault::_name = "unalign"; +FaultVect AlignmentFault::_vect = 0x0301; +FaultStat AlignmentFault::_stat; + +FaultName ResetFault::_name = "reset"; +FaultVect ResetFault::_vect = 0x0001; +FaultStat ResetFault::_stat; + +FaultName ArithmeticFault::_name = "arith"; +FaultVect ArithmeticFault::_vect = 0x0501; +FaultStat ArithmeticFault::_stat; + +FaultName InterruptFault::_name = "interrupt"; +FaultVect InterruptFault::_vect = 0x0101; +FaultStat InterruptFault::_stat; + +FaultName NDtbMissFault::_name = "dtb_miss_single"; +FaultVect NDtbMissFault::_vect = 0x0201; +FaultStat NDtbMissFault::_stat; + +FaultName PDtbMissFault::_name = "dtb_miss_double"; +FaultVect PDtbMissFault::_vect = 0x0281; +FaultStat PDtbMissFault::_stat; + +FaultName DtbPageFault::_name = "dfault"; +FaultVect DtbPageFault::_vect = 0x0381; +FaultStat DtbPageFault::_stat; + +FaultName DtbAcvFault::_name = "dfault"; +FaultVect DtbAcvFault::_vect = 0x0381; +FaultStat DtbAcvFault::_stat; + +FaultName ItbMissFault::_name = "itbmiss"; +FaultVect ItbMissFault::_vect = 0x0181; +FaultStat ItbMissFault::_stat; + +FaultName ItbPageFault::_name = "itbmiss"; +FaultVect ItbPageFault::_vect = 0x0181; +FaultStat ItbPageFault::_stat; + +FaultName ItbAcvFault::_name = "iaccvio"; +FaultVect ItbAcvFault::_vect = 0x0081; +FaultStat ItbAcvFault::_stat; + +FaultName UnimplementedOpcodeFault::_name = "opdec"; +FaultVect UnimplementedOpcodeFault::_vect = 0x0481; +FaultStat UnimplementedOpcodeFault::_stat; + +FaultName FloatEnableFault::_name = "fen"; +FaultVect FloatEnableFault::_vect = 0x0581; +FaultStat FloatEnableFault::_stat; + +FaultName PalFault::_name = "pal"; +FaultVect PalFault::_vect = 0x2001; +FaultStat PalFault::_stat; + +FaultName IntegerOverflowFault::_name = "intover"; +FaultVect IntegerOverflowFault::_vect = 0x0501; +FaultStat IntegerOverflowFault::_stat; + +#if FULL_SYSTEM + +void AlphaFault::invoke(ExecContext * xc) +{ + DPRINTF(Fault, "Fault %s at PC: %#x\n", name(), xc->regs.pc); + xc->cpu->recordEvent(csprintf("Fault %s", name())); + + assert(!xc->misspeculating()); + xc->kernelStats->fault(this); + + // exception restart address + if (setRestartAddress() || !xc->inPalMode()) + xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, xc->regs.pc); + + if (skipFaultingInstruction()) { + // traps... skip faulting instruction. + xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, + xc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4); + } + + xc->regs.pc = xc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect(); + xc->regs.npc = xc->regs.pc + sizeof(MachInst); +} + +void ArithmeticFault::invoke(ExecContext * xc) +{ + DPRINTF(Fault, "Fault %s at PC: %#x\n", name(), xc->regs.pc); + xc->cpu->recordEvent(csprintf("Fault %s", name())); + + assert(!xc->misspeculating()); + xc->kernelStats->fault(this); + + panic("Arithmetic traps are unimplemented!"); +} + + +/*void ArithmeticFault::invoke(ExecContext * xc) +{ + panic("Arithmetic traps are unimplemented!"); +}*/ + +#endif + +} // namespace AlphaISA + +/*Fault * ListOfFaults[] = { (Fault *)&NoFault, (Fault *)&ResetFault, (Fault *)&MachineCheckFault, @@ -77,4 +164,4 @@ Fault * ListOfFaults[] = { (Fault *)&IntegerOverflowFault, }; -int NumFaults = sizeof(ListOfFaults) / sizeof(Fault *); +int NumFaults = sizeof(ListOfFaults) / sizeof(Fault *);*/ diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index 3e25adc4e..c4a72e07c 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -30,131 +30,239 @@ #define __ALPHA_FAULTS_HH__ #include "sim/faults.hh" -#include "arch/isa_traits.hh" //For the Addr type -class AlphaFault : public FaultBase +// The design of the "name" and "vect" functions is in sim/faults.hh + +namespace AlphaISA +{ + +typedef const Addr FaultVect; + +class AlphaFault : public virtual FaultBase { + protected: + virtual bool skipFaultingInstruction() {return false;} + virtual bool setRestartAddress() {return true;} public: - AlphaFault(char * newName, int newId, Addr newVect) - : FaultBase(newName, newId), vect(newVect) - {;} +#if FULL_SYSTEM + void invoke(ExecContext * xc); +#endif + virtual FaultVect vect() = 0; +}; - Addr vect; +class MachineCheckFault : public AlphaFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} + bool isMachineCheckFault() {return true;} }; -extern class ResetFaultType : public AlphaFault +class AlignmentFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - ResetFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const ResetFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} + bool isAlignmentFault() {return true;} +}; -extern class ArithmeticFaultType : public AlphaFault +static inline Fault genMachineCheckFault() { + return new MachineCheckFault; +} + +static inline Fault genAlignmentFault() +{ + return new AlignmentFault; +} + +class ResetFault : public AlphaFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - ArithmeticFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const ArithmeticFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class InterruptFaultType : public AlphaFault +class ArithmeticFault : public AlphaFault { + protected: + bool skipFaultingInstruction() {return true;} + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - InterruptFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const InterruptFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +#if FULL_SYSTEM + void invoke(ExecContext * xc); +#endif +}; -extern class NDtbMissFaultType : public AlphaFault +class InterruptFault : public AlphaFault { + protected: + bool setRestartAddress() {return false;} + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - NDtbMissFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const NDtbMissFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class PDtbMissFaultType : public AlphaFault +class NDtbMissFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - PDtbMissFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const PDtbMissFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class DtbPageFaultType : public AlphaFault +class PDtbMissFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - DtbPageFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const DtbPageFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class DtbAcvFaultType : public AlphaFault +class DtbPageFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - DtbAcvFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const DtbAcvFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; + +class DtbAcvFault : public AlphaFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class ItbMissFaultType : public AlphaFault +class ItbMissFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - ItbMissFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const ItbMissFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class ItbPageFaultType : public AlphaFault +class ItbPageFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - ItbPageFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const ItbPageFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class ItbAcvFaultType : public AlphaFault +class ItbAcvFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - ItbAcvFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const ItbAcvFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class UnimplementedOpcodeFaultType : public AlphaFault +class UnimplementedOpcodeFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - UnimplementedOpcodeFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const UnimplementedOpcodeFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class FloatEnableFaultType : public AlphaFault +class FloatEnableFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - FloatEnableFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const FloatEnableFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class PalFaultType : public AlphaFault +class PalFault : public AlphaFault { + protected: + bool skipFaultingInstruction() {return true;} + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - PalFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const PalFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class IntegerOverflowFaultType : public AlphaFault +class IntegerOverflowFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - IntegerOverflowFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const IntegerOverflowFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern Fault * ListOfFaults[]; -extern int NumFaults; +} // AlphaISA namespace #endif // __FAULTS_HH__ diff --git a/arch/alpha/freebsd/system.cc b/arch/alpha/freebsd/system.cc new file mode 100644 index 000000000..e32053afd --- /dev/null +++ b/arch/alpha/freebsd/system.cc @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * Modifications for the FreeBSD kernel. + * Based on kern/linux/linux_system.cc. + * + */ + +#include "arch/alpha/system.hh" +#include "arch/alpha/freebsd/system.hh" +#include "base/loader/symtab.hh" +#include "cpu/exec_context.hh" +#include "mem/functional/memory_control.hh" +#include "mem/functional/physical.hh" +#include "arch/isa_traits.hh" +#include "sim/builder.hh" +#include "sim/byteswap.hh" +#include "arch/vtophys.hh" + +#define TIMER_FREQUENCY 1193180 + +using namespace std; +using namespace AlphaISA; + +FreebsdAlphaSystem::FreebsdAlphaSystem(Params *p) + : AlphaSystem(p) +{ + /** + * Any time DELAY is called just skip the function. + * Shouldn't we actually emulate the delay? + */ + skipDelayEvent = addKernelFuncEvent<SkipFuncEvent>("DELAY"); + skipCalibrateClocks = + addKernelFuncEvent<SkipCalibrateClocksEvent>("calibrate_clocks"); +} + + +FreebsdAlphaSystem::~FreebsdAlphaSystem() +{ + delete skipDelayEvent; + delete skipCalibrateClocks; +} + + +void +FreebsdAlphaSystem::doCalibrateClocks(ExecContext *xc) +{ + Addr ppc_vaddr = 0; + Addr timer_vaddr = 0; + Addr ppc_paddr = 0; + Addr timer_paddr = 0; + + ppc_vaddr = (Addr)xc->readIntReg(ArgumentReg1); + timer_vaddr = (Addr)xc->readIntReg(ArgumentReg2); + + ppc_paddr = vtophys(physmem, ppc_vaddr); + timer_paddr = vtophys(physmem, timer_vaddr); + + uint8_t *ppc = physmem->dma_addr(ppc_paddr, sizeof(uint32_t)); + uint8_t *timer = physmem->dma_addr(timer_paddr, sizeof(uint32_t)); + + *(uint32_t *)ppc = htog((uint32_t)Clock::Frequency); + *(uint32_t *)timer = htog((uint32_t)TIMER_FREQUENCY); +} + + +void +FreebsdAlphaSystem::SkipCalibrateClocksEvent::process(ExecContext *xc) +{ + SkipFuncEvent::process(xc); + ((FreebsdAlphaSystem *)xc->getSystemPtr())->doCalibrateClocks(xc); +} + + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(FreebsdAlphaSystem) + + Param<Tick> boot_cpu_frequency; + SimObjectParam<MemoryController *> memctrl; + SimObjectParam<PhysicalMemory *> physmem; + + Param<string> kernel; + Param<string> console; + Param<string> pal; + + Param<string> boot_osflags; + Param<string> readfile; + Param<unsigned int> init_param; + + Param<uint64_t> system_type; + Param<uint64_t> system_rev; + + Param<bool> bin; + VectorParam<string> binned_fns; + Param<bool> bin_int; + +END_DECLARE_SIM_OBJECT_PARAMS(FreebsdAlphaSystem) + +BEGIN_INIT_SIM_OBJECT_PARAMS(FreebsdAlphaSystem) + + INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"), + INIT_PARAM(memctrl, "memory controller"), + INIT_PARAM(physmem, "phsyical memory"), + INIT_PARAM(kernel, "file that contains the kernel code"), + INIT_PARAM(console, "file that contains the console code"), + INIT_PARAM(pal, "file that contains palcode"), + INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot", + "a"), + INIT_PARAM_DFLT(readfile, "file to read startup script from", ""), + INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0), + INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34), + INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10), + INIT_PARAM_DFLT(bin, "is this system to be binned", false), + INIT_PARAM(binned_fns, "functions to be broken down and binned"), + INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true) + +END_INIT_SIM_OBJECT_PARAMS(FreebsdAlphaSystem) + +CREATE_SIM_OBJECT(FreebsdAlphaSystem) +{ + AlphaSystem::Params *p = new AlphaSystem::Params; + p->name = getInstanceName(); + p->boot_cpu_frequency = boot_cpu_frequency; + p->memctrl = memctrl; + p->physmem = physmem; + p->kernel_path = kernel; + p->console_path = console; + p->palcode = pal; + p->boot_osflags = boot_osflags; + p->init_param = init_param; + p->readfile = readfile; + p->system_type = system_type; + p->system_rev = system_rev; + p->bin = bin; + p->binned_fns = binned_fns; + p->bin_int = bin_int; + return new FreebsdAlphaSystem(p); +} + +REGISTER_SIM_OBJECT("FreebsdAlphaSystem", FreebsdAlphaSystem) + diff --git a/arch/alpha/freebsd/system.hh b/arch/alpha/freebsd/system.hh new file mode 100644 index 000000000..5d996955e --- /dev/null +++ b/arch/alpha/freebsd/system.hh @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __KERN_FREEBSD_FREEBSD_SYSTEM_HH__ +#define __KERN_FREEBSD_FREEBSD_SYSTEM_HH__ + +#include "kern/system_events.hh" + +class FreebsdAlphaSystem : public AlphaSystem +{ + private: + class SkipCalibrateClocksEvent : public SkipFuncEvent + { + public: + SkipCalibrateClocksEvent(PCEventQueue *q, const std::string &desc, + Addr addr) + : SkipFuncEvent(q, desc, addr) {} + virtual void process(ExecContext *xc); + }; + + SkipFuncEvent *skipDelayEvent; + SkipCalibrateClocksEvent *skipCalibrateClocks; + + public: + FreebsdAlphaSystem(Params *p); + ~FreebsdAlphaSystem(); + void doCalibrateClocks(ExecContext *xc); + +}; + +#endif // __KERN_FREEBSD_FREEBSD_SYSTEM_HH__ diff --git a/arch/alpha/isa/branch.isa b/arch/alpha/isa/branch.isa index 9a7fb9d79..b528df938 100644 --- a/arch/alpha/isa/branch.isa +++ b/arch/alpha/isa/branch.isa @@ -46,7 +46,7 @@ output header {{ mutable const SymbolTable *cachedSymtab; /// Constructor - PCDependentDisassembly(const char *mnem, MachInst _machInst, + PCDependentDisassembly(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : AlphaStaticInst(mnem, _machInst, __opClass), cachedPC(0), cachedSymtab(0) @@ -68,7 +68,7 @@ output header {{ int32_t disp; /// Constructor. - Branch(const char *mnem, MachInst _machInst, OpClass __opClass) + Branch(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : PCDependentDisassembly(mnem, _machInst, __opClass), disp(BRDISP << 2) { @@ -93,7 +93,7 @@ output header {{ public: /// Constructor - Jump(const char *mnem, MachInst _machInst, OpClass __opClass) + Jump(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : PCDependentDisassembly(mnem, _machInst, __opClass), disp(BRDISP) { diff --git a/arch/alpha/isa/decoder.isa b/arch/alpha/isa/decoder.isa index 1817f65f2..e09673269 100644 --- a/arch/alpha/isa/decoder.isa +++ b/arch/alpha/isa/decoder.isa @@ -1,6 +1,6 @@ // -*- mode:c++ -*- -// Copyright (c) 2003-2005 The Regents of The University of Michigan +// Copyright (c) 2003-2006 The Regents of The University of Michigan // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -98,7 +98,7 @@ decode OPCODE default Unknown::unknown() { // signed overflow occurs when operands have same sign // and sign of result does not match. if (Ra.sl<31:> == Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) - fault = IntegerOverflowFault; + fault = new IntegerOverflowFault; Rc.sl = tmp; }}); 0x02: s4addl({{ Rc.sl = (Ra.sl << 2) + Rb_or_imm.sl; }}); @@ -110,7 +110,7 @@ decode OPCODE default Unknown::unknown() { // signed overflow occurs when operands have same sign // and sign of result does not match. if (Ra<63:> == Rb_or_imm<63:> && tmp<63:> != Ra<63:>) - fault = IntegerOverflowFault; + fault = new IntegerOverflowFault; Rc = tmp; }}); 0x22: s4addq({{ Rc = (Ra << 2) + Rb_or_imm; }}); @@ -124,7 +124,7 @@ decode OPCODE default Unknown::unknown() { // sign bit of the subtrahend (Rb), i.e., if the initial // signs are the *same* then no overflow can occur if (Ra.sl<31:> != Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) - fault = IntegerOverflowFault; + fault = new IntegerOverflowFault; Rc.sl = tmp; }}); 0x0b: s4subl({{ Rc.sl = (Ra.sl << 2) - Rb_or_imm.sl; }}); @@ -138,7 +138,7 @@ decode OPCODE default Unknown::unknown() { // sign bit of the subtrahend (Rb), i.e., if the initial // signs are the *same* then no overflow can occur if (Ra<63:> != Rb_or_imm<63:> && tmp<63:> != Ra<63:>) - fault = IntegerOverflowFault; + fault = new IntegerOverflowFault; Rc = tmp; }}); 0x2b: s4subq({{ Rc = (Ra << 2) - Rb_or_imm; }}); @@ -299,7 +299,7 @@ decode OPCODE default Unknown::unknown() { // checking the upper 33 bits for all 0s or all 1s. uint64_t sign_bits = tmp<63:31>; if (sign_bits != 0 && sign_bits != mask(33)) - fault = IntegerOverflowFault; + fault = new IntegerOverflowFault; Rc.sl = tmp<31:0>; }}, IntMultOp); 0x60: mulqv({{ @@ -310,7 +310,7 @@ decode OPCODE default Unknown::unknown() { // the lower 64 if (!((hi == 0 && lo<63:> == 0) || (hi == mask(64) && lo<63:> == 1))) - fault = IntegerOverflowFault; + fault = new IntegerOverflowFault; Rc = lo; }}, IntMultOp); } @@ -427,19 +427,19 @@ decode OPCODE default Unknown::unknown() { #if SS_COMPATIBLE_FP 0x0b: sqrts({{ if (Fb < 0.0) - fault = ArithmeticFault; + fault = new ArithmeticFault; Fc = sqrt(Fb); }}, FloatSqrtOp); #else 0x0b: sqrts({{ if (Fb.sf < 0.0) - fault = ArithmeticFault; + fault = new ArithmeticFault; Fc.sf = sqrt(Fb.sf); }}, FloatSqrtOp); #endif 0x2b: sqrtt({{ if (Fb < 0.0) - fault = ArithmeticFault; + fault = new ArithmeticFault; Fc = sqrt(Fb); }}, FloatSqrtOp); } @@ -570,7 +570,7 @@ decode OPCODE default Unknown::unknown() { // checking the upper 33 bits for all 0s or all 1s. uint64_t sign_bits = Fb.uq<63:31>; if (sign_bits != 0 && sign_bits != mask(33)) - fault = IntegerOverflowFault; + fault = new IntegerOverflowFault; Fc.uq = (Fb.uq<31:30> << 62) | (Fb.uq<29:0> << 29); }}); @@ -673,7 +673,7 @@ decode OPCODE default Unknown::unknown() { && xc->readMiscRegWithEffect(AlphaISA::IPR_ICM, fault) != AlphaISA::mode_kernel)) { // invalid pal function code, or attempt to do privileged // PAL call in non-kernel mode - fault = UnimplementedOpcodeFault; + fault = new UnimplementedOpcodeFault; } else { // check to see if simulator wants to do something special @@ -681,7 +681,6 @@ decode OPCODE default Unknown::unknown() { bool dopal = xc->simPalCheck(palFunc); if (dopal) { - AlphaISA::swap_palshadow(&xc->xcBase()->regs, true); xc->setMiscRegWithEffect(AlphaISA::IPR_EXC_ADDR, NPC); NPC = xc->readMiscRegWithEffect(AlphaISA::IPR_PAL_BASE, fault) + palOffset; } @@ -705,50 +704,56 @@ decode OPCODE default Unknown::unknown() { #endif #if FULL_SYSTEM - format HwLoad { - 0x1b: decode HW_LDST_QUAD { - 0: hw_ld({{ EA = (Rb + disp) & ~3; }}, {{ Ra = Mem.ul; }}, L); - 1: hw_ld({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }}, Q); + 0x1b: decode PALMODE { + 0: OpcdecFault::hw_st_quad(); + 1: decode HW_LDST_QUAD { + format HwLoad { + 0: hw_ld({{ EA = (Rb + disp) & ~3; }}, {{ Ra = Mem.ul; }}, L); + 1: hw_ld({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }}, Q); + } } } - format HwStore { - 0x1f: decode HW_LDST_COND { - 0: decode HW_LDST_QUAD { - 0: hw_st({{ EA = (Rb + disp) & ~3; }}, - {{ Mem.ul = Ra<31:0>; }}, L); - 1: hw_st({{ EA = (Rb + disp) & ~7; }}, - {{ Mem.uq = Ra.uq; }}, Q); - } + 0x1f: decode PALMODE { + 0: OpcdecFault::hw_st_cond(); + format HwStore { + 1: decode HW_LDST_COND { + 0: decode HW_LDST_QUAD { + 0: hw_st({{ EA = (Rb + disp) & ~3; }}, + {{ Mem.ul = Ra<31:0>; }}, L); + 1: hw_st({{ EA = (Rb + disp) & ~7; }}, + {{ Mem.uq = Ra.uq; }}, Q); + } - 1: FailUnimpl::hw_st_cond(); + 1: FailUnimpl::hw_st_cond(); + } } } - format HwMoveIPR { - 0x19: hw_mfpr({{ - // this instruction is only valid in PAL mode - if (!xc->inPalMode()) { - fault = UnimplementedOpcodeFault; - } - else { + 0x19: decode PALMODE { + 0: OpcdecFault::hw_mfpr(); + format HwMoveIPR { + 1: hw_mfpr({{ Ra = xc->readMiscRegWithEffect(ipr_index, fault); - } - }}); - 0x1d: hw_mtpr({{ - // this instruction is only valid in PAL mode - if (!xc->inPalMode()) { - fault = UnimplementedOpcodeFault; - } - else { + }}); + } + } + + 0x1d: decode PALMODE { + 0: OpcdecFault::hw_mtpr(); + format HwMoveIPR { + 1: hw_mtpr({{ xc->setMiscRegWithEffect(ipr_index, Ra); if (traceData) { traceData->setData(Ra); } - } - }}); + }}); + } } format BasicOperate { - 0x1e: hw_rei({{ xc->hwrei(); }}, IsSerializing); + 0x1e: decode PALMODE { + 0: OpcdecFault::hw_rei(); + 1:hw_rei({{ xc->hwrei(); }}, IsSerializing); + } // M5 special opcodes use the reserved 0x01 opcode space 0x01: decode M5FUNC { @@ -758,6 +763,15 @@ decode OPCODE default Unknown::unknown() { 0x01: quiesce({{ AlphaPseudo::quiesce(xc->xcBase()); }}, IsNonSpeculative); + 0x02: quiesceNs({{ + AlphaPseudo::quiesceNs(xc->xcBase(), R16); + }}, IsNonSpeculative); + 0x03: quiesceCycles({{ + AlphaPseudo::quiesceCycles(xc->xcBase(), R16); + }}, IsNonSpeculative); + 0x04: quiesceTime({{ + R0 = AlphaPseudo::quiesceTime(xc->xcBase()); + }}, IsNonSpeculative); 0x10: ivlb({{ AlphaPseudo::ivlb(xc->xcBase()); }}, No_OpClass, IsNonSpeculative); @@ -795,6 +809,9 @@ decode OPCODE default Unknown::unknown() { 0x53: m5addsymbol({{ AlphaPseudo::addsymbol(xc->xcBase(), R16, R17); }}, IsNonSpeculative); + 0x54: m5panic({{ + panic("M5 panic instruction called."); + }}, IsNonSpeculative); } } diff --git a/arch/alpha/isa/fp.isa b/arch/alpha/isa/fp.isa index 20a564045..f34c13c42 100644 --- a/arch/alpha/isa/fp.isa +++ b/arch/alpha/isa/fp.isa @@ -36,7 +36,7 @@ output exec {{ { Fault fault = NoFault; // dummy... this ipr access should not fault if (!EV5::ICSR_FPE(xc->readMiscRegWithEffect(AlphaISA::IPR_ICSR, fault))) { - fault = FloatEnableFault; + fault = new FloatEnableFault; } return fault; } @@ -106,7 +106,7 @@ output header {{ mutable bool warnedOnTrapping; /// Constructor - AlphaFP(const char *mnem, MachInst _machInst, OpClass __opClass) + AlphaFP(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : AlphaStaticInst(mnem, _machInst, __opClass), roundingMode((enum RoundingMode)FP_ROUNDMODE), trappingMode((enum TrappingMode)FP_TRAPMODE), diff --git a/arch/alpha/isa/int.isa b/arch/alpha/isa/int.isa index 049437f8c..17ecc1a51 100644 --- a/arch/alpha/isa/int.isa +++ b/arch/alpha/isa/int.isa @@ -37,7 +37,7 @@ output header {{ uint8_t imm; /// Constructor - IntegerImm(const char *mnem, MachInst _machInst, OpClass __opClass) + IntegerImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : AlphaStaticInst(mnem, _machInst, __opClass), imm(INTIMM) { } diff --git a/arch/alpha/isa/main.isa b/arch/alpha/isa/main.isa index ad9c2a55e..17c9989ab 100644 --- a/arch/alpha/isa/main.isa +++ b/arch/alpha/isa/main.isa @@ -79,6 +79,7 @@ namespace AlphaISA; // // Universal (format-independent) fields +def bitfield PALMODE <32:32>; def bitfield OPCODE <31:26>; def bitfield RA <25:21>; def bitfield RB <20:16>; @@ -153,9 +154,12 @@ def operands {{ # Int regs default to unsigned, but code should not count on this. # For clarity, descriptions that depend on unsigned behavior should # explicitly specify '.uq'. - 'Ra': ('IntReg', 'uq', 'RA', 'IsInteger', 1), - 'Rb': ('IntReg', 'uq', 'RB', 'IsInteger', 2), - 'Rc': ('IntReg', 'uq', 'RC', 'IsInteger', 3), + 'Ra': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RA] : RA', + 'IsInteger', 1), + 'Rb': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RB] : RB', + 'IsInteger', 2), + 'Rc': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RC] : RC', + 'IsInteger', 3), 'Fa': ('FloatReg', 'df', 'FA', 'IsFloating', 1), 'Fb': ('FloatReg', 'df', 'FB', 'IsFloating', 2), 'Fc': ('FloatReg', 'df', 'FC', 'IsFloating', 3), @@ -200,7 +204,7 @@ output header {{ }; /// Constructor. - AlphaStaticInst(const char *mnem, MachInst _machInst, + AlphaStaticInst(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : StaticInst(mnem, _machInst, __opClass) { @@ -272,7 +276,7 @@ def template BasicDeclare {{ { public: /// Constructor. - %(class_name)s(MachInst machInst); + %(class_name)s(ExtMachInst machInst); %(BasicExecDeclare)s }; @@ -280,7 +284,7 @@ def template BasicDeclare {{ // Basic instruction class constructor template. def template BasicConstructor {{ - inline %(class_name)s::%(class_name)s(MachInst machInst) + inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) { %(constructor)s; @@ -344,7 +348,7 @@ output header {{ public: /// Constructor - Nop(const std::string _originalDisassembly, MachInst _machInst) + Nop(const std::string _originalDisassembly, ExtMachInst _machInst) : AlphaStaticInst("nop", _machInst, No_OpClass), originalDisassembly(_originalDisassembly) { @@ -428,6 +432,9 @@ def format BasicOperateWithNopCheck(code, *opt_args) {{ // PAL instruction templates, formats, etc. ##include "m5/arch/alpha/isa/pal.isa" +// Opcdec fault instruction templates, formats, etc. +##include "m5/arch/alpha/isa/opcdec.isa" + // Unimplemented instruction templates, formats, etc. ##include "m5/arch/alpha/isa/unimp.isa" diff --git a/arch/alpha/isa/mem.isa b/arch/alpha/isa/mem.isa index 61d6ea8fa..3c8b4f755 100644 --- a/arch/alpha/isa/mem.isa +++ b/arch/alpha/isa/mem.isa @@ -42,7 +42,7 @@ output header {{ const StaticInstPtr memAccPtr; /// Constructor - Memory(const char *mnem, MachInst _machInst, OpClass __opClass, + Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass, StaticInstPtr _eaCompPtr = nullStaticInstPtr, StaticInstPtr _memAccPtr = nullStaticInstPtr) : AlphaStaticInst(mnem, _machInst, __opClass), @@ -70,7 +70,7 @@ output header {{ int32_t disp; /// Constructor. - MemoryDisp32(const char *mnem, MachInst _machInst, OpClass __opClass, + MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass, StaticInstPtr _eaCompPtr = nullStaticInstPtr, StaticInstPtr _memAccPtr = nullStaticInstPtr) : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), @@ -89,7 +89,7 @@ output header {{ { protected: /// Constructor - MemoryNoDisp(const char *mnem, MachInst _machInst, OpClass __opClass, + MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, StaticInstPtr _eaCompPtr = nullStaticInstPtr, StaticInstPtr _memAccPtr = nullStaticInstPtr) : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) @@ -141,7 +141,7 @@ def template LoadStoreDeclare {{ { public: /// Constructor - EAComp(MachInst machInst); + EAComp(ExtMachInst machInst); %(BasicExecDeclare)s }; @@ -153,7 +153,7 @@ def template LoadStoreDeclare {{ { public: /// Constructor - MemAcc(MachInst machInst); + MemAcc(ExtMachInst machInst); %(BasicExecDeclare)s }; @@ -161,7 +161,7 @@ def template LoadStoreDeclare {{ public: /// Constructor. - %(class_name)s(MachInst machInst); + %(class_name)s(ExtMachInst machInst); %(BasicExecDeclare)s @@ -186,19 +186,19 @@ def template LoadStoreConstructor {{ /** TODO: change op_class to AddrGenOp or something (requires * creating new member of OpClass enum in op_class.hh, updating * config files, etc.). */ - inline %(class_name)s::EAComp::EAComp(MachInst machInst) + inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) { %(ea_constructor)s; } - inline %(class_name)s::MemAcc::MemAcc(MachInst machInst) + inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) { %(memacc_constructor)s; } - inline %(class_name)s::%(class_name)s(MachInst machInst) + inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, new EAComp(machInst), new MemAcc(machInst)) { diff --git a/arch/alpha/isa/opcdec.isa b/arch/alpha/isa/opcdec.isa new file mode 100644 index 000000000..bb2f91e5c --- /dev/null +++ b/arch/alpha/isa/opcdec.isa @@ -0,0 +1,72 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-2005 The Regents of The University of Michigan +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +output header {{ + /** + * Static instruction class for instructions that cause an OPCDEC fault + * when executed. This is currently only for PAL mode instructions + * executed in non-PAL mode. + */ + class OpcdecFault : public AlphaStaticInst + { + public: + /// Constructor + OpcdecFault(ExtMachInst _machInst) + : AlphaStaticInst("opcdec fault", _machInst, No_OpClass) + { + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string + OpcdecFault::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return csprintf("%-10s (inst 0x%x, opcode 0x%x)", + " OPCDEC fault", machInst, OPCODE); + } +}}; + +output exec {{ + Fault + OpcdecFault::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + return new UnimplementedOpcodeFault; + } +}}; + +def format OpcdecFault() {{ + decode_block = 'return new OpcdecFault(machInst);\n' +}}; + diff --git a/arch/alpha/isa/pal.isa b/arch/alpha/isa/pal.isa index 49e5bff12..e07bea5a8 100644 --- a/arch/alpha/isa/pal.isa +++ b/arch/alpha/isa/pal.isa @@ -36,7 +36,7 @@ output header {{ protected: /// Constructor. - EmulatedCallPal(const char *mnem, MachInst _machInst, + EmulatedCallPal(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : AlphaStaticInst(mnem, _machInst, __opClass) { @@ -83,7 +83,7 @@ output header {{ bool palPriv; ///< is this call privileged? /// Constructor. - CallPalBase(const char *mnem, MachInst _machInst, + CallPalBase(const char *mnem, ExtMachInst _machInst, OpClass __opClass); std::string @@ -93,7 +93,7 @@ output header {{ output decoder {{ inline - CallPalBase::CallPalBase(const char *mnem, MachInst _machInst, + CallPalBase::CallPalBase(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : AlphaStaticInst(mnem, _machInst, __opClass), palFunc(PALFUNC) @@ -148,7 +148,7 @@ output header {{ int16_t disp; /// Constructor - HwLoadStore(const char *mnem, MachInst _machInst, OpClass __opClass, + HwLoadStore(const char *mnem, ExtMachInst _machInst, OpClass __opClass, StaticInstPtr _eaCompPtr = nullStaticInstPtr, StaticInstPtr _memAccPtr = nullStaticInstPtr); @@ -160,7 +160,7 @@ output header {{ output decoder {{ inline - HwLoadStore::HwLoadStore(const char *mnem, MachInst _machInst, + HwLoadStore::HwLoadStore(const char *mnem, ExtMachInst _machInst, OpClass __opClass, StaticInstPtr _eaCompPtr, StaticInstPtr _memAccPtr) @@ -231,7 +231,7 @@ output header {{ int ipr_index; /// Constructor - HwMoveIPR(const char *mnem, MachInst _machInst, OpClass __opClass) + HwMoveIPR(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : AlphaStaticInst(mnem, _machInst, __opClass), ipr_index(HW_IPR_IDX) { diff --git a/arch/alpha/isa/unimp.isa b/arch/alpha/isa/unimp.isa index de4ac3eaf..392522801 100644 --- a/arch/alpha/isa/unimp.isa +++ b/arch/alpha/isa/unimp.isa @@ -38,7 +38,7 @@ output header {{ { public: /// Constructor - FailUnimplemented(const char *_mnemonic, MachInst _machInst) + FailUnimplemented(const char *_mnemonic, ExtMachInst _machInst) : AlphaStaticInst(_mnemonic, _machInst, No_OpClass) { // don't call execute() (which panics) if we're on a @@ -69,7 +69,7 @@ output header {{ public: /// Constructor - WarnUnimplemented(const char *_mnemonic, MachInst _machInst) + WarnUnimplemented(const char *_mnemonic, ExtMachInst _machInst) : AlphaStaticInst(_mnemonic, _machInst, No_OpClass), warned(false) { // don't call execute() (which panics) if we're on a @@ -111,7 +111,7 @@ output exec {{ { panic("attempt to execute unimplemented instruction '%s' " "(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE); - return UnimplementedOpcodeFault; + return new UnimplementedOpcodeFault; } Fault @@ -148,7 +148,7 @@ output header {{ { public: /// Constructor - Unknown(MachInst _machInst) + Unknown(ExtMachInst _machInst) : AlphaStaticInst("unknown", _machInst, No_OpClass) { // don't call execute() (which panics) if we're on a diff --git a/arch/alpha/isa/unknown.isa b/arch/alpha/isa/unknown.isa index 4601b3684..47d166255 100644 --- a/arch/alpha/isa/unknown.isa +++ b/arch/alpha/isa/unknown.isa @@ -42,7 +42,7 @@ output exec {{ { panic("attempt to execute unknown instruction " "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE); - return UnimplementedOpcodeFault; + return new UnimplementedOpcodeFault; } }}; diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index a94777bee..b4084723f 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -57,16 +57,17 @@ namespace AlphaISA { typedef uint32_t MachInst; -// typedef uint64_t Addr; + typedef uint64_t ExtMachInst; typedef uint8_t RegIndex; enum { MemoryEnd = 0xffffffffffffffffULL, - NumIntRegs = 32, - NumFloatRegs = 32, + NumIntArchRegs = 32, + NumPALShadowRegs = 8, + NumFloatArchRegs = 32, // @todo: Figure out what this number really should be. - NumMiscRegs = 32, + NumMiscArchRegs = 32, MaxRegsOfAnyType = 32, // Static instruction parameters @@ -100,17 +101,23 @@ namespace AlphaISA DepNA = 0, }; + enum { + NumIntRegs = NumIntArchRegs + NumPALShadowRegs, + NumFloatRegs = NumFloatArchRegs, + NumMiscRegs = NumMiscArchRegs + }; + // These enumerate all the registers for dependence tracking. enum DependenceTags { // 0..31 are the integer regs 0..31 // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag) - FP_Base_DepTag = 32, - Ctrl_Base_DepTag = 64, - Fpcr_DepTag = 64, // floating point control register - Uniq_DepTag = 65, - Lock_Flag_DepTag = 66, - Lock_Addr_DepTag = 67, - IPR_Base_DepTag = 68 + FP_Base_DepTag = 40, + Ctrl_Base_DepTag = 72, + Fpcr_DepTag = 72, // floating point control register + Uniq_DepTag = 73, + Lock_Flag_DepTag = 74, + Lock_Addr_DepTag = 75, + IPR_Base_DepTag = 76 }; typedef uint64_t IntReg; @@ -132,6 +139,9 @@ extern const Addr PageBytes; extern const Addr PageMask; extern const Addr PageOffset; +// redirected register map, really only used for the full system case. +extern const int reg_redir[NumIntRegs]; + #if FULL_SYSTEM typedef uint64_t InternalProcReg; @@ -197,9 +207,7 @@ extern const Addr PageOffset; Addr pc; // program counter Addr npc; // next-cycle program counter #if FULL_SYSTEM - IntReg palregs[NumIntRegs]; // PAL shadow registers int intrflag; // interrupt flag - bool pal_shadow; // using pal_shadow registers inline int instAsid() { return EV5::ITB_ASN_ASN(miscRegs.ipr[IPR_ITB_ASN]); } inline int dataAsid() @@ -210,10 +218,12 @@ extern const Addr PageOffset; void unserialize(Checkpoint *cp, const std::string §ion); }; - StaticInstPtr decodeInst(MachInst); + static inline ExtMachInst makeExtMI(MachInst inst, const uint64_t &pc); + + StaticInstPtr decodeInst(ExtMachInst); // return a no-op instruction... used for instruction fetch faults - extern const MachInst NoopMachInst; + extern const ExtMachInst NoopMachInst; enum annotes { ANNOTE_NONE = 0, @@ -360,6 +370,18 @@ class SyscallReturn { #endif +static inline AlphaISA::ExtMachInst +AlphaISA::makeExtMI(AlphaISA::MachInst inst, const uint64_t &pc) { +#if FULL_SYSTEM + AlphaISA::ExtMachInst ext_inst = inst; + if (pc && 0x1) + return ext_inst|=(static_cast<AlphaISA::ExtMachInst>(pc & 0x1) << 32); + else + return ext_inst; +#else + return AlphaISA::ExtMachInst(inst); +#endif +} #if FULL_SYSTEM //typedef TheISA::InternalProcReg InternalProcReg; diff --git a/arch/alpha/linux/aligned.hh b/arch/alpha/linux/aligned.hh new file mode 100644 index 000000000..cabecb283 --- /dev/null +++ b/arch/alpha/linux/aligned.hh @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2004 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_ALPHA_LINUX_ALIGNED_HH__ +#define __ARCH_ALPHA_LINUX_ALIGNED_HH__ + + +/* GCC 3.3.X has a bug in which attributes+typedefs don't work. 3.2.X is fine + * as in 3.4.X, but the bug is marked will not fix in 3.3.X so here is + * the work around. + */ +#if (__GNUC__ == 3 && __GNUC_MINOR__ != 3) || __GNUC__ > 3 +typedef uint64_t uint64_ta __attribute__ ((aligned (8))) ; +typedef int64_t int64_ta __attribute__ ((aligned (8))) ; +typedef Addr Addr_a __attribute__ ((aligned (8))) ; +#else +#define uint64_ta uint64_t __attribute__ ((aligned (8))) +#define int64_ta int64_t __attribute__ ((aligned (8))) +#define Addr_a Addr __attribute__ ((aligned (8))) +#endif /* __GNUC__ __GNUC_MINOR__ */ + +#endif /* __ARCH_ALPHA_LINUX_ALIGNED_HH__ */ diff --git a/arch/alpha/linux/hwrpb.hh b/arch/alpha/linux/hwrpb.hh new file mode 100644 index 000000000..869ce026b --- /dev/null +++ b/arch/alpha/linux/hwrpb.hh @@ -0,0 +1,42 @@ +/* + * Copyright 1990 Hewlett-Packard Development Company, L.P. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __ARCH_ALPHA_LINUX_HWRPB_HH__ +#define __ARCH_ALPHA_LINUX_HWRPB_HH__ + +#include "arch/alpha/linux/aligned.hh" + +namespace Linux { + struct pcb_struct { + uint64_ta rpb_ksp; + uint64_ta rpb_usp; + uint64_ta rpb_ptbr; + uint32_t rpb_cc; + uint32_t rpb_psn; + uint64_ta rpb_unique; + uint64_ta rpb_fen; + uint64_ta res1, res2; + }; +} +#endif // __ARCH_ALPHA_LINUX_HWRPB_HH__ diff --git a/arch/alpha/linux/system.cc b/arch/alpha/linux/system.cc new file mode 100644 index 000000000..f9275d15e --- /dev/null +++ b/arch/alpha/linux/system.cc @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This code loads the linux kernel, console, pal and patches certain + * functions. The symbol tables are loaded so that traces can show + * the executing function and we can skip functions. Various delay + * loops are skipped and their final values manually computed to speed + * up boot time. + */ + +#include "arch/arguments.hh" +#include "arch/vtophys.hh" +#include "arch/alpha/linux/system.hh" +#include "arch/alpha/linux/threadinfo.hh" +#include "arch/alpha/system.hh" +#include "base/loader/symtab.hh" +#include "cpu/exec_context.hh" +#include "cpu/base.hh" +#include "dev/platform.hh" +#include "kern/linux/printk.hh" +#include "kern/linux/events.hh" +#include "mem/functional/memory_control.hh" +#include "mem/functional/physical.hh" +#include "sim/builder.hh" +#include "sim/byteswap.hh" + +using namespace std; +using namespace AlphaISA; +using namespace Linux; + +LinuxAlphaSystem::LinuxAlphaSystem(Params *p) + : AlphaSystem(p) +{ + Addr addr = 0; + Addr paddr = 0; + + /** + * The symbol swapper_pg_dir marks the beginning of the kernel and + * the location of bootloader passed arguments + */ + if (!kernelSymtab->findAddress("swapper_pg_dir", KernelStart)) { + panic("Could not determine start location of kernel"); + } + + /** + * Since we aren't using a bootloader, we have to copy the + * kernel arguments directly into the kernel's memory. + */ + paddr = vtophys(physmem, CommandLine()); + char *commandline = (char *)physmem->dma_addr(paddr, sizeof(uint64_t)); + if (commandline) + strncpy(commandline, params()->boot_osflags.c_str(), CommandLineSize); + + /** + * find the address of the est_cycle_freq variable and insert it + * so we don't through the lengthly process of trying to + * calculated it by using the PIT, RTC, etc. + */ + if (kernelSymtab->findAddress("est_cycle_freq", addr)) { + paddr = vtophys(physmem, addr); + uint8_t *est_cycle_frequency = + physmem->dma_addr(paddr, sizeof(uint64_t)); + + if (est_cycle_frequency) + *(uint64_t *)est_cycle_frequency = + Clock::Frequency / p->boot_cpu_frequency; + } + + + /** + * EV5 only supports 127 ASNs so we are going to tell the kernel that the + * paritiuclar EV6 we have only supports 127 asns. + * @todo At some point we should change ev5.hh and the palcode to support + * 255 ASNs. + */ + if (kernelSymtab->findAddress("dp264_mv", addr)) { + paddr = vtophys(physmem, addr); + char *dp264_mv = (char *)physmem->dma_addr(paddr, sizeof(uint64_t)); + + if (dp264_mv) { + *(uint32_t*)(dp264_mv+0x18) = LittleEndianGuest::htog((uint32_t)127); + } else + panic("could not translate dp264_mv addr\n"); + + } else + panic("could not find dp264_mv\n"); + +#ifndef NDEBUG + kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic"); + if (!kernelPanicEvent) + panic("could not find kernel symbol \'panic\'"); + +#if 0 + kernelDieEvent = addKernelFuncEvent<BreakPCEvent>("die_if_kernel"); + if (!kernelDieEvent) + panic("could not find kernel symbol \'die_if_kernel\'"); +#endif + +#endif + + /** + * Any time ide_delay_50ms, calibarte_delay or + * determine_cpu_caches is called just skip the + * function. Currently determine_cpu_caches only is used put + * information in proc, however if that changes in the future we + * will have to fill in the cache size variables appropriately. + */ + + skipIdeDelay50msEvent = + addKernelFuncEvent<SkipFuncEvent>("ide_delay_50ms"); + skipDelayLoopEvent = + addKernelFuncEvent<SkipDelayLoopEvent>("calibrate_delay"); + skipCacheProbeEvent = + addKernelFuncEvent<SkipFuncEvent>("determine_cpu_caches"); + debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk"); + idleStartEvent = addKernelFuncEvent<IdleStartEvent>("cpu_idle"); + + if (kernelSymtab->findAddress("alpha_switch_to", addr) && DTRACE(Thread)) { + printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo", + addr + sizeof(MachInst) * 6); + } else { + printThreadEvent = NULL; + } + + if (params()->bin_int) { + intStartEvent = addPalFuncEvent<InterruptStartEvent>("sys_int_21"); + if (!intStartEvent) + panic("could not find symbol: sys_int_21\n"); + + intEndEvent = addPalFuncEvent<InterruptEndEvent>("rti_to_kern"); + if (!intEndEvent) + panic("could not find symbol: rti_to_kern\n"); + + intEndEvent2 = addPalFuncEvent<InterruptEndEvent>("rti_to_user"); + if (!intEndEvent2) + panic("could not find symbol: rti_to_user\n"); + + intEndEvent3 = addKernelFuncEvent<InterruptEndEvent>("do_softirq"); + if (!intEndEvent3) + panic("could not find symbol: do_softirq\n"); + } +} + +LinuxAlphaSystem::~LinuxAlphaSystem() +{ +#ifndef NDEBUG + delete kernelPanicEvent; +#endif + delete skipIdeDelay50msEvent; + delete skipDelayLoopEvent; + delete skipCacheProbeEvent; + delete debugPrintkEvent; + delete idleStartEvent; + delete printThreadEvent; + delete intStartEvent; + delete intEndEvent; + delete intEndEvent2; +} + + +void +LinuxAlphaSystem::setDelayLoop(ExecContext *xc) +{ + Addr addr = 0; + if (kernelSymtab->findAddress("loops_per_jiffy", addr)) { + Addr paddr = vtophys(physmem, addr); + + uint8_t *loops_per_jiffy = + physmem->dma_addr(paddr, sizeof(uint32_t)); + + Tick cpuFreq = xc->getCpuPtr()->frequency(); + Tick intrFreq = platform->intrFrequency(); + *(uint32_t *)loops_per_jiffy = + (uint32_t)((cpuFreq / intrFreq) * 0.9988); + } +} + + +void +LinuxAlphaSystem::SkipDelayLoopEvent::process(ExecContext *xc) +{ + SkipFuncEvent::process(xc); + // calculate and set loops_per_jiffy + ((LinuxAlphaSystem *)xc->getSystemPtr())->setDelayLoop(xc); +} + +void +LinuxAlphaSystem::PrintThreadInfo::process(ExecContext *xc) +{ + Linux::ThreadInfo ti(xc); + + DPRINTF(Thread, "Currently Executing Thread %s, pid %d, started at: %d\n", + ti.curTaskName(), ti.curTaskPID(), ti.curTaskStart()); +} + + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxAlphaSystem) + + Param<Tick> boot_cpu_frequency; + SimObjectParam<MemoryController *> memctrl; + SimObjectParam<PhysicalMemory *> physmem; + + Param<string> kernel; + Param<string> console; + Param<string> pal; + + Param<string> boot_osflags; + Param<string> readfile; + Param<unsigned int> init_param; + + Param<uint64_t> system_type; + Param<uint64_t> system_rev; + + Param<bool> bin; + VectorParam<string> binned_fns; + Param<bool> bin_int; + +END_DECLARE_SIM_OBJECT_PARAMS(LinuxAlphaSystem) + +BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxAlphaSystem) + + INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"), + INIT_PARAM(memctrl, "memory controller"), + INIT_PARAM(physmem, "phsyical memory"), + INIT_PARAM(kernel, "file that contains the kernel code"), + INIT_PARAM(console, "file that contains the console code"), + INIT_PARAM(pal, "file that contains palcode"), + INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot", + "a"), + INIT_PARAM_DFLT(readfile, "file to read startup script from", ""), + INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0), + INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34), + INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10), + INIT_PARAM_DFLT(bin, "is this system to be binned", false), + INIT_PARAM(binned_fns, "functions to be broken down and binned"), + INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true) + +END_INIT_SIM_OBJECT_PARAMS(LinuxAlphaSystem) + +CREATE_SIM_OBJECT(LinuxAlphaSystem) +{ + AlphaSystem::Params *p = new AlphaSystem::Params; + p->name = getInstanceName(); + p->boot_cpu_frequency = boot_cpu_frequency; + p->memctrl = memctrl; + p->physmem = physmem; + p->kernel_path = kernel; + p->console_path = console; + p->palcode = pal; + p->boot_osflags = boot_osflags; + p->init_param = init_param; + p->readfile = readfile; + p->system_type = system_type; + p->system_rev = system_rev; + p->bin = bin; + p->binned_fns = binned_fns; + p->bin_int = bin_int; + return new LinuxAlphaSystem(p); +} + +REGISTER_SIM_OBJECT("LinuxAlphaSystem", LinuxAlphaSystem) + diff --git a/arch/alpha/linux/system.hh b/arch/alpha/linux/system.hh new file mode 100644 index 000000000..035e2a427 --- /dev/null +++ b/arch/alpha/linux/system.hh @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2004-2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_ALPHA_LINUX_SYSTEM_HH__ +#define __ARCH_ALPHA_LINUX_SYSTEM_HH__ + +class ExecContext; + +class BreakPCEvent; +class IdleStartEvent; + +#include "arch/alpha/system.hh" +#include "kern/linux/events.hh" + +using namespace AlphaISA; +using namespace Linux; +using namespace std; + +/** + * This class contains linux specific system code (Loading, Events, Binning). + * It points to objects that are the system binaries to load and patches them + * appropriately to work in simulator. + */ +class LinuxAlphaSystem : public AlphaSystem +{ + private: + class SkipDelayLoopEvent : public SkipFuncEvent + { + public: + SkipDelayLoopEvent(PCEventQueue *q, const std::string &desc, Addr addr) + : SkipFuncEvent(q, desc, addr) {} + virtual void process(ExecContext *xc); + }; + + class PrintThreadInfo : public PCEvent + { + public: + PrintThreadInfo(PCEventQueue *q, const std::string &desc, Addr addr) + : PCEvent(q, desc, addr) {} + virtual void process(ExecContext *xc); + }; + + + /** + * Addresses defining where the kernel bootloader places various + * elements. Details found in include/asm-alpha/system.h + */ + Addr KernelStart; // Lookup the symbol swapper_pg_dir + + public: + Addr InitStack() const { return KernelStart + 0x02000; } + Addr EmptyPGT() const { return KernelStart + 0x04000; } + Addr EmptyPGE() const { return KernelStart + 0x08000; } + Addr ZeroPGE() const { return KernelStart + 0x0A000; } + Addr StartAddr() const { return KernelStart + 0x10000; } + + Addr Param() const { return ZeroPGE() + 0x0; } + Addr CommandLine() const { return Param() + 0x0; } + Addr InitrdStart() const { return Param() + 0x100; } + Addr InitrdSize() const { return Param() + 0x108; } + static const int CommandLineSize = 256; + + private: +#ifndef NDEBUG + /** Event to halt the simulator if the kernel calls panic() */ + BreakPCEvent *kernelPanicEvent; + + /** Event to halt the simulator if the kernel calls die_if_kernel */ + BreakPCEvent *kernelDieEvent; +#endif + + /** + * Event to skip determine_cpu_caches() because we don't support + * the IPRs that the code can access to figure out cache sizes + */ + SkipFuncEvent *skipCacheProbeEvent; + + /** PC based event to skip the ide_delay_50ms() call */ + SkipFuncEvent *skipIdeDelay50msEvent; + + /** + * PC based event to skip the dprink() call and emulate its + * functionality + */ + DebugPrintkEvent *debugPrintkEvent; + + /** + * Skip calculate_delay_loop() rather than waiting for this to be + * calculated + */ + SkipDelayLoopEvent *skipDelayLoopEvent; + + /** + * Event to print information about thread switches if the trace flag + * Thread is set + */ + PrintThreadInfo *printThreadEvent; + + /** + * Event to bin Interrupts seperately from kernel code + */ + InterruptStartEvent *intStartEvent; + + /** + * Event to bin Interrupts seperately from kernel code + */ + InterruptEndEvent *intEndEvent; + InterruptEndEvent *intEndEvent2; + InterruptEndEvent *intEndEvent3; + + /** Grab the PCBB of the idle process when it starts */ + IdleStartEvent *idleStartEvent; + + public: + LinuxAlphaSystem(Params *p); + ~LinuxAlphaSystem(); + + void setDelayLoop(ExecContext *xc); +}; + +#endif // __ARCH_ALPHA_LINUX_SYSTEM_HH__ diff --git a/arch/alpha/linux/thread_info.hh b/arch/alpha/linux/thread_info.hh new file mode 100644 index 000000000..88791b00d --- /dev/null +++ b/arch/alpha/linux/thread_info.hh @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_ALPHA_LINUX_THREAD_INFO_H__ +#define __ARCH_ALPHA_LINUX_THREAD_INFO_H__ + +#include "arch/alpha/linux/hwrpb.hh" + +namespace Linux { + struct thread_info { + struct pcb_struct pcb; + Addr_a task; + }; +} + +#endif // __ARCH_ALPHA_LINUX_THREAD_INFO_H__ diff --git a/arch/alpha/linux/threadinfo.hh b/arch/alpha/linux/threadinfo.hh new file mode 100644 index 000000000..8f03c9314 --- /dev/null +++ b/arch/alpha/linux/threadinfo.hh @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2004 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_ALPHA_LINUX_LINUX_TREADNIFO_HH__ +#define __ARCH_ALPHA_LINUX_LINUX_TREADNIFO_HH__ + +#include "arch/alpha/linux/thread_info.hh" +#include "cpu/exec_context.hh" +#include "kern/linux/sched.hh" +#include "sim/vptr.hh" + +namespace Linux { + +class ThreadInfo +{ + private: + ExecContext *xc; + + public: + ThreadInfo(ExecContext *exec) : xc(exec) {} + ~ThreadInfo() {} + + inline VPtr<thread_info> + curThreadInfo() + { + Addr current; + + /* Each kernel stack is only 2 pages, the start of which is the + * thread_info struct. So we can get the address by masking off + * the lower 14 bits. + */ + current = xc->readIntReg(TheISA::StackPointerReg) & ~0x3fff; + return VPtr<thread_info>(xc, current); + } + + inline VPtr<task_struct> + curTaskInfo() + { + Addr task = curThreadInfo()->task; + return VPtr<task_struct>(xc, task); + } + + std::string + curTaskName() + { + return curTaskInfo()->name; + } + + int32_t + curTaskPID() + { + return curTaskInfo()->pid; + } + + uint64_t + curTaskStart() + { + return curTaskInfo()->start; + } +}; + +/* namespace Linux */ } + +#endif // __ARCH_ALPHA_LINUX_LINUX_THREADINFO_HH__ diff --git a/arch/alpha/alpha_linux_process.cc b/arch/alpha/linux_process.cc index 63913d68e..b80966133 100644 --- a/arch/alpha/alpha_linux_process.cc +++ b/arch/alpha/linux_process.cc @@ -26,8 +26,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "arch/alpha/alpha_common_syscall_emul.hh" -#include "arch/alpha/alpha_linux_process.hh" +#include "arch/alpha/common_syscall_emul.hh" +#include "arch/alpha/linux_process.hh" #include "arch/alpha/isa_traits.hh" #include "base/trace.hh" diff --git a/arch/alpha/alpha_linux_process.hh b/arch/alpha/linux_process.hh index 7de1b1ac1..7de1b1ac1 100644 --- a/arch/alpha/alpha_linux_process.hh +++ b/arch/alpha/linux_process.hh diff --git a/arch/alpha/process.cc b/arch/alpha/process.cc new file mode 100644 index 000000000..b2dbe7ad1 --- /dev/null +++ b/arch/alpha/process.cc @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2003-2004 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "arch/alpha/process.hh" + +namespace AlphaISA +{ + +LiveProcess * +createProcess(const std::string &nm, ObjectFile * objFile, + int stdin_fd, int stdout_fd, int stderr_fd, + std::vector<std::string> &argv, std::vector<std::string> &envp) +{ + LiveProcess * process = NULL; + if (objFile->getArch() != ObjectFile::Alpha) + fatal("Object file does not match architecture."); + switch (objFile->getOpSys()) { + case ObjectFile::Tru64: + process = new AlphaTru64Process(nm, objFile, + stdin_fd, stdout_fd, stderr_fd, + argv, envp); + break; + + case ObjectFile::Linux: + process = new AlphaLinuxProcess(nm, objFile, + stdin_fd, stdout_fd, stderr_fd, + argv, envp); + break; + + default: + fatal("Unknown/unsupported operating system."); + } + return process; +} + +} // namespace AlphaISA diff --git a/arch/alpha/process.hh b/arch/alpha/process.hh new file mode 100644 index 000000000..7b660ddd0 --- /dev/null +++ b/arch/alpha/process.hh @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2003-2004 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ALPHA_PROCESS_HH__ +#define __ALPHA_PROCESS_HH__ + +#include <string> + +#include "arch/alpha/linux_process.hh" +#include "arch/alpha/tru64_process.hh" +#include "base/loader/object_file.hh" + +namespace AlphaISA +{ + +LiveProcess * +createProcess(const std::string &nm, ObjectFile * objFile, + int stdin_fd, int stdout_fd, int stderr_fd, + std::vector<std::string> &argv, std::vector<std::string> &envp); + +} // namespace AlphaISA + +#endif // __ALPHA_PROCESS_HH__ diff --git a/arch/alpha/system.cc b/arch/alpha/system.cc new file mode 100644 index 000000000..1e80c7768 --- /dev/null +++ b/arch/alpha/system.cc @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "arch/alpha/system.hh" +#include "arch/vtophys.hh" +#include "base/remote_gdb.hh" +#include "base/loader/object_file.hh" +#include "base/loader/symtab.hh" +#include "base/trace.hh" +#include "mem/functional/memory_control.hh" +#include "mem/functional/physical.hh" +#include "sim/byteswap.hh" +#include "sim/builder.hh" + +using namespace LittleEndianGuest; + +AlphaSystem::AlphaSystem(Params *p) + : System(p) +{ + consoleSymtab = new SymbolTable; + palSymtab = new SymbolTable; + + + /** + * Load the pal, and console code into memory + */ + // Load Console Code + console = createObjectFile(params()->console_path); + if (console == NULL) + fatal("Could not load console file %s", params()->console_path); + + // Load pal file + pal = createObjectFile(params()->palcode); + if (pal == NULL) + fatal("Could not load PALcode file %s", params()->palcode); + + + // Load program sections into memory + pal->loadSections(physmem, true); + console->loadSections(physmem, true); + + // load symbols + if (!console->loadGlobalSymbols(consoleSymtab)) + panic("could not load console symbols\n"); + + if (!pal->loadGlobalSymbols(palSymtab)) + panic("could not load pal symbols\n"); + + if (!pal->loadLocalSymbols(palSymtab)) + panic("could not load pal symbols\n"); + + if (!console->loadGlobalSymbols(debugSymbolTable)) + panic("could not load console symbols\n"); + + if (!pal->loadGlobalSymbols(debugSymbolTable)) + panic("could not load pal symbols\n"); + + if (!pal->loadLocalSymbols(debugSymbolTable)) + panic("could not load pal symbols\n"); + + Addr addr = 0; +#ifndef NDEBUG + consolePanicEvent = addConsoleFuncEvent<BreakPCEvent>("panic"); +#endif + + /** + * Copy the osflags (kernel arguments) into the consoles + * memory. (Presently Linux does not use the console service + * routine to get these command line arguments, but Tru64 and + * others do.) + */ + if (consoleSymtab->findAddress("env_booted_osflags", addr)) { + Addr paddr = vtophys(physmem, addr); + char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t)); + + if (osflags) + strcpy(osflags, params()->boot_osflags.c_str()); + } + + /** + * Set the hardware reset parameter block system type and revision + * information to Tsunami. + */ + if (consoleSymtab->findAddress("m5_rpb", addr)) { + Addr paddr = vtophys(physmem, addr); + char *hwrpb = (char *)physmem->dma_addr(paddr, sizeof(uint64_t)); + + if (!hwrpb) + panic("could not translate hwrpb addr\n"); + + *(uint64_t*)(hwrpb+0x50) = htog(params()->system_type); + *(uint64_t*)(hwrpb+0x58) = htog(params()->system_rev); + } else + panic("could not find hwrpb\n"); + +} + +AlphaSystem::~AlphaSystem() +{ + delete consoleSymtab; + delete console; + delete pal; +#ifdef DEBUG + delete consolePanicEvent; +#endif +} + +/** + * This function fixes up addresses that are used to match PCs for + * hooking simulator events on to target function executions. + * + * Alpha binaries may have multiple global offset table (GOT) + * sections. A function that uses the GOT starts with a + * two-instruction prolog which sets the global pointer (gp == r29) to + * the appropriate GOT section. The proper gp value is calculated + * based on the function address, which must be passed by the caller + * in the procedure value register (pv aka t12 == r27). This sequence + * looks like the following: + * + * opcode Ra Rb offset + * ldah gp,X(pv) 09 29 27 X + * lda gp,Y(gp) 08 29 29 Y + * + * for some constant offsets X and Y. The catch is that the linker + * (or maybe even the compiler, I'm not sure) may recognize that the + * caller and callee are using the same GOT section, making this + * prolog redundant, and modify the call target to skip these + * instructions. If we check for execution of the first instruction + * of a function (the one the symbol points to) to detect when to skip + * it, we'll miss all these modified calls. It might work to + * unconditionally check for the third instruction, but not all + * functions have this prolog, and there's some chance that those + * first two instructions could have undesired consequences. So we do + * the Right Thing and pattern-match the first two instructions of the + * function to decide where to patch. + * + * Eventually this code should be moved into an ISA-specific file. + */ +Addr +AlphaSystem::fixFuncEventAddr(Addr addr) +{ + // mask for just the opcode, Ra, and Rb fields (not the offset) + const uint32_t inst_mask = 0xffff0000; + // ldah gp,X(pv): opcode 9, Ra = 29, Rb = 27 + const uint32_t gp_ldah_pattern = (9 << 26) | (29 << 21) | (27 << 16); + // lda gp,Y(gp): opcode 8, Ra = 29, rb = 29 + const uint32_t gp_lda_pattern = (8 << 26) | (29 << 21) | (29 << 16); + // instruction size + const int sz = sizeof(uint32_t); + + Addr paddr = vtophys(physmem, addr); + uint32_t i1 = *(uint32_t *)physmem->dma_addr(paddr, sz); + uint32_t i2 = *(uint32_t *)physmem->dma_addr(paddr+sz, sz); + + if ((i1 & inst_mask) == gp_ldah_pattern && + (i2 & inst_mask) == gp_lda_pattern) { + Addr new_addr = addr + 2*sz; + DPRINTF(Loader, "fixFuncEventAddr: %p -> %p", addr, new_addr); + return new_addr; + } else { + return addr; + } +} + + +void +AlphaSystem::setAlphaAccess(Addr access) +{ + Addr addr = 0; + if (consoleSymtab->findAddress("m5AlphaAccess", addr)) { + Addr paddr = vtophys(physmem, addr); + uint64_t *m5AlphaAccess = + (uint64_t *)physmem->dma_addr(paddr, sizeof(uint64_t)); + + if (!m5AlphaAccess) + panic("could not translate m5AlphaAccess addr\n"); + + *m5AlphaAccess = htog(EV5::Phys2K0Seg(access)); + } else + panic("could not find m5AlphaAccess\n"); +} + +bool +AlphaSystem::breakpoint() +{ + return remoteGDB[0]->trap(ALPHA_KENTRY_INT); +} + +void +AlphaSystem::serialize(std::ostream &os) +{ + System::serialize(os); + consoleSymtab->serialize("console_symtab", os); + palSymtab->serialize("pal_symtab", os); +} + + +void +AlphaSystem::unserialize(Checkpoint *cp, const std::string §ion) +{ + System::unserialize(cp,section); + consoleSymtab->unserialize("console_symtab", cp, section); + palSymtab->unserialize("pal_symtab", cp, section); +} + + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem) + + Param<Tick> boot_cpu_frequency; + SimObjectParam<MemoryController *> memctrl; + SimObjectParam<PhysicalMemory *> physmem; + + Param<std::string> kernel; + Param<std::string> console; + Param<std::string> pal; + + Param<std::string> boot_osflags; + Param<std::string> readfile; + Param<unsigned int> init_param; + + Param<uint64_t> system_type; + Param<uint64_t> system_rev; + + Param<bool> bin; + VectorParam<std::string> binned_fns; + Param<bool> bin_int; + +END_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem) + +BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaSystem) + + INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"), + INIT_PARAM(memctrl, "memory controller"), + INIT_PARAM(physmem, "phsyical memory"), + INIT_PARAM(kernel, "file that contains the kernel code"), + INIT_PARAM(console, "file that contains the console code"), + INIT_PARAM(pal, "file that contains palcode"), + INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot", + "a"), + INIT_PARAM_DFLT(readfile, "file to read startup script from", ""), + INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0), + INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34), + INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10), + INIT_PARAM_DFLT(bin, "is this system to be binned", false), + INIT_PARAM(binned_fns, "functions to be broken down and binned"), + INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true) + +END_INIT_SIM_OBJECT_PARAMS(AlphaSystem) + +CREATE_SIM_OBJECT(AlphaSystem) +{ + AlphaSystem::Params *p = new AlphaSystem::Params; + p->name = getInstanceName(); + p->boot_cpu_frequency = boot_cpu_frequency; + p->memctrl = memctrl; + p->physmem = physmem; + p->kernel_path = kernel; + p->console_path = console; + p->palcode = pal; + p->boot_osflags = boot_osflags; + p->init_param = init_param; + p->readfile = readfile; + p->system_type = system_type; + p->system_rev = system_rev; + p->bin = bin; + p->binned_fns = binned_fns; + p->bin_int = bin_int; + return new AlphaSystem(p); +} + +REGISTER_SIM_OBJECT("AlphaSystem", AlphaSystem) + + diff --git a/arch/alpha/system.hh b/arch/alpha/system.hh new file mode 100644 index 000000000..fe1307ac3 --- /dev/null +++ b/arch/alpha/system.hh @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_ALPHA_SYSTEM_HH__ +#define __ARCH_ALPHA_SYSTEM_HH__ + +#include <string> +#include <vector> + +#include "sim/system.hh" +#include "base/loader/symtab.hh" +#include "cpu/pc_event.hh" +#include "kern/system_events.hh" +#include "sim/sim_object.hh" + +class AlphaSystem : public System +{ + public: + struct Params : public System::Params + { + std::string console_path; + std::string palcode; + std::string boot_osflags; + uint64_t system_type; + uint64_t system_rev; + }; + + AlphaSystem(Params *p); + + ~AlphaSystem(); + + virtual bool breakpoint(); + +/** + * Serialization stuff + */ + public: + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); + + /** + * Set the m5AlphaAccess pointer in the console + */ + void setAlphaAccess(Addr access); + + /** console symbol table */ + SymbolTable *consoleSymtab; + + /** pal symbol table */ + SymbolTable *palSymtab; + + /** Object pointer for the console code */ + ObjectFile *console; + + /** Object pointer for the PAL code */ + ObjectFile *pal; + +#ifndef NDEBUG + /** Event to halt the simulator if the console calls panic() */ + BreakPCEvent *consolePanicEvent; +#endif + protected: + const Params *params() const { return (const Params *)_params; } + + /** Add a function-based event to PALcode. */ + template <class T> + T *AlphaSystem::addPalFuncEvent(const char *lbl) + { + return addFuncEvent<T>(palSymtab, lbl); + } + + /** Add a function-based event to the console code. */ + template <class T> + T *AlphaSystem::addConsoleFuncEvent(const char *lbl) + { + return addFuncEvent<T>(consoleSymtab, lbl); + } + + virtual Addr fixFuncEventAddr(Addr addr); + +}; + +#endif + diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/tlb.cc index 9b43ad39e..e30a8e595 100644 --- a/arch/alpha/alpha_memory.cc +++ b/arch/alpha/tlb.cc @@ -30,7 +30,7 @@ #include <string> #include <vector> -#include "arch/alpha/alpha_memory.hh" +#include "arch/alpha/tlb.hh" #include "base/inifile.hh" #include "base/str.hh" #include "base/trace.hh" @@ -321,7 +321,7 @@ AlphaITB::translate(MemReqPtr &req) const if (!validVirtualAddress(req->vaddr)) { fault(req->vaddr, req->xc); acv++; - return ItbAcvFault; + return new ItbAcvFault; } @@ -338,7 +338,7 @@ AlphaITB::translate(MemReqPtr &req) const AlphaISA::mode_kernel) { fault(req->vaddr, req->xc); acv++; - return ItbAcvFault; + return new ItbAcvFault; } req->paddr = req->vaddr & PAddrImplMask; @@ -360,7 +360,7 @@ AlphaITB::translate(MemReqPtr &req) const if (!pte) { fault(req->vaddr, req->xc); misses++; - return ItbPageFault; + return new ItbPageFault; } req->paddr = (pte->ppn << AlphaISA::PageShift) + @@ -372,7 +372,7 @@ AlphaITB::translate(MemReqPtr &req) const // instruction access fault fault(req->vaddr, req->xc); acv++; - return ItbAcvFault; + return new ItbAcvFault; } hits++; @@ -381,7 +381,7 @@ AlphaITB::translate(MemReqPtr &req) const // check that the physical address is ok (catch bad physical addresses) if (req->paddr & ~PAddrImplMask) - return MachineCheckFault; + return genMachineCheckFault(); checkCacheability(req); @@ -510,7 +510,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const fault(req, write ? MM_STAT_WR_MASK : 0); DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->vaddr, req->size); - return AlignmentFault; + return genAlignmentFault(); } if (pc & 0x1) { @@ -530,7 +530,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const MM_STAT_ACV_MASK); if (write) { write_acv++; } else { read_acv++; } - return DtbPageFault; + return new DtbPageFault; } // Check for "superpage" mapping @@ -547,7 +547,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const fault(req, ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK)); if (write) { write_acv++; } else { read_acv++; } - return DtbAcvFault; + return new DtbAcvFault; } req->paddr = req->vaddr & PAddrImplMask; @@ -577,7 +577,9 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const fault(req, (write ? MM_STAT_WR_MASK : 0) | MM_STAT_DTB_MISS_MASK); if (write) { write_misses++; } else { read_misses++; } - return (req->flags & VPTE) ? (Fault)PDtbMissFault : (Fault)NDtbMissFault; + return (req->flags & VPTE) ? + (Fault)(new PDtbMissFault) : + (Fault)(new NDtbMissFault); } req->paddr = (pte->ppn << AlphaISA::PageShift) + @@ -590,25 +592,25 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const MM_STAT_ACV_MASK | (pte->fonw ? MM_STAT_FONW_MASK : 0)); write_acv++; - return DtbPageFault; + return new DtbPageFault; } if (pte->fonw) { fault(req, MM_STAT_WR_MASK | MM_STAT_FONW_MASK); write_acv++; - return DtbPageFault; + return new DtbPageFault; } } else { if (!(pte->xre & MODE2MASK(mode))) { fault(req, MM_STAT_ACV_MASK | (pte->fonr ? MM_STAT_FONR_MASK : 0)); read_acv++; - return DtbAcvFault; + return new DtbAcvFault; } if (pte->fonr) { fault(req, MM_STAT_FONR_MASK); read_acv++; - return DtbPageFault; + return new DtbPageFault; } } } @@ -621,7 +623,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const // check that the physical address is ok (catch bad physical addresses) if (req->paddr & ~PAddrImplMask) - return MachineCheckFault; + return genMachineCheckFault(); checkCacheability(req); diff --git a/arch/alpha/alpha_memory.hh b/arch/alpha/tlb.hh index de955fa46..de955fa46 100644 --- a/arch/alpha/alpha_memory.hh +++ b/arch/alpha/tlb.hh diff --git a/arch/alpha/tru64/system.cc b/arch/alpha/tru64/system.cc new file mode 100644 index 000000000..d09a0c85d --- /dev/null +++ b/arch/alpha/tru64/system.cc @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "arch/alpha/tru64/system.hh" +#include "arch/isa_traits.hh" +#include "arch/vtophys.hh" +#include "base/loader/symtab.hh" +#include "base/trace.hh" +#include "cpu/base.hh" +#include "cpu/exec_context.hh" +#include "kern/tru64/tru64_events.hh" +#include "kern/system_events.hh" +#include "mem/functional/memory_control.hh" +#include "mem/functional/physical.hh" +#include "sim/builder.hh" + +using namespace std; + +Tru64AlphaSystem::Tru64AlphaSystem(Tru64AlphaSystem::Params *p) + : AlphaSystem(p) +{ + Addr addr = 0; + if (kernelSymtab->findAddress("enable_async_printf", addr)) { + Addr paddr = vtophys(physmem, addr); + uint8_t *enable_async_printf = + physmem->dma_addr(paddr, sizeof(uint32_t)); + + if (enable_async_printf) + *(uint32_t *)enable_async_printf = 0; + } + +#ifdef DEBUG + kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic"); + if (!kernelPanicEvent) + panic("could not find kernel symbol \'panic\'"); +#endif + + badaddrEvent = addKernelFuncEvent<BadAddrEvent>("badaddr"); + if (!badaddrEvent) + panic("could not find kernel symbol \'badaddr\'"); + + skipPowerStateEvent = + addKernelFuncEvent<SkipFuncEvent>("tl_v48_capture_power_state"); + skipScavengeBootEvent = + addKernelFuncEvent<SkipFuncEvent>("pmap_scavenge_boot"); + +#if TRACING_ON + printfEvent = addKernelFuncEvent<PrintfEvent>("printf"); + debugPrintfEvent = addKernelFuncEvent<DebugPrintfEvent>("m5printf"); + debugPrintfrEvent = addKernelFuncEvent<DebugPrintfrEvent>("m5printfr"); + dumpMbufEvent = addKernelFuncEvent<DumpMbufEvent>("m5_dump_mbuf"); +#endif +} + +Tru64AlphaSystem::~Tru64AlphaSystem() +{ +#ifdef DEBUG + delete kernelPanicEvent; +#endif + delete badaddrEvent; + delete skipPowerStateEvent; + delete skipScavengeBootEvent; +#if TRACING_ON + delete printfEvent; + delete debugPrintfEvent; + delete debugPrintfrEvent; + delete dumpMbufEvent; +#endif +} + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64AlphaSystem) + + Param<Tick> boot_cpu_frequency; + SimObjectParam<MemoryController *> memctrl; + SimObjectParam<PhysicalMemory *> physmem; + + Param<string> kernel; + Param<string> console; + Param<string> pal; + + Param<string> boot_osflags; + Param<string> readfile; + Param<unsigned int> init_param; + + Param<uint64_t> system_type; + Param<uint64_t> system_rev; + + Param<bool> bin; + VectorParam<string> binned_fns; + +END_DECLARE_SIM_OBJECT_PARAMS(Tru64AlphaSystem) + +BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64AlphaSystem) + + INIT_PARAM(boot_cpu_frequency, "frequency of the boot cpu"), + INIT_PARAM(memctrl, "memory controller"), + INIT_PARAM(physmem, "phsyical memory"), + INIT_PARAM(kernel, "file that contains the kernel code"), + INIT_PARAM(console, "file that contains the console code"), + INIT_PARAM(pal, "file that contains palcode"), + INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot", + "a"), + INIT_PARAM_DFLT(readfile, "file to read startup script from", ""), + INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0), + INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 12), + INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 2<<1), + INIT_PARAM_DFLT(bin, "is this system to be binned", false), + INIT_PARAM(binned_fns, "functions to be broken down and binned") + +END_INIT_SIM_OBJECT_PARAMS(Tru64AlphaSystem) + +CREATE_SIM_OBJECT(Tru64AlphaSystem) +{ + AlphaSystem::Params *p = new AlphaSystem::Params; + p->name = getInstanceName(); + p->boot_cpu_frequency = boot_cpu_frequency; + p->memctrl = memctrl; + p->physmem = physmem; + p->kernel_path = kernel; + p->console_path = console; + p->palcode = pal; + p->boot_osflags = boot_osflags; + p->init_param = init_param; + p->readfile = readfile; + p->system_type = system_type; + p->system_rev = system_rev; + p->bin = bin; + p->binned_fns = binned_fns; + p->bin_int = false; + + return new Tru64AlphaSystem(p); +} + +REGISTER_SIM_OBJECT("Tru64AlphaSystem", Tru64AlphaSystem) diff --git a/arch/alpha/tru64/system.hh b/arch/alpha/tru64/system.hh new file mode 100644 index 000000000..0e0cc1bc8 --- /dev/null +++ b/arch/alpha/tru64/system.hh @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_ALPHA_TRU64_SYSTEM_HH__ +#define __ARCH_ALPHA_TRU64_SYSTEM_HH__ + +#include "arch/alpha/system.hh" +#include "arch/isa_traits.hh" +#include "sim/system.hh" + +class ExecContext; + +class BreakPCEvent; +class BadAddrEvent; +class SkipFuncEvent; +class PrintfEvent; +class DebugPrintfEvent; +class DebugPrintfrEvent; +class DumpMbufEvent; +class AlphaArguments; + +class Tru64AlphaSystem : public AlphaSystem +{ + private: +#ifdef DEBUG + /** Event to halt the simulator if the kernel calls panic() */ + BreakPCEvent *kernelPanicEvent; +#endif + + BadAddrEvent *badaddrEvent; + SkipFuncEvent *skipPowerStateEvent; + SkipFuncEvent *skipScavengeBootEvent; + PrintfEvent *printfEvent; + DebugPrintfEvent *debugPrintfEvent; + DebugPrintfrEvent *debugPrintfrEvent; + DumpMbufEvent *dumpMbufEvent; + + public: + Tru64AlphaSystem(Params *p); + ~Tru64AlphaSystem(); + + static void Printf(AlphaArguments args); + static void DumpMbuf(AlphaArguments args); +}; + +#endif // __ARCH_ALPHA_TRU64_SYSTEM_HH__ diff --git a/arch/alpha/alpha_tru64_process.cc b/arch/alpha/tru64_process.cc index 7c0bc49e9..5f6b802e9 100644 --- a/arch/alpha/alpha_tru64_process.cc +++ b/arch/alpha/tru64_process.cc @@ -27,8 +27,8 @@ */ #include "arch/alpha/isa_traits.hh" -#include "arch/alpha/alpha_common_syscall_emul.hh" -#include "arch/alpha/alpha_tru64_process.hh" +#include "arch/alpha/common_syscall_emul.hh" +#include "arch/alpha/tru64_process.hh" #include "cpu/exec_context.hh" #include "kern/tru64/tru64.hh" #include "mem/functional/functional.hh" diff --git a/arch/alpha/alpha_tru64_process.hh b/arch/alpha/tru64_process.hh index 051760702..051760702 100644 --- a/arch/alpha/alpha_tru64_process.hh +++ b/arch/alpha/tru64_process.hh |