/* * Copyright (C) 2018-2025 Intel Corporation * * SPDX-License-Identifier: MIT * */ #include "shared/source/built_ins/sip.h" #include "shared/source/command_stream/linear_stream.h" #include "shared/source/command_stream/preemption.h" #include "shared/source/command_stream/preemption_mode.h" #include "shared/source/device/device.h" #include "shared/source/execution_environment/execution_environment.h" #include "shared/source/helpers/compiler_product_helper.h" #include "shared/source/helpers/gfx_core_helper.h" #include "shared/source/helpers/pipe_control_args.h" #include "shared/source/helpers/preamble.h" #include "shared/source/memory_manager/graphics_allocation.h" namespace NEO { template void PreemptionHelper::programCsrBaseAddress(LinearStream &preambleCmdStream, Device &device, const GraphicsAllocation *preemptionCsr) { bool debuggingEnabled = device.getDebugger() != nullptr; bool isMidThreadPreemption = device.getPreemptionMode() == PreemptionMode::MidThread; if (isMidThreadPreemption && !debuggingEnabled) { programCsrBaseAddressCmd(preambleCmdStream, preemptionCsr); } } template void PreemptionHelper::programCsrBaseAddressCmd(LinearStream &preambleCmdStream, const GraphicsAllocation *preemptionCsr) { using GPGPU_CSR_BASE_ADDRESS = typename GfxFamily::GPGPU_CSR_BASE_ADDRESS; auto csr = reinterpret_cast(preambleCmdStream.getSpace(sizeof(GPGPU_CSR_BASE_ADDRESS))); GPGPU_CSR_BASE_ADDRESS cmd = GfxFamily::cmdInitGpgpuCsrBaseAddress; cmd.setGpgpuCsrBaseAddress(preemptionCsr->getGpuAddressToPatch()); *csr = cmd; } template void PreemptionHelper::programStateSip(LinearStream &preambleCmdStream, Device &device, OsContext *context) { auto &helper = device.getGfxCoreHelper(); if (!helper.isStateSipRequired()) { return; } bool debuggingEnabled = device.getDebugger() != nullptr; bool isMidThreadPreemption = device.getPreemptionMode() == PreemptionMode::MidThread; auto &compilerProductHelper = device.getCompilerProductHelper(); bool useFullAddress = compilerProductHelper.isHeaplessModeEnabled(device.getHardwareInfo()); if (isMidThreadPreemption || debuggingEnabled) { GraphicsAllocation *sipAllocation = SipKernel::getSipKernel(device, context).getSipAllocation(); programStateSipCmd(preambleCmdStream, sipAllocation, useFullAddress); } } template void PreemptionHelper::programStateSipCmd(LinearStream &preambleCmdStream, GraphicsAllocation *sipAllocation, bool useFullAddress) { using STATE_SIP = typename GfxFamily::STATE_SIP; auto sip = reinterpret_cast(preambleCmdStream.getSpace(sizeof(STATE_SIP))); STATE_SIP cmd = GfxFamily::cmdInitStateSip; if (useFullAddress) { cmd.setSystemInstructionPointer(sipAllocation->getGpuAddress()); } else { cmd.setSystemInstructionPointer(sipAllocation->getGpuAddressToPatch()); } *sip = cmd; } template 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::midThreadVal | PreemptionConfig::mask; } else if (newPreemptionMode == PreemptionMode::ThreadGroup) { regVal = PreemptionConfig::threadGroupVal | PreemptionConfig::mask; } else { regVal = PreemptionConfig::cmdLevelVal | PreemptionConfig::mask; } LriHelper::program(&cmdStream, PreemptionConfig::mmioAddress, regVal, true, false); } template size_t PreemptionHelper::getRequiredCmdStreamSize(PreemptionMode newPreemptionMode, PreemptionMode oldPreemptionMode) { if (newPreemptionMode == oldPreemptionMode) { return 0; } return sizeof(typename GfxFamily::MI_LOAD_REGISTER_IMM); } template size_t PreemptionHelper::getRequiredPreambleSize(const Device &device) { bool debuggingEnabled = device.getDebugger() != nullptr; bool isMidThreadPreemption = device.getPreemptionMode() == PreemptionMode::MidThread; if (isMidThreadPreemption || debuggingEnabled) { return sizeof(typename GfxFamily::GPGPU_CSR_BASE_ADDRESS); } return 0; } template size_t PreemptionHelper::getRequiredStateSipCmdSize(Device &device, bool isRcs) { auto &helper = device.getGfxCoreHelper(); if (!helper.isStateSipRequired()) { return 0; } size_t size = 0; bool isMidThreadPreemption = device.getPreemptionMode() == PreemptionMode::MidThread; bool debuggingEnabled = device.getDebugger() != nullptr; if (isMidThreadPreemption || debuggingEnabled) { size += sizeof(typename GfxFamily::STATE_SIP); } return size; } template void PreemptionHelper::programInterfaceDescriptorDataPreemption(InterfaceDescriptorType *idd, PreemptionMode preemptionMode) {} template const uint32_t PreemptionConfig::mmioAddress = 0x2580; template const uint32_t PreemptionConfig::mask = ((1 << 1) | (1 << 2)) << 16; template const uint32_t PreemptionConfig::threadGroupVal = (1 << 1); template const uint32_t PreemptionConfig::cmdLevelVal = (1 << 2); template const uint32_t PreemptionConfig::midThreadVal = 0; } // namespace NEO