mt.hh (6329:5d8b91875859) | mt.hh (6376:eaf61ef6a8f2) |
---|---|
1/* 2 * Copyright (c) 2007 MIPS Technologies, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 26 unchanged lines hidden (view full) --- 35 * @file 36 * 37 * ISA-specific helper functions for multithreaded execution. 38 */ 39 40#include "arch/mips/faults.hh" 41#include "arch/mips/isa_traits.hh" 42#include "arch/mips/mt_constants.hh" | 1/* 2 * Copyright (c) 2007 MIPS Technologies, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 26 unchanged lines hidden (view full) --- 35 * @file 36 * 37 * ISA-specific helper functions for multithreaded execution. 38 */ 39 40#include "arch/mips/faults.hh" 41#include "arch/mips/isa_traits.hh" 42#include "arch/mips/mt_constants.hh" |
43#include "arch/mips/pra_constants.hh" |
|
43#include "arch/mips/registers.hh" 44#include "base/bitfield.hh" 45#include "base/trace.hh" 46#include "base/misc.hh" 47 48#include <iostream> 49 50namespace MipsISA 51{ 52 53 54template <class TC> 55inline unsigned 56getVirtProcNum(TC *tc) 57{ | 44#include "arch/mips/registers.hh" 45#include "base/bitfield.hh" 46#include "base/trace.hh" 47#include "base/misc.hh" 48 49#include <iostream> 50 51namespace MipsISA 52{ 53 54 55template <class TC> 56inline unsigned 57getVirtProcNum(TC *tc) 58{ |
58 MiscReg tcbind = tc->readMiscRegNoEffect(TCBind); 59 return bits(tcbind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO); | 59 TCBindReg tcbind = tc->readMiscRegNoEffect(TCBind); 60 return tcbind.curVPE; |
60} 61 62template <class TC> 63inline unsigned 64getTargetThread(TC *tc) 65{ | 61} 62 63template <class TC> 64inline unsigned 65getTargetThread(TC *tc) 66{ |
66 MiscReg vpec_ctrl = tc->readMiscRegNoEffect(VPEControl); 67 return bits(vpec_ctrl, VPEC_TARG_TC_HI, VPEC_TARG_TC_LO); | 67 VPEControlReg vpeCtrl = tc->readMiscRegNoEffect(VPEControl); 68 return vpeCtrl.targTC; |
68} 69 70template <class TC> 71inline void 72haltThread(TC *tc) 73{ 74 if (tc->status() == TC::Active) { 75 tc->halt(); --- 26 unchanged lines hidden (view full) --- 102 tc->readPC()); 103 } 104} 105 106template <class TC> 107void 108forkThread(TC *tc, Fault &fault, int Rd_bits, int Rs, int Rt) 109{ | 69} 70 71template <class TC> 72inline void 73haltThread(TC *tc) 74{ 75 if (tc->status() == TC::Active) { 76 tc->halt(); --- 26 unchanged lines hidden (view full) --- 103 tc->readPC()); 104 } 105} 106 107template <class TC> 108void 109forkThread(TC *tc, Fault &fault, int Rd_bits, int Rs, int Rt) 110{ |
110 int num_threads = bits(tc->readMiscRegNoEffect(MVPConf0), MVPC0_PTC_HI, MVPC0_PTC_LO) + 1; | 111 MVPConf0Reg mvpConf = tc->readMiscRegNoEffect(MVPConf0); 112 int num_threads = mvpConf.ptc + 1; |
111 112 int success = 0; 113 for (ThreadID tid = 0; tid < num_threads && success == 0; tid++) { | 113 114 int success = 0; 115 for (ThreadID tid = 0; tid < num_threads && success == 0; tid++) { |
114 unsigned tid_TCBind = tc->readRegOtherThread(MipsISA::TCBind + Ctrl_Base_DepTag, 115 tid); 116 unsigned tc_bind = tc->readMiscRegNoEffect(MipsISA::TCBind); | 116 TCBindReg tidTCBind = 117 tc->readRegOtherThread(TCBind + Ctrl_Base_DepTag, tid); 118 TCBindReg tcBind = tc->readMiscRegNoEffect(TCBind); |
117 | 119 |
118 if (bits(tid_TCBind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO) == 119 bits(tc_bind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO)) { | 120 if (tidTCBind.curVPE = tcBind.curVPE) { |
120 | 121 |
121 unsigned tid_TCStatus = tc->readRegOtherThread(MipsISA::TCStatus + Ctrl_Base_DepTag, 122 tid); | 122 TCStatusReg tidTCStatus = 123 tc->readRegOtherThread(TCStatus + Ctrl_Base_DepTag,tid); |
123 | 124 |
124 unsigned tid_TCHalt = tc->readRegOtherThread(MipsISA::TCHalt + Ctrl_Base_DepTag, 125 tid); | 125 TCHaltReg tidTCHalt = 126 tc->readRegOtherThread(TCHalt + Ctrl_Base_DepTag,tid); |
126 | 127 |
127 if (bits(tid_TCStatus, TCS_DA) == 1 && 128 bits(tid_TCHalt, TCH_H) == 0 && 129 bits(tid_TCStatus, TCS_A) == 0 && 130 success == 0) { | 128 if (tidTCStatus.da == 1 && tidTCHalt.h == 0 && 129 tidTCStatus.a == 0 && success == 0) { |
131 | 130 |
132 tc->setRegOtherThread(MipsISA::TCRestart + Ctrl_Base_DepTag, Rs, tid); 133 | 131 tc->setRegOtherThread(TCRestart + Ctrl_Base_DepTag, Rs, tid); |
134 tc->setRegOtherThread(Rd_bits, Rt, tid); 135 | 132 tc->setRegOtherThread(Rd_bits, Rt, tid); 133 |
136 unsigned status_ksu = bits(tc->readMiscReg(MipsISA::Status), 137 S_KSU_HI, S_KSU_LO); 138 unsigned tc_status_asid = bits(tc->readMiscReg(MipsISA::TCStatus), 139 TCS_ASID_HI, TCS_ASID_LO); | 134 StatusReg status = tc->readMiscReg(Status); 135 TCStatusReg tcStatus = tc->readMiscReg(TCStatus); |
140 141 // Set Run-State to Running | 136 137 // Set Run-State to Running |
142 replaceBits(tid_TCStatus, TCSTATUS_RNST_HI, TCSTATUS_RNST_LO, 0); 143 | 138 tidTCStatus.rnst = 0; |
144 // Set Delay-Slot to 0 | 139 // Set Delay-Slot to 0 |
145 replaceBits(tid_TCStatus, TCSTATUS_TDS, 0); 146 | 140 tidTCStatus.tds = 0; |
147 // Set Dirty TC to 1 | 141 // Set Dirty TC to 1 |
148 replaceBits(tid_TCStatus, TCSTATUS_DT, 1); 149 | 142 tidTCStatus.dt = 1; |
150 // Set Activated to 1 | 143 // Set Activated to 1 |
151 replaceBits(tid_TCStatus, TCSTATUS_A, 1); 152 | 144 tidTCStatus.a = 1; |
153 // Set status to previous thread's status | 145 // Set status to previous thread's status |
154 replaceBits(tid_TCStatus, TCSTATUS_TKSU_HI, TCSTATUS_TKSU_LO, status_ksu); 155 | 146 tidTCStatus.tksu = status.ksu; |
156 // Set ASID to previous thread's state | 147 // Set ASID to previous thread's state |
157 replaceBits(tid_TCStatus, TCSTATUS_ASID_HI, TCSTATUS_ASID_LO, tc_status_asid); | 148 tidTCStatus.asid = tcStatus.asid; |
158 159 // Write Status Register | 149 150 // Write Status Register |
160 tc->setRegOtherThread(MipsISA::TCStatus + Ctrl_Base_DepTag, 161 tid_TCStatus, tid); | 151 tc->setRegOtherThread(TCStatus + Ctrl_Base_DepTag, 152 tidTCStatus, tid); |
162 163 // Mark As Successful Fork 164 success = 1; 165 } 166 } else { 167 std::cerr << "Bad VPEs" << std::endl; 168 } 169 } 170 171 if (success == 0) { | 153 154 // Mark As Successful Fork 155 success = 1; 156 } 157 } else { 158 std::cerr << "Bad VPEs" << std::endl; 159 } 160 } 161 162 if (success == 0) { |
172 unsigned vpe_control = tc->readMiscRegNoEffect(MipsISA::VPEControl); 173 tc->setMiscReg(VPEControl, insertBits(vpe_control, VPEC_EXCPT_HI, VPEC_EXCPT_LO, 1)); | 163 VPEControlReg vpeControl = tc->readMiscRegNoEffect(VPEControl); 164 vpeControl.excpt = 1; 165 tc->setMiscReg(VPEControl, vpeControl); |
174 fault = new ThreadFault(); 175 } 176} 177 178 179template <class TC> 180int 181yieldThread(TC *tc, Fault &fault, int src_reg, uint32_t yield_mask) 182{ 183 if (src_reg == 0) { | 166 fault = new ThreadFault(); 167 } 168} 169 170 171template <class TC> 172int 173yieldThread(TC *tc, Fault &fault, int src_reg, uint32_t yield_mask) 174{ 175 if (src_reg == 0) { |
184 unsigned mvpconf0 = tc->readMiscRegNoEffect(MVPConf0); 185 ThreadID num_threads = bits(mvpconf0, MVPC0_PTC_HI, MVPC0_PTC_LO) + 1; | 176 MVPConf0Reg mvpConf0 = tc->readMiscRegNoEffect(MVPConf0); 177 ThreadID num_threads = mvpConf0.ptc + 1; |
186 187 int ok = 0; 188 189 // Get Current VPE & TC numbers from calling thread | 178 179 int ok = 0; 180 181 // Get Current VPE & TC numbers from calling thread |
190 unsigned tcbind = tc->readMiscRegNoEffect(TCBind); 191 unsigned cur_vpe = bits(tcbind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO); 192 unsigned cur_tc = bits(tcbind, TCB_CUR_TC_HI, TCB_CUR_TC_LO); | 182 TCBindReg tcBind = tc->readMiscRegNoEffect(TCBind); |
193 194 for (ThreadID tid = 0; tid < num_threads; tid++) { | 183 184 for (ThreadID tid = 0; tid < num_threads; tid++) { |
195 unsigned tid_TCStatus = tc->readRegOtherThread(MipsISA::TCStatus + Ctrl_Base_DepTag, 196 tid); 197 unsigned tid_TCHalt = tc->readRegOtherThread(MipsISA::TCHalt + Ctrl_Base_DepTag, 198 tid); 199 unsigned tid_TCBind = tc->readRegOtherThread(MipsISA::TCBind + Ctrl_Base_DepTag, 200 tid); | 185 TCStatusReg tidTCStatus = 186 tc->readRegOtherThread(TCStatus + Ctrl_Base_DepTag, tid); 187 TCHaltReg tidTCHalt = 188 tc->readRegOtherThread(TCHalt + Ctrl_Base_DepTag, tid); 189 TCBindReg tidTCBind = 190 tc->readRegOtherThread(TCBind + Ctrl_Base_DepTag, tid); |
201 | 191 |
202 unsigned tid_vpe = bits(tid_TCBind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO); 203 unsigned tid_tc = bits(tid_TCBind, TCB_CUR_TC_HI, TCB_CUR_TC_LO); 204 unsigned tid_tcstatus_da = bits(tid_TCStatus, TCS_DA); 205 unsigned tid_tcstatus_a = bits(tid_TCStatus, TCS_A); 206 unsigned tid_tchalt_h = bits(tid_TCHalt, TCH_H); 207 208 if (tid_vpe == cur_vpe && 209 tid_tc == cur_tc && 210 tid_tcstatus_da == 1 && 211 tid_tchalt_h == 0 && 212 tid_tcstatus_a == 1) { | 192 if (tidTCBind.curVPE == tcBind.curVPE && 193 tidTCBind.curTC == tcBind.curTC && 194 tidTCStatus.da == 1 && 195 tidTCHalt.h == 0 && 196 tidTCStatus.a == 1) { |
213 ok = 1; 214 } 215 } 216 217 if (ok == 1) { | 197 ok = 1; 198 } 199 } 200 201 if (ok == 1) { |
218 unsigned tcstatus = tc->readMiscRegNoEffect(TCStatus); 219 tc->setMiscReg(TCStatus, insertBits(tcstatus, TCS_A, TCS_A, 0)); 220 warn("%i: Deactivating Hardware Thread Context #%i", curTick, tc->threadId()); | 202 TCStatusReg tcStatus = tc->readMiscRegNoEffect(TCStatus); 203 tcStatus.a = 0; 204 tc->setMiscReg(TCStatus, tcStatus); 205 warn("%i: Deactivating Hardware Thread Context #%i", 206 curTick, tc->threadId()); |
221 } 222 } else if (src_reg > 0) { 223 if (src_reg && !yield_mask != 0) { | 207 } 208 } else if (src_reg > 0) { 209 if (src_reg && !yield_mask != 0) { |
224 unsigned vpe_control = tc->readMiscReg(VPEControl); 225 tc->setMiscReg(VPEControl, insertBits(vpe_control, VPEC_EXCPT_HI, VPEC_EXCPT_LO, 2)); | 210 VPEControlReg vpeControl = tc->readMiscReg(VPEControl); 211 vpeControl.excpt = 2; 212 tc->setMiscReg(VPEControl, vpeControl); |
226 fault = new ThreadFault(); 227 } else { | 213 fault = new ThreadFault(); 214 } else { |
228 //tc->setThreadRescheduleCondition(src_reg & yield_mask); | |
229 } 230 } else if (src_reg != -2) { | 215 } 216 } else if (src_reg != -2) { |
231 unsigned tcstatus = tc->readMiscRegNoEffect(TCStatus); 232 unsigned vpe_control = tc->readMiscRegNoEffect(VPEControl); 233 unsigned tcstatus_dt = bits(tcstatus, TCS_DT); 234 unsigned vpe_control_ysi = bits(vpe_control, VPEC_YSI); | 217 TCStatusReg tcStatus = tc->readMiscRegNoEffect(TCStatus); 218 VPEControlReg vpeControl = tc->readMiscRegNoEffect(VPEControl); |
235 | 219 |
236 if (vpe_control_ysi == 1 && tcstatus_dt == 1 ) { 237 tc->setMiscReg(VPEControl, insertBits(vpe_control, VPEC_EXCPT_HI, VPEC_EXCPT_LO, 4)); | 220 if (vpeControl.ysi == 1 && tcStatus.dt == 1 ) { 221 vpeControl.excpt = 4; |
238 fault = new ThreadFault(); 239 } else { | 222 fault = new ThreadFault(); 223 } else { |
240 //tc->ScheduleOtherThreads(); 241 //std::cerr << "T" << tc->threadId() << "YIELD: Schedule Other Threads.\n" << std::endl; 242 //tc->suspend(); 243 // Save last known PC in TCRestart 244 // @TODO: Needs to check if this is a branch and if so, take previous instruction 245 //tc->setMiscRegWithEffect(TCRestart, tc->readNextPC()); | |
246 } 247 } 248 249 return src_reg & yield_mask; 250} 251 252 253// TC will usually be a object derived from ThreadContext 254// (src/cpu/thread_context.hh) 255template <class TC> 256inline void 257updateStatusView(TC *tc) 258{ 259 // TCStatus' register view must be the same as 260 // Status register view for CU, MX, KSU bits | 224 } 225 } 226 227 return src_reg & yield_mask; 228} 229 230 231// TC will usually be a object derived from ThreadContext 232// (src/cpu/thread_context.hh) 233template <class TC> 234inline void 235updateStatusView(TC *tc) 236{ 237 // TCStatus' register view must be the same as 238 // Status register view for CU, MX, KSU bits |
261 MiscReg tc_status = tc->readMiscRegNoEffect(TCStatus); 262 MiscReg status = tc->readMiscRegNoEffect(Status); | 239 TCStatusReg tcStatus = tc->readMiscRegNoEffect(TCStatus); 240 StatusReg status = tc->readMiscRegNoEffect(Status); |
263 | 241 |
264 unsigned cu_bits = bits(tc_status, TCS_TCU_HI, TCS_TCU_LO); 265 replaceBits(status, S_CU_HI, S_CU_LO, cu_bits); | 242 status.cu = tcStatus.tcu; 243 status.mx = tcStatus.tmx; 244 status.ksu = tcStatus.tksu; |
266 | 245 |
267 unsigned mx_bits = bits(tc_status, TCS_TMX); 268 replaceBits(status, S_MX, S_MX, mx_bits); 269 270 unsigned ksu_bits = bits(tc_status, TCS_TKSU_HI, TCS_TKSU_LO); 271 replaceBits(status, S_KSU_HI, S_KSU_LO, ksu_bits); 272 | |
273 tc->setMiscRegNoEffect(Status, status); 274} 275 276// TC will usually be a object derived from ThreadContext 277// (src/cpu/thread_context.hh) 278template <class TC> 279inline void 280updateTCStatusView(TC *tc) 281{ 282 // TCStatus' register view must be the same as 283 // Status register view for CU, MX, KSU bits | 246 tc->setMiscRegNoEffect(Status, status); 247} 248 249// TC will usually be a object derived from ThreadContext 250// (src/cpu/thread_context.hh) 251template <class TC> 252inline void 253updateTCStatusView(TC *tc) 254{ 255 // TCStatus' register view must be the same as 256 // Status register view for CU, MX, KSU bits |
284 MiscReg tc_status = tc->readMiscRegNoEffect(TCStatus); 285 MiscReg status = tc->readMiscRegNoEffect(Status); | 257 TCStatusReg tcStatus = tc->readMiscRegNoEffect(TCStatus); 258 StatusReg status = tc->readMiscRegNoEffect(Status); |
286 | 259 |
287 unsigned cu_bits = bits(status, S_CU_HI, S_CU_LO); 288 replaceBits(tc_status, TCS_TCU_HI, TCS_TCU_LO, cu_bits); | 260 tcStatus.tcu = status.cu; 261 tcStatus.tmx = status.mx; 262 tcStatus.tksu = status.ksu; |
289 | 263 |
290 unsigned mx_bits = bits(status, S_MX, S_MX); 291 replaceBits(tc_status, TCS_TMX, mx_bits); 292 293 unsigned ksu_bits = bits(status, S_KSU_HI, S_KSU_LO); 294 replaceBits(tc_status, TCS_TKSU_HI, TCS_TKSU_LO, ksu_bits); 295 296 tc->setMiscRegNoEffect(TCStatus, tc_status); | 264 tc->setMiscRegNoEffect(TCStatus, tcStatus); |
297} 298 299} // namespace MipsISA 300 301 302#endif | 265} 266 267} // namespace MipsISA 268 269 270#endif |