1 /* 2 * SPDX-FileCopyrightText: Copyright (c) 1993-2021 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 "core/core.h" 25 #include "os/os.h" 26 #include "gpu/gpu.h" 27 #include "gpu/subdevice/generic_engine.h" 28 #include "gpu/subdevice/subdevice.h" 29 #include "rmapi/client.h" 30 31 #include <class/cl90e6.h> 32 #include <class/cl90e7.h> 33 34 35 NV_STATUS 36 genapiConstruct_IMPL 37 ( 38 GenericEngineApi *pGenericEngineApi, 39 CALL_CONTEXT *pCallContext, 40 RS_RES_ALLOC_PARAMS_INTERNAL *pParams 41 ) 42 { 43 RS_ITERATOR it; 44 OBJGPU *pGpu = GPU_RES_GET_GPU(pGenericEngineApi); 45 46 if (!gpuIsClassSupported(pGpu, pCallContext->pResourceRef->externalClassId)) 47 return NV_ERR_INVALID_CLASS; 48 49 // 50 // We allow multiple instances of GenericEngineApi class, however, only want 51 // to allow a single instance of each external class id type. E.g.: 52 // GF100_SUBDEVICE_GRAPHICS is allowed alongside GF100_SUBDEVICE_FB. 53 // 54 it = clientRefIter(pCallContext->pClient, 55 pCallContext->pResourceRef->pParentRef, 56 classId(GenericEngineApi), RS_ITERATE_CHILDREN, NV_TRUE); 57 58 while (clientRefIterNext(pCallContext->pClient, &it)) 59 { 60 if (it.pResourceRef->externalClassId == pCallContext->pResourceRef->externalClassId && 61 it.pResourceRef != pCallContext->pResourceRef) 62 { 63 return NV_ERR_STATE_IN_USE; 64 } 65 } 66 67 return NV_OK; 68 } 69 70 void 71 genapiDestruct_IMPL 72 ( 73 GenericEngineApi *pGenericEngineApi 74 ) 75 { 76 } 77 78 NV_STATUS 79 genapiControl_IMPL 80 ( 81 GenericEngineApi *pGenericEngineApi, 82 CALL_CONTEXT *pCallContext, 83 RS_RES_CONTROL_PARAMS_INTERNAL *pParams 84 ) 85 { 86 if (RES_GET_EXT_CLASS_ID(pGenericEngineApi) == GF100_SUBDEVICE_INFOROM) 87 { 88 OBJGPU *pGpu = GPU_RES_GET_GPU(pGenericEngineApi); 89 OBJINFOROM *pInforom = GPU_GET_INFOROM(pGpu); 90 if (!IS_GSP_CLIENT(pGpu) && pInforom == NULL) 91 { 92 return NV_ERR_NOT_SUPPORTED; 93 } 94 } 95 96 return gpuresControl_IMPL(staticCast(pGenericEngineApi, GpuResource), 97 pCallContext, pParams); 98 } 99 100 NV_STATUS 101 genapiMap_IMPL 102 ( 103 GenericEngineApi *pGenericEngineApi, 104 CALL_CONTEXT *pCallContext, 105 RS_CPU_MAP_PARAMS *pParams, 106 RsCpuMapping *pCpuMapping 107 ) 108 { 109 OBJGPU *pGpu; 110 NvU32 engineOffset, regSize, regBase; 111 NvU32 protect; 112 NV_STATUS rmStatus; 113 114 pGpu = GPU_RES_GET_GPU(pGenericEngineApi); 115 116 // XXX The default should really be more restrictive 117 protect = NV_PROTECT_READ_WRITE; 118 119 switch (RES_GET_EXT_CLASS_ID(pGenericEngineApi)) 120 { 121 case GF100_SUBDEVICE_MASTER: 122 { 123 regSize = sizeof(GF100MASTERMap); 124 regBase = NV_REG_BASE_MASTER; 125 protect = NV_PROTECT_READABLE; 126 break; 127 } 128 default: 129 return NV_ERR_INVALID_CLASS; 130 } 131 132 // Get the offset to the engine registers 133 rmStatus = gpuGetRegBaseOffset_HAL(pGpu, regBase, &engineOffset); 134 if (rmStatus != NV_OK) 135 return rmStatus; 136 137 // Round down to nearest 4k page 138 engineOffset &= ~(0x1000-1); 139 140 // Check the caller is requesting more privilieges than we allow 141 if (pCpuMapping->pPrivate->protect & ~protect) 142 { 143 NV_PRINTF(LEVEL_ERROR, "%s%saccess not allowed on class 0x%x\n", 144 (pCpuMapping->pPrivate->protect & ~protect) & NV_PROTECT_READABLE ? "Read " : "", 145 (pCpuMapping->pPrivate->protect & ~protect) & NV_PROTECT_WRITEABLE ? "Write " : "", 146 RES_GET_EXT_CLASS_ID(pGenericEngineApi)); 147 148 return NV_ERR_PROTECTION_FAULT; 149 } 150 151 // Create mapping 152 rmStatus = rmapiMapGpuCommon(staticCast(pGenericEngineApi, RsResource), 153 pCallContext, 154 pCpuMapping, 155 pGpu, 156 engineOffset, 157 regSize); 158 pCpuMapping->processId = osGetCurrentProcess(); 159 160 if (pParams->ppCpuVirtAddr) 161 *pParams->ppCpuVirtAddr = pCpuMapping->pLinearAddress; 162 163 return rmStatus; 164 } 165 166 NV_STATUS 167 genapiGetMapAddrSpace_IMPL 168 ( 169 GenericEngineApi *pGenericEngineApi, 170 CALL_CONTEXT *pCallContext, 171 NvU32 mapFlags, 172 NV_ADDRESS_SPACE *pAddrSpace 173 ) 174 { 175 if (pAddrSpace) 176 *pAddrSpace = ADDR_REGMEM; 177 178 return NV_OK; 179 } 180 181