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