1 /*
2  * Copyright (C) 2019-2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  */
7 
8 #include "shared/source/command_stream/preemption.h"
9 #include "shared/source/command_stream/stream_properties.h"
10 #include "shared/test/common/helpers/debug_manager_state_restore.h"
11 #include "shared/test/unit_test/preamble/preamble_fixture.h"
12 
13 #include "reg_configs_common.h"
14 
15 using namespace NEO;
16 
17 typedef PreambleFixture TglLpSlm;
18 
HWTEST2_F(TglLpSlm,givenTglLpWhenPreambleIsBeingProgrammedThenThreadArbitrationPolicyIsIgnored,IsTGLLP)19 HWTEST2_F(TglLpSlm, givenTglLpWhenPreambleIsBeingProgrammedThenThreadArbitrationPolicyIsIgnored, IsTGLLP) {
20     DebugManagerStateRestore dbgRestore;
21     DebugManager.flags.ForcePreemptionMode.set(static_cast<int32_t>(PreemptionMode::Disabled));
22     typedef TGLLPFamily::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
23     LinearStream &cs = linearStream;
24     uint32_t l3Config = PreambleHelper<TGLLPFamily>::getL3Config(pDevice->getHardwareInfo(), true);
25     MockDevice mockDevice;
26     PreambleHelper<TGLLPFamily>::programPreamble(&linearStream, mockDevice, l3Config,
27                                                  ThreadArbitrationPolicy::RoundRobin,
28                                                  nullptr);
29 
30     parseCommands<TGLLPFamily>(cs);
31 
32     // parse through commands and ensure that 0xE404 is not being programmed
33     EXPECT_EQ(0U, countMmio<FamilyType>(cmdList.begin(), cmdList.end(), 0xE404));
34 }
35 
HWTEST2_F(TglLpSlm,WhenCheckingL3IsConfigurableThenExpectItToBeFalse,IsTGLLP)36 HWTEST2_F(TglLpSlm, WhenCheckingL3IsConfigurableThenExpectItToBeFalse, IsTGLLP) {
37     bool isL3Programmable =
38         PreambleHelper<TGLLPFamily>::isL3Configurable(*defaultHwInfo);
39 
40     EXPECT_FALSE(isL3Programmable);
41 }
42 
HWTEST2_F(TglLpSlm,WhenPreambleIsCreatedThenSlmIsDisabled,IsTGLLP)43 HWTEST2_F(TglLpSlm, WhenPreambleIsCreatedThenSlmIsDisabled, IsTGLLP) {
44     typedef TGLLPFamily::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
45     LinearStream &cs = linearStream;
46     uint32_t l3Config = PreambleHelper<FamilyType>::getL3Config(pDevice->getHardwareInfo(), true);
47     PreambleHelper<FamilyType>::programL3(&cs, l3Config);
48 
49     parseCommands<TGLLPFamily>(cs);
50 
51     auto itorLRI = find<MI_LOAD_REGISTER_IMM *>(cmdList.begin(), cmdList.end());
52     ASSERT_EQ(cmdList.end(), itorLRI);
53 }
54 
55 typedef PreambleFixture Gen12LpUrbEntryAllocationSize;
HWTEST2_F(Gen12LpUrbEntryAllocationSize,WhenPreambleIsCreatedThenUrbEntryAllocationSizeIsCorrect,IsTGLLP)56 HWTEST2_F(Gen12LpUrbEntryAllocationSize, WhenPreambleIsCreatedThenUrbEntryAllocationSizeIsCorrect, IsTGLLP) {
57     uint32_t actualVal = PreambleHelper<FamilyType>::getUrbEntryAllocationSize();
58     EXPECT_EQ(1024u, actualVal);
59 }
60 
61 typedef PreambleVfeState Gen12LpPreambleVfeState;
HWTEST2_F(Gen12LpPreambleVfeState,GivenWaOffWhenProgrammingVfeStateThenProgrammingIsCorrect,IsTGLLP)62 HWTEST2_F(Gen12LpPreambleVfeState, GivenWaOffWhenProgrammingVfeStateThenProgrammingIsCorrect, IsTGLLP) {
63     typedef typename FamilyType::PIPE_CONTROL PIPE_CONTROL;
64     testWaTable->flags.waSendMIFLUSHBeforeVFE = 0;
65     LinearStream &cs = linearStream;
66     auto pVfeCmd = PreambleHelper<FamilyType>::getSpaceForVfeState(&linearStream, pDevice->getHardwareInfo(), EngineGroupType::RenderCompute);
67     StreamProperties emptyProperties{};
68     PreambleHelper<FamilyType>::programVfeState(pVfeCmd, pDevice->getHardwareInfo(), 0u, 0, 672u, emptyProperties);
69 
70     parseCommands<FamilyType>(cs);
71 
72     auto itorPC = find<PIPE_CONTROL *>(cmdList.begin(), cmdList.end());
73     ASSERT_NE(cmdList.end(), itorPC);
74 
75     const auto &pc = *reinterpret_cast<PIPE_CONTROL *>(*itorPC);
76     EXPECT_FALSE(pc.getRenderTargetCacheFlushEnable());
77     EXPECT_FALSE(pc.getDepthCacheFlushEnable());
78     EXPECT_FALSE(pc.getDepthStallEnable());
79     EXPECT_FALSE(pc.getDcFlushEnable());
80     EXPECT_EQ(1u, pc.getCommandStreamerStallEnable());
81 }
82 
HWTEST2_F(Gen12LpPreambleVfeState,givenCcsEngineWhenWaIsSetThenAppropriatePipeControlFlushesAreSet,IsTGLLP)83 HWTEST2_F(Gen12LpPreambleVfeState, givenCcsEngineWhenWaIsSetThenAppropriatePipeControlFlushesAreSet, IsTGLLP) {
84     typedef typename FamilyType::PIPE_CONTROL PIPE_CONTROL;
85     testWaTable->flags.waSendMIFLUSHBeforeVFE = 1;
86     LinearStream &cs = linearStream;
87 
88     auto pVfeCmd = PreambleHelper<FamilyType>::getSpaceForVfeState(&linearStream, pDevice->getHardwareInfo(), EngineGroupType::Compute);
89     StreamProperties emptyProperties{};
90     PreambleHelper<FamilyType>::programVfeState(pVfeCmd, pDevice->getHardwareInfo(), 0u, 0, 672u, emptyProperties);
91 
92     parseCommands<FamilyType>(cs);
93 
94     auto itorPC = find<PIPE_CONTROL *>(cmdList.begin(), cmdList.end());
95     ASSERT_NE(cmdList.end(), itorPC);
96 
97     const auto &pc = *reinterpret_cast<PIPE_CONTROL *>(*itorPC);
98     EXPECT_FALSE(pc.getRenderTargetCacheFlushEnable());
99     EXPECT_FALSE(pc.getDepthCacheFlushEnable());
100     EXPECT_TRUE(pc.getDcFlushEnable());
101     EXPECT_EQ(1u, pc.getCommandStreamerStallEnable());
102 }
103 
HWTEST2_F(Gen12LpPreambleVfeState,givenRcsEngineWhenWaIsSetThenAppropriatePipeControlFlushesAreSet,IsTGLLP)104 HWTEST2_F(Gen12LpPreambleVfeState, givenRcsEngineWhenWaIsSetThenAppropriatePipeControlFlushesAreSet, IsTGLLP) {
105     using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
106     testWaTable->flags.waSendMIFLUSHBeforeVFE = 1;
107     LinearStream &cs = linearStream;
108 
109     auto pVfeCmd = PreambleHelper<FamilyType>::getSpaceForVfeState(&linearStream, pDevice->getHardwareInfo(), EngineGroupType::RenderCompute);
110     StreamProperties emptyProperties{};
111     PreambleHelper<FamilyType>::programVfeState(pVfeCmd, pDevice->getHardwareInfo(), 0u, 0, 672u, emptyProperties);
112 
113     parseCommands<FamilyType>(cs);
114 
115     auto itorPC = find<PIPE_CONTROL *>(cmdList.begin(), cmdList.end());
116     ASSERT_NE(cmdList.end(), itorPC);
117 
118     const auto &pc = *reinterpret_cast<PIPE_CONTROL *>(*itorPC);
119     EXPECT_TRUE(pc.getRenderTargetCacheFlushEnable());
120     EXPECT_TRUE(pc.getDepthCacheFlushEnable());
121     EXPECT_TRUE(pc.getDepthStallEnable());
122     EXPECT_TRUE(pc.getDcFlushEnable());
123     EXPECT_EQ(1u, pc.getCommandStreamerStallEnable());
124 }
125 
HWTEST2_F(Gen12LpPreambleVfeState,givenDefaultPipeControlWhenItIsProgrammedThenCsStallBitIsSet,IsTGLLP)126 HWTEST2_F(Gen12LpPreambleVfeState, givenDefaultPipeControlWhenItIsProgrammedThenCsStallBitIsSet, IsTGLLP) {
127     using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL;
128 
129     PIPE_CONTROL *pipeControl = static_cast<PIPE_CONTROL *>(linearStream.getSpace(sizeof(PIPE_CONTROL)));
130     *pipeControl = FamilyType::cmdInitPipeControl;
131 
132     EXPECT_EQ(1u, pipeControl->getCommandStreamerStallEnable());
133 }
134 
HWTEST2_F(Gen12LpPreambleVfeState,givenCfeFusedEuDispatchFlagsWhenprogramAdditionalFieldsInVfeStateIsCalledThenGetDisableSlice0Subslice2ReturnsCorrectValues,IsTGLLP)135 HWTEST2_F(Gen12LpPreambleVfeState, givenCfeFusedEuDispatchFlagsWhenprogramAdditionalFieldsInVfeStateIsCalledThenGetDisableSlice0Subslice2ReturnsCorrectValues, IsTGLLP) {
136     using MEDIA_VFE_STATE = typename FamilyType::MEDIA_VFE_STATE;
137 
138     DebugManagerStateRestore restorer;
139     auto pHwInfo = pDevice->getRootDeviceEnvironment().getMutableHardwareInfo();
140     auto pMediaVfeState = reinterpret_cast<MEDIA_VFE_STATE *>(linearStream.getSpace(sizeof(MEDIA_VFE_STATE)));
141     *pMediaVfeState = FamilyType::cmdInitMediaVfeState;
142     auto &waTable = pHwInfo->workaroundTable;
143 
144     std::tuple<bool, bool, int32_t> testParams[]{
145         {false, false, 0},
146         {false, true, 0},
147         {false, false, -1},
148         {true, false, 1},
149         {true, true, -1},
150         {true, true, 1}};
151 
152     for (auto &[expectedValue, waDisableFusedThreadScheduling, debugKeyValue] : testParams) {
153         waTable.flags.waDisableFusedThreadScheduling = waDisableFusedThreadScheduling;
154         ::DebugManager.flags.CFEFusedEUDispatch.set(debugKeyValue);
155         PreambleHelper<FamilyType>::programAdditionalFieldsInVfeState(pMediaVfeState, *pHwInfo);
156         EXPECT_EQ(expectedValue, pMediaVfeState->getDisableSlice0Subslice2());
157     }
158 }
159 
HWTEST2_F(Gen12LpPreambleVfeState,givenMaxNumberOfDssDebugVariableWhenMediaVfeStateIsProgrammedThenFieldIsSet,IsTGLLP)160 HWTEST2_F(Gen12LpPreambleVfeState, givenMaxNumberOfDssDebugVariableWhenMediaVfeStateIsProgrammedThenFieldIsSet, IsTGLLP) {
161     using MEDIA_VFE_STATE = typename FamilyType::MEDIA_VFE_STATE;
162 
163     DebugManagerStateRestore restorer;
164     DebugManager.flags.MediaVfeStateMaxSubSlices.set(2);
165     auto pHwInfo = pDevice->getRootDeviceEnvironment().getMutableHardwareInfo();
166     auto pMediaVfeState = reinterpret_cast<MEDIA_VFE_STATE *>(linearStream.getSpace(sizeof(MEDIA_VFE_STATE)));
167     *pMediaVfeState = FamilyType::cmdInitMediaVfeState;
168     PreambleHelper<FamilyType>::programAdditionalFieldsInVfeState(pMediaVfeState, *pHwInfo);
169     EXPECT_EQ(2u, pMediaVfeState->getMaximumNumberOfDualSubslices());
170 }
171 
172 typedef PreambleFixture ThreadArbitrationGen12Lp;
GEN12LPTEST_F(ThreadArbitrationGen12Lp,givenPolicyWhenThreadArbitrationProgrammedThenDoNothing)173 GEN12LPTEST_F(ThreadArbitrationGen12Lp, givenPolicyWhenThreadArbitrationProgrammedThenDoNothing) {
174     LinearStream &cs = linearStream;
175 
176     PreambleHelper<FamilyType>::programThreadArbitration(&cs, ThreadArbitrationPolicy::RoundRobin);
177 
178     EXPECT_EQ(0u, cs.getUsed());
179     EXPECT_EQ(0u, HwHelperHw<FamilyType>::get().getDefaultThreadArbitrationPolicy());
180 }
181 
GEN12LPTEST_F(ThreadArbitrationGen12Lp,whenGetSupportThreadArbitrationPoliciesIsCalledThenEmptyVectorIsReturned)182 GEN12LPTEST_F(ThreadArbitrationGen12Lp, whenGetSupportThreadArbitrationPoliciesIsCalledThenEmptyVectorIsReturned) {
183     auto supportedPolicies = PreambleHelper<FamilyType>::getSupportedThreadArbitrationPolicies();
184 
185     EXPECT_EQ(0u, supportedPolicies.size());
186 }
187 
188 typedef PreambleFixture PreemptionWatermarkGen12LP;
GEN12LPTEST_F(PreemptionWatermarkGen12LP,WhenPreambleIsCreatedThenPreambleWorkAroundsIsNotProgrammed)189 GEN12LPTEST_F(PreemptionWatermarkGen12LP, WhenPreambleIsCreatedThenPreambleWorkAroundsIsNotProgrammed) {
190     PreambleHelper<FamilyType>::programGenSpecificPreambleWorkArounds(&linearStream, pDevice->getHardwareInfo());
191 
192     parseCommands<FamilyType>(linearStream);
193 
194     auto cmd = findMmioCmd<FamilyType>(cmdList.begin(), cmdList.end(), FfSliceCsChknReg2::address);
195     ASSERT_EQ(nullptr, cmd);
196 
197     MockDevice mockDevice;
198     mockDevice.setDebuggerActive(false);
199     size_t expectedSize = PreemptionHelper::getRequiredPreambleSize<FamilyType>(mockDevice);
200     EXPECT_EQ(expectedSize, PreambleHelper<FamilyType>::getAdditionalCommandsSize(mockDevice));
201 
202     mockDevice.setDebuggerActive(true);
203     expectedSize += PreambleHelper<FamilyType>::getKernelDebuggingCommandsSize(mockDevice.isDebuggerActive());
204     EXPECT_EQ(expectedSize, PreambleHelper<FamilyType>::getAdditionalCommandsSize(mockDevice));
205 }
206 
207 using PreambleFixtureGen12lp = PreambleFixture;
GEN12LPTEST_F(PreambleFixtureGen12lp,whenKernelDebuggingCommandsAreProgrammedThenCorrectRegisterAddressesAndValuesAreSet)208 GEN12LPTEST_F(PreambleFixtureGen12lp, whenKernelDebuggingCommandsAreProgrammedThenCorrectRegisterAddressesAndValuesAreSet) {
209     typedef typename FamilyType::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM;
210 
211     auto bufferSize = PreambleHelper<FamilyType>::getKernelDebuggingCommandsSize(true);
212     auto buffer = std::unique_ptr<char[]>(new char[bufferSize]);
213 
214     LinearStream stream(buffer.get(), bufferSize);
215     PreambleHelper<FamilyType>::programKernelDebugging(&stream);
216 
217     HardwareParse hwParser;
218     hwParser.parseCommands<FamilyType>(stream);
219     auto cmdList = hwParser.getCommandsList<MI_LOAD_REGISTER_IMM>();
220 
221     ASSERT_EQ(2u, cmdList.size());
222 
223     auto it = cmdList.begin();
224 
225     MI_LOAD_REGISTER_IMM *pCmd = reinterpret_cast<MI_LOAD_REGISTER_IMM *>(*it);
226     EXPECT_EQ(0x20d8u, pCmd->getRegisterOffset());
227     EXPECT_EQ((1u << 5) | (1u << 21), pCmd->getDataDword());
228     it++;
229 
230     pCmd = reinterpret_cast<MI_LOAD_REGISTER_IMM *>(*it);
231     EXPECT_EQ(0xe400u, pCmd->getRegisterOffset());
232     EXPECT_EQ((1u << 7) | (1u << 4), pCmd->getDataDword());
233 }