mt.hh revision 5222
14661Sksewell@umich.edu/* 25222Sksewell@umich.edu * Copyright .AN) 2007 MIPS Technologies, Inc. All Rights Reserved 34661Sksewell@umich.edu * 45222Sksewell@umich.edu * This software is part of the M5 simulator. 54661Sksewell@umich.edu * 65222Sksewell@umich.edu * THIS IS A LEGAL AGREEMENT. BY DOWNLOADING, USING, COPYING, CREATING 75222Sksewell@umich.edu * DERIVATIVE WORKS, AND/OR DISTRIBUTING THIS SOFTWARE YOU ARE AGREEING 85222Sksewell@umich.edu * TO THESE TERMS AND CONDITIONS. 94661Sksewell@umich.edu * 105222Sksewell@umich.edu * Permission is granted to use, copy, create derivative works and 115222Sksewell@umich.edu * distribute this software and such derivative works for any purpose, 125222Sksewell@umich.edu * so long as (1) the copyright notice above, this grant of permission, 135222Sksewell@umich.edu * and the disclaimer below appear in all copies and derivative works 145222Sksewell@umich.edu * made, (2) the copyright notice above is augmented as appropriate to 155222Sksewell@umich.edu * reflect the addition of any new copyrightable work in a derivative 165222Sksewell@umich.edu * work (e.g., Copyright .AN) <Publication Year> Copyright Owner), and (3) 175222Sksewell@umich.edu * the name of MIPS Technologies, Inc. ($B!H(BMIPS$B!I(B) is not used in any 185222Sksewell@umich.edu * advertising or publicity pertaining to the use or distribution of 195222Sksewell@umich.edu * this software without specific, written prior authorization. 205222Sksewell@umich.edu * 215222Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED $B!H(BAS IS.$B!I(B MIPS MAKES NO WARRANTIES AND 225222Sksewell@umich.edu * DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, STATUTORY, IMPLIED OR 235222Sksewell@umich.edu * OTHERWISE, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 245222Sksewell@umich.edu * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND 255222Sksewell@umich.edu * NON-INFRINGEMENT OF THIRD PARTY RIGHTS, REGARDING THIS SOFTWARE. 265222Sksewell@umich.edu * IN NO EVENT SHALL MIPS BE LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, 275222Sksewell@umich.edu * INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL, OR PUNITIVE DAMAGES OF 285222Sksewell@umich.edu * ANY KIND OR NATURE, ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT, 295222Sksewell@umich.edu * THIS SOFTWARE AND/OR THE USE OF THIS SOFTWARE, WHETHER SUCH LIABILITY 305222Sksewell@umich.edu * IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE OR 315222Sksewell@umich.edu * STRICT LIABILITY), OR OTHERWISE, EVEN IF MIPS HAS BEEN WARNED OF THE 325222Sksewell@umich.edu * POSSIBILITY OF ANY SUCH LOSS OR DAMAGE IN ADVANCE. 335222Sksewell@umich.edu * 345222Sksewell@umich.edu * Authors: Jaidev Patwardhan 355222Sksewell@umich.edu * 364661Sksewell@umich.edu */ 374661Sksewell@umich.edu 384661Sksewell@umich.edu#ifndef __ARCH_MIPS_MT_HH__ 394661Sksewell@umich.edu#define __ARCH_MIPS_MT_HH__ 404661Sksewell@umich.edu 414661Sksewell@umich.edu/** 424661Sksewell@umich.edu * @file 434661Sksewell@umich.edu * 444661Sksewell@umich.edu * ISA-specific helper functions for multithreaded execution. 454661Sksewell@umich.edu */ 464661Sksewell@umich.edu 474661Sksewell@umich.edu#include "arch/isa_traits.hh" 484661Sksewell@umich.edu#include "arch/mips/faults.hh" 494661Sksewell@umich.edu#include "arch/mips/mt_constants.hh" 504661Sksewell@umich.edu#include "base/bitfield.hh" 514661Sksewell@umich.edu#include "base/trace.hh" 524661Sksewell@umich.edu#include "base/misc.hh" 534661Sksewell@umich.edu 544661Sksewell@umich.edu#include <iostream> 554661Sksewell@umich.eduusing namespace std; 564661Sksewell@umich.edu 574661Sksewell@umich.edunamespace MipsISA 584661Sksewell@umich.edu{ 594661Sksewell@umich.edu 604661Sksewell@umich.edu 614661Sksewell@umich.edutemplate <class TC> 624661Sksewell@umich.eduinline unsigned 634661Sksewell@umich.edugetVirtProcNum(TC *tc) 644661Sksewell@umich.edu{ 654661Sksewell@umich.edu MiscReg tcbind = tc->readMiscRegNoEffect(TCBind); 664661Sksewell@umich.edu return bits(tcbind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO); 674661Sksewell@umich.edu} 684661Sksewell@umich.edu 694661Sksewell@umich.edutemplate <class TC> 704661Sksewell@umich.eduinline unsigned 714661Sksewell@umich.edugetTargetThread(TC *tc) 724661Sksewell@umich.edu{ 734661Sksewell@umich.edu MiscReg vpec_ctrl = tc->readMiscRegNoEffect(VPEControl); 744661Sksewell@umich.edu return bits(vpec_ctrl, VPEC_TARG_TC_HI, VPEC_TARG_TC_LO); 754661Sksewell@umich.edu} 764661Sksewell@umich.edu 774661Sksewell@umich.edutemplate <class TC> 784661Sksewell@umich.eduinline void 794661Sksewell@umich.eduhaltThread(TC *tc) 804661Sksewell@umich.edu{ 814661Sksewell@umich.edu if (tc->status() == TC::Active) { 824661Sksewell@umich.edu tc->halt(); 834661Sksewell@umich.edu 844661Sksewell@umich.edu // Save last known PC in TCRestart 854661Sksewell@umich.edu // @TODO: Needs to check if this is a branch and if so, take previous instruction 864661Sksewell@umich.edu tc->setMiscReg(TCRestart, tc->readNextPC()); 874661Sksewell@umich.edu 884661Sksewell@umich.edu warn("%i: Halting thread %i in %s @ PC %x, setting restart PC to %x", curTick, tc->getThreadNum(), tc->getCpuPtr()->name(), 894661Sksewell@umich.edu tc->readPC(), tc->readNextPC()); 904661Sksewell@umich.edu } 914661Sksewell@umich.edu} 924661Sksewell@umich.edu 934661Sksewell@umich.edutemplate <class TC> 944661Sksewell@umich.eduinline void 954661Sksewell@umich.edurestoreThread(TC *tc) 964661Sksewell@umich.edu{ 974661Sksewell@umich.edu if (tc->status() != TC::Active) { 984661Sksewell@umich.edu // Restore PC from TCRestart 994661Sksewell@umich.edu IntReg pc = tc->readMiscRegNoEffect(TCRestart); 1004661Sksewell@umich.edu 1014661Sksewell@umich.edu // TODO: SET PC WITH AN EVENT INSTEAD OF INSTANTANEOUSLY 1024661Sksewell@umich.edu // tc->setPCEvent(pc, pc + 4, pc + 8); 1034661Sksewell@umich.edu tc->setPC(pc); 1044661Sksewell@umich.edu tc->setNextPC(pc + 4); 1054661Sksewell@umich.edu tc->setNextNPC(pc + 8); 1064661Sksewell@umich.edu tc->activate(0); 1074661Sksewell@umich.edu 1084661Sksewell@umich.edu warn("%i: Restoring thread %i in %s @ PC %x", curTick, tc->getThreadNum(), tc->getCpuPtr()->name(), 1094661Sksewell@umich.edu tc->readPC()); 1104661Sksewell@umich.edu } 1114661Sksewell@umich.edu} 1124661Sksewell@umich.edu 1134661Sksewell@umich.edutemplate <class TC> 1144661Sksewell@umich.eduvoid 1154661Sksewell@umich.eduforkThread(TC *tc, Fault &fault, int Rd_bits, int Rs, int Rt) 1164661Sksewell@umich.edu{ 1174661Sksewell@umich.edu int num_threads = bits(tc->readMiscRegNoEffect(MVPConf0), MVPC0_PTC_HI, MVPC0_PTC_LO) + 1; 1184661Sksewell@umich.edu 1194661Sksewell@umich.edu int success = 0; 1204661Sksewell@umich.edu for (int tid = 0; tid < num_threads && success == 0; tid++) { 1214661Sksewell@umich.edu unsigned tid_TCBind = tc->readRegOtherThread(MipsISA::TCBind + Ctrl_Base_DepTag, 1224661Sksewell@umich.edu tid); 1234661Sksewell@umich.edu unsigned tc_bind = tc->readMiscRegNoEffect(MipsISA::TCBind); 1244661Sksewell@umich.edu 1254661Sksewell@umich.edu if (bits(tid_TCBind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO) == 1264661Sksewell@umich.edu bits(tc_bind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO)) { 1274661Sksewell@umich.edu 1284661Sksewell@umich.edu unsigned tid_TCStatus = tc->readRegOtherThread(MipsISA::TCStatus + Ctrl_Base_DepTag, 1294661Sksewell@umich.edu tid); 1304661Sksewell@umich.edu 1314661Sksewell@umich.edu unsigned tid_TCHalt = tc->readRegOtherThread(MipsISA::TCHalt + Ctrl_Base_DepTag, 1324661Sksewell@umich.edu tid); 1334661Sksewell@umich.edu 1344661Sksewell@umich.edu if (bits(tid_TCStatus, TCS_DA) == 1 && 1354661Sksewell@umich.edu bits(tid_TCHalt, TCH_H) == 0 && 1364661Sksewell@umich.edu bits(tid_TCStatus, TCS_A) == 0 && 1374661Sksewell@umich.edu success == 0) { 1384661Sksewell@umich.edu 1394661Sksewell@umich.edu tc->setRegOtherThread(MipsISA::TCRestart + Ctrl_Base_DepTag, Rs, tid); 1404661Sksewell@umich.edu 1414661Sksewell@umich.edu tc->setRegOtherThread(Rd_bits, Rt, tid); 1424661Sksewell@umich.edu 1434661Sksewell@umich.edu unsigned status_ksu = bits(tc->readMiscReg(MipsISA::Status), 1444661Sksewell@umich.edu S_KSU_HI, S_KSU_LO); 1454661Sksewell@umich.edu unsigned tc_status_asid = bits(tc->readMiscReg(MipsISA::TCStatus), 1464661Sksewell@umich.edu TCS_ASID_HI, TCS_ASID_LO); 1474661Sksewell@umich.edu 1484661Sksewell@umich.edu // Set Run-State to Running 1494661Sksewell@umich.edu replaceBits(tid_TCStatus, TCSTATUS_RNST_HI, TCSTATUS_RNST_LO, 0); 1504661Sksewell@umich.edu 1514661Sksewell@umich.edu // Set Delay-Slot to 0 1524661Sksewell@umich.edu replaceBits(tid_TCStatus, TCSTATUS_TDS, 0); 1534661Sksewell@umich.edu 1544661Sksewell@umich.edu // Set Dirty TC to 1 1554661Sksewell@umich.edu replaceBits(tid_TCStatus, TCSTATUS_DT, 1); 1564661Sksewell@umich.edu 1574661Sksewell@umich.edu // Set Activated to 1 1584661Sksewell@umich.edu replaceBits(tid_TCStatus, TCSTATUS_A, 1); 1594661Sksewell@umich.edu 1604661Sksewell@umich.edu // Set status to previous thread's status 1614661Sksewell@umich.edu replaceBits(tid_TCStatus, TCSTATUS_TKSU_HI, TCSTATUS_TKSU_LO, status_ksu); 1624661Sksewell@umich.edu 1634661Sksewell@umich.edu // Set ASID to previous thread's state 1644661Sksewell@umich.edu replaceBits(tid_TCStatus, TCSTATUS_ASID_HI, TCSTATUS_ASID_LO, tc_status_asid); 1654661Sksewell@umich.edu 1664661Sksewell@umich.edu // Write Status Register 1674661Sksewell@umich.edu tc->setRegOtherThread(MipsISA::TCStatus + Ctrl_Base_DepTag, 1684661Sksewell@umich.edu tid_TCStatus, tid); 1694661Sksewell@umich.edu 1704661Sksewell@umich.edu // Mark As Successful Fork 1714661Sksewell@umich.edu success = 1; 1724661Sksewell@umich.edu } 1734661Sksewell@umich.edu } else { 1744661Sksewell@umich.edu std::cerr << "Bad VPEs" << endl; 1754661Sksewell@umich.edu } 1764661Sksewell@umich.edu } 1774661Sksewell@umich.edu 1784661Sksewell@umich.edu if (success == 0) { 1794661Sksewell@umich.edu unsigned vpe_control = tc->readMiscRegNoEffect(MipsISA::VPEControl); 1804661Sksewell@umich.edu tc->setMiscReg(VPEControl, insertBits(vpe_control, VPEC_EXCPT_HI, VPEC_EXCPT_LO, 1)); 1814661Sksewell@umich.edu fault = new ThreadFault(); 1824661Sksewell@umich.edu } 1834661Sksewell@umich.edu} 1844661Sksewell@umich.edu 1854661Sksewell@umich.edu 1864661Sksewell@umich.edutemplate <class TC> 1874661Sksewell@umich.eduint 1884661Sksewell@umich.eduyieldThread(TC *tc, Fault &fault, int src_reg, uint32_t yield_mask) 1894661Sksewell@umich.edu{ 1904661Sksewell@umich.edu if (src_reg == 0) { 1914661Sksewell@umich.edu unsigned mvpconf0 = tc->readMiscRegNoEffect(MVPConf0); 1924661Sksewell@umich.edu int num_threads = bits(mvpconf0, MVPC0_PTC_HI, MVPC0_PTC_LO) + 1; 1934661Sksewell@umich.edu 1944661Sksewell@umich.edu int ok = 0; 1954661Sksewell@umich.edu 1964661Sksewell@umich.edu // Get Current VPE & TC numbers from calling thread 1974661Sksewell@umich.edu unsigned tcbind = tc->readMiscRegNoEffect(TCBind); 1984661Sksewell@umich.edu unsigned cur_vpe = bits(tcbind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO); 1994661Sksewell@umich.edu unsigned cur_tc = bits(tcbind, TCB_CUR_TC_HI, TCB_CUR_TC_LO); 2004661Sksewell@umich.edu 2014661Sksewell@umich.edu for (int tid = 0; tid < num_threads; tid++) { 2024661Sksewell@umich.edu unsigned tid_TCStatus = tc->readRegOtherThread(MipsISA::TCStatus + Ctrl_Base_DepTag, 2034661Sksewell@umich.edu tid); 2044661Sksewell@umich.edu unsigned tid_TCHalt = tc->readRegOtherThread(MipsISA::TCHalt + Ctrl_Base_DepTag, 2054661Sksewell@umich.edu tid); 2064661Sksewell@umich.edu unsigned tid_TCBind = tc->readRegOtherThread(MipsISA::TCBind + Ctrl_Base_DepTag, 2074661Sksewell@umich.edu tid); 2084661Sksewell@umich.edu 2094661Sksewell@umich.edu unsigned tid_vpe = bits(tid_TCBind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO); 2104661Sksewell@umich.edu unsigned tid_tc = bits(tid_TCBind, TCB_CUR_TC_HI, TCB_CUR_TC_LO); 2114661Sksewell@umich.edu unsigned tid_tcstatus_da = bits(tid_TCStatus, TCS_DA); 2124661Sksewell@umich.edu unsigned tid_tcstatus_a = bits(tid_TCStatus, TCS_A); 2134661Sksewell@umich.edu unsigned tid_tchalt_h = bits(tid_TCHalt, TCH_H); 2144661Sksewell@umich.edu 2154661Sksewell@umich.edu if (tid_vpe == cur_vpe && 2164661Sksewell@umich.edu tid_tc == cur_tc && 2174661Sksewell@umich.edu tid_tcstatus_da == 1 && 2184661Sksewell@umich.edu tid_tchalt_h == 0 && 2194661Sksewell@umich.edu tid_tcstatus_a == 1) { 2204661Sksewell@umich.edu ok = 1; 2214661Sksewell@umich.edu } 2224661Sksewell@umich.edu } 2234661Sksewell@umich.edu 2244661Sksewell@umich.edu if (ok == 1) { 2254661Sksewell@umich.edu unsigned tcstatus = tc->readMiscRegNoEffect(TCStatus); 2264661Sksewell@umich.edu tc->setMiscReg(TCStatus, insertBits(tcstatus, TCS_A, TCS_A, 0)); 2274661Sksewell@umich.edu warn("%i: Deactivating Hardware Thread Context #%i", curTick, tc->getThreadNum()); 2284661Sksewell@umich.edu } 2294661Sksewell@umich.edu } else if (src_reg > 0) { 2304661Sksewell@umich.edu if (src_reg & !yield_mask != 0) { 2314661Sksewell@umich.edu unsigned vpe_control = tc->readMiscReg(VPEControl); 2324661Sksewell@umich.edu tc->setMiscReg(VPEControl, insertBits(vpe_control, VPEC_EXCPT_HI, VPEC_EXCPT_LO, 2)); 2334661Sksewell@umich.edu fault = new ThreadFault(); 2344661Sksewell@umich.edu } else { 2354661Sksewell@umich.edu //tc->setThreadRescheduleCondition(src_reg & yield_mask); 2364661Sksewell@umich.edu } 2374661Sksewell@umich.edu } else if (src_reg != -2) { 2384661Sksewell@umich.edu unsigned tcstatus = tc->readMiscRegNoEffect(TCStatus); 2394661Sksewell@umich.edu unsigned vpe_control = tc->readMiscRegNoEffect(VPEControl); 2404661Sksewell@umich.edu unsigned tcstatus_dt = bits(tcstatus, TCS_DT); 2414661Sksewell@umich.edu unsigned vpe_control_ysi = bits(vpe_control, VPEC_YSI); 2424661Sksewell@umich.edu 2434661Sksewell@umich.edu if (vpe_control_ysi == 1 && tcstatus_dt == 1 ) { 2444661Sksewell@umich.edu tc->setMiscReg(VPEControl, insertBits(vpe_control, VPEC_EXCPT_HI, VPEC_EXCPT_LO, 4)); 2454661Sksewell@umich.edu fault = new ThreadFault(); 2464661Sksewell@umich.edu } else { 2474661Sksewell@umich.edu //tc->ScheduleOtherThreads(); 2484661Sksewell@umich.edu //std::cerr << "T" << tc->getThreadNum() << "YIELD: Schedule Other Threads.\n" << std::endl; 2494661Sksewell@umich.edu //tc->suspend(); 2504661Sksewell@umich.edu // Save last known PC in TCRestart 2514661Sksewell@umich.edu // @TODO: Needs to check if this is a branch and if so, take previous instruction 2524661Sksewell@umich.edu //tc->setMiscRegWithEffect(TCRestart, tc->readNextPC()); 2534661Sksewell@umich.edu } 2544661Sksewell@umich.edu } 2554661Sksewell@umich.edu 2564661Sksewell@umich.edu return src_reg & yield_mask; 2574661Sksewell@umich.edu} 2584661Sksewell@umich.edu 2594661Sksewell@umich.edu 2604661Sksewell@umich.edu// TC will usually be a object derived from ThreadContext 2614661Sksewell@umich.edu// (src/cpu/thread_context.hh) 2624661Sksewell@umich.edutemplate <class TC> 2634661Sksewell@umich.eduinline void 2644661Sksewell@umich.eduupdateStatusView(TC *tc) 2654661Sksewell@umich.edu{ 2664661Sksewell@umich.edu // TCStatus' register view must be the same as 2674661Sksewell@umich.edu // Status register view for CU, MX, KSU bits 2684661Sksewell@umich.edu MiscReg tc_status = tc->readMiscRegNoEffect(TCStatus); 2694661Sksewell@umich.edu MiscReg status = tc->readMiscRegNoEffect(Status); 2704661Sksewell@umich.edu 2714661Sksewell@umich.edu unsigned cu_bits = bits(tc_status, TCS_TCU_HI, TCS_TCU_LO); 2724661Sksewell@umich.edu replaceBits(status, S_CU_HI, S_CU_LO, cu_bits); 2734661Sksewell@umich.edu 2744661Sksewell@umich.edu unsigned mx_bits = bits(tc_status, TCS_TMX); 2754661Sksewell@umich.edu replaceBits(status, S_MX, S_MX, mx_bits); 2764661Sksewell@umich.edu 2774661Sksewell@umich.edu unsigned ksu_bits = bits(tc_status, TCS_TKSU_HI, TCS_TKSU_LO); 2784661Sksewell@umich.edu replaceBits(status, S_KSU_HI, S_KSU_LO, ksu_bits); 2794661Sksewell@umich.edu 2804661Sksewell@umich.edu tc->setMiscRegNoEffect(Status, status); 2814661Sksewell@umich.edu} 2824661Sksewell@umich.edu 2834661Sksewell@umich.edu// TC will usually be a object derived from ThreadContext 2844661Sksewell@umich.edu// (src/cpu/thread_context.hh) 2854661Sksewell@umich.edutemplate <class TC> 2864661Sksewell@umich.eduinline void 2874661Sksewell@umich.eduupdateTCStatusView(TC *tc) 2884661Sksewell@umich.edu{ 2894661Sksewell@umich.edu // TCStatus' register view must be the same as 2904661Sksewell@umich.edu // Status register view for CU, MX, KSU bits 2914661Sksewell@umich.edu MiscReg tc_status = tc->readMiscRegNoEffect(TCStatus); 2924661Sksewell@umich.edu MiscReg status = tc->readMiscRegNoEffect(Status); 2934661Sksewell@umich.edu 2944661Sksewell@umich.edu unsigned cu_bits = bits(status, S_CU_HI, S_CU_LO); 2954661Sksewell@umich.edu replaceBits(tc_status, TCS_TCU_HI, TCS_TCU_LO, cu_bits); 2964661Sksewell@umich.edu 2974661Sksewell@umich.edu unsigned mx_bits = bits(status, S_MX, S_MX); 2984661Sksewell@umich.edu replaceBits(tc_status, TCS_TMX, mx_bits); 2994661Sksewell@umich.edu 3004661Sksewell@umich.edu unsigned ksu_bits = bits(status, S_KSU_HI, S_KSU_LO); 3014661Sksewell@umich.edu replaceBits(tc_status, TCS_TKSU_HI, TCS_TKSU_LO, ksu_bits); 3024661Sksewell@umich.edu 3034661Sksewell@umich.edu tc->setMiscRegNoEffect(TCStatus, tc_status); 3044661Sksewell@umich.edu} 3054661Sksewell@umich.edu 3064661Sksewell@umich.edu} // namespace MipsISA 3074661Sksewell@umich.edu 3084661Sksewell@umich.edu 3094661Sksewell@umich.edu#endif 310