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