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  * @file
10  * @brief This file contains macro definitions for accessing ARM TrustZone CryptoCell register space.
11  */
12 
13 #ifndef _CC_REGS_H_
14 #define _CC_REGS_H_
15 
16 #include "cc_bitops.h"
17 
18 #if !defined(CC_REE) && !defined(CC_IOT) && !defined(CC_SB_SUPPORT_IOT)
19 #include "dx_nvm.h"
20 #endif
21 
22 /* Register Offset macro */
23 #define CC_REG_OFFSET(unit_name, reg_name)               \
24     (DX_BASE_ ## unit_name + DX_ ## reg_name ## _REG_OFFSET)
25 
26 #define CC_REG_BIT_SHIFT(reg_name, field_name)               \
27     (DX_ ## reg_name ## _ ## field_name ## _BIT_SHIFT)
28 
29 /* Register Offset macros (from registers base address in host) */
30 #if defined(CC_REE) || defined(CC_TEE) || defined(CC_IOT) || defined(CC_SB_SUPPORT_IOT)
31 
32 #include "dx_reg_base_host.h"
33 
34 /* Read-Modify-Write a field of a register */
35 #define MODIFY_REGISTER_FLD(unitName, regName, fldName, fldVal)         \
36 do {                                            \
37     uint32_t regVal;                            \
38     regVal = READ_REGISTER(CC_REG_ADDR(unitName, regName));       \
39     CC_REG_FLD_SET(unitName, regName, fldName, regVal, fldVal); \
40     WRITE_REGISTER(CC_REG_ADDR(unitName, regName), regVal);       \
41 } while (0)
42 
43 #else
44 #error Execution domain is not CC_REE/CC_TEE/CC_IOT
45 #endif
46 
47 /* Registers address macros for ENV registers (development FPGA only) */
48 #ifdef DX_BASE_ENV_REGS
49 
50 /* This offset should be added to mapping address of DX_BASE_ENV_REGS */
51 #define CC_ENV_REG_OFFSET(reg_name) (DX_ENV_ ## reg_name ## _REG_OFFSET)
52 
53 #endif /*DX_BASE_ENV_REGS*/
54 
55 /*! Bit fields get */
56 #define CC_REG_FLD_GET(unit_name, reg_name, fld_name, reg_val)        \
57     (DX_ ## reg_name ## _ ## fld_name ## _BIT_SIZE == 0x20 ?          \
58     reg_val /*!< \internal Optimization for 32b fields */ :               \
59     BITFIELD_GET(reg_val, DX_ ## reg_name ## _ ## fld_name ## _BIT_SHIFT, \
60              DX_ ## reg_name ## _ ## fld_name ## _BIT_SIZE))
61 
62 /*! Bit fields access */
63 #define CC_REG_FLD_GET2(unit_name, reg_name, fld_name, reg_val)       \
64     (CC_ ## reg_name ## _ ## fld_name ## _BIT_SIZE == 0x20 ?          \
65     reg_val /*!< \internal Optimization for 32b fields */ :               \
66     BITFIELD_GET(reg_val, CC_ ## reg_name ## _ ## fld_name ## _BIT_SHIFT, \
67              CC_ ## reg_name ## _ ## fld_name ## _BIT_SIZE))
68 
69 /*! Bit fields set */
70 #define CC_REG_FLD_SET(                                               \
71     unit_name, reg_name, fld_name, reg_shadow_var, new_fld_val)      \
72 do {                                                                     \
73     if (DX_ ## reg_name ## _ ## fld_name ## _BIT_SIZE == 0x20)       \
74         reg_shadow_var = new_fld_val; /*!< \internal Optimization for 32b fields */\
75     else                                                             \
76         BITFIELD_SET(reg_shadow_var,                             \
77             DX_ ## reg_name ## _ ## fld_name ## _BIT_SHIFT,  \
78             DX_ ## reg_name ## _ ## fld_name ## _BIT_SIZE,   \
79             new_fld_val);                                    \
80 } while (0)
81 
82 /*! Bit fields set */
83 #define CC_REG_FLD_SET2(                                               \
84     unit_name, reg_name, fld_name, reg_shadow_var, new_fld_val)      \
85 do {                                                                     \
86     if (CC_ ## reg_name ## _ ## fld_name ## _BIT_SIZE == 0x20)       \
87         reg_shadow_var = new_fld_val; /*!< \internal Optimization for 32b fields */\
88     else                                                             \
89         BITFIELD_SET(reg_shadow_var,                             \
90             CC_ ## reg_name ## _ ## fld_name ## _BIT_SHIFT,  \
91             CC_ ## reg_name ## _ ## fld_name ## _BIT_SIZE,   \
92             new_fld_val);                                    \
93 } while (0)
94 
95 /* Usage example:
96    uint32_t reg_shadow = READ_REGISTER(CC_REG_ADDR(CRY_KERNEL,AES_CONTROL));
97    CC_REG_FLD_SET(CRY_KERNEL,AES_CONTROL,NK_KEY0,reg_shadow, 3);
98    CC_REG_FLD_SET(CRY_KERNEL,AES_CONTROL,NK_KEY1,reg_shadow, 1);
99    WRITE_REGISTER(CC_REG_ADDR(CRY_KERNEL,AES_CONTROL), reg_shadow);
100  */
101 
102 #endif /*_CC_REGS_H_*/
103