29
29
#include <stdio.h>
30
30
31
31
#include "arm64_arch.h"
32
+ #include "arm64_mmu.h"
32
33
33
34
/****************************************************************************
34
35
* Pre-processor Definitions
35
36
****************************************************************************/
36
37
37
38
#define GCR_EL1_VAL 0x10001
38
39
40
+ /* The alignment length of the MTE must be a multiple of sixteen */
41
+
42
+ #define MTE_MM_AILGN 16
43
+
44
+ #define MTE_TAG_SHIFT 56
45
+
39
46
/****************************************************************************
40
47
* Private Functions
41
48
****************************************************************************/
42
49
43
- static int arm64_mte_is_support (void )
50
+ static int mte_is_support (void )
44
51
{
45
52
int supported ;
46
53
__asm__ volatile (
@@ -53,15 +60,86 @@ static int arm64_mte_is_support(void)
53
60
return supported != 0 ;
54
61
}
55
62
63
+ static void mte_set_tcf (bool enable )
64
+ {
65
+ uint64_t val = read_sysreg (sctlr_el1 );
66
+
67
+ if (enable )
68
+ {
69
+ val |= SCTLR_TCF1_BIT ;
70
+ }
71
+ else
72
+ {
73
+ val &= ~SCTLR_TCF1_BIT ;
74
+ }
75
+
76
+ write_sysreg (val , sctlr_el1 );
77
+ }
78
+
79
+ static inline uint8_t mte_get_ptr_tag (const void * ptr )
80
+ {
81
+ return 0xf0 | (uint8_t )(((uint64_t )(ptr )) >> MTE_TAG_SHIFT );
82
+ }
83
+
56
84
/****************************************************************************
57
85
* Public Functions
58
86
****************************************************************************/
59
87
60
- void arm64_enable_mte (void )
88
+ uint8_t arm64_mte_get_random_tag (const void * addr )
89
+ {
90
+ asm("irg %0, %0" : "=r" (addr ));
91
+
92
+ return mte_get_ptr_tag (addr );
93
+ }
94
+
95
+ FAR void * arm64_mte_get_untagged_addr (const void * addr )
96
+ {
97
+ return (FAR void * )
98
+ (((uint64_t )(addr )) & ~((uint64_t )0xff << MTE_TAG_SHIFT ));
99
+ }
100
+
101
+ FAR void * arm64_mte_get_tagged_addr (const void * addr , uint8_t tag )
102
+ {
103
+ return (FAR void * )
104
+ (((uint64_t )(addr )) | ((uint64_t )tag << MTE_TAG_SHIFT ));
105
+ }
106
+
107
+ /* Disable MTE by clearing the TCF1 bit in SCTLR_EL1 */
108
+
109
+ void arm64_mte_disable (void )
110
+ {
111
+ mte_set_tcf (false);
112
+ }
113
+
114
+ /* Enable MTE by setting the TCF1 bit in SCTLR_EL1 */
115
+
116
+ void arm64_mte_enable (void )
117
+ {
118
+ mte_set_tcf (true);
119
+ }
120
+
121
+ /* Set memory tags for a given memory range */
122
+
123
+ void arm64_mte_set_tag (const void * addr , size_t size )
124
+ {
125
+ size_t i ;
126
+
127
+ DEBUGASSERT ((uintptr_t )addr % MTE_MM_AILGN == 0 );
128
+ DEBUGASSERT (size % MTE_MM_AILGN == 0 );
129
+
130
+ for (i = 0 ; i < size ; i += MTE_MM_AILGN )
131
+ {
132
+ asm("stg %0, [%0]" : : "r" (addr + i ));
133
+ }
134
+ }
135
+
136
+ /* Initialize MTE settings and enable memory tagging */
137
+
138
+ void arm64_mte_init (void )
61
139
{
62
140
uint64_t val ;
63
141
64
- if (!arm64_mte_is_support ())
142
+ if (!mte_is_support ())
65
143
{
66
144
return ;
67
145
}
@@ -78,6 +156,14 @@ void arm64_enable_mte(void)
78
156
assert (!(read_sysreg (ttbr0_el1 ) & TTBR_CNP_BIT ));
79
157
assert (!(read_sysreg (ttbr1_el1 ) & TTBR_CNP_BIT ));
80
158
159
+ /* Controls the default value for skipping high bytes */
160
+
161
+ val = read_sysreg (tcr_el1 );
162
+ val |= TCR_TCMA1 ;
163
+ write_sysreg (val , tcr_el1 );
164
+
165
+ /* Enable the MTE function */
166
+
81
167
val = read_sysreg (sctlr_el1 );
82
168
val |= SCTLR_ATA_BIT | SCTLR_TCF1_BIT ;
83
169
write_sysreg (val , sctlr_el1 );
0 commit comments