1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright(c) 2021-2022, Intel Corporation. All rights reserved. 4 */ 5 6 #include "drm/i915_drm.h" 7 #include "i915_drv.h" 8 9 #include "gem/i915_gem_region.h" 10 #include "gt/intel_gt.h" 11 12 #include "intel_pxp.h" 13 #include "intel_pxp_huc.h" 14 #include "intel_pxp_tee.h" 15 #include "intel_pxp_types.h" 16 #include "intel_pxp_tee_interface.h" 17 18 int intel_pxp_huc_load_and_auth(struct intel_pxp *pxp) 19 { 20 struct intel_gt *gt = pxp_to_gt(pxp); 21 struct intel_huc *huc = >->uc.huc; 22 struct pxp_tee_start_huc_auth_in huc_in = {0}; 23 struct pxp_tee_start_huc_auth_out huc_out = {0}; 24 dma_addr_t huc_phys_addr; 25 u8 client_id = 0; 26 u8 fence_id = 0; 27 int err; 28 29 if (!pxp->pxp_component) 30 return -ENODEV; 31 32 huc_phys_addr = i915_gem_object_get_dma_address(huc->fw.obj, 0); 33 34 /* write the PXP message into the lmem (the sg list) */ 35 huc_in.header.api_version = PXP_TEE_43_APIVER; 36 huc_in.header.command_id = PXP_TEE_43_START_HUC_AUTH; 37 huc_in.header.status = 0; 38 huc_in.header.buffer_len = sizeof(huc_in.huc_base_address); 39 huc_in.huc_base_address = huc_phys_addr; 40 41 err = intel_pxp_tee_stream_message(pxp, client_id, fence_id, 42 &huc_in, sizeof(huc_in), 43 &huc_out, sizeof(huc_out)); 44 if (err < 0) { 45 drm_err(>->i915->drm, 46 "Failed to send HuC load and auth command to GSC [%d]!\n", 47 err); 48 return err; 49 } 50 51 /* 52 * HuC does sometimes survive suspend/resume (it depends on how "deep" 53 * a sleep state the device reaches) so we can end up here on resume 54 * with HuC already loaded, in which case the GSC will return 55 * PXP_STATUS_OP_NOT_PERMITTED. We can therefore consider the GuC 56 * correctly transferred in this scenario; if the same error is ever 57 * returned with HuC not loaded we'll still catch it when we check the 58 * authentication bit later. 59 */ 60 if (huc_out.header.status != PXP_STATUS_SUCCESS && 61 huc_out.header.status != PXP_STATUS_OP_NOT_PERMITTED) { 62 drm_err(>->i915->drm, 63 "HuC load failed with GSC error = 0x%x\n", 64 huc_out.header.status); 65 return -EPROTO; 66 } 67 68 return 0; 69 } 70