1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2018-2020 NXP
4  *
5  * Brief   CAAM Controller Hardware Abstration Layer.
6  *         Implementation of primitives to access HW.
7  */
8 #include <caam_hal_ctrl.h>
9 #include <caam_io.h>
10 #include <caam_trace.h>
11 #include <config.h>
12 #include <registers/ctrl_regs.h>
13 #include <registers/version_regs.h>
14 #include <kernel/panic.h>
15 
caam_hal_ctrl_era(vaddr_t baseaddr)16 uint8_t caam_hal_ctrl_era(vaddr_t baseaddr)
17 {
18 	/* Read the number of instance */
19 	uint32_t val = io_caam_read32(baseaddr + CCBVID);
20 
21 	return GET_CCBVID_CAAM_ERA(val);
22 }
23 
caam_hal_ctrl_jrnum(vaddr_t baseaddr)24 uint8_t caam_hal_ctrl_jrnum(vaddr_t baseaddr)
25 {
26 	uint32_t val = 0;
27 	uint8_t jrnum = 0;
28 
29 	if (caam_hal_ctrl_era(baseaddr) < 10) {
30 		val = io_caam_read32(baseaddr + CHANUM_MS);
31 		jrnum = GET_CHANUM_MS_JRNUM(val);
32 	} else {
33 		val = io_caam_read32(baseaddr + JR_VERSION);
34 		jrnum = GET_JR_VERSION_JRNUM(val);
35 	}
36 
37 	return jrnum;
38 }
39 
caam_hal_ctrl_hash_limit(vaddr_t baseaddr)40 uint8_t caam_hal_ctrl_hash_limit(vaddr_t baseaddr)
41 {
42 	uint32_t val = 0;
43 
44 	if (caam_hal_ctrl_era(baseaddr) < 10) {
45 		/* Read the number of instance */
46 		val = io_caam_read32(baseaddr + CHANUM_LS);
47 
48 		if (GET_CHANUM_LS_MDNUM(val)) {
49 			/* Hashing is supported */
50 			val = io_caam_read32(baseaddr + CHAVID_LS);
51 			val &= BM_CHAVID_LS_MDVID;
52 			if (val == CHAVID_LS_MDVID_LP256)
53 				return TEE_MAIN_ALGO_SHA256;
54 
55 			return TEE_MAIN_ALGO_SHA512;
56 		}
57 	} else {
58 		/* Read the number of instance */
59 		val = io_caam_read32(baseaddr + MDHA_VERSION);
60 
61 		if (GET_MDHA_VERSION_MDNUM(val)) {
62 			/* Hashing is supported */
63 			val &= BM_MDHA_VERSION_MDVID;
64 			if (val == MDHA_VERSION_MDVID_LP256)
65 				return TEE_MAIN_ALGO_SHA256;
66 
67 			return TEE_MAIN_ALGO_SHA512;
68 		}
69 	}
70 
71 	return UINT8_MAX;
72 }
73 
caam_hal_ctrl_splitkey_support(vaddr_t baseaddr)74 bool caam_hal_ctrl_splitkey_support(vaddr_t baseaddr)
75 {
76 	uint32_t val = io_caam_read32(baseaddr + CTPR_LS);
77 
78 	return GET_CTPR_LS_SPLIT_KEY(val);
79 }
80 
caam_hal_ctrl_pknum(vaddr_t baseaddr)81 uint8_t caam_hal_ctrl_pknum(vaddr_t baseaddr)
82 {
83 	uint32_t val = 0;
84 	uint8_t pknum = 0;
85 
86 	if (caam_hal_ctrl_era(baseaddr) < 10) {
87 		val = io_caam_read32(baseaddr + CHANUM_LS);
88 		pknum = GET_CHANUM_LS_PKNUM(val);
89 	} else {
90 		val = io_caam_read32(baseaddr + PKHA_VERSION);
91 		pknum = GET_PKHA_VERSION_PKNUM(val);
92 	}
93 
94 	return pknum;
95 }
96 
97 #define PRIBLOB_MASK	GENMASK_32(1, 0)
98 
caam_hal_ctrl_inc_priblob(vaddr_t baseaddr)99 void caam_hal_ctrl_inc_priblob(vaddr_t baseaddr)
100 {
101 	uint32_t val = 0;
102 	uint32_t blob = 0;
103 
104 	if (!IS_ENABLED(CFG_CAAM_INC_PRIBLOB))
105 		return;
106 
107 	val = io_caam_read32(baseaddr + SCFGR);
108 	val &= PRIBLOB_MASK;
109 	CTRL_TRACE("Reading CAAM PRIBLOB: 0x%"PRIx32, val);
110 
111 	if (val == 0 || val == 2)
112 		blob = val + 1;
113 	else if (val == 1)
114 		blob = val + 2;
115 	else
116 		panic("Error locking PRIBLOB, PRIBLOB =3");
117 
118 	CTRL_TRACE("New CAAM PRIBLOB value: 0x%"PRIx32, blob);
119 
120 	val = io_caam_read32(baseaddr + SCFGR);
121 	val |= blob;
122 	io_caam_write32(baseaddr + SCFGR, val);
123 
124 	val = io_caam_read32(baseaddr + SCFGR);
125 	val &= PRIBLOB_MASK;
126 	CTRL_TRACE("Checking: CAAM PRIBLOB: 0x%"PRIx32 " want: 0x%"PRIx32, val,
127 		   blob);
128 	if (val != blob)
129 		panic("Written PRIBLOB and read PRIBLOB do not match!");
130 }
131