mt.hh revision 6424
14661Sksewell@umich.edu/* 25268Sksewell@umich.edu * Copyright (c) 2007 MIPS Technologies, Inc. 35268Sksewell@umich.edu * All rights reserved. 44661Sksewell@umich.edu * 55268Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without 65268Sksewell@umich.edu * modification, are permitted provided that the following conditions are 75268Sksewell@umich.edu * met: redistributions of source code must retain the above copyright 85268Sksewell@umich.edu * notice, this list of conditions and the following disclaimer; 95268Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright 105268Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the 115268Sksewell@umich.edu * documentation and/or other materials provided with the distribution; 125268Sksewell@umich.edu * neither the name of the copyright holders nor the names of its 135268Sksewell@umich.edu * contributors may be used to endorse or promote products derived from 145268Sksewell@umich.edu * this software without specific prior written permission. 154661Sksewell@umich.edu * 165268Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175268Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185268Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195268Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205268Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215268Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225268Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235268Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245268Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255268Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265268Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275222Sksewell@umich.edu * 285254Sksewell@umich.edu * Authors: Korey Sewell 294661Sksewell@umich.edu */ 304661Sksewell@umich.edu 314661Sksewell@umich.edu#ifndef __ARCH_MIPS_MT_HH__ 324661Sksewell@umich.edu#define __ARCH_MIPS_MT_HH__ 334661Sksewell@umich.edu 344661Sksewell@umich.edu/** 354661Sksewell@umich.edu * @file 364661Sksewell@umich.edu * 374661Sksewell@umich.edu * ISA-specific helper functions for multithreaded execution. 384661Sksewell@umich.edu */ 394661Sksewell@umich.edu 404661Sksewell@umich.edu#include "arch/mips/faults.hh" 416329Sgblack@eecs.umich.edu#include "arch/mips/isa_traits.hh" 424661Sksewell@umich.edu#include "arch/mips/mt_constants.hh" 436376Sgblack@eecs.umich.edu#include "arch/mips/pra_constants.hh" 446329Sgblack@eecs.umich.edu#include "arch/mips/registers.hh" 454661Sksewell@umich.edu#include "base/bitfield.hh" 464661Sksewell@umich.edu#include "base/trace.hh" 474661Sksewell@umich.edu#include "base/misc.hh" 484661Sksewell@umich.edu 494661Sksewell@umich.edu#include <iostream> 504661Sksewell@umich.edu 514661Sksewell@umich.edunamespace MipsISA 524661Sksewell@umich.edu{ 534661Sksewell@umich.edu 544661Sksewell@umich.edutemplate <class TC> 554661Sksewell@umich.eduinline unsigned 564661Sksewell@umich.edugetVirtProcNum(TC *tc) 574661Sksewell@umich.edu{ 586383Sgblack@eecs.umich.edu TCBindReg tcbind = tc->readMiscRegNoEffect(MISCREG_TC_BIND); 596376Sgblack@eecs.umich.edu return tcbind.curVPE; 604661Sksewell@umich.edu} 614661Sksewell@umich.edu 624661Sksewell@umich.edutemplate <class TC> 634661Sksewell@umich.eduinline unsigned 644661Sksewell@umich.edugetTargetThread(TC *tc) 654661Sksewell@umich.edu{ 666383Sgblack@eecs.umich.edu VPEControlReg vpeCtrl = tc->readMiscRegNoEffect(MISCREG_VPE_CONTROL); 676376Sgblack@eecs.umich.edu return vpeCtrl.targTC; 684661Sksewell@umich.edu} 694661Sksewell@umich.edu 704661Sksewell@umich.edutemplate <class TC> 714661Sksewell@umich.eduinline void 724661Sksewell@umich.eduhaltThread(TC *tc) 734661Sksewell@umich.edu{ 744661Sksewell@umich.edu if (tc->status() == TC::Active) { 754661Sksewell@umich.edu tc->halt(); 764661Sksewell@umich.edu 774661Sksewell@umich.edu // Save last known PC in TCRestart 786378Sgblack@eecs.umich.edu // @TODO: Needs to check if this is a branch and if so, 796378Sgblack@eecs.umich.edu // take previous instruction 806383Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TC_RESTART, tc->readNextPC()); 814661Sksewell@umich.edu 826378Sgblack@eecs.umich.edu warn("%i: Halting thread %i in %s @ PC %x, setting restart PC to %x", 836378Sgblack@eecs.umich.edu curTick, tc->threadId(), tc->getCpuPtr()->name(), 846378Sgblack@eecs.umich.edu tc->readPC(), tc->readNextPC()); 854661Sksewell@umich.edu } 864661Sksewell@umich.edu} 874661Sksewell@umich.edu 884661Sksewell@umich.edutemplate <class TC> 894661Sksewell@umich.eduinline void 904661Sksewell@umich.edurestoreThread(TC *tc) 914661Sksewell@umich.edu{ 924661Sksewell@umich.edu if (tc->status() != TC::Active) { 934661Sksewell@umich.edu // Restore PC from TCRestart 946383Sgblack@eecs.umich.edu IntReg pc = tc->readMiscRegNoEffect(MISCREG_TC_RESTART); 954661Sksewell@umich.edu 964661Sksewell@umich.edu // TODO: SET PC WITH AN EVENT INSTEAD OF INSTANTANEOUSLY 974661Sksewell@umich.edu tc->setPC(pc); 984661Sksewell@umich.edu tc->setNextPC(pc + 4); 994661Sksewell@umich.edu tc->setNextNPC(pc + 8); 1004661Sksewell@umich.edu tc->activate(0); 1014661Sksewell@umich.edu 1026378Sgblack@eecs.umich.edu warn("%i: Restoring thread %i in %s @ PC %x", 1036378Sgblack@eecs.umich.edu curTick, tc->threadId(), tc->getCpuPtr()->name(), 1046378Sgblack@eecs.umich.edu tc->readPC()); 1054661Sksewell@umich.edu } 1064661Sksewell@umich.edu} 1074661Sksewell@umich.edu 1084661Sksewell@umich.edutemplate <class TC> 1094661Sksewell@umich.eduvoid 1104661Sksewell@umich.eduforkThread(TC *tc, Fault &fault, int Rd_bits, int Rs, int Rt) 1114661Sksewell@umich.edu{ 1126383Sgblack@eecs.umich.edu MVPConf0Reg mvpConf = tc->readMiscRegNoEffect(MISCREG_MVP_CONF0); 1136376Sgblack@eecs.umich.edu int num_threads = mvpConf.ptc + 1; 1144661Sksewell@umich.edu 1154661Sksewell@umich.edu int success = 0; 1166221Snate@binkert.org for (ThreadID tid = 0; tid < num_threads && success == 0; tid++) { 1176376Sgblack@eecs.umich.edu TCBindReg tidTCBind = 1186383Sgblack@eecs.umich.edu tc->readRegOtherThread(MISCREG_TC_BIND + Ctrl_Base_DepTag, tid); 1196383Sgblack@eecs.umich.edu TCBindReg tcBind = tc->readMiscRegNoEffect(MISCREG_TC_BIND); 1204661Sksewell@umich.edu 1216424Snate@binkert.org if (tidTCBind.curVPE == tcBind.curVPE) { 1224661Sksewell@umich.edu 1236376Sgblack@eecs.umich.edu TCStatusReg tidTCStatus = 1246383Sgblack@eecs.umich.edu tc->readRegOtherThread(MISCREG_TC_STATUS + 1256383Sgblack@eecs.umich.edu Ctrl_Base_DepTag,tid); 1264661Sksewell@umich.edu 1276376Sgblack@eecs.umich.edu TCHaltReg tidTCHalt = 1286383Sgblack@eecs.umich.edu tc->readRegOtherThread(MISCREG_TC_HALT + Ctrl_Base_DepTag,tid); 1294661Sksewell@umich.edu 1306376Sgblack@eecs.umich.edu if (tidTCStatus.da == 1 && tidTCHalt.h == 0 && 1316376Sgblack@eecs.umich.edu tidTCStatus.a == 0 && success == 0) { 1324661Sksewell@umich.edu 1336383Sgblack@eecs.umich.edu tc->setRegOtherThread(MISCREG_TC_RESTART + 1346383Sgblack@eecs.umich.edu Ctrl_Base_DepTag, Rs, tid); 1354661Sksewell@umich.edu tc->setRegOtherThread(Rd_bits, Rt, tid); 1364661Sksewell@umich.edu 1376383Sgblack@eecs.umich.edu StatusReg status = tc->readMiscReg(MISCREG_STATUS); 1386383Sgblack@eecs.umich.edu TCStatusReg tcStatus = tc->readMiscReg(MISCREG_TC_STATUS); 1394661Sksewell@umich.edu 1404661Sksewell@umich.edu // Set Run-State to Running 1416376Sgblack@eecs.umich.edu tidTCStatus.rnst = 0; 1424661Sksewell@umich.edu // Set Delay-Slot to 0 1436376Sgblack@eecs.umich.edu tidTCStatus.tds = 0; 1444661Sksewell@umich.edu // Set Dirty TC to 1 1456376Sgblack@eecs.umich.edu tidTCStatus.dt = 1; 1464661Sksewell@umich.edu // Set Activated to 1 1476376Sgblack@eecs.umich.edu tidTCStatus.a = 1; 1484661Sksewell@umich.edu // Set status to previous thread's status 1496376Sgblack@eecs.umich.edu tidTCStatus.tksu = status.ksu; 1504661Sksewell@umich.edu // Set ASID to previous thread's state 1516376Sgblack@eecs.umich.edu tidTCStatus.asid = tcStatus.asid; 1524661Sksewell@umich.edu 1534661Sksewell@umich.edu // Write Status Register 1546383Sgblack@eecs.umich.edu tc->setRegOtherThread(MISCREG_TC_STATUS + Ctrl_Base_DepTag, 1556376Sgblack@eecs.umich.edu tidTCStatus, tid); 1564661Sksewell@umich.edu 1574661Sksewell@umich.edu // Mark As Successful Fork 1584661Sksewell@umich.edu success = 1; 1594661Sksewell@umich.edu } 1604661Sksewell@umich.edu } else { 1615991Ssteve.reinhardt@amd.com std::cerr << "Bad VPEs" << std::endl; 1624661Sksewell@umich.edu } 1634661Sksewell@umich.edu } 1644661Sksewell@umich.edu 1654661Sksewell@umich.edu if (success == 0) { 1666383Sgblack@eecs.umich.edu VPEControlReg vpeControl = 1676383Sgblack@eecs.umich.edu tc->readMiscRegNoEffect(MISCREG_VPE_CONTROL); 1686376Sgblack@eecs.umich.edu vpeControl.excpt = 1; 1696383Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_VPE_CONTROL, vpeControl); 1704661Sksewell@umich.edu fault = new ThreadFault(); 1714661Sksewell@umich.edu } 1724661Sksewell@umich.edu} 1734661Sksewell@umich.edu 1744661Sksewell@umich.edu 1754661Sksewell@umich.edutemplate <class TC> 1764661Sksewell@umich.eduint 1774661Sksewell@umich.eduyieldThread(TC *tc, Fault &fault, int src_reg, uint32_t yield_mask) 1784661Sksewell@umich.edu{ 1794661Sksewell@umich.edu if (src_reg == 0) { 1806383Sgblack@eecs.umich.edu MVPConf0Reg mvpConf0 = tc->readMiscRegNoEffect(MISCREG_MVP_CONF0); 1816376Sgblack@eecs.umich.edu ThreadID num_threads = mvpConf0.ptc + 1; 1824661Sksewell@umich.edu 1834661Sksewell@umich.edu int ok = 0; 1844661Sksewell@umich.edu 1854661Sksewell@umich.edu // Get Current VPE & TC numbers from calling thread 1866383Sgblack@eecs.umich.edu TCBindReg tcBind = tc->readMiscRegNoEffect(MISCREG_TC_BIND); 1874661Sksewell@umich.edu 1886221Snate@binkert.org for (ThreadID tid = 0; tid < num_threads; tid++) { 1896376Sgblack@eecs.umich.edu TCStatusReg tidTCStatus = 1906383Sgblack@eecs.umich.edu tc->readRegOtherThread(MISCREG_TC_STATUS + Ctrl_Base_DepTag, 1916383Sgblack@eecs.umich.edu tid); 1926376Sgblack@eecs.umich.edu TCHaltReg tidTCHalt = 1936383Sgblack@eecs.umich.edu tc->readRegOtherThread(MISCREG_TC_HALT + Ctrl_Base_DepTag, 1946383Sgblack@eecs.umich.edu tid); 1956376Sgblack@eecs.umich.edu TCBindReg tidTCBind = 1966383Sgblack@eecs.umich.edu tc->readRegOtherThread(MISCREG_TC_BIND + Ctrl_Base_DepTag, 1976383Sgblack@eecs.umich.edu tid); 1984661Sksewell@umich.edu 1996376Sgblack@eecs.umich.edu if (tidTCBind.curVPE == tcBind.curVPE && 2006376Sgblack@eecs.umich.edu tidTCBind.curTC == tcBind.curTC && 2016376Sgblack@eecs.umich.edu tidTCStatus.da == 1 && 2026376Sgblack@eecs.umich.edu tidTCHalt.h == 0 && 2036376Sgblack@eecs.umich.edu tidTCStatus.a == 1) { 2044661Sksewell@umich.edu ok = 1; 2054661Sksewell@umich.edu } 2064661Sksewell@umich.edu } 2074661Sksewell@umich.edu 2084661Sksewell@umich.edu if (ok == 1) { 2096383Sgblack@eecs.umich.edu TCStatusReg tcStatus = tc->readMiscRegNoEffect(MISCREG_TC_STATUS); 2106376Sgblack@eecs.umich.edu tcStatus.a = 0; 2116383Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_TC_STATUS, tcStatus); 2126376Sgblack@eecs.umich.edu warn("%i: Deactivating Hardware Thread Context #%i", 2136376Sgblack@eecs.umich.edu curTick, tc->threadId()); 2144661Sksewell@umich.edu } 2154661Sksewell@umich.edu } else if (src_reg > 0) { 2165561Snate@binkert.org if (src_reg && !yield_mask != 0) { 2176383Sgblack@eecs.umich.edu VPEControlReg vpeControl = tc->readMiscReg(MISCREG_VPE_CONTROL); 2186376Sgblack@eecs.umich.edu vpeControl.excpt = 2; 2196383Sgblack@eecs.umich.edu tc->setMiscReg(MISCREG_VPE_CONTROL, vpeControl); 2204661Sksewell@umich.edu fault = new ThreadFault(); 2214661Sksewell@umich.edu } else { 2224661Sksewell@umich.edu } 2234661Sksewell@umich.edu } else if (src_reg != -2) { 2246383Sgblack@eecs.umich.edu TCStatusReg tcStatus = tc->readMiscRegNoEffect(MISCREG_TC_STATUS); 2256383Sgblack@eecs.umich.edu VPEControlReg vpeControl = 2266383Sgblack@eecs.umich.edu tc->readMiscRegNoEffect(MISCREG_VPE_CONTROL); 2274661Sksewell@umich.edu 2286376Sgblack@eecs.umich.edu if (vpeControl.ysi == 1 && tcStatus.dt == 1 ) { 2296376Sgblack@eecs.umich.edu vpeControl.excpt = 4; 2304661Sksewell@umich.edu fault = new ThreadFault(); 2314661Sksewell@umich.edu } else { 2324661Sksewell@umich.edu } 2334661Sksewell@umich.edu } 2344661Sksewell@umich.edu 2354661Sksewell@umich.edu return src_reg & yield_mask; 2364661Sksewell@umich.edu} 2374661Sksewell@umich.edu 2384661Sksewell@umich.edu 2394661Sksewell@umich.edu// TC will usually be a object derived from ThreadContext 2404661Sksewell@umich.edu// (src/cpu/thread_context.hh) 2414661Sksewell@umich.edutemplate <class TC> 2424661Sksewell@umich.eduinline void 2434661Sksewell@umich.eduupdateStatusView(TC *tc) 2444661Sksewell@umich.edu{ 2454661Sksewell@umich.edu // TCStatus' register view must be the same as 2464661Sksewell@umich.edu // Status register view for CU, MX, KSU bits 2476383Sgblack@eecs.umich.edu TCStatusReg tcStatus = tc->readMiscRegNoEffect(MISCREG_TC_STATUS); 2486383Sgblack@eecs.umich.edu StatusReg status = tc->readMiscRegNoEffect(MISCREG_STATUS); 2494661Sksewell@umich.edu 2506376Sgblack@eecs.umich.edu status.cu = tcStatus.tcu; 2516376Sgblack@eecs.umich.edu status.mx = tcStatus.tmx; 2526376Sgblack@eecs.umich.edu status.ksu = tcStatus.tksu; 2534661Sksewell@umich.edu 2546383Sgblack@eecs.umich.edu tc->setMiscRegNoEffect(MISCREG_STATUS, status); 2554661Sksewell@umich.edu} 2564661Sksewell@umich.edu 2574661Sksewell@umich.edu// TC will usually be a object derived from ThreadContext 2584661Sksewell@umich.edu// (src/cpu/thread_context.hh) 2594661Sksewell@umich.edutemplate <class TC> 2604661Sksewell@umich.eduinline void 2614661Sksewell@umich.eduupdateTCStatusView(TC *tc) 2624661Sksewell@umich.edu{ 2634661Sksewell@umich.edu // TCStatus' register view must be the same as 2644661Sksewell@umich.edu // Status register view for CU, MX, KSU bits 2656383Sgblack@eecs.umich.edu TCStatusReg tcStatus = tc->readMiscRegNoEffect(MISCREG_TC_STATUS); 2666383Sgblack@eecs.umich.edu StatusReg status = tc->readMiscRegNoEffect(MISCREG_STATUS); 2674661Sksewell@umich.edu 2686376Sgblack@eecs.umich.edu tcStatus.tcu = status.cu; 2696376Sgblack@eecs.umich.edu tcStatus.tmx = status.mx; 2706376Sgblack@eecs.umich.edu tcStatus.tksu = status.ksu; 2714661Sksewell@umich.edu 2726383Sgblack@eecs.umich.edu tc->setMiscRegNoEffect(MISCREG_TC_STATUS, tcStatus); 2734661Sksewell@umich.edu} 2744661Sksewell@umich.edu 2754661Sksewell@umich.edu} // namespace MipsISA 2764661Sksewell@umich.edu 2774661Sksewell@umich.edu 2784661Sksewell@umich.edu#endif 279