1 /*
2  * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 
8 
9 #ifndef PKA_HW_DEFS_H
10 #define PKA_HW_DEFS_H
11 
12 #ifdef __cplusplus
13 extern "C"
14 {
15 #endif
16 
17 #include "cc_pal_types.h"
18 #include "dx_crys_kernel.h"
19 #include "cc_regs.h"
20 #include "cc_hal_plat.h"
21 #include "cc_pal_mutex.h"
22 #include "cc_pal_abort.h"
23 #include "cc_bitops.h"
24 #include "pka_defs.h"
25 #include "cc_util_pm.h"
26 
27 
28 /* PKA OPCODE register fields positions (low bit position) */
29 #define PKA_OPCODE_RES_OPERAND_MSBIT_OFFSET   5
30 #define PKA_OPCODE_TAG_POS                        CC_REG_BIT_SHIFT(OPCODE, TAG)     // bit shift   0
31 #define PKA_OPCODE_RESULT_POS                     CC_REG_BIT_SHIFT(OPCODE, REG_R)   // bit shift   6
32 #define PKA_OPCODE_OPERAND_2_POS                  CC_REG_BIT_SHIFT(OPCODE, REG_B)   // bit shift  12
33 #define PKA_OPCODE_OPERAND_1_POS                  CC_REG_BIT_SHIFT(OPCODE, REG_A)   // bit shift  18
34 #define PKA_OPCODE_LEN_POS                        CC_REG_BIT_SHIFT(OPCODE, LEN)     // bit shift  24
35 #define PKA_OPCODE_OPERATION_ID_POS               CC_REG_BIT_SHIFT(OPCODE, OPCODE)      // bit shift  27
36 #define PKA_OPCODE_R_DISCARD_POS                  (PKA_OPCODE_RESULT_POS + PKA_OPCODE_RES_OPERAND_MSBIT_OFFSET)
37 #define PKA_OPCODE_OPERAND_2_IMMED_POS            (PKA_OPCODE_OPERAND_2_POS + PKA_OPCODE_RES_OPERAND_MSBIT_OFFSET)
38 #define PKA_OPCODE_OPERAND_1_IMMED_POS            (PKA_OPCODE_OPERAND_1_POS + PKA_OPCODE_RES_OPERAND_MSBIT_OFFSET)
39 
40 /* PKA STATUS register fields positions (low bit position) */
41 #define PKA_STATUS_ALU_OUT_ZERO_POS               CC_REG_BIT_SHIFT(PKA_STATUS, ALU_OUT_ZERO)  // bit shift  12
42 #define PKA_STATUS_DIV_BY_ZERO_POS                CC_REG_BIT_SHIFT(PKA_STATUS, DIV_BY_ZERO)   // bit shift  14
43 #define PKA_STATUS_ALU_CARRY_POS                  CC_REG_BIT_SHIFT(PKA_STATUS, ALU_CARRY)     // bit shift  9
44 
45 
46 /* PKA N_NP_T0_T1 register fields positions (low bit position) */
47 #define PKA_N_NP_T0_T1_REG_N_POS                  CC_REG_BIT_SHIFT(N_NP_T0_T1_ADDR, N_VIRTUAL_ADDR)    // bit shift  0
48 #define PKA_N_NP_T0_T1_REG_NP_POS                 CC_REG_BIT_SHIFT(N_NP_T0_T1_ADDR, NP_VIRTUAL_ADDR)   // bit shift  5
49 #define PKA_N_NP_T0_T1_REG_T0_POS                 CC_REG_BIT_SHIFT(N_NP_T0_T1_ADDR, T0_VIRTUAL_ADDR)   // bit shift  10
50 #define PKA_N_NP_T0_T1_REG_T1_POS                 CC_REG_BIT_SHIFT(N_NP_T0_T1_ADDR, T1_VIRTUAL_ADDR)   // bit shift  15
51 
52 /* PKA N_NP_T0_T1 register default (reset) value: N=0, NP=1, T0=30, T1=31 */
53 #define PKA_REG_N                                           0
54 #define PKA_REG_NP                                          1
55 #define PKA_REG_T0                                          30
56 #define PKA_REG_T1                                          31
57 #define PKA_N_NP_T0_T1_REG_DEFAULT_VAL                  (PKA_REG_N  << PKA_N_NP_T0_T1_REG_N_POS  | \
58                                                          PKA_REG_NP << PKA_N_NP_T0_T1_REG_NP_POS | \
59                                                          PKA_REG_T0 << PKA_N_NP_T0_T1_REG_T0_POS | \
60                                                          PKA_REG_T1 << PKA_N_NP_T0_T1_REG_T1_POS)
61 
62 /* PKA control values  */
63 #define PKA_PIPE_READY                                   1
64 #define PKA_OP_DONE                                      1
65 
66 
67 /* PKA HW defined OPCODE values, according to HW documentation  */
68 #define PKA_OPCODE_ID_ADD           0x4U    // @0x4 - Add,Inc
69 #define PKA_OPCODE_ID_SUB           0x5U    // @0x5 - Sub,Dec,Neg
70 #define PKA_OPCODE_ID_MODADD        0x6U    // @0x6 - ModAdd,ModInc
71 #define PKA_OPCODE_ID_MODSUB        0x7U    // @0x7 - ModSub,ModDec,ModNeg
72 #define PKA_OPCODE_ID_AND           0x8U    // @0x8 - AND,TST0,CLR0
73 #define PKA_OPCODE_ID_OR            0x9U    // @0x9 - OR,COPY,SET0
74 #define PKA_OPCODE_ID_XOR           0xAU    // @0xa - XOR,FLIP0,INVERT,COMPARE
75 #define PKA_OPCODE_ID_SHR0          0xCU    // @0xc - SHR0
76 #define PKA_OPCODE_ID_SHR1          0xDU    // @0xd - SHR1
77 #define PKA_OPCODE_ID_SHL0          0xEU    // @0xe - SHL0
78 #define PKA_OPCODE_ID_SHL1          0xFU    // @0xf - SHL1
79 #define PKA_OPCODE_ID_MULLOW        0x10U   // @0x10 - MulLow
80 #define PKA_OPCODE_ID_MODMUL        0x11U   // @0x11 - ModMul
81 #define PKA_OPCODE_ID_MODMULN       0x12U   // @0x12 - ModMulN
82 #define PKA_OPCODE_ID_MODEXP        0x13U   // @0x13 - ModExp
83 #define PKA_OPCODE_ID_DIVISION      0x14U   // @0x14 - Division
84 #define PKA_OPCODE_ID_MODINV        0x15U   // @0x15 - ModInv
85 //#define PKA_OPCODE_ID_DIV         0x16U   // @0x16 - RL the code not used
86 #define PKA_OPCODE_ID_MULHIGH           0x17U   // 0x17 - MULHigh
87 #define PKA_OPCODE_ID_MODMLAC       0x18U   // 0x18 - ModMulAcc
88 #define PKA_OPCODE_ID_MODMLACNR         0x19U   // 0x19 - ModMulAccNR
89 #define PKA_OPCODE_ID_SEPINT        0x1AU   // 0x1A - sepInt
90 #define PKA_OPCODE_ID_REDUCTION         0x1BU   // 0x1B - Reduction
91 #define PKA_OPCODE_ID_TERMINATE     0x0U    // @0x00 - Terminate
92 
93 #define   PKA_MAX_OPCODE    0x1BU
94 
95 
96 /*************************************************************/
97 /* Macros for waiting PKA machine ready states               */
98 /*************************************************************/
99 
100 
101 /* defining a macro for waiting to the PKA_PIPE_READY */
102 #define PKA_WAIT_ON_PKA_PIPE_READY() \
103 do { \
104    volatile uint32_t output_reg_val; \
105    do \
106    { \
107       output_reg_val = CC_HAL_READ_REGISTER(CC_REG_OFFSET (CRY_KERNEL, PKA_PIPE_RDY) ); \
108    }while( (output_reg_val & 0x01) != PKA_PIPE_READY ); \
109 }while(0)
110 
111 /* defining a macro for waiting to the PKA_OP_DONE */
112 #define PKA_WAIT_ON_PKA_DONE() \
113 do { \
114    volatile uint32_t output_reg_val; \
115    do \
116    { \
117       output_reg_val = CC_HAL_READ_REGISTER(CC_REG_OFFSET (CRY_KERNEL, PKA_DONE) ); \
118    }while( (output_reg_val & 0x01) != PKA_OP_DONE ); \
119 }while(0)
120 
121 
122 /**************************************************************/
123 /*  Macros for controlling PKA machine and changing           */
124 /*  PKA sizes table and mapping table settings.               */
125 /**************************************************************/
126 
127 /*  Set_N_NP_T0_T1_REG:  Sets addresses of registers N,NP,T0,T1 into special register */
128 #define   PKA_SET_N_NP_T0_T1_REG(N, NP, T0, T1) \
129         PKA_WAIT_ON_PKA_DONE();  /*!! Needed to wait PKA not to disturb in the it's work !!!*/\
130         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, N_NP_T0_T1_ADDR), \
131        (uint32_t)( (N) << PKA_N_NP_T0_T1_REG_N_POS   | \
132                     (NP) << PKA_N_NP_T0_T1_REG_NP_POS  | \
133                     (T0) << PKA_N_NP_T0_T1_REG_T0_POS  | \
134                     (T1) << PKA_N_NP_T0_T1_REG_T1_POS  ) )
135 
136 /*  Set default N_NP_T0_T1_REG:  Sets default values of registers addresses
137     N=0, NP=1, T0=30, T1=31 into special register N_NP_T0_T1_REG */
138 #define   PKA_DEFAULT_N_NP_T0_T1_REG()  \
139         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, N_NP_T0_T1_ADDR), \
140                               PKA_N_NP_T0_T1_REG_DEFAULT_VAL)
141 
142 /* Returns the ALU Zero-bit from PKA_STATUS register */
143 #define PKA_GET_STATUS_ALU_OUT_ZERO(status)  { \
144     PKA_WAIT_ON_PKA_DONE(); \
145     status = CC_HAL_READ_REGISTER(CC_REG_OFFSET (CRY_KERNEL,PKA_STATUS)); \
146     status = ((status) >> PKA_STATUS_ALU_OUT_ZERO_POS ) & 1UL; \
147 }
148 
149 /*Returns the DividerIsZero-bit from PKA_STATUS register */
150 #define PKA_GET_STATUS_DIV_BY_ZERO( status)  { \
151     PKA_WAIT_ON_PKA_DONE(); \
152     status = CC_HAL_READ_REGISTER( CC_REG_OFFSET (CRY_KERNEL,PKA_STATUS)); \
153     status = ((status) >> PKA_STATUS_DIV_BY_ZERO_POS ) & 1; \
154 }
155 
156 /* Returns the ALU Carry-bit from PKA_STATUS register */
157 #define PKA_GET_STATUS_CARRY(status)  { \
158     PKA_WAIT_ON_PKA_DONE(); \
159     status = CC_HAL_READ_REGISTER(CC_REG_OFFSET (CRY_KERNEL,PKA_STATUS)); \
160     status = ((status) >> PKA_STATUS_ALU_CARRY_POS ) & 1; \
161 }
162 
163 
164 /******************************************************************/
165 /* Macros for setting and reading sizes from PKA regsSizesTable   */
166 /******************************************************************/
167 
168 /*  Sets the size into regsSizesTable entry */
169 #define PKA_SET_REG_SIZE(SizeBits, EntryNum) \
170     PKA_WAIT_ON_PKA_DONE(); /*!! Needed to wait PKA not to disturb in the it's work !!!*/\
171     CC_HAL_WRITE_REGISTER((CC_REG_OFFSET(CRY_KERNEL ,PKA_L0) + 4*(EntryNum)), (SizeBits) )
172 
173 /*  Gets the size from regsSizesTable entry */
174 #define PKA_GET_REG_SIZE(SizeBits, EntryNum) \
175     PKA_WAIT_ON_PKA_DONE(); /*!! Needed to wait PKA to get right results !!!*/\
176     SizeBits = CC_HAL_READ_REGISTER(CC_REG_OFFSET(CRY_KERNEL ,PKA_L0) + 4*(EntryNum))
177 
178 /******************************************************************/
179 /* Macros for setting and reading addresses of PKA data registers */
180 /******************************************************************/
181 
182 /*The following macros are used for setting and reading the data registers addresses in mapping table.*/
183 
184 /*  Sets the physical address PhysAddr of register VirtReg in mapping table */
185 #define PKA_SET_REG_ADDRESS(VirtReg, PhysAddr) \
186     PKA_WAIT_ON_PKA_DONE(); /*!! Needed to wait PKA to complete before changing mapping !!!*/\
187     CC_HAL_WRITE_REGISTER((CC_REG_OFFSET(CRY_KERNEL, MEMORY_MAP0) + 4*(VirtReg)), (PhysAddr))
188 
189 /*  Returns the physical address of register VirtReg from mapping table  */
190 #define PKA_GET_REG_ADDRESS(VirtReg, PhysAddr)\
191     PKA_WAIT_ON_PKA_DONE(); /*!! Needed to wait PKA to complete before changing mapping !!!*/\
192     (PhysAddr) = CC_HAL_READ_REGISTER(CC_REG_OFFSET(CRY_KERNEL, MEMORY_MAP0) + 4*(VirtReg))
193 
194 
195 /******************************************************************/
196 /*          Macros for setting Full PKI opcode                    */
197 /******************************************************************/
198 #define PKA_SET_FULL_OPCODE( Opcode,LenID,IsAImmed,OpA,IsBImmed,OpB,ResDiscard,Res,Tag ) \
199     ( ((Opcode))      << PKA_OPCODE_OPERATION_ID_POS     | \
200       ((LenID))       << PKA_OPCODE_LEN_POS              | \
201       ((IsAImmed))    << PKA_OPCODE_OPERAND_1_IMMED_POS  | \
202       ((OpA))         << PKA_OPCODE_OPERAND_1_POS        | \
203       ((IsBImmed))    << PKA_OPCODE_OPERAND_2_IMMED_POS  | \
204       ((OpB))         << PKA_OPCODE_OPERAND_2_POS        | \
205       ((ResDiscard))  << PKA_OPCODE_R_DISCARD_POS        | \
206       ((Res))         << PKA_OPCODE_RESULT_POS           | \
207       ((Tag))         << PKA_OPCODE_TAG_POS  )
208 
209 
210 /******************************************************************/
211 /*          Macros for reading and loading PKA memory data        */
212 /******************************************************************/
213 /* macros to lock/unlock the Mutex on each SRAM read/write    *
214 *  used only when symmetric driver uses the one or more of the following regs:
215 *  PKA_SRAM_ADDR, PKA_SRAM_RDATA, PKA_SRAM_WDATA, SRAM_DATA_READY     */
216 #ifdef CC_IOT
217     #define PKA_MUTEX_LOCK
218     #define PKA_MUTEX_UNLOCK
219 #else
220     extern CC_PalMutex CCSymCryptoMutex;
221 
222     #define PKA_MUTEX_LOCK  \
223         if(CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE) != CC_SUCCESS) { \
224            CC_PalAbort("Fail to acquire mutex\n");}
225 
226     #define PKA_MUTEX_UNLOCK \
227         if(CC_PalMutexUnlock(&CCSymCryptoMutex) != CC_SUCCESS) { \
228            CC_PalAbort("Fail to release mutex\n");}
229 #endif
230 
231 /* ******************************************************************* */
232 /* MACRO DEFINITIONS FOR WORKING WITH INDIRECT ACCESS TO PKA SRAM DATA */
233 /* ******************************************************************* */
234 /* defining a macro to clear the not-completed part of PKA big word*
235 *  ii value was set in macro calling  PKA_SRAM_WRITE_CLR()         */
236 #define PKA_SRAM_WRITE_CLR(SizeWords) \
237    for(; ii < (((SizeWords+(PKA_WORD_SIZE_IN_32BIT_WORDS-1))/PKA_WORD_SIZE_IN_32BIT_WORDS)*PKA_WORD_SIZE_IN_32BIT_WORDS) ; ii++) { \
238        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_WDATA), 0); \
239        WAIT_SRAM_DATA_READY; \
240    }
241 
242 
243 /* defining a macro to wait on SRAM ready;
244        currently waiting is not needed   */
245 // #define DO_WAIT_SRAM_DATA_READY
246 // #define PKA_DELEY 0
247 #ifndef DO_WAIT_SRAM_DATA_READY
248     #define WAIT_SRAM_DATA_READY
249 #elif defined PKA_DELEY
250     #define WAIT_SRAM_DATA_READY  { \
251         volatile uint32_t ii; \
252         for(ii=0; ii<PKA_DELEY; ) ii++; \
253     }
254 #else
255     #define WAIT_SRAM_DATA_READY { \
256         volatile uint32_t dummy; \
257         do { \
258             dummy = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, SRAM_DATA_READY)); \
259            }while(!(dummy & 0x1));\
260     }
261 #endif
262 
263 /* macro to load block to SRAM memory */
264 #define PKA_HW_LOAD_BLOCK_TO_PKA_MEM(Addr, ptr, SizeWords) \
265 do { \
266    uint32_t ii; \
267    PKA_MUTEX_LOCK; \
268    PKA_WAIT_ON_PKA_DONE();\
269    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, PKA_SRAM_ADDR), (Addr)); \
270    for(ii = 0; ii < (SizeWords); ii++) \
271    { \
272        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_WDATA), ((uint32_t*)(ptr))[ii]); \
273        WAIT_SRAM_DATA_READY; \
274    } \
275    PKA_SRAM_WRITE_CLR(SizeWords) \
276    PKA_MUTEX_UNLOCK; \
277 }while(0)
278 
279 /* macro to load a value to SRAM with 32-bit access */
280 #define PKA_HW_LOAD_VALUE_TO_PKA_MEM(Addr, Val) \
281 do { \
282    PKA_MUTEX_LOCK; \
283    PKA_WAIT_ON_PKA_DONE();\
284    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_ADDR), (Addr)); \
285    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_WDATA), (Val)); \
286    WAIT_SRAM_DATA_READY; \
287    PKA_MUTEX_UNLOCK; \
288 }while(0)
289 
290 
291 /* macro to clear PKA memory: Addr must be alighned to PKA_WORD_SIZE */
292 #define PKA_HW_CLEAR_PKA_MEM(Addr, SizeWords) \
293 do { \
294    uint32_t ii; \
295    PKA_MUTEX_LOCK; \
296    PKA_WAIT_ON_PKA_DONE();\
297    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_ADDR), (Addr)); \
298    for( ii = 0; ii < (uint32_t)(SizeWords); ii++ ) \
299    { \
300       CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_WDATA), 0x0UL ); \
301       WAIT_SRAM_DATA_READY; \
302    }\
303    PKA_SRAM_WRITE_CLR((SizeWords)); \
304    PKA_MUTEX_UNLOCK; \
305 }while(0)
306 
307 /* macro to read a value from the PKA data memory */
308 #define PKA_HW_READ_VALUE_FROM_PKA_MEM(Addr, Val) \
309 do { \
310    volatile uint32_t dummy; \
311    PKA_MUTEX_LOCK; \
312    PKA_WAIT_ON_PKA_DONE();\
313    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_RADDR), (Addr)); \
314    WAIT_SRAM_DATA_READY; \
315    dummy = CC_HAL_READ_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_RDATA)); \
316    (Val) = dummy; \
317    WAIT_SRAM_DATA_READY; \
318    PKA_MUTEX_UNLOCK; \
319 }while(0)
320 
321 /* macro to read a block from the PKA data memory */
322 #define PKA_HW_READ_BLOCK_FROM_PKA_MEM(Addr, ptr, SizeWords) \
323 do { \
324    uint32_t ii; \
325    volatile uint32_t dummy; \
326    PKA_MUTEX_LOCK; \
327    PKA_WAIT_ON_PKA_DONE();\
328    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_RADDR), (Addr)); \
329    for(ii = 0; ii < (SizeWords); ii++) \
330    { \
331       WAIT_SRAM_DATA_READY; \
332       dummy = CC_HAL_READ_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_RDATA));\
333       ((uint32_t*)(ptr))[ii] = (dummy); \
334    } \
335    WAIT_SRAM_DATA_READY; \
336    PKA_MUTEX_UNLOCK; \
337 }while(0)
338 
339 /************************ Enums ********************************/
340 
341 #ifdef __cplusplus
342 }
343 #endif
344 
345 #endif // PKA_HW_DEFS_H
346 
347 
348