hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/*
 * Copyright 2022 Rockchip Electronics Co., Ltd
 *
 * SPDX-License-Identifier:    GPL-2.0+
 */
 
#include <common.h>
#include <asm/arch/rockchip_smccc.h>
#include <asm/arch/vendor.h>
 
#define HDCP_SIGNED        0x4B534541    /* "AESK" */
#define HDCP_FLG_AES        (1 << 0)
 
struct hdcpdata {
   unsigned int signature;
   unsigned int length;
   unsigned int crc32;
   unsigned int flags;
   unsigned char data[0];
};
 
int vendor_handle_hdcp(struct vendor_item *vhead)
{
   struct arm_smccc_res res;
   struct hdcpdata *hdcp;
   char *shm;
   u32 crc, len;
   int ret;
 
   hdcp = (void *)vhead + sizeof(struct vendor_item);
   if ((hdcp->signature != HDCP_SIGNED) || !(hdcp->flags & HDCP_FLG_AES))
       return 0;
 
   crc = crc32(0, hdcp->data, hdcp->length);
   if (crc != hdcp->crc32) {
       printf("%s: bad crc32 0x%08x != 0x%08x\n",
              __func__, crc, hdcp->crc32);
       return -EIO;
   }
 
   res = sip_smc_request_share_mem(2, SHARE_PAGE_TYPE_HDCP);
   if (res.a0) {
       printf("%s: Can't get share mem\n", __func__);
       return -EIO;
   }
 
   shm = (char *)res.a1;
   len = sizeof(struct hdcpdata) + hdcp->length;
 
   memcpy(shm, hdcp, len);
   flush_dcache_range((ulong)shm, (ulong)(shm + len));
 
   ret = sip_smc_hdcp_config(HDCP_FUNC_STORAGE_ENCRYPT, 0, 0);
   if (ret) {
       printf("%s: failed, ret=%d\n", __func__, ret);
       return -EIO;
   }
 
   invalidate_dcache_range((ulong)shm, (ulong)(shm + len));
   memcpy(hdcp, shm, len);
 
   return 0;
}