exec_context.hh revision 11608:6319a1125f1c
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 "mem/request.hh" 62#include "debug/MinorExecute.hh" 63 64namespace Minor 65{ 66 67/* Forward declaration of Execute */ 68class Execute; 69 70/** ExecContext bears the exec_context interface for Minor. This nicely 71 * separates that interface from other classes such as Pipeline, MinorCPU 72 * and DynMinorInst and makes it easier to see what state is accessed by it. 73 */ 74class ExecContext : public ::ExecContext 75{ 76 public: 77 MinorCPU &cpu; 78 79 /** ThreadState object, provides all the architectural state. */ 80 SimpleThread &thread; 81 82 /** The execute stage so we can peek at its contents. */ 83 Execute &execute; 84 85 /** Instruction for the benefit of memory operations and for PC */ 86 MinorDynInstPtr inst; 87 88 ExecContext ( 89 MinorCPU &cpu_, 90 SimpleThread &thread_, Execute &execute_, 91 MinorDynInstPtr inst_) : 92 cpu(cpu_), 93 thread(thread_), 94 execute(execute_), 95 inst(inst_) 96 { 97 DPRINTF(MinorExecute, "ExecContext setting PC: %s\n", inst->pc); 98 pcState(inst->pc); 99 setPredicate(true); 100 thread.setIntReg(TheISA::ZeroReg, 0); 101#if THE_ISA == ALPHA_ISA 102 thread.setFloatReg(TheISA::ZeroReg, 0.0); 103#endif 104 } 105 106 Fault 107 initiateMemRead(Addr addr, unsigned int size, Request::Flags flags) 108 { 109 execute.getLSQ().pushRequest(inst, true /* load */, nullptr, 110 size, addr, flags, NULL); 111 return NoFault; 112 } 113 114 Fault 115 writeMem(uint8_t *data, unsigned int size, Addr addr, 116 Request::Flags flags, uint64_t *res) 117 { 118 execute.getLSQ().pushRequest(inst, false /* store */, data, 119 size, addr, flags, res); 120 return NoFault; 121 } 122 123 IntReg 124 readIntRegOperand(const StaticInst *si, int idx) 125 { 126 return thread.readIntReg(si->srcRegIdx(idx)); 127 } 128 129 TheISA::FloatReg 130 readFloatRegOperand(const StaticInst *si, int idx) 131 { 132 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base; 133 return thread.readFloatReg(reg_idx); 134 } 135 136 TheISA::FloatRegBits 137 readFloatRegOperandBits(const StaticInst *si, int idx) 138 { 139 int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base; 140 return thread.readFloatRegBits(reg_idx); 141 } 142 143 void 144 setIntRegOperand(const StaticInst *si, int idx, IntReg val) 145 { 146 thread.setIntReg(si->destRegIdx(idx), val); 147 } 148 149 void 150 setFloatRegOperand(const StaticInst *si, int idx, 151 TheISA::FloatReg val) 152 { 153 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base; 154 thread.setFloatReg(reg_idx, val); 155 } 156 157 void 158 setFloatRegOperandBits(const StaticInst *si, int idx, 159 TheISA::FloatRegBits val) 160 { 161 int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base; 162 thread.setFloatRegBits(reg_idx, val); 163 } 164 165 bool 166 readPredicate() 167 { 168 return thread.readPredicate(); 169 } 170 171 void 172 setPredicate(bool val) 173 { 174 thread.setPredicate(val); 175 } 176 177 TheISA::PCState 178 pcState() const 179 { 180 return thread.pcState(); 181 } 182 183 void 184 pcState(const TheISA::PCState &val) 185 { 186 thread.pcState(val); 187 } 188 189 TheISA::MiscReg 190 readMiscRegNoEffect(int misc_reg) const 191 { 192 return thread.readMiscRegNoEffect(misc_reg); 193 } 194 195 TheISA::MiscReg 196 readMiscReg(int misc_reg) 197 { 198 return thread.readMiscReg(misc_reg); 199 } 200 201 void 202 setMiscReg(int misc_reg, const TheISA::MiscReg &val) 203 { 204 thread.setMiscReg(misc_reg, val); 205 } 206 207 TheISA::MiscReg 208 readMiscRegOperand(const StaticInst *si, int idx) 209 { 210 int reg_idx = si->srcRegIdx(idx) - TheISA::Misc_Reg_Base; 211 return thread.readMiscReg(reg_idx); 212 } 213 214 void 215 setMiscRegOperand(const StaticInst *si, int idx, 216 const TheISA::MiscReg &val) 217 { 218 int reg_idx = si->destRegIdx(idx) - TheISA::Misc_Reg_Base; 219 return thread.setMiscReg(reg_idx, val); 220 } 221 222 Fault 223 hwrei() 224 { 225#if THE_ISA == ALPHA_ISA 226 return thread.hwrei(); 227#else 228 return NoFault; 229#endif 230 } 231 232 bool 233 simPalCheck(int palFunc) 234 { 235#if THE_ISA == ALPHA_ISA 236 return thread.simPalCheck(palFunc); 237#else 238 return false; 239#endif 240 } 241 242 void 243 syscall(int64_t callnum) 244 { 245 if (FullSystem) 246 panic("Syscall emulation isn't available in FS mode.\n"); 247 248 thread.syscall(callnum); 249 } 250 251 ThreadContext *tcBase() { return thread.getTC(); } 252 253 /* @todo, should make stCondFailures persistent somewhere */ 254 unsigned int readStCondFailures() const { return 0; } 255 void setStCondFailures(unsigned int st_cond_failures) {} 256 257 ContextID contextId() { return thread.contextId(); } 258 /* ISA-specific (or at least currently ISA singleton) functions */ 259 260 /* X86: TLB twiddling */ 261 void 262 demapPage(Addr vaddr, uint64_t asn) 263 { 264 thread.getITBPtr()->demapPage(vaddr, asn); 265 thread.getDTBPtr()->demapPage(vaddr, asn); 266 } 267 268 TheISA::CCReg 269 readCCRegOperand(const StaticInst *si, int idx) 270 { 271 int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base; 272 return thread.readCCReg(reg_idx); 273 } 274 275 void 276 setCCRegOperand(const StaticInst *si, int idx, TheISA::CCReg val) 277 { 278 int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base; 279 thread.setCCReg(reg_idx, val); 280 } 281 282 void 283 demapInstPage(Addr vaddr, uint64_t asn) 284 { 285 thread.getITBPtr()->demapPage(vaddr, asn); 286 } 287 288 void 289 demapDataPage(Addr vaddr, uint64_t asn) 290 { 291 thread.getDTBPtr()->demapPage(vaddr, asn); 292 } 293 294 /* ALPHA/POWER: Effective address storage */ 295 void setEA(Addr ea) 296 { 297 inst->ea = ea; 298 } 299 300 BaseCPU *getCpuPtr() { return &cpu; } 301 302 /* POWER: Effective address storage */ 303 Addr getEA() const 304 { 305 return inst->ea; 306 } 307 308 /* MIPS: other thread register reading/writing */ 309 uint64_t 310 readRegOtherThread(int idx, ThreadID tid = InvalidThreadID) 311 { 312 SimpleThread *other_thread = (tid == InvalidThreadID 313 ? &thread : cpu.threads[tid]); 314 315 if (idx < TheISA::FP_Reg_Base) { /* Integer */ 316 return other_thread->readIntReg(idx); 317 } else if (idx < TheISA::Misc_Reg_Base) { /* Float */ 318 return other_thread->readFloatRegBits(idx 319 - TheISA::FP_Reg_Base); 320 } else { /* Misc */ 321 return other_thread->readMiscReg(idx 322 - TheISA::Misc_Reg_Base); 323 } 324 } 325 326 void 327 setRegOtherThread(int idx, const TheISA::MiscReg &val, 328 ThreadID tid = InvalidThreadID) 329 { 330 SimpleThread *other_thread = (tid == InvalidThreadID 331 ? &thread : cpu.threads[tid]); 332 333 if (idx < TheISA::FP_Reg_Base) { /* Integer */ 334 return other_thread->setIntReg(idx, val); 335 } else if (idx < TheISA::Misc_Reg_Base) { /* Float */ 336 return other_thread->setFloatRegBits(idx 337 - TheISA::FP_Reg_Base, val); 338 } else { /* Misc */ 339 return other_thread->setMiscReg(idx 340 - TheISA::Misc_Reg_Base, val); 341 } 342 } 343 344 public: 345 // monitor/mwait funtions 346 void armMonitor(Addr address) 347 { getCpuPtr()->armMonitor(inst->id.threadId, address); } 348 349 bool mwait(PacketPtr pkt) 350 { return getCpuPtr()->mwait(inst->id.threadId, pkt); } 351 352 void mwaitAtomic(ThreadContext *tc) 353 { return getCpuPtr()->mwaitAtomic(inst->id.threadId, tc, thread.dtb); } 354 355 AddressMonitor *getAddrMonitor() 356 { return getCpuPtr()->getCpuAddrMonitor(inst->id.threadId); } 357}; 358 359} 360 361#endif /* __CPU_MINOR_EXEC_CONTEXT_HH__ */ 362