isa.cc revision 8299
17405SAli.Saidi@ARM.com/*
211573SDylan.Johnson@ARM.com * Copyright (c) 2009 The Regents of The University of Michigan
37405SAli.Saidi@ARM.com * All rights reserved.
47405SAli.Saidi@ARM.com *
57405SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without
67405SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are
77405SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright
87405SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer;
97405SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright
107405SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the
117405SAli.Saidi@ARM.com * documentation and/or other materials provided with the distribution;
127405SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its
137405SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from
147405SAli.Saidi@ARM.com * this software without specific prior written permission.
157405SAli.Saidi@ARM.com *
167405SAli.Saidi@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
177405SAli.Saidi@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
187405SAli.Saidi@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
197405SAli.Saidi@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
207405SAli.Saidi@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
217405SAli.Saidi@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
227405SAli.Saidi@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
237405SAli.Saidi@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
247405SAli.Saidi@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
257405SAli.Saidi@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
267405SAli.Saidi@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
277405SAli.Saidi@ARM.com *
287405SAli.Saidi@ARM.com * Authors: Gabe Black
297405SAli.Saidi@ARM.com */
307405SAli.Saidi@ARM.com
317405SAli.Saidi@ARM.com#include "arch/mips/isa.hh"
327405SAli.Saidi@ARM.com#include "arch/mips/mt.hh"
337405SAli.Saidi@ARM.com#include "arch/mips/mt_constants.hh"
347405SAli.Saidi@ARM.com#include "arch/mips/pra_constants.hh"
357405SAli.Saidi@ARM.com#include "base/bitfield.hh"
367405SAli.Saidi@ARM.com#include "cpu/base.hh"
377405SAli.Saidi@ARM.com#include "cpu/thread_context.hh"
387405SAli.Saidi@ARM.com#include "debug/MipsPRA.hh"
397405SAli.Saidi@ARM.com
407405SAli.Saidi@ARM.comnamespace MipsISA
417405SAli.Saidi@ARM.com{
4211793Sbrandon.potter@amd.com
4310461SAndreas.Sandberg@ARM.comstd::string
449050Schander.sudanthi@arm.comISA::miscRegNames[NumMiscRegs] =
4511793Sbrandon.potter@amd.com{
468887Sgeoffrey.blake@arm.com    "Index", "MVPControl", "MVPConf0", "MVPConf1", "", "", "", "",
478232Snate@binkert.org    "Random", "VPEControl", "VPEConf0", "VPEConf1",
488232Snate@binkert.org        "YQMask", "VPESchedule", "VPEScheFBack", "VPEOpt",
4910844Sandreas.sandberg@arm.com    "EntryLo0", "TCStatus", "TCBind", "TCRestart",
509384SAndreas.Sandberg@arm.com        "TCHalt", "TCContext", "TCSchedule", "TCScheFBack",
517678Sgblack@eecs.umich.edu    "EntryLo1", "", "", "", "", "", "", "",
528059SAli.Saidi@ARM.com    "Context", "ContextConfig", "", "", "", "", "", "",
538284SAli.Saidi@ARM.com    "PageMask", "PageGrain", "", "", "", "", "", "",
547405SAli.Saidi@ARM.com    "Wired", "SRSConf0", "SRCConf1", "SRSConf2",
557405SAli.Saidi@ARM.com        "SRSConf3", "SRSConf4", "", "",
567405SAli.Saidi@ARM.com    "HWREna", "", "", "", "", "", "", "",
577405SAli.Saidi@ARM.com    "BadVAddr", "", "", "", "", "", "", "",
5810037SARM gem5 Developers    "Count", "", "", "", "", "", "", "",
5910037SARM gem5 Developers    "EntryHi", "", "", "", "", "", "", "",
6011768SCurtis.Dunham@arm.com    "Compare", "", "", "", "", "", "", "",
6110037SARM gem5 Developers    "Status", "IntCtl", "SRSCtl", "SRSMap", "", "", "", "",
6210037SARM gem5 Developers    "Cause", "", "", "", "", "", "", "",
6310037SARM gem5 Developers    "EPC", "", "", "", "", "", "", "",
6410037SARM gem5 Developers    "PRId", "EBase", "", "", "", "", "", "",
6511768SCurtis.Dunham@arm.com    "Config", "Config1", "Config2", "Config3", "", "", "", "",
6610037SARM gem5 Developers    "LLAddr", "", "", "", "", "", "", "",
6710037SARM gem5 Developers    "WatchLo0", "WatchLo1", "WatchLo2", "WatchLo3",
6811768SCurtis.Dunham@arm.com        "WatchLo4", "WatchLo5", "WatchLo6", "WatchLo7",
6911768SCurtis.Dunham@arm.com    "WatchHi0", "WatchHi1", "WatchHi2", "WatchHi3",
7011768SCurtis.Dunham@arm.com        "WatchHi4", "WatchHi5", "WatchHi6", "WatchHi7",
7111768SCurtis.Dunham@arm.com    "XCContext64", "", "", "", "", "", "", "",
7211768SCurtis.Dunham@arm.com    "", "", "", "", "", "", "", "",
7311768SCurtis.Dunham@arm.com    "", "", "", "", "", "", "", "",
7411768SCurtis.Dunham@arm.com    "Debug", "TraceControl1", "TraceControl2", "UserTraceData",
7511768SCurtis.Dunham@arm.com        "TraceBPC", "", "", "",
7611768SCurtis.Dunham@arm.com    "DEPC", "", "", "", "", "", "", "",
7711768SCurtis.Dunham@arm.com    "PerfCnt0", "PerfCnt1", "PerfCnt2", "PerfCnt3",
7811768SCurtis.Dunham@arm.com        "PerfCnt4", "PerfCnt5", "PerfCnt6", "PerfCnt7",
7911768SCurtis.Dunham@arm.com    "ErrCtl", "", "", "", "", "", "", "",
8010037SARM gem5 Developers    "CacheErr0", "CacheErr1", "CacheErr2", "CacheErr3", "", "", "", "",
8110037SARM gem5 Developers    "TagLo0", "DataLo1", "TagLo2", "DataLo3",
8210037SARM gem5 Developers        "TagLo4", "DataLo5", "TagLo6", "DataLo7",
8311768SCurtis.Dunham@arm.com    "TagHi0", "DataHi1", "TagHi2", "DataHi3",
8411768SCurtis.Dunham@arm.com        "TagHi4", "DataHi5", "TagHi6", "DataHi7",
8511768SCurtis.Dunham@arm.com    "ErrorEPC", "", "", "", "", "", "", "",
8611768SCurtis.Dunham@arm.com    "DESAVE", "", "", "", "", "", "", "",
8711768SCurtis.Dunham@arm.com    "LLFlag"
8811768SCurtis.Dunham@arm.com};
8911768SCurtis.Dunham@arm.com
9011768SCurtis.Dunham@arm.comISA::ISA(uint8_t num_threads, uint8_t num_vpes)
9110037SARM gem5 Developers{
9211768SCurtis.Dunham@arm.com    numThreads = num_threads;
9311768SCurtis.Dunham@arm.com    numVpes = num_vpes;
9411768SCurtis.Dunham@arm.com
9511768SCurtis.Dunham@arm.com    miscRegFile.resize(NumMiscRegs);
9610037SARM gem5 Developers    bankType.resize(NumMiscRegs);
9711768SCurtis.Dunham@arm.com
9811768SCurtis.Dunham@arm.com    for (int i=0; i < NumMiscRegs; i++) {
9911768SCurtis.Dunham@arm.com        miscRegFile[i].resize(1);
10011768SCurtis.Dunham@arm.com        bankType[i] = perProcessor;
10111768SCurtis.Dunham@arm.com    }
10211768SCurtis.Dunham@arm.com
10311768SCurtis.Dunham@arm.com    miscRegFile_WriteMask.resize(NumMiscRegs);
10411768SCurtis.Dunham@arm.com
10511768SCurtis.Dunham@arm.com    for (int i = 0; i < NumMiscRegs; i++) {
10611768SCurtis.Dunham@arm.com        miscRegFile_WriteMask[i].push_back(0);
10711768SCurtis.Dunham@arm.com    }
10811768SCurtis.Dunham@arm.com
10911768SCurtis.Dunham@arm.com    // Initialize all Per-VPE regs
11011768SCurtis.Dunham@arm.com    uint32_t per_vpe_regs[] = { MISCREG_VPE_CONTROL,
11111768SCurtis.Dunham@arm.com                                MISCREG_VPE_CONF0, MISCREG_VPE_CONF1,
11211768SCurtis.Dunham@arm.com                                MISCREG_YQMASK,
11311768SCurtis.Dunham@arm.com                                MISCREG_VPE_SCHEDULE, MISCREG_VPE_SCHEFBACK,
11411768SCurtis.Dunham@arm.com                                MISCREG_VPE_OPT, MISCREG_SRS_CONF0,
11510037SARM gem5 Developers                                MISCREG_SRS_CONF1, MISCREG_SRS_CONF2,
11611768SCurtis.Dunham@arm.com                                MISCREG_SRS_CONF3, MISCREG_SRS_CONF4,
11711768SCurtis.Dunham@arm.com                                MISCREG_EBASE
11811768SCurtis.Dunham@arm.com                              };
11911768SCurtis.Dunham@arm.com    uint32_t num_vpe_regs = sizeof(per_vpe_regs) / 4;
12010037SARM gem5 Developers    for (int i = 0; i < num_vpe_regs; i++) {
12111768SCurtis.Dunham@arm.com        if (numVpes > 1) {
12211768SCurtis.Dunham@arm.com            miscRegFile[per_vpe_regs[i]].resize(numVpes);
12311768SCurtis.Dunham@arm.com        }
12411768SCurtis.Dunham@arm.com        bankType[per_vpe_regs[i]] = perVirtProcessor;
12511768SCurtis.Dunham@arm.com    }
12611768SCurtis.Dunham@arm.com
12710037SARM gem5 Developers    // Initialize all Per-TC regs
12811768SCurtis.Dunham@arm.com    uint32_t per_tc_regs[] = { MISCREG_STATUS,
12911768SCurtis.Dunham@arm.com                               MISCREG_TC_STATUS, MISCREG_TC_BIND,
13011768SCurtis.Dunham@arm.com                               MISCREG_TC_RESTART, MISCREG_TC_HALT,
13111768SCurtis.Dunham@arm.com                               MISCREG_TC_CONTEXT, MISCREG_TC_SCHEDULE,
13211768SCurtis.Dunham@arm.com                               MISCREG_TC_SCHEFBACK,
13311768SCurtis.Dunham@arm.com                               MISCREG_DEBUG, MISCREG_LLADDR
13411768SCurtis.Dunham@arm.com                             };
13511768SCurtis.Dunham@arm.com    uint32_t num_tc_regs = sizeof(per_tc_regs) /  4;
13611768SCurtis.Dunham@arm.com
13711768SCurtis.Dunham@arm.com    for (int i = 0; i < num_tc_regs; i++) {
13811768SCurtis.Dunham@arm.com        miscRegFile[per_tc_regs[i]].resize(numThreads);
13911768SCurtis.Dunham@arm.com        bankType[per_tc_regs[i]] = perThreadContext;
14011768SCurtis.Dunham@arm.com    }
14111768SCurtis.Dunham@arm.com
14211768SCurtis.Dunham@arm.com    clear();
14311768SCurtis.Dunham@arm.com}
14411768SCurtis.Dunham@arm.com
14511768SCurtis.Dunham@arm.comvoid
14611768SCurtis.Dunham@arm.comISA::clear()
14711768SCurtis.Dunham@arm.com{
14811768SCurtis.Dunham@arm.com    for(int i = 0; i < NumMiscRegs; i++) {
14911768SCurtis.Dunham@arm.com        for (int j = 0; j < miscRegFile[i].size(); j++)
15011768SCurtis.Dunham@arm.com            miscRegFile[i][j] = 0;
15111768SCurtis.Dunham@arm.com
15211768SCurtis.Dunham@arm.com        for (int k = 0; k < miscRegFile_WriteMask[i].size(); k++)
15311768SCurtis.Dunham@arm.com            miscRegFile_WriteMask[i][k] = (long unsigned int)(-1);
15411768SCurtis.Dunham@arm.com    }
15511768SCurtis.Dunham@arm.com}
15611768SCurtis.Dunham@arm.com
15711768SCurtis.Dunham@arm.com
15811768SCurtis.Dunham@arm.comvoid
15911768SCurtis.Dunham@arm.comISA::configCP()
16011768SCurtis.Dunham@arm.com{
16111768SCurtis.Dunham@arm.com    DPRINTF(MipsPRA, "Resetting CP0 State with %i TCs and %i VPEs\n",
16211768SCurtis.Dunham@arm.com            numThreads, numVpes);
16311768SCurtis.Dunham@arm.com
16411768SCurtis.Dunham@arm.com    CoreSpecific cp;
16511768SCurtis.Dunham@arm.com    panic("CP state must be set before the following code is used");
16611768SCurtis.Dunham@arm.com
16711768SCurtis.Dunham@arm.com    // Do Default CP0 initialization HERE
16811768SCurtis.Dunham@arm.com
16911768SCurtis.Dunham@arm.com    // Do Initialization for MT cores here (eventually use
17011768SCurtis.Dunham@arm.com    // core_name parameter to toggle this initialization)
17111768SCurtis.Dunham@arm.com    // ===================================================
17211768SCurtis.Dunham@arm.com    DPRINTF(MipsPRA, "Initializing CP0 State.... ");
17311768SCurtis.Dunham@arm.com
17411768SCurtis.Dunham@arm.com    PRIdReg procId = readMiscRegNoEffect(MISCREG_PRID);
17511768SCurtis.Dunham@arm.com    procId.coOp = cp.CP0_PRId_CompanyOptions;
17611768SCurtis.Dunham@arm.com    procId.coId = cp.CP0_PRId_CompanyID;
17711768SCurtis.Dunham@arm.com    procId.procId = cp.CP0_PRId_ProcessorID;
17811768SCurtis.Dunham@arm.com    procId.rev = cp.CP0_PRId_Revision;
17911768SCurtis.Dunham@arm.com    setMiscRegNoEffect(MISCREG_PRID, procId);
18011768SCurtis.Dunham@arm.com
18111768SCurtis.Dunham@arm.com    // Now, create Write Mask for ProcID register
18211768SCurtis.Dunham@arm.com    MiscReg procIDMask = 0; // Read-Only register
18311768SCurtis.Dunham@arm.com    replaceBits(procIDMask, 0, 32, 0);
18411768SCurtis.Dunham@arm.com    setRegMask(MISCREG_PRID, procIDMask);
18511768SCurtis.Dunham@arm.com
18611768SCurtis.Dunham@arm.com    // Config
18711768SCurtis.Dunham@arm.com    ConfigReg cfg = readMiscRegNoEffect(MISCREG_CONFIG);
18811768SCurtis.Dunham@arm.com    cfg.be = cp.CP0_Config_BE;
18911768SCurtis.Dunham@arm.com    cfg.at = cp.CP0_Config_AT;
19011768SCurtis.Dunham@arm.com    cfg.ar = cp.CP0_Config_AR;
19111768SCurtis.Dunham@arm.com    cfg.mt = cp.CP0_Config_MT;
19211768SCurtis.Dunham@arm.com    cfg.vi = cp.CP0_Config_VI;
19311768SCurtis.Dunham@arm.com    cfg.m = 1;
19411768SCurtis.Dunham@arm.com    setMiscRegNoEffect(MISCREG_CONFIG, cfg);
19511768SCurtis.Dunham@arm.com    // Now, create Write Mask for Config register
19611768SCurtis.Dunham@arm.com    MiscReg cfg_Mask = 0x7FFF0007;
19711768SCurtis.Dunham@arm.com    replaceBits(cfg_Mask, 0, 32, 0);
19811768SCurtis.Dunham@arm.com    setRegMask(MISCREG_CONFIG, cfg_Mask);
19911768SCurtis.Dunham@arm.com
20011768SCurtis.Dunham@arm.com    // Config1
20111768SCurtis.Dunham@arm.com    Config1Reg cfg1 = readMiscRegNoEffect(MISCREG_CONFIG1);
20211768SCurtis.Dunham@arm.com    cfg1.mmuSize = cp.CP0_Config1_MMU;
20311768SCurtis.Dunham@arm.com    cfg1.is = cp.CP0_Config1_IS;
20411768SCurtis.Dunham@arm.com    cfg1.il = cp.CP0_Config1_IL;
20510037SARM gem5 Developers    cfg1.ia = cp.CP0_Config1_IA;
20610037SARM gem5 Developers    cfg1.ds = cp.CP0_Config1_DS;
20710037SARM gem5 Developers    cfg1.dl = cp.CP0_Config1_DL;
2089384SAndreas.Sandberg@arm.com    cfg1.da = cp.CP0_Config1_DA;
20910461SAndreas.Sandberg@ARM.com    cfg1.fp = cp.CP0_Config1_FP;
21010461SAndreas.Sandberg@ARM.com    cfg1.ep = cp.CP0_Config1_EP;
21111165SRekai.GonzalezAlberquilla@arm.com    cfg1.wr = cp.CP0_Config1_WR;
21212109SRekai.GonzalezAlberquilla@arm.com    cfg1.md = cp.CP0_Config1_MD;
21310461SAndreas.Sandberg@ARM.com    cfg1.c2 = cp.CP0_Config1_C2;
21410461SAndreas.Sandberg@ARM.com    cfg1.pc = cp.CP0_Config1_PC;
2159384SAndreas.Sandberg@arm.com    cfg1.m = cp.CP0_Config1_M;
21611770SCurtis.Dunham@arm.com    setMiscRegNoEffect(MISCREG_CONFIG1, cfg1);
21710037SARM gem5 Developers    // Now, create Write Mask for Config register
21810461SAndreas.Sandberg@ARM.com    MiscReg cfg1_Mask = 0; // Read Only Register
21910461SAndreas.Sandberg@ARM.com    replaceBits(cfg1_Mask, 0, 32, 0);
22010461SAndreas.Sandberg@ARM.com    setRegMask(MISCREG_CONFIG1, cfg1_Mask);
22110461SAndreas.Sandberg@ARM.com
22210461SAndreas.Sandberg@ARM.com    // Config2
22310461SAndreas.Sandberg@ARM.com    Config2Reg cfg2 = readMiscRegNoEffect(MISCREG_CONFIG2);
22410609Sandreas.sandberg@arm.com    cfg2.tu = cp.CP0_Config2_TU;
22510609Sandreas.sandberg@arm.com    cfg2.ts = cp.CP0_Config2_TS;
22610609Sandreas.sandberg@arm.com    cfg2.tl = cp.CP0_Config2_TL;
22710037SARM gem5 Developers    cfg2.ta = cp.CP0_Config2_TA;
22810037SARM gem5 Developers    cfg2.su = cp.CP0_Config2_SU;
22910037SARM gem5 Developers    cfg2.ss = cp.CP0_Config2_SS;
23010037SARM gem5 Developers    cfg2.sl = cp.CP0_Config2_SL;
23111771SCurtis.Dunham@arm.com    cfg2.sa = cp.CP0_Config2_SA;
23210037SARM gem5 Developers    cfg2.m = cp.CP0_Config2_M;
23310037SARM gem5 Developers    setMiscRegNoEffect(MISCREG_CONFIG2, cfg2);
23410037SARM gem5 Developers    // Now, create Write Mask for Config register
23510037SARM gem5 Developers    MiscReg cfg2_Mask = 0x7000F000; // Read Only Register
23610037SARM gem5 Developers    replaceBits(cfg2_Mask, 0, 32, 0);
23710037SARM gem5 Developers    setRegMask(MISCREG_CONFIG2, cfg2_Mask);
23811771SCurtis.Dunham@arm.com
23910037SARM gem5 Developers    // Config3
24010037SARM gem5 Developers    Config3Reg cfg3 = readMiscRegNoEffect(MISCREG_CONFIG3);
24110037SARM gem5 Developers    cfg3.dspp = cp.CP0_Config3_DSPP;
24210037SARM gem5 Developers    cfg3.lpa = cp.CP0_Config3_LPA;
24310037SARM gem5 Developers    cfg3.veic = cp.CP0_Config3_VEIC;
24410037SARM gem5 Developers    cfg3.vint = cp.CP0_Config3_VInt;
24511768SCurtis.Dunham@arm.com    cfg3.sp = cp.CP0_Config3_SP;
24611768SCurtis.Dunham@arm.com    cfg3.mt = cp.CP0_Config3_MT;
24710037SARM gem5 Developers    cfg3.sm = cp.CP0_Config3_SM;
24810037SARM gem5 Developers    cfg3.tl = cp.CP0_Config3_TL;
24910037SARM gem5 Developers    setMiscRegNoEffect(MISCREG_CONFIG3, cfg3);
25010037SARM gem5 Developers    // Now, create Write Mask for Config register
2519384SAndreas.Sandberg@arm.com    MiscReg cfg3_Mask = 0; // Read Only Register
2529384SAndreas.Sandberg@arm.com    replaceBits(cfg3_Mask, 0, 32, 0);
2539384SAndreas.Sandberg@arm.com    setRegMask(MISCREG_CONFIG3, cfg3_Mask);
2549384SAndreas.Sandberg@arm.com
2559384SAndreas.Sandberg@arm.com    // EBase - CPUNum
2569384SAndreas.Sandberg@arm.com    EBaseReg eBase = readMiscRegNoEffect(MISCREG_EBASE);
2579384SAndreas.Sandberg@arm.com    eBase.cpuNum = cp.CP0_EBase_CPUNum;
2589384SAndreas.Sandberg@arm.com    replaceBits(eBase, 31, 31, 1);
2599384SAndreas.Sandberg@arm.com    setMiscRegNoEffect(MISCREG_EBASE, eBase);
2607427Sgblack@eecs.umich.edu    // Now, create Write Mask for Config register
2617427Sgblack@eecs.umich.edu    MiscReg EB_Mask = 0x3FFFF000;// Except Exception Base, the
2627427Sgblack@eecs.umich.edu                                 // entire register is read only
2639385SAndreas.Sandberg@arm.com    replaceBits(EB_Mask, 0, 32, 0);
2649385SAndreas.Sandberg@arm.com    setRegMask(MISCREG_EBASE, EB_Mask);
2657427Sgblack@eecs.umich.edu
2667427Sgblack@eecs.umich.edu    // SRS Control - HSS (Highest Shadow Set)
26710037SARM gem5 Developers    SRSCtlReg scsCtl = readMiscRegNoEffect(MISCREG_SRSCTL);
26810037SARM gem5 Developers    scsCtl.hss = cp.CP0_SrsCtl_HSS;
26910037SARM gem5 Developers    setMiscRegNoEffect(MISCREG_SRSCTL, scsCtl);
27010037SARM gem5 Developers    // Now, create Write Mask for the SRS Ctl register
27110037SARM gem5 Developers    MiscReg SC_Mask = 0x0000F3C0;
27210037SARM gem5 Developers    replaceBits(SC_Mask, 0, 32, 0);
27310037SARM gem5 Developers    setRegMask(MISCREG_SRSCTL, SC_Mask);
27410037SARM gem5 Developers
27510037SARM gem5 Developers    // IntCtl - IPTI, IPPCI
27610037SARM gem5 Developers    IntCtlReg intCtl = readMiscRegNoEffect(MISCREG_INTCTL);
27710037SARM gem5 Developers    intCtl.ipti = cp.CP0_IntCtl_IPTI;
27810037SARM gem5 Developers    intCtl.ippci = cp.CP0_IntCtl_IPPCI;
27910037SARM gem5 Developers    setMiscRegNoEffect(MISCREG_INTCTL, intCtl);
28010037SARM gem5 Developers    // Now, create Write Mask for the IntCtl register
2817427Sgblack@eecs.umich.edu    MiscReg IC_Mask = 0x000003E0;
2827427Sgblack@eecs.umich.edu    replaceBits(IC_Mask, 0, 32, 0);
2837427Sgblack@eecs.umich.edu    setRegMask(MISCREG_INTCTL, IC_Mask);
2847427Sgblack@eecs.umich.edu
2857427Sgblack@eecs.umich.edu    // Watch Hi - M - FIXME (More than 1 Watch register)
2867427Sgblack@eecs.umich.edu    WatchHiReg watchHi = readMiscRegNoEffect(MISCREG_WATCHHI0);
28710037SARM gem5 Developers    watchHi.m = cp.CP0_WatchHi_M;
28810037SARM gem5 Developers    setMiscRegNoEffect(MISCREG_WATCHHI0, watchHi);
28910037SARM gem5 Developers    // Now, create Write Mask for the IntCtl register
29010037SARM gem5 Developers    MiscReg wh_Mask = 0x7FFF0FFF;
2917427Sgblack@eecs.umich.edu    replaceBits(wh_Mask, 0, 32, 0);
2927427Sgblack@eecs.umich.edu    setRegMask(MISCREG_WATCHHI0, wh_Mask);
2937427Sgblack@eecs.umich.edu
29410037SARM gem5 Developers    // Perf Ctr - M - FIXME (More than 1 PerfCnt Pair)
29510204SAli.Saidi@ARM.com    PerfCntCtlReg perfCntCtl = readMiscRegNoEffect(MISCREG_PERFCNT0);
29610204SAli.Saidi@ARM.com    perfCntCtl.m = cp.CP0_PerfCtr_M;
29710037SARM gem5 Developers    perfCntCtl.w = cp.CP0_PerfCtr_W;
2987427Sgblack@eecs.umich.edu    setMiscRegNoEffect(MISCREG_PERFCNT0, perfCntCtl);
29910037SARM gem5 Developers    // Now, create Write Mask for the IntCtl register
3007427Sgblack@eecs.umich.edu    MiscReg pc_Mask = 0x00007FF;
30110037SARM gem5 Developers    replaceBits(pc_Mask, 0, 32, 0);
3027427Sgblack@eecs.umich.edu    setRegMask(MISCREG_PERFCNT0, pc_Mask);
3037427Sgblack@eecs.umich.edu
30410037SARM gem5 Developers    // Random
3057427Sgblack@eecs.umich.edu    setMiscRegNoEffect(MISCREG_CP0_RANDOM, 63);
3067427Sgblack@eecs.umich.edu    // Now, create Write Mask for the IntCtl register
3077427Sgblack@eecs.umich.edu    MiscReg random_Mask = 0;
3087427Sgblack@eecs.umich.edu    replaceBits(random_Mask, 0, 32, 0);
3097427Sgblack@eecs.umich.edu    setRegMask(MISCREG_CP0_RANDOM, random_Mask);
3107427Sgblack@eecs.umich.edu
3117427Sgblack@eecs.umich.edu    // PageGrain
3127427Sgblack@eecs.umich.edu    PageGrainReg pageGrain = readMiscRegNoEffect(MISCREG_PAGEGRAIN);
3137427Sgblack@eecs.umich.edu    pageGrain.esp = cp.CP0_Config3_SP;
3147427Sgblack@eecs.umich.edu    setMiscRegNoEffect(MISCREG_PAGEGRAIN, pageGrain);
3157427Sgblack@eecs.umich.edu    // Now, create Write Mask for the IntCtl register
3167427Sgblack@eecs.umich.edu    MiscReg pg_Mask = 0x10000000;
3177427Sgblack@eecs.umich.edu    replaceBits(pg_Mask, 0, 32, 0);
3187427Sgblack@eecs.umich.edu    setRegMask(MISCREG_PAGEGRAIN, pg_Mask);
3197427Sgblack@eecs.umich.edu
3207427Sgblack@eecs.umich.edu    // Status
3217427Sgblack@eecs.umich.edu    StatusReg status = readMiscRegNoEffect(MISCREG_STATUS);
3227427Sgblack@eecs.umich.edu    // Only CU0 and IE are modified on a reset - everything else needs
3237427Sgblack@eecs.umich.edu    // to be controlled on a per CPU model basis
3247427Sgblack@eecs.umich.edu
3257427Sgblack@eecs.umich.edu    // Enable CP0 on reset
3267427Sgblack@eecs.umich.edu    // status.cu0 = 1;
3277427Sgblack@eecs.umich.edu
3287436Sdam.sunwoo@arm.com    // Enable ERL bit on a reset
3297436Sdam.sunwoo@arm.com    status.erl = 1;
33010037SARM gem5 Developers    // Enable BEV bit on a reset
33110037SARM gem5 Developers    status.bev = 1;
3327436Sdam.sunwoo@arm.com
3337436Sdam.sunwoo@arm.com    setMiscRegNoEffect(MISCREG_STATUS, status);
3347436Sdam.sunwoo@arm.com    // Now, create Write Mask for the Status register
3357436Sdam.sunwoo@arm.com    MiscReg stat_Mask = 0xFF78FF17;
3367436Sdam.sunwoo@arm.com    replaceBits(stat_Mask, 0, 32, 0);
3377436Sdam.sunwoo@arm.com    setRegMask(MISCREG_STATUS, stat_Mask);
3387436Sdam.sunwoo@arm.com
3397436Sdam.sunwoo@arm.com
3407436Sdam.sunwoo@arm.com    // MVPConf0
3417436Sdam.sunwoo@arm.com    MVPConf0Reg mvpConf0 = readMiscRegNoEffect(MISCREG_MVP_CONF0);
3427436Sdam.sunwoo@arm.com    mvpConf0.tca = 1;
3437436Sdam.sunwoo@arm.com    mvpConf0.pvpe = numVpes - 1;
34410037SARM gem5 Developers    mvpConf0.ptc = numThreads - 1;
3457436Sdam.sunwoo@arm.com    setMiscRegNoEffect(MISCREG_MVP_CONF0, mvpConf0);
3467436Sdam.sunwoo@arm.com
3477436Sdam.sunwoo@arm.com    // VPEConf0
3487436Sdam.sunwoo@arm.com    VPEConf0Reg vpeConf0 = readMiscRegNoEffect(MISCREG_VPE_CONF0);
3497436Sdam.sunwoo@arm.com    vpeConf0.mvp = 1;
3507436Sdam.sunwoo@arm.com    setMiscRegNoEffect(MISCREG_VPE_CONF0, vpeConf0);
3517436Sdam.sunwoo@arm.com
3527436Sdam.sunwoo@arm.com    // TCBind
3537436Sdam.sunwoo@arm.com    for (ThreadID tid = 0; tid < numThreads; tid++) {
3547436Sdam.sunwoo@arm.com        TCBindReg tcBind = readMiscRegNoEffect(MISCREG_TC_BIND, tid);
3557436Sdam.sunwoo@arm.com        tcBind.curTC = tid;
3567436Sdam.sunwoo@arm.com        setMiscRegNoEffect(MISCREG_TC_BIND, tcBind, tid);
3577436Sdam.sunwoo@arm.com    }
3587436Sdam.sunwoo@arm.com    // TCHalt
3597436Sdam.sunwoo@arm.com    TCHaltReg tcHalt = readMiscRegNoEffect(MISCREG_TC_HALT);
3607436Sdam.sunwoo@arm.com    tcHalt.h = 0;
3617644Sali.saidi@arm.com    setMiscRegNoEffect(MISCREG_TC_HALT, tcHalt);
3628147SAli.Saidi@ARM.com
3639385SAndreas.Sandberg@arm.com    // TCStatus
3649385SAndreas.Sandberg@arm.com    // Set TCStatus Activated to 1 for the initial thread that is running
3659385SAndreas.Sandberg@arm.com    TCStatusReg tcStatus = readMiscRegNoEffect(MISCREG_TC_STATUS);
3669385SAndreas.Sandberg@arm.com    tcStatus.a = 1;
3679385SAndreas.Sandberg@arm.com    setMiscRegNoEffect(MISCREG_TC_STATUS, tcStatus);
3689385SAndreas.Sandberg@arm.com
3699385SAndreas.Sandberg@arm.com    // Set Dynamically Allocatable bit to 1 for all other threads
3709385SAndreas.Sandberg@arm.com    for (ThreadID tid = 1; tid < numThreads; tid++) {
3719385SAndreas.Sandberg@arm.com        tcStatus = readMiscRegNoEffect(MISCREG_TC_STATUS, tid);
3729385SAndreas.Sandberg@arm.com        tcStatus.da = 1;
3739385SAndreas.Sandberg@arm.com        setMiscRegNoEffect(MISCREG_TC_STATUS, tcStatus, tid);
3749385SAndreas.Sandberg@arm.com    }
3759385SAndreas.Sandberg@arm.com
3769385SAndreas.Sandberg@arm.com
37710037SARM gem5 Developers    MiscReg mask = 0x7FFFFFFF;
37810037SARM gem5 Developers
37910037SARM gem5 Developers    // Now, create Write Mask for the Index register
38010037SARM gem5 Developers    replaceBits(mask, 0, 32, 0);
38110037SARM gem5 Developers    setRegMask(MISCREG_INDEX, mask);
38210037SARM gem5 Developers
38310037SARM gem5 Developers    mask = 0x3FFFFFFF;
38410037SARM gem5 Developers    replaceBits(mask, 0, 32, 0);
38510037SARM gem5 Developers    setRegMask(MISCREG_ENTRYLO0, mask);
38610037SARM gem5 Developers    setRegMask(MISCREG_ENTRYLO1, mask);
38710037SARM gem5 Developers
38810037SARM gem5 Developers    mask = 0xFF800000;
38910037SARM gem5 Developers    replaceBits(mask, 0, 32, 0);
39010037SARM gem5 Developers    setRegMask(MISCREG_CONTEXT, mask);
39110037SARM gem5 Developers
39210037SARM gem5 Developers    mask = 0x1FFFF800;
3938147SAli.Saidi@ARM.com    replaceBits(mask, 0, 32, 0);
3947427Sgblack@eecs.umich.edu    setRegMask(MISCREG_PAGEMASK, mask);
3957427Sgblack@eecs.umich.edu
3967427Sgblack@eecs.umich.edu    mask = 0x0;
39710037SARM gem5 Developers    replaceBits(mask, 0, 32, 0);
39810037SARM gem5 Developers    setRegMask(MISCREG_BADVADDR, mask);
39910037SARM gem5 Developers    setRegMask(MISCREG_LLADDR, mask);
40010037SARM gem5 Developers
40110037SARM gem5 Developers    mask = 0x08C00300;
40210037SARM gem5 Developers    replaceBits(mask, 0, 32, 0);
40310037SARM gem5 Developers    setRegMask(MISCREG_CAUSE, mask);
40410037SARM gem5 Developers
40510037SARM gem5 Developers}
40610037SARM gem5 Developers
40710037SARM gem5 Developersinline unsigned
40810037SARM gem5 DevelopersISA::getVPENum(ThreadID tid)
40910037SARM gem5 Developers{
41010037SARM gem5 Developers    TCBindReg tcBind = miscRegFile[MISCREG_TC_BIND][tid];
41110037SARM gem5 Developers    return tcBind.curVPE;
41210037SARM gem5 Developers}
41310037SARM gem5 Developers
41410037SARM gem5 DevelopersMiscReg
41510037SARM gem5 DevelopersISA::readMiscRegNoEffect(int misc_reg, ThreadID tid)
41610037SARM gem5 Developers{
41710037SARM gem5 Developers    unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
41810037SARM gem5 Developers        ? tid : getVPENum(tid);
41910037SARM gem5 Developers    DPRINTF(MipsPRA, "Reading CP0 Register:%u Select:%u (%s) (%lx).\n",
42010037SARM gem5 Developers            misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg],
42110037SARM gem5 Developers            miscRegFile[misc_reg][reg_sel]);
42210037SARM gem5 Developers    return miscRegFile[misc_reg][reg_sel];
42310037SARM gem5 Developers}
42410037SARM gem5 Developers
42510037SARM gem5 Developers//@TODO: MIPS MT's register view automatically connects
42610037SARM gem5 Developers//       Status to TCStatus depending on current thread
42710037SARM gem5 Developers//template <class TC>
42810037SARM gem5 DevelopersMiscReg
42910037SARM gem5 DevelopersISA::readMiscReg(int misc_reg, ThreadContext *tc,  ThreadID tid)
43010037SARM gem5 Developers{
43110037SARM gem5 Developers    unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
43210037SARM gem5 Developers        ? tid : getVPENum(tid);
43311770SCurtis.Dunham@arm.com    DPRINTF(MipsPRA,
43410037SARM gem5 Developers            "Reading CP0 Register:%u Select:%u (%s) with effect (%lx).\n",
43511574SCurtis.Dunham@arm.com            misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg],
43611770SCurtis.Dunham@arm.com            miscRegFile[misc_reg][reg_sel]);
43711770SCurtis.Dunham@arm.com
43810037SARM gem5 Developers    return miscRegFile[misc_reg][reg_sel];
43911770SCurtis.Dunham@arm.com}
44011770SCurtis.Dunham@arm.com
44110037SARM gem5 Developersvoid
44210037SARM gem5 DevelopersISA::setMiscRegNoEffect(int misc_reg, const MiscReg &val, ThreadID tid)
44310037SARM gem5 Developers{
44410037SARM gem5 Developers    unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
44510037SARM gem5 Developers        ? tid : getVPENum(tid);
44610037SARM gem5 Developers    DPRINTF(MipsPRA,
44710037SARM gem5 Developers            "[tid:%i]: Setting (direct set) CP0 Register:%u "
44810461SAndreas.Sandberg@ARM.com            "Select:%u (%s) to %#x.\n",
44910461SAndreas.Sandberg@ARM.com            tid, misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], val);
45010461SAndreas.Sandberg@ARM.com
45110461SAndreas.Sandberg@ARM.com    miscRegFile[misc_reg][reg_sel] = val;
45210037SARM gem5 Developers}
45310037SARM gem5 Developers
45410037SARM gem5 Developersvoid
45510037SARM gem5 DevelopersISA::setRegMask(int misc_reg, const MiscReg &val, ThreadID tid)
45610037SARM gem5 Developers{
45710037SARM gem5 Developers    unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
45810461SAndreas.Sandberg@ARM.com        ? tid : getVPENum(tid);
45910461SAndreas.Sandberg@ARM.com    DPRINTF(MipsPRA,
46010461SAndreas.Sandberg@ARM.com            "[tid:%i]: Setting CP0 Register: %u Select: %u (%s) to %#x\n",
46110461SAndreas.Sandberg@ARM.com            tid, misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], val);
46210461SAndreas.Sandberg@ARM.com    miscRegFile_WriteMask[misc_reg][reg_sel] = val;
46310037SARM gem5 Developers}
46410037SARM gem5 Developers
46510037SARM gem5 Developers// PROGRAMMER'S NOTES:
46610037SARM gem5 Developers// (1) Some CP0 Registers have fields that cannot
46710037SARM gem5 Developers// be overwritten. Make sure to handle those particular registers
46811574SCurtis.Dunham@arm.com// with care!
46910037SARM gem5 Developersvoid
47010037SARM gem5 DevelopersISA::setMiscReg(int misc_reg, const MiscReg &val,
47110037SARM gem5 Developers                    ThreadContext *tc, ThreadID tid)
47211574SCurtis.Dunham@arm.com{
47310037SARM gem5 Developers    int reg_sel = (bankType[misc_reg] == perThreadContext)
47410037SARM gem5 Developers        ? tid : getVPENum(tid);
47510037SARM gem5 Developers
47610037SARM gem5 Developers    DPRINTF(MipsPRA,
47710037SARM gem5 Developers            "[tid:%i]: Setting CP0 Register:%u "
47810037SARM gem5 Developers            "Select:%u (%s) to %#x, with effect.\n",
47910037SARM gem5 Developers            tid, misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], val);
48010037SARM gem5 Developers
48110037SARM gem5 Developers    MiscReg cp0_val = filterCP0Write(misc_reg, reg_sel, val);
48210037SARM gem5 Developers
4837405SAli.Saidi@ARM.com    miscRegFile[misc_reg][reg_sel] = cp0_val;
48410035Sandreas.hansson@arm.com
4857405SAli.Saidi@ARM.com    scheduleCP0Update(tc->getCpuPtr(), 1);
4867405SAli.Saidi@ARM.com}
4877614Sminkyu.jeong@arm.com
48811771SCurtis.Dunham@arm.com/**
48911771SCurtis.Dunham@arm.com * This method doesn't need to adjust the Control Register Offset
49011771SCurtis.Dunham@arm.com * since it has already been done in the calling method
49111771SCurtis.Dunham@arm.com * (setRegWithEffect)
4927405SAli.Saidi@ARM.com*/
4937405SAli.Saidi@ARM.comMiscReg
4947405SAli.Saidi@ARM.comISA::filterCP0Write(int misc_reg, int reg_sel, const MiscReg &val)
4957405SAli.Saidi@ARM.com{
4967405SAli.Saidi@ARM.com    MiscReg retVal = val;
4977405SAli.Saidi@ARM.com
49810037SARM gem5 Developers    // Mask off read-only regions
49910037SARM gem5 Developers    retVal &= miscRegFile_WriteMask[misc_reg][reg_sel];
50010037SARM gem5 Developers    MiscReg curVal = miscRegFile[misc_reg][reg_sel];
5019050Schander.sudanthi@arm.com    // Mask off current alue with inverse mask (clear writeable bits)
5027405SAli.Saidi@ARM.com    curVal &= (~miscRegFile_WriteMask[misc_reg][reg_sel]);
50310037SARM gem5 Developers    retVal |= curVal; // Combine the two
50410037SARM gem5 Developers    DPRINTF(MipsPRA,
5057720Sgblack@eecs.umich.edu            "filterCP0Write: Mask: %lx, Inverse Mask: %lx, write Val: %x, "
5067720Sgblack@eecs.umich.edu            "current val: %lx, written val: %x\n",
5077405SAli.Saidi@ARM.com            miscRegFile_WriteMask[misc_reg][reg_sel],
5087405SAli.Saidi@ARM.com            ~miscRegFile_WriteMask[misc_reg][reg_sel],
5097757SAli.Saidi@ARM.com            val, miscRegFile[misc_reg][reg_sel], retVal);
51010037SARM gem5 Developers    return retVal;
51110037SARM gem5 Developers}
51210037SARM gem5 Developers
51310037SARM gem5 Developersvoid
51410037SARM gem5 DevelopersISA::scheduleCP0Update(BaseCPU *cpu, int delay)
51510037SARM gem5 Developers{
51610037SARM gem5 Developers    if (!cp0Updated) {
51710037SARM gem5 Developers        cp0Updated = true;
51810037SARM gem5 Developers
51910037SARM gem5 Developers        //schedule UPDATE
52010037SARM gem5 Developers        CP0Event *cp0_event = new CP0Event(this, cpu, UpdateCP0);
52110037SARM gem5 Developers        cpu->schedule(cp0_event, curTick() + cpu->ticks(delay));
52210037SARM gem5 Developers    }
52310037SARM gem5 Developers}
52410037SARM gem5 Developers
52510037SARM gem5 Developersvoid
52610037SARM gem5 DevelopersISA::updateCPU(BaseCPU *cpu)
52710037SARM gem5 Developers{
52810037SARM gem5 Developers    ///////////////////////////////////////////////////////////////////
52910037SARM gem5 Developers    //
53010037SARM gem5 Developers    // EVALUATE CP0 STATE FOR MIPS MT
53110037SARM gem5 Developers    //
53210037SARM gem5 Developers    ///////////////////////////////////////////////////////////////////
53310037SARM gem5 Developers    MVPConf0Reg mvpConf0 = readMiscRegNoEffect(MISCREG_MVP_CONF0);
53410037SARM gem5 Developers    ThreadID num_threads = mvpConf0.ptc + 1;
53510037SARM gem5 Developers
53610037SARM gem5 Developers    for (ThreadID tid = 0; tid < num_threads; tid++) {
53710037SARM gem5 Developers        TCStatusReg tcStatus = readMiscRegNoEffect(MISCREG_TC_STATUS, tid);
53810037SARM gem5 Developers        TCHaltReg tcHalt = readMiscRegNoEffect(MISCREG_TC_HALT, tid);
53910037SARM gem5 Developers
54010037SARM gem5 Developers        //@todo: add vpe/mt check here thru mvpcontrol & vpecontrol regs
54110037SARM gem5 Developers        if (tcHalt.h == 1 || tcStatus.a == 0)  {
54210037SARM gem5 Developers            haltThread(cpu->getContext(tid));
54310037SARM gem5 Developers        } else if (tcHalt.h == 0 && tcStatus.a == 1) {
54410037SARM gem5 Developers            restoreThread(cpu->getContext(tid));
54510037SARM gem5 Developers        }
54610037SARM gem5 Developers    }
54710037SARM gem5 Developers
54810037SARM gem5 Developers    num_threads = mvpConf0.ptc + 1;
54910037SARM gem5 Developers
55010037SARM gem5 Developers    // Toggle update flag after we finished updating
55110037SARM gem5 Developers    cp0Updated = false;
55210037SARM gem5 Developers}
55310037SARM gem5 Developers
55410037SARM gem5 DevelopersISA::CP0Event::CP0Event(CP0 *_cp0, BaseCPU *_cpu, CP0EventType e_type)
55510037SARM gem5 Developers    : Event(CPU_Tick_Pri), cp0(_cp0), cpu(_cpu), cp0EventType(e_type)
5568284SAli.Saidi@ARM.com{  }
55710037SARM gem5 Developers
55810037SARM gem5 Developersvoid
55910037SARM gem5 DevelopersISA::CP0Event::process()
56010037SARM gem5 Developers{
5619050Schander.sudanthi@arm.com    switch (cp0EventType)
56210037SARM gem5 Developers    {
56310037SARM gem5 Developers      case UpdateCP0:
56410037SARM gem5 Developers        cp0->updateCPU(cpu);
56510037SARM gem5 Developers        break;
56610037SARM gem5 Developers    }
56710037SARM gem5 Developers}
56810037SARM gem5 Developers
56910037SARM gem5 Developersconst char *
57010037SARM gem5 DevelopersISA::CP0Event::description() const
57110037SARM gem5 Developers{
57210037SARM gem5 Developers    return "Coprocessor-0 event";
57310037SARM gem5 Developers}
57410037SARM gem5 Developers
57510037SARM gem5 Developersvoid
57610037SARM gem5 DevelopersISA::CP0Event::scheduleEvent(int delay)
57710037SARM gem5 Developers{
57810037SARM gem5 Developers    cpu->reschedule(this, curTick() + cpu->ticks(delay), true);
57910037SARM gem5 Developers}
5809050Schander.sudanthi@arm.com
5818284SAli.Saidi@ARM.comvoid
58210037SARM gem5 DevelopersISA::CP0Event::unscheduleEvent()
58310037SARM gem5 Developers{
58410037SARM gem5 Developers    if (scheduled())
58510037SARM gem5 Developers        squash();
58610037SARM gem5 Developers}
58710037SARM gem5 Developers
58810037SARM gem5 Developers}
5897405SAli.Saidi@ARM.com