diff -r f348cf78072c configs/common/FSConfig.py --- a/configs/common/FSConfig.py Thu Jan 12 10:15:00 2012 -0500 +++ b/configs/common/FSConfig.py Fri Jan 13 03:22:43 2012 +0800 @@ -267,11 +267,6 @@ def makeLinuxMipsSystem(mem_mode, mdesc = None): - class BaseMalta(Malta): - ethernet = NSGigE(pci_bus=0, pci_dev=1, pci_func=0) - ide = IdeController(disks=[Parent.disk0, Parent.disk2], - pci_func=0, pci_dev=0, pci_bus=0) - self = LinuxMipsSystem() if not mdesc: # generic system @@ -280,26 +275,19 @@ self.iobus = Bus(bus_id=0) self.membus = MemBus(bus_id=1) self.bridge = Bridge(delay='50ns', nack_delay='4ns') - self.physmem = PhysicalMemory(range = AddrRange('1GB')) + self.physmem = PhysicalMemory(range = AddrRange(Addr('64MB')), zero = True) self.bridge.side_a = self.iobus.port self.bridge.side_b = self.membus.port self.physmem.port = self.membus.port - self.disk0 = CowIdeDisk(driveID='master') - self.disk2 = CowIdeDisk(driveID='master') - self.disk0.childImage(mdesc.disk()) - self.disk2.childImage(disk('linux-bigswap2.img')) - self.malta = BaseMalta() - self.malta.attachIO(self.iobus) - self.malta.ide.pio = self.iobus.port - self.malta.ethernet.pio = self.iobus.port - self.simple_disk = SimpleDisk(disk=RawDiskImage(image_file = mdesc.disk(), - read_only = True)) + + self.realview = RealViewPBX() + self.realview.attachOnChipIO(self.membus) + self.realview.attachIO(self.iobus) self.intrctrl = IntrControl() self.mem_mode = mem_mode self.terminal = Terminal() - self.kernel = binary('mips/vmlinux') - self.console = binary('mips/console') - self.boot_osflags = 'root=/dev/hda1 console=ttyS0' + self.kernel = binary('vmlinux.mips') + self.boot_osflags = 'console=ttyAMA0 lpj=19988480' return self diff -r f348cf78072c configs/example/fs.py --- a/configs/example/fs.py Thu Jan 12 10:15:00 2012 -0500 +++ b/configs/example/fs.py Fri Jan 13 03:22:43 2012 +0800 @@ -179,8 +179,8 @@ if options.fastmem: test_sys.cpu[i].physmem_port = test_sys.physmem.port -if buildEnv['TARGET_ISA'] == 'mips': - setMipsOptions(TestCPUClass) +#if buildEnv['TARGET_ISA'] == 'mips': +# setMipsOptions(TestCPUClass) if len(bm) == 2: if buildEnv['TARGET_ISA'] == 'alpha': diff -r f348cf78072c src/arch/mips/MipsSystem.py --- a/src/arch/mips/MipsSystem.py Thu Jan 12 10:15:00 2012 -0500 +++ b/src/arch/mips/MipsSystem.py Fri Jan 13 03:22:43 2012 +0800 @@ -28,31 +28,25 @@ # # Authors: Jaidev Patwardhan -from m5.defines import buildEnv from m5.params import * -from m5.proxy import * from System import System class MipsSystem(System): type = 'MipsSystem' - console = Param.String("file that contains the console code") - bare_iron = Param.Bool(False, "Using Bare Iron Mode?") - hex_file_name = Param.String("test.hex","hex file that contains [address,data] pairs") - system_type = Param.UInt64("Type of system we are emulating") - system_rev = Param.UInt64("Revision of system we are emulating") - load_addr_mask = 0xffffffffff + load_addr_mask = 0xffffffff + # 0x35 Implementor is '5' from "M5" + # 0x0 Variant + # 0xf Architecture from CPUID scheme + # 0xf00 Primary part number + # 0x0 Revision + midr_regval = Param.UInt32(0x350ff000, "MIDR value") + boot_loader = Param.String("", "File that contains the boot loader code if any") + boot_loader_mem = Param.PhysicalMemory(NULL, + "Memory object that boot loader is to be loaded into") + gic_cpu_addr = Param.Addr(0, "Addres of the GIC CPU interface") + flags_addr = Param.Addr(0, "Address of the flags register for MP booting") -if buildEnv['FULL_SYSTEM']: - class LinuxMipsSystem(MipsSystem): - type = 'LinuxMipsSystem' - system_type = 34 - system_rev = 1 << 10 - - class BareIronMipsSystem(MipsSystem): - type = 'BareIronMipsSystem' - bare_iron = True - system_type = 34 - system_rev = 1 << 10 - hex_file_name = Param.String('test.hex',"hex file that contains [address,data] pairs") - +class LinuxMipsSystem(MipsSystem): + type = 'LinuxMipsSystem' + load_addr_mask = 0x1fffffff diff -r f348cf78072c src/arch/mips/SConscript --- a/src/arch/mips/SConscript Thu Jan 12 10:15:00 2012 -0500 +++ b/src/arch/mips/SConscript Fri Jan 13 03:22:43 2012 +0800 @@ -54,7 +54,7 @@ Source('stacktrace.cc') Source('linux/system.cc') Source('interrupts.cc') - Source('bare_iron/system.cc') + #Source('bare_iron/system.cc') else: Source('process.cc') Source('linux/linux.cc') diff -r f348cf78072c src/arch/mips/interrupts.hh --- a/src/arch/mips/interrupts.hh Thu Jan 12 10:15:00 2012 -0500 +++ b/src/arch/mips/interrupts.hh Fri Jan 13 03:22:43 2012 +0800 @@ -46,9 +46,24 @@ namespace MipsISA { +enum InterruptTypes +{ + IT_SOFT_INT0, + IT_SOFT_INT1, + IT_HARD_INT0, + IT_HARD_INT1, + IT_HARD_INT2, + IT_HARD_INT3, + IT_HARD_INT4, + IT_HARD_INT5, + NumInterruptTypes +}; + class Interrupts : public SimObject { public: + uint8_t intVector; + typedef MipsInterruptsParams Params; const Params * diff -r f348cf78072c src/arch/mips/interrupts.cc --- a/src/arch/mips/interrupts.cc Thu Jan 12 10:15:00 2012 -0500 +++ b/src/arch/mips/interrupts.cc Fri Jan 13 03:22:43 2012 +0800 @@ -36,6 +36,7 @@ #include "arch/mips/pra_constants.hh" #include "base/trace.hh" #include "cpu/thread_context.hh" +#include "debug/Interrupt.hh" namespace MipsISA { @@ -68,14 +69,22 @@ void Interrupts::post(int int_num, int index) { - fatal("Must use Thread Context when posting MIPS Interrupts in M5"); + DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); + + if (int_num < 0 || int_num >= NumInterruptTypes) + panic("int_num out of bounds\n"); + + if (index != 0) + panic("No support for other interrupt indexes\n"); + + intVector |= 1 << int_num; } void Interrupts::clear(int int_num, ThreadContext* tc) { DPRINTF(Interrupt, "Interrupt %d cleared\n", int_num); - if (int_num < 0 || int_num >= NumInterruptLevels) + if (int_num < 0 || int_num >= NumInterruptTypes) panic("int_num out of bounds\n"); uint8_t intstatus = getCauseIP(tc); @@ -86,7 +95,15 @@ void Interrupts::clear(int int_num, int index) { - fatal("Must use Thread Context when clearing MIPS Interrupts in M5"); + DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); + + if (int_num < 0 || int_num >= NumInterruptTypes) + panic("int_num out of bounds\n"); + + if (index != 0) + panic("No support for other interrupt indexes\n"); + + intVector &= ~((1) << int_num); } void @@ -100,7 +117,8 @@ void Interrupts::clearAll() { - fatal("Must use Thread Context when clearing MIPS Interrupts in M5"); + DPRINTF(Interrupt, "Interrupts all cleared\n"); + intVector = 0; } @@ -119,7 +137,7 @@ // So if any interrupt that isn't masked is detected, jump to interrupt // handler CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE); - if (status.im && cause.ip) { + if (status.im & cause.ip) { DPRINTF(Interrupt, "Interrupt! IM[7:0]=%d IP[7:0]=%d \n", (unsigned)status.im, (unsigned)cause.ip); return new InterruptFault; @@ -148,19 +166,18 @@ bool Interrupts::interruptsPending(ThreadContext *tc) const { - //if there is a on cpu timer interrupt (i.e. Compare == Count) - //update CauseIP before proceeding to interrupt - if (onCpuTimerInterrupt(tc)) { - DPRINTF(Interrupt, "Interrupts OnCpuTimerINterrupt(tc) == true\n"); - //determine timer interrupt IP # - IntCtlReg intCtl = tc->readMiscRegNoEffect(MISCREG_INTCTL); - uint8_t intStatus = getCauseIP(tc); - intStatus |= 1 << intCtl.ipti; - setCauseIP(tc, intStatus); + if (!intVector) + return false; + + StatusReg status = tc->readMiscRegNoEffect(MISCREG_STATUS); + if ((status.ie == 1) && (status.erl == 0) && (status.exl == 0)) { + uint8_t intstatus = getCauseIP(tc); + intstatus |= intVector; + setCauseIP(tc, intstatus); + return intVector; + } else { + return false; } - - return (getCauseIP(tc) != 0); - } } diff -r f348cf78072c src/arch/mips/isa.cc --- a/src/arch/mips/isa.cc Thu Jan 12 10:15:00 2012 -0500 +++ b/src/arch/mips/isa.cc Fri Jan 13 03:22:43 2012 +0800 @@ -152,6 +152,8 @@ for (int k = 0; k < miscRegFile_WriteMask[i].size(); k++) miscRegFile_WriteMask[i][k] = (long unsigned int)(-1); } + + configCP(); } @@ -162,9 +164,67 @@ numThreads, numVpes); CoreSpecific cp; - panic("CP state must be set before the following code is used"); // Do Default CP0 initialization HERE + // Move here from FSConfig.py --zxli + // 1. CP0 Configuration + cp.CP0_PRId_CompanyOptions = 0; + cp.CP0_PRId_CompanyID = 1; + cp.CP0_PRId_ProcessorID = 147; + cp.CP0_PRId_Revision = 0; + + // 2. CP0 Interrupt Control + cp.CP0_IntCtl_IPTI = 7; + cp.CP0_IntCtl_IPPCI = 7; + + // 3. Config Register + //cp.CP0_Config_K23 = 0 # Since TLB + //cp.CP0_Config_KU = 0 # Since TLB + cp.CP0_Config_BE = 0; // Little Endian + cp.CP0_Config_AR = 1; // Architecture Revision 2 + cp.CP0_Config_AT = 0; // MIPS32 + cp.CP0_Config_MT = 1; // TLB MMU + //cp.CP0_Config_K0 = 2; // Uncached + + // 4. Config 1 Register + cp.CP0_Config1_M = 1; // Config2 Implemented + cp.CP0_Config1_MMU = 63; // TLB Size + // ***VERY IMPORTANT*** + // Remember to modify CP0_Config1 according to cache specs + // Examine file ../common/Cache.py + cp.CP0_Config1_IS = 1; // I-Cache Sets Per Way, 16KB cache, i.e., 1 (128) + cp.CP0_Config1_IL = 5; // I-Cache Line Size, default in Cache.py is 64, i.e 5 + cp.CP0_Config1_IA = 1; // I-Cache Associativity, default in Cache.py is 2, i.e, a value of 1 + cp.CP0_Config1_DS = 2; // D-Cache Sets Per Way (see below), 32KB cache, i.e., 2 + cp.CP0_Config1_DL = 5; // D-Cache Line Size, default is 64, i.e., 5 + cp.CP0_Config1_DA = 1; // D-Cache Associativity, default is 2, i.e. 1 + cp.CP0_Config1_C2 = 0; // Coprocessor 2 not implemented(?) + cp.CP0_Config1_MD = 0; // MDMX ASE not implemented in Mips32 + cp.CP0_Config1_PC = 1; // Performance Counters Implemented + cp.CP0_Config1_WR = 0; // Watch Registers Implemented + cp.CP0_Config1_CA = 0; // Mips16e NOT implemented + cp.CP0_Config1_EP = 0; // EJTag Not Implemented + cp.CP0_Config1_FP = 0; // FPU Implemented + + // 5. Config 2 Register + cp.CP0_Config2_M = 1; //Config3 Implemented + cp.CP0_Config2_TU = 0; //Tertiary Cache Control + cp.CP0_Config2_TS = 0; //Tertiary Cache Sets Per Way + cp.CP0_Config2_TL = 0; //Tertiary Cache Line Size + cp.CP0_Config2_TA = 0; //Tertiary Cache Associativity + cp.CP0_Config2_SU = 0; //Secondary Cache Control + cp.CP0_Config2_SS = 0; //Secondary Cache Sets Per Way + cp.CP0_Config2_SL = 0; //Secondary Cache Line Size + cp.CP0_Config2_SA = 0; //Secondary Cache Associativity + + // 6. Config 3 Register + cp.CP0_Config3_M = 0; //Config4 Not Implemented + cp.CP0_Config3_DSPP = 1; //DSP ASE Present + cp.CP0_Config3_LPA = 0; //Large Physical Addresses Not supported in Mips32 + cp.CP0_Config3_VEIC = 0; //EIC Supported + cp.CP0_Config3_VInt = 0; //Vectored Interrupts Implemented + cp.CP0_Config3_SP = 0; //Small Pages Supported (PageGrain reg. exists) + // Do Initialization for MT cores here (eventually use // core_name parameter to toggle this initialization) diff -r f348cf78072c src/arch/mips/isa/decoder.isa --- a/src/arch/mips/isa/decoder.isa Thu Jan 12 10:15:00 2012 -0500 +++ b/src/arch/mips/isa/decoder.isa Fri Jan 13 03:22:43 2012 +0800 @@ -649,7 +649,8 @@ StatusReg status = Status; ConfigReg config = Config; SRSCtlReg srsCtl = SRSCtl; - DPRINTF(MipsPRA,"Restoring PC - %x\n",EPC); + // TODO: here met a compiling error: NPC may be used uninitialized + DPRINTF(MipsPRA,"Restoring PC - %x, NPC=%x, NNPC=%x\n",EPC, NPC, NNPC); if (status.erl == 1) { status.erl = 0; NPC = ErrorEPC; @@ -777,6 +778,9 @@ SP = 1; } Ptr->insertAt(newEntry, Index & 0x7FFFFFFF, SP); + // Add here for unify the ITB and DTB --zxli + Ptr = xc->tcBase()->getDTBPtr(); + Ptr->insertAt(newEntry, Index & 0x7FFFFFFF, SP); }}); 0x06: tlbwr({{ //Create PTE @@ -841,7 +845,14 @@ bits(pageGrain, pageGrain.esp) == 1) { SP = 1; } - Ptr->insertAt(newEntry, Random, SP); + + // TODO: generate a real random number here + static int random = 0; + random = (random + 1) % 64; + Ptr->insertAt(newEntry, random, SP); + // Add here for unify the ITB and DTB --zxli + Ptr = xc->tcBase()->getDTBPtr(); + Ptr->insertAt(newEntry, random, SP); }}); 0x08: tlbp({{ @@ -867,9 +878,10 @@ } }}); } - format CP0Unimpl { - 0x20: wait(); - } + 0x20: BasicOp::wait({{ + // TODO: check the function of wait instruction + //fault = new CoprocessorUnusableFault(0); + }}, IsMemBarrier); default: CP0Unimpl::unknown(); } } @@ -2430,11 +2442,14 @@ } } } - 0x3: decode OP default FailUnimpl::rdhwr() { + 0x3: decode OP { 0x0: decode FULL_SYSTEM { 0: decode RD { 29: BasicOp::rdhwr_se({{ Rt = TpValue; }}); } + 1: CP0Control::rdhwr({{ + fault = new CoprocessorUnusableFault(0); + }}); } } } diff -r f348cf78072c src/arch/mips/linux/system.hh --- a/src/arch/mips/linux/system.hh Thu Jan 12 10:15:00 2012 -0500 +++ b/src/arch/mips/linux/system.hh Fri Jan 13 03:22:43 2012 +0800 @@ -33,105 +33,50 @@ #ifndef __ARCH_MIPS_LINUX_SYSTEM_HH__ #define __ARCH_MIPS_LINUX_SYSTEM_HH__ -class ThreadContext; +#include +#include -class BreakPCEvent; -class IdleStartEvent; - -#include "arch/mips/idle_event.hh" #include "arch/mips/system.hh" #include "kern/linux/events.hh" #include "params/LinuxMipsSystem.hh" -/** - * This class contains linux specific system code (Loading, Events). - * It points to objects that are the system binaries to load and patches them - * appropriately to work in simulator. - */ class LinuxMipsSystem : public MipsSystem { - private: - class SkipDelayLoopEvent : public SkipFuncEvent - { - public: - SkipDelayLoopEvent(PCEventQueue *q, const std::string &desc, Addr addr) - : SkipFuncEvent(q, desc, addr) {} - virtual void process(ThreadContext *tc); - }; - - class PrintThreadInfo : public PCEvent - { - public: - PrintThreadInfo(PCEventQueue *q, const std::string &desc, Addr addr) - : PCEvent(q, desc, addr) {} - virtual void process(ThreadContext *tc); - }; - - - /** - * Addresses defining where the kernel bootloader places various - * elements. Details found in include/asm-mips/system.h - */ - Addr KernelStart; // Lookup the symbol swapper_pg_dir + protected: + static const int ParamsList = 0x100; 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; } + /** Boilerplate params code */ + typedef LinuxMipsSystemParams Params; + const Params * + params() const + { + return dynamic_cast(_params); + } - 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; + LinuxMipsSystem(Params *p); + ~LinuxMipsSystem(); + + void initState(); private: #ifndef NDEBUG /** Event to halt the simulator if the kernel calls panic() */ BreakPCEvent *kernelPanicEvent; +#endif + /** + * PC based event to skip udelay(