1 /*
2 * SPDX-FileCopyrightText: Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3 * SPDX-License-Identifier: MIT
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "gpu/sec2/kernel_sec2.h"
25
26 #include "core/bin_data.h"
27 #include "core/core.h"
28 #include "gpu/falcon/kernel_falcon.h"
29 #include "gpu/gpu.h"
30 #include "os/nv_memory_type.h"
31
32 #include "published/turing/tu102/dev_sec_pri.h"
33 #include "published/turing/tu102/dev_sec_addendum.h"
34
35 #include "rmflcnbl.h"
36
37 NV_STATUS
ksec2ConfigureFalcon_TU102(OBJGPU * pGpu,KernelSec2 * pKernelSec2)38 ksec2ConfigureFalcon_TU102
39 (
40 OBJGPU *pGpu,
41 KernelSec2 *pKernelSec2
42 )
43 {
44 KernelFalconEngineConfig falconConfig;
45
46 portMemSet(&falconConfig, 0, sizeof(falconConfig));
47
48 falconConfig.registerBase = DRF_BASE(NV_PSEC);
49 falconConfig.riscvRegisterBase = 0; // RISC-V unused or unsupported
50 falconConfig.fbifBase = NV_PSEC_FBIF_BASE;
51 falconConfig.bBootFromHs = NV_FALSE;
52 falconConfig.pmcEnableMask = 0;
53 falconConfig.bIsPmcDeviceEngine = NV_FALSE;
54 falconConfig.physEngDesc = ENG_SEC2;
55 falconConfig.ctxAttr = NV_MEMORY_UNCACHED;
56 falconConfig.ctxBufferSize = FLCN_CTX_ENG_BUFFER_SIZE_HW << 4;
57 falconConfig.addrSpaceList = memdescAddrSpaceListToU32(ADDRLIST_FBMEM_PREFERRED);
58
59 kflcnConfigureEngine(pGpu, staticCast(pKernelSec2, KernelFalcon), &falconConfig);
60 return NV_OK;
61 }
62
63 NV_STATUS
ksec2ResetHw_TU102(OBJGPU * pGpu,KernelSec2 * pKernelSec2)64 ksec2ResetHw_TU102
65 (
66 OBJGPU *pGpu,
67 KernelSec2 *pKernelSec2
68 )
69 {
70 GPU_FLD_WR_DRF_DEF(pGpu, _PSEC, _FALCON_ENGINE, _RESET, _TRUE);
71
72 // Reg read cycles needed for signal propagation.
73 for (NvU32 i = 0; i < FLCN_RESET_PROPAGATION_DELAY_COUNT; i++)
74 {
75 GPU_REG_RD32(pGpu, NV_PSEC_FALCON_ENGINE);
76 }
77
78 GPU_FLD_WR_DRF_DEF(pGpu, _PSEC, _FALCON_ENGINE, _RESET, _FALSE);
79
80 // Reg read cycles needed for signal propagation.
81 for (NvU32 i = 0; i < FLCN_RESET_PROPAGATION_DELAY_COUNT; i++)
82 {
83 GPU_REG_RD32(pGpu, NV_PSEC_FALCON_ENGINE);
84 }
85
86 return NV_OK;
87 }
88
89 static NV_STATUS
s_allocateGenericBlUcode(OBJGPU * pGpu,KernelSec2 * pKernelSec2,const RM_FLCN_BL_DESC ** ppDesc,const NvU8 ** ppImg)90 s_allocateGenericBlUcode
91 (
92 OBJGPU *pGpu,
93 KernelSec2 *pKernelSec2,
94 const RM_FLCN_BL_DESC **ppDesc,
95 const NvU8 **ppImg
96 )
97 {
98 NV_STATUS status = NV_OK;
99
100 const BINDATA_ARCHIVE *pBinArchive;
101 const BINDATA_STORAGE *pBinDesc;
102 const BINDATA_STORAGE *pBinImg;
103 NvLength descSizeAligned;
104 NvLength imgSizeAligned;
105
106 RM_FLCN_BL_DESC *pGenericBlUcodeDesc = NULL;
107 NvU8 *pGenericBlUcodeImg = NULL;
108
109 NV_ASSERT_OR_RETURN(ppDesc != NULL, NV_ERR_INVALID_ARGUMENT);
110 NV_ASSERT_OR_RETURN(ppImg != NULL, NV_ERR_INVALID_ARGUMENT);
111
112 pBinArchive = ksec2GetBinArchiveBlUcode_HAL(pGpu, pKernelSec2);
113 NV_ASSERT_OR_GOTO(pBinArchive != NULL, out);
114
115 // allocate desc
116 pBinDesc = bindataArchiveGetStorage(pBinArchive, "ucode_desc");
117 NV_ASSERT_OR_GOTO(pBinDesc != NULL, out);
118
119 descSizeAligned = RM_ALIGN_UP(bindataGetBufferSize(pBinDesc), FLCN_BLK_ALIGNMENT);
120 pGenericBlUcodeDesc = portMemAllocNonPaged(descSizeAligned);
121 if (pGenericBlUcodeDesc == NULL)
122 {
123 status = NV_ERR_NO_MEMORY;
124 goto out;
125 }
126
127 NV_ASSERT_OK_OR_GOTO(status,
128 bindataWriteToBuffer(pBinDesc, (NvU8 *) pGenericBlUcodeDesc, descSizeAligned), out);
129
130 // allocate img
131 pBinImg = bindataArchiveGetStorage(pBinArchive, "ucode_image");
132 imgSizeAligned = RM_ALIGN_UP(bindataGetBufferSize(pBinImg), FLCN_BLK_ALIGNMENT);
133
134 if (pGenericBlUcodeDesc->blImgHeader.blCodeSize > imgSizeAligned)
135 {
136 status = NV_ERR_INVALID_DATA;
137 goto out;
138 }
139
140 pGenericBlUcodeImg = portMemAllocNonPaged(imgSizeAligned);
141 if (pGenericBlUcodeImg == NULL)
142 {
143 status = NV_ERR_NO_MEMORY;
144 goto out;
145 }
146
147 NV_ASSERT_OK_OR_GOTO(status,
148 bindataWriteToBuffer(pBinImg, pGenericBlUcodeImg, imgSizeAligned), out);
149
150 *ppDesc = pGenericBlUcodeDesc;
151 *ppImg = pGenericBlUcodeImg;
152
153 return status;
154
155 out:
156 portMemFree(pGenericBlUcodeDesc);
157 portMemFree(pGenericBlUcodeImg);
158 return status;
159 }
160
161 /*!
162 * Get the generic falcon bootloader ucode descriptor and image
163 *
164 * Note: this bootloader works for both SEC2 and GSP
165 * (though it is defined only on KernelSec2)
166 *
167 * @param[in] pGpu OBJGPU pointer
168 * @param[in] pKernelSec2 KernelSec2 pointer
169 * @param[out] ppDesc pointer to ucode descriptor
170 * @param[out] ppImg pointer to ucode image
171 */
172 NV_STATUS
ksec2GetGenericBlUcode_TU102(OBJGPU * pGpu,KernelSec2 * pKernelSec2,const RM_FLCN_BL_DESC ** ppDesc,const NvU8 ** ppImg)173 ksec2GetGenericBlUcode_TU102
174 (
175 OBJGPU *pGpu,
176 KernelSec2 *pKernelSec2,
177 const RM_FLCN_BL_DESC **ppDesc,
178 const NvU8 **ppImg
179 )
180 {
181 NV_STATUS status = NV_OK;
182
183 NV_ASSERT_OR_RETURN(ppDesc != NULL, NV_ERR_INVALID_ARGUMENT);
184 NV_ASSERT_OR_RETURN(ppImg != NULL, NV_ERR_INVALID_ARGUMENT);
185
186 if (pKernelSec2->pGenericBlUcodeDesc == NULL)
187 {
188 NV_ASSERT_OR_RETURN(pKernelSec2->pGenericBlUcodeImg == NULL, NV_ERR_INVALID_STATE);
189 NV_ASSERT_OK_OR_RETURN(
190 s_allocateGenericBlUcode(pGpu, pKernelSec2,
191 &pKernelSec2->pGenericBlUcodeDesc,
192 &pKernelSec2->pGenericBlUcodeImg));
193 }
194
195 NV_ASSERT_OR_RETURN(pKernelSec2->pGenericBlUcodeDesc != NULL, NV_ERR_INVALID_STATE);
196 NV_ASSERT_OR_RETURN(pKernelSec2->pGenericBlUcodeImg != NULL, NV_ERR_INVALID_STATE);
197
198 *ppDesc = pKernelSec2->pGenericBlUcodeDesc;
199 *ppImg = pKernelSec2->pGenericBlUcodeImg;
200
201 return status;
202 }
203