shader.cc revision 12749
111308Santhony.gutierrez@amd.com/* 211308Santhony.gutierrez@amd.com * Copyright (c) 2011-2015 Advanced Micro Devices, Inc. 311308Santhony.gutierrez@amd.com * All rights reserved. 411308Santhony.gutierrez@amd.com * 511308Santhony.gutierrez@amd.com * For use for simulation and test purposes only 611308Santhony.gutierrez@amd.com * 711308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without 811308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are met: 911308Santhony.gutierrez@amd.com * 1011308Santhony.gutierrez@amd.com * 1. Redistributions of source code must retain the above copyright notice, 1111308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer. 1211308Santhony.gutierrez@amd.com * 1311308Santhony.gutierrez@amd.com * 2. Redistributions in binary form must reproduce the above copyright notice, 1411308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer in the documentation 1511308Santhony.gutierrez@amd.com * and/or other materials provided with the distribution. 1611308Santhony.gutierrez@amd.com * 1712697Santhony.gutierrez@amd.com * 3. Neither the name of the copyright holder nor the names of its 1812697Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from this 1912697Santhony.gutierrez@amd.com * software without specific prior written permission. 2011308Santhony.gutierrez@amd.com * 2111308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2211308Santhony.gutierrez@amd.com * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2311308Santhony.gutierrez@amd.com * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2411308Santhony.gutierrez@amd.com * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2511308Santhony.gutierrez@amd.com * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2611308Santhony.gutierrez@amd.com * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2711308Santhony.gutierrez@amd.com * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2811308Santhony.gutierrez@amd.com * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2911308Santhony.gutierrez@amd.com * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3011308Santhony.gutierrez@amd.com * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3111308Santhony.gutierrez@amd.com * POSSIBILITY OF SUCH DAMAGE. 3211308Santhony.gutierrez@amd.com * 3312697Santhony.gutierrez@amd.com * Authors: Steve Reinhardt 3411308Santhony.gutierrez@amd.com */ 3511308Santhony.gutierrez@amd.com 3611308Santhony.gutierrez@amd.com#include "gpu-compute/shader.hh" 3711308Santhony.gutierrez@amd.com 3811308Santhony.gutierrez@amd.com#include <limits> 3911308Santhony.gutierrez@amd.com 4011308Santhony.gutierrez@amd.com#include "arch/x86/linux/linux.hh" 4111308Santhony.gutierrez@amd.com#include "base/chunk_generator.hh" 4211308Santhony.gutierrez@amd.com#include "debug/GPUDisp.hh" 4311308Santhony.gutierrez@amd.com#include "debug/GPUMem.hh" 4411308Santhony.gutierrez@amd.com#include "debug/HSAIL.hh" 4511308Santhony.gutierrez@amd.com#include "gpu-compute/dispatcher.hh" 4611308Santhony.gutierrez@amd.com#include "gpu-compute/gpu_static_inst.hh" 4711308Santhony.gutierrez@amd.com#include "gpu-compute/qstruct.hh" 4811308Santhony.gutierrez@amd.com#include "gpu-compute/wavefront.hh" 4911308Santhony.gutierrez@amd.com#include "mem/packet.hh" 5011308Santhony.gutierrez@amd.com#include "mem/ruby/system/RubySystem.hh" 5111308Santhony.gutierrez@amd.com#include "sim/sim_exit.hh" 5211308Santhony.gutierrez@amd.com 5312126Sspwilson2@wisc.eduShader::Shader(const Params *p) 5412126Sspwilson2@wisc.edu : ClockedObject(p), clock(p->clk_domain->clockPeriod()), 5512126Sspwilson2@wisc.edu cpuThread(nullptr), gpuTc(nullptr), cpuPointer(p->cpu_pointer), 5612126Sspwilson2@wisc.edu tickEvent([this]{ processTick(); }, "Shader tick", 5712126Sspwilson2@wisc.edu false, Event::CPU_Tick_Pri), 5812126Sspwilson2@wisc.edu timingSim(p->timing), hsail_mode(SIMT), 5912126Sspwilson2@wisc.edu impl_kern_boundary_sync(p->impl_kern_boundary_sync), 6012126Sspwilson2@wisc.edu separate_acquire_release(p->separate_acquire_release), coissue_return(1), 6112126Sspwilson2@wisc.edu trace_vgpr_all(1), n_cu((p->CUs).size()), n_wf(p->n_wf), 6212126Sspwilson2@wisc.edu globalMemSize(p->globalmem), nextSchedCu(0), sa_n(0), tick_cnt(0), 6312126Sspwilson2@wisc.edu box_tick_cnt(0), start_tick_cnt(0) 6411308Santhony.gutierrez@amd.com{ 6511308Santhony.gutierrez@amd.com 6611308Santhony.gutierrez@amd.com cuList.resize(n_cu); 6711308Santhony.gutierrez@amd.com 6811308Santhony.gutierrez@amd.com for (int i = 0; i < n_cu; ++i) { 6911308Santhony.gutierrez@amd.com cuList[i] = p->CUs[i]; 7011308Santhony.gutierrez@amd.com assert(i == cuList[i]->cu_id); 7111308Santhony.gutierrez@amd.com cuList[i]->shader = this; 7211308Santhony.gutierrez@amd.com } 7311308Santhony.gutierrez@amd.com} 7411308Santhony.gutierrez@amd.com 7511308Santhony.gutierrez@amd.comAddr 7611308Santhony.gutierrez@amd.comShader::mmap(int length) 7711308Santhony.gutierrez@amd.com{ 7811308Santhony.gutierrez@amd.com 7911308Santhony.gutierrez@amd.com Addr start; 8011308Santhony.gutierrez@amd.com 8111308Santhony.gutierrez@amd.com // round up length to the next page 8211308Santhony.gutierrez@amd.com length = roundUp(length, TheISA::PageBytes); 8311308Santhony.gutierrez@amd.com 8411386Ssteve.reinhardt@amd.com Process *proc = gpuTc->getProcessPtr(); 8511886Sbrandon.potter@amd.com auto mem_state = proc->memState; 8611386Ssteve.reinhardt@amd.com 8711386Ssteve.reinhardt@amd.com if (proc->mmapGrowsDown()) { 8811308Santhony.gutierrez@amd.com DPRINTF(HSAIL, "GROWS DOWN"); 8911905SBrandon.Potter@amd.com start = mem_state->getMmapEnd() - length; 9011905SBrandon.Potter@amd.com mem_state->setMmapEnd(start); 9111308Santhony.gutierrez@amd.com } else { 9211308Santhony.gutierrez@amd.com DPRINTF(HSAIL, "GROWS UP"); 9311905SBrandon.Potter@amd.com start = mem_state->getMmapEnd(); 9411905SBrandon.Potter@amd.com mem_state->setMmapEnd(start + length); 9511308Santhony.gutierrez@amd.com 9611308Santhony.gutierrez@amd.com // assertion to make sure we don't overwrite the stack (it grows down) 9711905SBrandon.Potter@amd.com assert(mem_state->getStackBase() - mem_state->getMaxStackSize() > 9811905SBrandon.Potter@amd.com mem_state->getMmapEnd()); 9911308Santhony.gutierrez@amd.com } 10011308Santhony.gutierrez@amd.com 10111308Santhony.gutierrez@amd.com DPRINTF(HSAIL,"Shader::mmap start= %#x, %#x\n", start, length); 10211308Santhony.gutierrez@amd.com 10311386Ssteve.reinhardt@amd.com proc->allocateMem(start, length); 10411308Santhony.gutierrez@amd.com 10511308Santhony.gutierrez@amd.com return start; 10611308Santhony.gutierrez@amd.com} 10711308Santhony.gutierrez@amd.com 10811308Santhony.gutierrez@amd.comvoid 10911308Santhony.gutierrez@amd.comShader::init() 11011308Santhony.gutierrez@amd.com{ 11111308Santhony.gutierrez@amd.com // grab the threadContext of the thread running on the CPU 11211308Santhony.gutierrez@amd.com assert(cpuPointer); 11311308Santhony.gutierrez@amd.com gpuTc = cpuPointer->getContext(0); 11411308Santhony.gutierrez@amd.com assert(gpuTc); 11511308Santhony.gutierrez@amd.com} 11611308Santhony.gutierrez@amd.com 11711308Santhony.gutierrez@amd.comShader::~Shader() 11811308Santhony.gutierrez@amd.com{ 11911308Santhony.gutierrez@amd.com for (int j = 0; j < n_cu; ++j) 12011308Santhony.gutierrez@amd.com delete cuList[j]; 12111308Santhony.gutierrez@amd.com} 12211308Santhony.gutierrez@amd.com 12311308Santhony.gutierrez@amd.comvoid 12411435Smitch.hayenga@arm.comShader::updateContext(int cid) { 12511435Smitch.hayenga@arm.com // context of the thread which dispatched work 12611308Santhony.gutierrez@amd.com assert(cpuPointer); 12711435Smitch.hayenga@arm.com gpuTc = cpuPointer->getContext(cid); 12811308Santhony.gutierrez@amd.com assert(gpuTc); 12911308Santhony.gutierrez@amd.com} 13011308Santhony.gutierrez@amd.com 13111308Santhony.gutierrez@amd.comvoid 13211308Santhony.gutierrez@amd.comShader::hostWakeUp(BaseCPU *cpu) { 13311308Santhony.gutierrez@amd.com if (cpuPointer == cpu) { 13411308Santhony.gutierrez@amd.com if (gpuTc->status() == ThreadContext::Suspended) 13511308Santhony.gutierrez@amd.com cpu->activateContext(gpuTc->threadId()); 13611308Santhony.gutierrez@amd.com } else { 13711308Santhony.gutierrez@amd.com //Make sure both dispatcher and shader are trying to 13811308Santhony.gutierrez@amd.com //wakeup same host. Hack here to enable kernel launch 13911308Santhony.gutierrez@amd.com //from multiple CPUs 14011308Santhony.gutierrez@amd.com panic("Dispatcher wants to wakeup a different host"); 14111308Santhony.gutierrez@amd.com } 14211308Santhony.gutierrez@amd.com} 14311308Santhony.gutierrez@amd.com 14411308Santhony.gutierrez@amd.comShader* 14511308Santhony.gutierrez@amd.comShaderParams::create() 14611308Santhony.gutierrez@amd.com{ 14711308Santhony.gutierrez@amd.com return new Shader(this); 14811308Santhony.gutierrez@amd.com} 14911308Santhony.gutierrez@amd.com 15011308Santhony.gutierrez@amd.comvoid 15111308Santhony.gutierrez@amd.comShader::exec() 15211308Santhony.gutierrez@amd.com{ 15311308Santhony.gutierrez@amd.com tick_cnt = curTick(); 15411308Santhony.gutierrez@amd.com box_tick_cnt = curTick() - start_tick_cnt; 15511308Santhony.gutierrez@amd.com 15611308Santhony.gutierrez@amd.com // apply any scheduled adds 15711308Santhony.gutierrez@amd.com for (int i = 0; i < sa_n; ++i) { 15811308Santhony.gutierrez@amd.com if (sa_when[i] <= tick_cnt) { 15911308Santhony.gutierrez@amd.com *sa_val[i] += sa_x[i]; 16011308Santhony.gutierrez@amd.com sa_val.erase(sa_val.begin() + i); 16111308Santhony.gutierrez@amd.com sa_x.erase(sa_x.begin() + i); 16211308Santhony.gutierrez@amd.com sa_when.erase(sa_when.begin() + i); 16311308Santhony.gutierrez@amd.com --sa_n; 16411308Santhony.gutierrez@amd.com --i; 16511308Santhony.gutierrez@amd.com } 16611308Santhony.gutierrez@amd.com } 16711308Santhony.gutierrez@amd.com 16811308Santhony.gutierrez@amd.com // clock all of the cu's 16911308Santhony.gutierrez@amd.com for (int i = 0; i < n_cu; ++i) 17011308Santhony.gutierrez@amd.com cuList[i]->exec(); 17111308Santhony.gutierrez@amd.com} 17211308Santhony.gutierrez@amd.com 17311308Santhony.gutierrez@amd.combool 17411308Santhony.gutierrez@amd.comShader::dispatch_workgroups(NDRange *ndr) 17511308Santhony.gutierrez@amd.com{ 17611308Santhony.gutierrez@amd.com bool scheduledSomething = false; 17711308Santhony.gutierrez@amd.com int cuCount = 0; 17811308Santhony.gutierrez@amd.com int curCu = nextSchedCu; 17911308Santhony.gutierrez@amd.com 18011308Santhony.gutierrez@amd.com while (cuCount < n_cu) { 18111308Santhony.gutierrez@amd.com //Every time we try a CU, update nextSchedCu 18211308Santhony.gutierrez@amd.com nextSchedCu = (nextSchedCu + 1) % n_cu; 18311308Santhony.gutierrez@amd.com 18411308Santhony.gutierrez@amd.com // dispatch workgroup iff the following two conditions are met: 18511308Santhony.gutierrez@amd.com // (a) wg_rem is true - there are unassigned workgroups in the grid 18611308Santhony.gutierrez@amd.com // (b) there are enough free slots in cu cuList[i] for this wg 18711308Santhony.gutierrez@amd.com if (ndr->wg_disp_rem && cuList[curCu]->ReadyWorkgroup(ndr)) { 18811308Santhony.gutierrez@amd.com scheduledSomething = true; 18911308Santhony.gutierrez@amd.com DPRINTF(GPUDisp, "Dispatching a workgroup to CU %d\n", curCu); 19011308Santhony.gutierrez@amd.com 19111308Santhony.gutierrez@amd.com // ticks() member function translates cycles to simulation ticks. 19211308Santhony.gutierrez@amd.com if (!tickEvent.scheduled()) { 19311308Santhony.gutierrez@amd.com schedule(tickEvent, curTick() + this->ticks(1)); 19411308Santhony.gutierrez@amd.com } 19511308Santhony.gutierrez@amd.com 19611308Santhony.gutierrez@amd.com cuList[curCu]->StartWorkgroup(ndr); 19711308Santhony.gutierrez@amd.com ndr->wgId[0]++; 19811308Santhony.gutierrez@amd.com ndr->globalWgId++; 19911308Santhony.gutierrez@amd.com if (ndr->wgId[0] * ndr->q.wgSize[0] >= ndr->q.gdSize[0]) { 20011308Santhony.gutierrez@amd.com ndr->wgId[0] = 0; 20111308Santhony.gutierrez@amd.com ndr->wgId[1]++; 20211308Santhony.gutierrez@amd.com 20311308Santhony.gutierrez@amd.com if (ndr->wgId[1] * ndr->q.wgSize[1] >= ndr->q.gdSize[1]) { 20411308Santhony.gutierrez@amd.com ndr->wgId[1] = 0; 20511308Santhony.gutierrez@amd.com ndr->wgId[2]++; 20611308Santhony.gutierrez@amd.com 20711308Santhony.gutierrez@amd.com if (ndr->wgId[2] * ndr->q.wgSize[2] >= ndr->q.gdSize[2]) { 20811308Santhony.gutierrez@amd.com ndr->wg_disp_rem = false; 20911308Santhony.gutierrez@amd.com break; 21011308Santhony.gutierrez@amd.com } 21111308Santhony.gutierrez@amd.com } 21211308Santhony.gutierrez@amd.com } 21311308Santhony.gutierrez@amd.com } 21411308Santhony.gutierrez@amd.com 21511308Santhony.gutierrez@amd.com ++cuCount; 21611308Santhony.gutierrez@amd.com curCu = nextSchedCu; 21711308Santhony.gutierrez@amd.com } 21811308Santhony.gutierrez@amd.com 21911308Santhony.gutierrez@amd.com return scheduledSomething; 22011308Santhony.gutierrez@amd.com} 22111308Santhony.gutierrez@amd.com 22211308Santhony.gutierrez@amd.comvoid 22311308Santhony.gutierrez@amd.comShader::handshake(GpuDispatcher *_dispatcher) 22411308Santhony.gutierrez@amd.com{ 22511308Santhony.gutierrez@amd.com dispatcher = _dispatcher; 22611308Santhony.gutierrez@amd.com} 22711308Santhony.gutierrez@amd.com 22811308Santhony.gutierrez@amd.comvoid 22912749Sgiacomo.travaglini@arm.comShader::doFunctionalAccess(const RequestPtr &req, MemCmd cmd, void *data, 23011308Santhony.gutierrez@amd.com bool suppress_func_errors, int cu_id) 23111308Santhony.gutierrez@amd.com{ 23211698Santhony.gutierrez@amd.com int block_size = cuList.at(cu_id)->cacheLineSize(); 23311308Santhony.gutierrez@amd.com unsigned size = req->getSize(); 23411308Santhony.gutierrez@amd.com 23511308Santhony.gutierrez@amd.com Addr tmp_addr; 23611308Santhony.gutierrez@amd.com BaseTLB::Mode trans_mode; 23711308Santhony.gutierrez@amd.com 23811308Santhony.gutierrez@amd.com if (cmd == MemCmd::ReadReq) { 23911308Santhony.gutierrez@amd.com trans_mode = BaseTLB::Read; 24011308Santhony.gutierrez@amd.com } else if (cmd == MemCmd::WriteReq) { 24111308Santhony.gutierrez@amd.com trans_mode = BaseTLB::Write; 24211308Santhony.gutierrez@amd.com } else { 24311308Santhony.gutierrez@amd.com fatal("unexcepted MemCmd\n"); 24411308Santhony.gutierrez@amd.com } 24511308Santhony.gutierrez@amd.com 24611308Santhony.gutierrez@amd.com tmp_addr = req->getVaddr(); 24711308Santhony.gutierrez@amd.com Addr split_addr = roundDown(tmp_addr + size - 1, block_size); 24811308Santhony.gutierrez@amd.com 24911308Santhony.gutierrez@amd.com assert(split_addr <= tmp_addr || split_addr - tmp_addr < block_size); 25011308Santhony.gutierrez@amd.com 25111308Santhony.gutierrez@amd.com // Misaligned access 25211308Santhony.gutierrez@amd.com if (split_addr > tmp_addr) { 25311308Santhony.gutierrez@amd.com RequestPtr req1, req2; 25411308Santhony.gutierrez@amd.com req->splitOnVaddr(split_addr, req1, req2); 25511308Santhony.gutierrez@amd.com 25611308Santhony.gutierrez@amd.com 25711308Santhony.gutierrez@amd.com PacketPtr pkt1 = new Packet(req2, cmd); 25811308Santhony.gutierrez@amd.com PacketPtr pkt2 = new Packet(req1, cmd); 25911308Santhony.gutierrez@amd.com 26011308Santhony.gutierrez@amd.com functionalTLBAccess(pkt1, cu_id, trans_mode); 26111308Santhony.gutierrez@amd.com functionalTLBAccess(pkt2, cu_id, trans_mode); 26211308Santhony.gutierrez@amd.com 26311308Santhony.gutierrez@amd.com PacketPtr new_pkt1 = new Packet(pkt1->req, cmd); 26411308Santhony.gutierrez@amd.com PacketPtr new_pkt2 = new Packet(pkt2->req, cmd); 26511308Santhony.gutierrez@amd.com 26611308Santhony.gutierrez@amd.com new_pkt1->dataStatic(data); 26711308Santhony.gutierrez@amd.com new_pkt2->dataStatic((uint8_t*)data + req1->getSize()); 26811308Santhony.gutierrez@amd.com 26911308Santhony.gutierrez@amd.com if (suppress_func_errors) { 27011308Santhony.gutierrez@amd.com new_pkt1->setSuppressFuncError(); 27111308Santhony.gutierrez@amd.com new_pkt2->setSuppressFuncError(); 27211308Santhony.gutierrez@amd.com } 27311308Santhony.gutierrez@amd.com 27411308Santhony.gutierrez@amd.com // fixme: this should be cuList[cu_id] if cu_id != n_cu 27511308Santhony.gutierrez@amd.com // The latter requires a memPort in the dispatcher 27611308Santhony.gutierrez@amd.com cuList[0]->memPort[0]->sendFunctional(new_pkt1); 27711308Santhony.gutierrez@amd.com cuList[0]->memPort[0]->sendFunctional(new_pkt2); 27811308Santhony.gutierrez@amd.com 27911308Santhony.gutierrez@amd.com delete new_pkt1; 28011308Santhony.gutierrez@amd.com delete new_pkt2; 28111308Santhony.gutierrez@amd.com delete pkt1; 28211308Santhony.gutierrez@amd.com delete pkt2; 28311308Santhony.gutierrez@amd.com } else { 28411308Santhony.gutierrez@amd.com PacketPtr pkt = new Packet(req, cmd); 28511308Santhony.gutierrez@amd.com functionalTLBAccess(pkt, cu_id, trans_mode); 28611308Santhony.gutierrez@amd.com PacketPtr new_pkt = new Packet(pkt->req, cmd); 28711308Santhony.gutierrez@amd.com new_pkt->dataStatic(data); 28811308Santhony.gutierrez@amd.com 28911308Santhony.gutierrez@amd.com if (suppress_func_errors) { 29011308Santhony.gutierrez@amd.com new_pkt->setSuppressFuncError(); 29111308Santhony.gutierrez@amd.com }; 29211308Santhony.gutierrez@amd.com 29311308Santhony.gutierrez@amd.com // fixme: this should be cuList[cu_id] if cu_id != n_cu 29411308Santhony.gutierrez@amd.com // The latter requires a memPort in the dispatcher 29511308Santhony.gutierrez@amd.com cuList[0]->memPort[0]->sendFunctional(new_pkt); 29611308Santhony.gutierrez@amd.com 29711308Santhony.gutierrez@amd.com delete new_pkt; 29811308Santhony.gutierrez@amd.com delete pkt; 29911308Santhony.gutierrez@amd.com } 30011308Santhony.gutierrez@amd.com} 30111308Santhony.gutierrez@amd.com 30211308Santhony.gutierrez@amd.combool 30311308Santhony.gutierrez@amd.comShader::busy() 30411308Santhony.gutierrez@amd.com{ 30511308Santhony.gutierrez@amd.com for (int i_cu = 0; i_cu < n_cu; ++i_cu) { 30611308Santhony.gutierrez@amd.com if (!cuList[i_cu]->isDone()) { 30711308Santhony.gutierrez@amd.com return true; 30811308Santhony.gutierrez@amd.com } 30911308Santhony.gutierrez@amd.com } 31011308Santhony.gutierrez@amd.com 31111308Santhony.gutierrez@amd.com return false; 31211308Santhony.gutierrez@amd.com} 31311308Santhony.gutierrez@amd.com 31411308Santhony.gutierrez@amd.comvoid 31511308Santhony.gutierrez@amd.comShader::ScheduleAdd(uint32_t *val,Tick when,int x) 31611308Santhony.gutierrez@amd.com{ 31711308Santhony.gutierrez@amd.com sa_val.push_back(val); 31811308Santhony.gutierrez@amd.com sa_when.push_back(tick_cnt + when); 31911308Santhony.gutierrez@amd.com sa_x.push_back(x); 32011308Santhony.gutierrez@amd.com ++sa_n; 32111308Santhony.gutierrez@amd.com} 32211308Santhony.gutierrez@amd.com 32311308Santhony.gutierrez@amd.com 32411308Santhony.gutierrez@amd.comvoid 32512126Sspwilson2@wisc.eduShader::processTick() 32611308Santhony.gutierrez@amd.com{ 32712126Sspwilson2@wisc.edu if (busy()) { 32812126Sspwilson2@wisc.edu exec(); 32912126Sspwilson2@wisc.edu schedule(tickEvent, curTick() + ticks(1)); 33011308Santhony.gutierrez@amd.com } 33111308Santhony.gutierrez@amd.com} 33211308Santhony.gutierrez@amd.com 33311308Santhony.gutierrez@amd.comvoid 33411308Santhony.gutierrez@amd.comShader::AccessMem(uint64_t address, void *ptr, uint32_t size, int cu_id, 33511308Santhony.gutierrez@amd.com MemCmd cmd, bool suppress_func_errors) 33611308Santhony.gutierrez@amd.com{ 33711308Santhony.gutierrez@amd.com uint8_t *data_buf = (uint8_t*)ptr; 33811308Santhony.gutierrez@amd.com 33911698Santhony.gutierrez@amd.com for (ChunkGenerator gen(address, size, cuList.at(cu_id)->cacheLineSize()); 34011308Santhony.gutierrez@amd.com !gen.done(); gen.next()) { 34112749Sgiacomo.travaglini@arm.com 34212749Sgiacomo.travaglini@arm.com RequestPtr req = std::make_shared<Request>( 34312749Sgiacomo.travaglini@arm.com 0, gen.addr(), gen.size(), 0, 34412749Sgiacomo.travaglini@arm.com cuList[0]->masterId(), 0, 0, nullptr); 34511308Santhony.gutierrez@amd.com 34611308Santhony.gutierrez@amd.com doFunctionalAccess(req, cmd, data_buf, suppress_func_errors, cu_id); 34711308Santhony.gutierrez@amd.com data_buf += gen.size(); 34811308Santhony.gutierrez@amd.com } 34911308Santhony.gutierrez@amd.com} 35011308Santhony.gutierrez@amd.com 35111308Santhony.gutierrez@amd.comvoid 35211308Santhony.gutierrez@amd.comShader::ReadMem(uint64_t address, void *ptr, uint32_t size, int cu_id) 35311308Santhony.gutierrez@amd.com{ 35411308Santhony.gutierrez@amd.com AccessMem(address, ptr, size, cu_id, MemCmd::ReadReq, false); 35511308Santhony.gutierrez@amd.com} 35611308Santhony.gutierrez@amd.com 35711308Santhony.gutierrez@amd.comvoid 35811308Santhony.gutierrez@amd.comShader::ReadMem(uint64_t address, void *ptr, uint32_t size, int cu_id, 35911308Santhony.gutierrez@amd.com bool suppress_func_errors) 36011308Santhony.gutierrez@amd.com{ 36111308Santhony.gutierrez@amd.com AccessMem(address, ptr, size, cu_id, MemCmd::ReadReq, suppress_func_errors); 36211308Santhony.gutierrez@amd.com} 36311308Santhony.gutierrez@amd.com 36411308Santhony.gutierrez@amd.comvoid 36511308Santhony.gutierrez@amd.comShader::WriteMem(uint64_t address, void *ptr,uint32_t size, int cu_id) 36611308Santhony.gutierrez@amd.com{ 36711308Santhony.gutierrez@amd.com AccessMem(address, ptr, size, cu_id, MemCmd::WriteReq, false); 36811308Santhony.gutierrez@amd.com} 36911308Santhony.gutierrez@amd.com 37011308Santhony.gutierrez@amd.comvoid 37111308Santhony.gutierrez@amd.comShader::WriteMem(uint64_t address, void *ptr, uint32_t size, int cu_id, 37211308Santhony.gutierrez@amd.com bool suppress_func_errors) 37311308Santhony.gutierrez@amd.com{ 37411308Santhony.gutierrez@amd.com AccessMem(address, ptr, size, cu_id, MemCmd::WriteReq, 37511308Santhony.gutierrez@amd.com suppress_func_errors); 37611308Santhony.gutierrez@amd.com} 37711308Santhony.gutierrez@amd.com 37811308Santhony.gutierrez@amd.com/* 37911308Santhony.gutierrez@amd.com * Send a packet through the appropriate TLB functional port. 38011308Santhony.gutierrez@amd.com * If cu_id=n_cu, then this is the dispatcher's TLB. 38111308Santhony.gutierrez@amd.com * Otherwise it's the TLB of the cu_id compute unit. 38211308Santhony.gutierrez@amd.com */ 38311308Santhony.gutierrez@amd.comvoid 38411308Santhony.gutierrez@amd.comShader::functionalTLBAccess(PacketPtr pkt, int cu_id, BaseTLB::Mode mode) 38511308Santhony.gutierrez@amd.com{ 38611308Santhony.gutierrez@amd.com // update senderState. Need to know the gpuTc and the TLB mode 38711308Santhony.gutierrez@amd.com pkt->senderState = 38811308Santhony.gutierrez@amd.com new TheISA::GpuTLB::TranslationState(mode, gpuTc, false); 38911308Santhony.gutierrez@amd.com 39011308Santhony.gutierrez@amd.com if (cu_id == n_cu) { 39111308Santhony.gutierrez@amd.com dispatcher->tlbPort->sendFunctional(pkt); 39211308Santhony.gutierrez@amd.com } else { 39311308Santhony.gutierrez@amd.com // even when the perLaneTLB flag is turned on 39411308Santhony.gutierrez@amd.com // it's ok tp send all accesses through lane 0 39511308Santhony.gutierrez@amd.com // since the lane # is not known here, 39611308Santhony.gutierrez@amd.com // This isn't important since these are functional accesses. 39711308Santhony.gutierrez@amd.com cuList[cu_id]->tlbPort[0]->sendFunctional(pkt); 39811308Santhony.gutierrez@amd.com } 39911308Santhony.gutierrez@amd.com 40011308Santhony.gutierrez@amd.com /* safe_cast the senderState */ 40111308Santhony.gutierrez@amd.com TheISA::GpuTLB::TranslationState *sender_state = 40211308Santhony.gutierrez@amd.com safe_cast<TheISA::GpuTLB::TranslationState*>(pkt->senderState); 40311308Santhony.gutierrez@amd.com 40411308Santhony.gutierrez@amd.com delete sender_state->tlbEntry; 40511308Santhony.gutierrez@amd.com delete pkt->senderState; 40611308Santhony.gutierrez@amd.com} 407