exec_context.hh revision 11567
1/* 2 * Copyright (c) 2011-2014 ARM Limited 3 * Copyright (c) 2013 Advanced Micro Devices, Inc. 4 * All rights reserved 5 * 6 * The license below extends only to copyright in the software and shall 7 * not be construed as granting a license to any other intellectual 8 * property including but not limited to intellectual property relating 9 * to a hardware implementation of the functionality of the software 10 * licensed hereunder. You may use the software subject to the license 11 * terms below provided that you ensure that this notice is replicated 12 * unmodified and in its entirety in all distributions of the software, 13 * modified or unmodified, in source code or in binary form. 14 * 15 * Copyright (c) 2002-2005 The Regents of The University of Michigan 16 * All rights reserved. 17 * 18 * Redistribution and use in source and binary forms, with or without 19 * modification, are permitted provided that the following conditions are 20 * met: redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer; 22 * redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in the 24 * documentation and/or other materials provided with the distribution; 25 * neither the name of the copyright holders nor the names of its 26 * contributors may be used to endorse or promote products derived from 27 * this software without specific prior written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 * Authors: Steve Reinhardt 42 * Dave Greene 43 * Nathan Binkert 44 * Andrew Bardsley 45 */ 46 47/** 48 * @file 49 * 50 * ExecContext bears the exec_context interface for Minor. 51 */ 52 53#ifndef __CPU_MINOR_EXEC_CONTEXT_HH__ 54#define __CPU_MINOR_EXEC_CONTEXT_HH__ 55 56#include "cpu/exec_context.hh" 57#include "cpu/minor/execute.hh" 58#include "cpu/minor/pipeline.hh" 59#include "cpu/base.hh" 60#include "cpu/simple_thread.hh" 61#include "debug/MinorExecute.hh" 62 63namespace Minor 64{ 65 66/* Forward declaration of Execute */ 67class Execute; 68 69/** ExecContext bears the exec_context interface for Minor. This nicely 70 * separates that interface from other classes such as Pipeline, MinorCPU 71 * and DynMinorInst and makes it easier to see what state is accessed by it. 72 */ 73class ExecContext : public ::ExecContext 74{ 75 public: 76 MinorCPU &cpu; 77 78 /** ThreadState object, provides all the architectural state. */ 79 SimpleThread &thread; 80 81 /** The execute stage so we can peek at its contents. */ 82 Execute &execute; 83 84 /** Instruction for the benefit of memory operations and for PC */ 85 MinorDynInstPtr inst; 86 87 ExecContext ( 88 MinorCPU &cpu_, 89 SimpleThread &thread_, Execute &execute_, 90 MinorDynInstPtr inst_) : 91 cpu(cpu_), 92 thread(thread_), 93 execute(execute_), 94 inst(inst_) 95 { 96 DPRINTF(MinorExecute, "ExecContext setting PC: %s\n", inst->pc); 97 pcState(inst->pc); 98 setPredicate(true); 99 thread.setIntReg(TheISA::ZeroReg, 0); 100#if THE_ISA == ALPHA_ISA 101 thread.setFloatReg(TheISA::ZeroReg, 0.0); 102#endif 103 } 104 105 Fault 106 initiateMemRead(Addr addr, unsigned int size, unsigned int flags) 107 { 108 execute.getLSQ().pushRequest(inst, true /* load */, nullptr, 109 size, addr, flags, NULL); 110 return NoFault; 111 } 112 113 Fault 114 writeMem(uint8_t *data, unsigned int size, Addr addr, 115 unsigned int flags, uint64_t *res) 116 { 117 execute.getLSQ().pushRequest(inst, false /* store */, data, 118 size, addr, flags, res); 119 return NoFault; 120 } 121 122 IntReg 123 readIntRegOperand(const StaticInst *si, int idx) 124 { 125 return thread.readIntReg(si->srcRegIdx(idx)); 126 } 127 128 TheISA::FloatReg 129 readFloatRegOperand(const StaticInst *si, int idx) 130 { 131 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base; 132 return thread.readFloatReg(reg_idx); 133 } 134 135 TheISA::FloatRegBits 136 readFloatRegOperandBits(const StaticInst *si, int idx) 137 { 138 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base; 139 return thread.readFloatRegBits(reg_idx); 140 } 141 142 void 143 setIntRegOperand(const StaticInst *si, int idx, IntReg val) 144 { 145 thread.setIntReg(si->destRegIdx(idx), val); 146 } 147 148 void 149 setFloatRegOperand(const StaticInst *si, int idx, 150 TheISA::FloatReg val) 151 { 152 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base; 153 thread.setFloatReg(reg_idx, val); 154 } 155 156 void 157 setFloatRegOperandBits(const StaticInst *si, int idx, 158 TheISA::FloatRegBits val) 159 { 160 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base; 161 thread.setFloatRegBits(reg_idx, val); 162 } 163 164 bool 165 readPredicate() 166 { 167 return thread.readPredicate(); 168 } 169 170 void 171 setPredicate(bool val) 172 { 173 thread.setPredicate(val); 174 } 175 176 TheISA::PCState 177 pcState() const 178 { 179 return thread.pcState(); 180 } 181 182 void 183 pcState(const TheISA::PCState &val) 184 { 185 thread.pcState(val); 186 } 187 188 TheISA::MiscReg 189 readMiscRegNoEffect(int misc_reg) const 190 { 191 return thread.readMiscRegNoEffect(misc_reg); 192 } 193 194 TheISA::MiscReg 195 readMiscReg(int misc_reg) 196 { 197 return thread.readMiscReg(misc_reg); 198 } 199 200 void 201 setMiscReg(int misc_reg, const TheISA::MiscReg &val) 202 { 203 thread.setMiscReg(misc_reg, val); 204 } 205 206 TheISA::MiscReg 207 readMiscRegOperand(const StaticInst *si, int idx) 208 { 209 int reg_idx = si->srcRegIdx(idx) - TheISA::Misc_Reg_Base; 210 return thread.readMiscReg(reg_idx); 211 } 212 213 void 214 setMiscRegOperand(const StaticInst *si, int idx, 215 const TheISA::MiscReg &val) 216 { 217 int reg_idx = si->destRegIdx(idx) - TheISA::Misc_Reg_Base; 218 return thread.setMiscReg(reg_idx, val); 219 } 220 221 Fault 222 hwrei() 223 { 224#if THE_ISA == ALPHA_ISA 225 return thread.hwrei(); 226#else 227 return NoFault; 228#endif 229 } 230 231 bool 232 simPalCheck(int palFunc) 233 { 234#if THE_ISA == ALPHA_ISA 235 return thread.simPalCheck(palFunc); 236#else 237 return false; 238#endif 239 } 240 241 void 242 syscall(int64_t callnum) 243 { 244 if (FullSystem) 245 panic("Syscall emulation isn't available in FS mode.\n"); 246 247 thread.syscall(callnum); 248 } 249 250 ThreadContext *tcBase() { return thread.getTC(); } 251 252 /* @todo, should make stCondFailures persistent somewhere */ 253 unsigned int readStCondFailures() const { return 0; } 254 void setStCondFailures(unsigned int st_cond_failures) {} 255 256 ContextID contextId() { return thread.contextId(); } 257 /* ISA-specific (or at least currently ISA singleton) functions */ 258 259 /* X86: TLB twiddling */ 260 void 261 demapPage(Addr vaddr, uint64_t asn) 262 { 263 thread.getITBPtr()->demapPage(vaddr, asn); 264 thread.getDTBPtr()->demapPage(vaddr, asn); 265 } 266 267 TheISA::CCReg 268 readCCRegOperand(const StaticInst *si, int idx) 269 { 270 int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base; 271 return thread.readCCReg(reg_idx); 272 } 273 274 void 275 setCCRegOperand(const StaticInst *si, int idx, TheISA::CCReg val) 276 { 277 int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base; 278 thread.setCCReg(reg_idx, val); 279 } 280 281 void 282 demapInstPage(Addr vaddr, uint64_t asn) 283 { 284 thread.getITBPtr()->demapPage(vaddr, asn); 285 } 286 287 void 288 demapDataPage(Addr vaddr, uint64_t asn) 289 { 290 thread.getDTBPtr()->demapPage(vaddr, asn); 291 } 292 293 /* ALPHA/POWER: Effective address storage */ 294 void setEA(Addr ea) 295 { 296 inst->ea = ea; 297 } 298 299 BaseCPU *getCpuPtr() { return &cpu; } 300 301 /* POWER: Effective address storage */ 302 Addr getEA() const 303 { 304 return inst->ea; 305 } 306 307 /* MIPS: other thread register reading/writing */ 308 uint64_t 309 readRegOtherThread(int idx, ThreadID tid = InvalidThreadID) 310 { 311 SimpleThread *other_thread = (tid == InvalidThreadID 312 ? &thread : cpu.threads[tid]); 313 314 if (idx < TheISA::FP_Reg_Base) { /* Integer */ 315 return other_thread->readIntReg(idx); 316 } else if (idx < TheISA::Misc_Reg_Base) { /* Float */ 317 return other_thread->readFloatRegBits(idx 318 - TheISA::FP_Reg_Base); 319 } else { /* Misc */ 320 return other_thread->readMiscReg(idx 321 - TheISA::Misc_Reg_Base); 322 } 323 } 324 325 void 326 setRegOtherThread(int idx, const TheISA::MiscReg &val, 327 ThreadID tid = InvalidThreadID) 328 { 329 SimpleThread *other_thread = (tid == InvalidThreadID 330 ? &thread : cpu.threads[tid]); 331 332 if (idx < TheISA::FP_Reg_Base) { /* Integer */ 333 return other_thread->setIntReg(idx, val); 334 } else if (idx < TheISA::Misc_Reg_Base) { /* Float */ 335 return other_thread->setFloatRegBits(idx 336 - TheISA::FP_Reg_Base, val); 337 } else { /* Misc */ 338 return other_thread->setMiscReg(idx 339 - TheISA::Misc_Reg_Base, val); 340 } 341 } 342 343 public: 344 // monitor/mwait funtions 345 void armMonitor(Addr address) 346 { getCpuPtr()->armMonitor(inst->id.threadId, address); } 347 348 bool mwait(PacketPtr pkt) 349 { return getCpuPtr()->mwait(inst->id.threadId, pkt); } 350 351 void mwaitAtomic(ThreadContext *tc) 352 { return getCpuPtr()->mwaitAtomic(inst->id.threadId, tc, thread.dtb); } 353 354 AddressMonitor *getAddrMonitor() 355 { return getCpuPtr()->getCpuAddrMonitor(inst->id.threadId); } 356}; 357 358} 359 360#endif /* __CPU_MINOR_EXEC_CONTEXT_HH__ */ 361