1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
/*
* Copyright (C) 2017-2020 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/built_ins/sip.h"
#include "shared/source/command_stream/preemption.h"
#include "shared/source/device/device.h"
#include "shared/source/helpers/hw_helper.h"
#include "shared/source/memory_manager/graphics_allocation.h"
#include "opencl/source/command_queue/gpgpu_walker.h"
namespace NEO {
template <typename GfxFamily>
void PreemptionHelper::programCsrBaseAddress(LinearStream &preambleCmdStream, Device &device, const GraphicsAllocation *preemptionCsr) {
using GPGPU_CSR_BASE_ADDRESS = typename GfxFamily::GPGPU_CSR_BASE_ADDRESS;
bool isMidThreadPreemption = device.getPreemptionMode() == PreemptionMode::MidThread;
if (isMidThreadPreemption) {
UNRECOVERABLE_IF(nullptr == preemptionCsr);
auto csr = reinterpret_cast<GPGPU_CSR_BASE_ADDRESS *>(preambleCmdStream.getSpace(sizeof(GPGPU_CSR_BASE_ADDRESS)));
GPGPU_CSR_BASE_ADDRESS cmd = GfxFamily::cmdInitGpgpuCsrBaseAddress;
cmd.setGpgpuCsrBaseAddress(preemptionCsr->getGpuAddressToPatch());
*csr = cmd;
}
}
template <typename GfxFamily>
void PreemptionHelper::programStateSip(LinearStream &preambleCmdStream, Device &device) {
using STATE_SIP = typename GfxFamily::STATE_SIP;
bool debuggerActive = device.isDebuggerActive();
bool isMidThreadPreemption = device.getPreemptionMode() == PreemptionMode::MidThread;
if (isMidThreadPreemption || debuggerActive) {
auto sipAllocation = SipKernel::getSipKernelAllocation(device);
auto sip = reinterpret_cast<STATE_SIP *>(preambleCmdStream.getSpace(sizeof(STATE_SIP)));
STATE_SIP cmd = GfxFamily::cmdInitStateSip;
cmd.setSystemInstructionPointer(sipAllocation->getGpuAddressToPatch());
*sip = cmd;
}
}
template <typename GfxFamily>
void PreemptionHelper::programCmdStream(LinearStream &cmdStream, PreemptionMode newPreemptionMode,
PreemptionMode oldPreemptionMode, GraphicsAllocation *preemptionCsr) {
if (oldPreemptionMode == newPreemptionMode) {
return;
}
uint32_t regVal = 0;
if (newPreemptionMode == PreemptionMode::MidThread) {
regVal = PreemptionConfig<GfxFamily>::midThreadVal | PreemptionConfig<GfxFamily>::mask;
} else if (newPreemptionMode == PreemptionMode::ThreadGroup) {
regVal = PreemptionConfig<GfxFamily>::threadGroupVal | PreemptionConfig<GfxFamily>::mask;
} else {
regVal = PreemptionConfig<GfxFamily>::cmdLevelVal | PreemptionConfig<GfxFamily>::mask;
}
LriHelper<GfxFamily>::program(&cmdStream, PreemptionConfig<GfxFamily>::mmioAddress, regVal, true);
}
template <typename GfxFamily>
size_t PreemptionHelper::getRequiredCmdStreamSize(PreemptionMode newPreemptionMode, PreemptionMode oldPreemptionMode) {
if (newPreemptionMode == oldPreemptionMode) {
return 0;
}
return sizeof(typename GfxFamily::MI_LOAD_REGISTER_IMM);
}
template <typename GfxFamily>
size_t PreemptionHelper::getRequiredPreambleSize(const Device &device) {
if (device.getPreemptionMode() == PreemptionMode::MidThread) {
return sizeof(typename GfxFamily::GPGPU_CSR_BASE_ADDRESS);
}
return 0;
}
template <typename GfxFamily>
size_t PreemptionHelper::getRequiredStateSipCmdSize(const Device &device) {
size_t size = 0;
bool isMidThreadPreemption = device.getPreemptionMode() == PreemptionMode::MidThread;
if (isMidThreadPreemption || device.isDebuggerActive()) {
size += sizeof(typename GfxFamily::STATE_SIP);
}
return size;
}
template <typename GfxFamily>
size_t PreemptionHelper::getPreemptionWaCsSize(const Device &device) {
return 0u;
}
template <typename GfxFamily>
void PreemptionHelper::applyPreemptionWaCmdsBegin(LinearStream *pCommandStream, const Device &device) {
}
template <typename GfxFamily>
void PreemptionHelper::applyPreemptionWaCmdsEnd(LinearStream *pCommandStream, const Device &device) {
}
template <typename GfxFamily>
void PreemptionHelper::programInterfaceDescriptorDataPreemption(INTERFACE_DESCRIPTOR_DATA<GfxFamily> *idd, PreemptionMode preemptionMode) {
using INTERFACE_DESCRIPTOR_DATA = typename GfxFamily::INTERFACE_DESCRIPTOR_DATA;
if (preemptionMode == PreemptionMode::MidThread) {
idd->setThreadPreemptionDisable(INTERFACE_DESCRIPTOR_DATA::THREAD_PREEMPTION_DISABLE_DISABLE);
} else {
idd->setThreadPreemptionDisable(INTERFACE_DESCRIPTOR_DATA::THREAD_PREEMPTION_DISABLE_ENABLE);
}
}
template <typename GfxFamily>
constexpr uint32_t PreemptionConfig<GfxFamily>::mmioAddress = 0x2580;
template <typename GfxFamily>
constexpr uint32_t PreemptionConfig<GfxFamily>::mask = ((1 << 1) | (1 << 2)) << 16;
template <typename GfxFamily>
constexpr uint32_t PreemptionConfig<GfxFamily>::threadGroupVal = (1 << 1);
template <typename GfxFamily>
constexpr uint32_t PreemptionConfig<GfxFamily>::cmdLevelVal = (1 << 2);
template <typename GfxFamily>
constexpr uint32_t PreemptionConfig<GfxFamily>::midThreadVal = 0;
} // namespace NEO
|