Skip to content

Commit d085464

Browse files
tomi-fontendre-nordic
authored andcommitted
nrf_security: drivers: cracen: make PK mem writes word-aligned on 54L20
Make the sx_*pkmem*() functions perform word-aligned and word-sized writes on 54L20, which requires that. Also, turn sx_rdpkmem() into an inline memcpy() as that's what the implementation was basically doing. Other than that, the original implementation is left untouched on other board targets to avoid potential breakages. ref: DLT-3873 Signed-off-by: Tomi Fontanilles <[email protected]>
1 parent e45b802 commit d085464

File tree

2 files changed

+101
-15
lines changed
  • subsys/nrf_security/src/drivers/cracen/silexpk

2 files changed

+101
-15
lines changed

subsys/nrf_security/src/drivers/cracen/silexpk/include/silexpk/iomem.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#ifndef IOMEM_HEADER_FILE
88
#define IOMEM_HEADER_FILE
99

10+
#include <string.h>
11+
1012
#ifdef SX_INSTRUMENT_MMIO_WITH_PRINTFS
1113
#define SX_WARN_UNALIGNED_ADDR(addr) printk("%s: WARNING: unaligned address %p\r\n", __func__, addr)
1214
#else
@@ -44,11 +46,15 @@ void sx_wrpkmem(void *dst, const void *src, size_t sz);
4446
* Will be modified after this call
4547
* @param[in] input_byte The byte value to be written.
4648
*/
49+
#ifndef CONFIG_SOC_NRF54L20
4750
static inline void sx_wrpkmem_byte(void *dst, char input_byte)
4851
{
4952
volatile char *d = (volatile char *)dst;
5053
*d = input_byte;
5154
}
55+
#else
56+
void sx_wrpkmem_byte(void *dst, char input_byte);
57+
#endif
5258

5359
/** Read from device memory at src into normal memory at dst.
5460
*
@@ -60,7 +66,10 @@ static inline void sx_wrpkmem_byte(void *dst, char input_byte)
6066
* @param[in] src Source of read operation
6167
* @param[in] sz The number of bytes to read from src to dst
6268
*/
63-
void sx_rdpkmem(void *dst, const void *src, size_t sz);
69+
static inline void sx_rdpkmem(void *dst, const void *src, size_t sz)
70+
{
71+
memcpy(dst, src, sz);
72+
}
6473

6574
/** Read a byte from device memory at src.
6675
*

subsys/nrf_security/src/drivers/cracen/silexpk/src/iomem.c

Lines changed: 91 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
*/
66

77
#include <stdint.h>
8-
#include <string.h>
98
#include <silexpk/iomem.h>
109

10+
#ifndef CONFIG_SOC_NRF54L20
11+
1112
#define PTR_ALIGNMENT(ptr, type) (((uintptr_t)ptr) & (sizeof(type) - 1))
1213
#define IS_NATURAL_ALIGNED(ptr, type) !PTR_ALIGNMENT(ptr, type)
1314
#define IS_SAME_ALIGNMENT(p1, p2, type) (PTR_ALIGNMENT(p1, type) == PTR_ALIGNMENT(p2, type))
@@ -67,19 +68,95 @@ void sx_wrpkmem(void *dst, const void *src, size_t sz)
6768
memcpy((char *)d, (char *)s, sz);
6869
}
6970

70-
void sx_rdpkmem(void *dst, const void *src, size_t sz)
71+
#else /* 54L20 requires word-aligned, word-sized memory accesses */
72+
73+
static void write_incomplete_word(uint32_t *dst, const uint8_t *bytes,
74+
size_t first_byte_pos, size_t num_bytes)
75+
{
76+
uint32_t word = *dst;
77+
78+
for (size_t i = 0; i != num_bytes; ++i) {
79+
((uint8_t *)&word)[first_byte_pos + i] = bytes[i];
80+
}
81+
82+
#ifdef SX_INSTRUMENT_MMIO_WITH_PRINTFS
83+
printk("write_incomplete_word(%p, 0x%x, %zu, %zu): 0x%x to 0x%x\r\n",
84+
dst, *(const uint32_t *)bytes, first_byte_pos, num_bytes, *dst, word);
85+
#endif
86+
if ((uintptr_t)dst % 4) {
87+
SX_WARN_UNALIGNED_ADDR(dst);
88+
}
89+
90+
*dst = word;
91+
}
92+
93+
void sx_clrpkmem(void *dst, size_t sz)
94+
{
95+
if (sz == 0) {
96+
return;
97+
}
98+
#ifdef SX_INSTRUMENT_MMIO_WITH_PRINTFS
99+
printk("sx_clrpkmem(%p, %zu)\r\n", dst, sz);
100+
#endif
101+
102+
const uint8_t zero[4] = {};
103+
const uintptr_t dst_addr = (uintptr_t)dst;
104+
105+
if (dst_addr % 4) {
106+
const size_t first_byte_pos = dst_addr % 4;
107+
const size_t byte_count = 4 - first_byte_pos;
108+
109+
write_incomplete_word((uint32_t *)(dst_addr & ~3), zero,
110+
first_byte_pos, byte_count);
111+
dst = (void *)(dst_addr + byte_count);
112+
sz -= byte_count;
113+
}
114+
uint32_t *word_dst = (uint32_t *)dst;
115+
116+
for (size_t i = 0; i != sz / 4; ++i) {
117+
word_dst[i] = 0;
118+
}
119+
if (sz % 4) {
120+
write_incomplete_word(&word_dst[sz / 4], zero, 0, sz % 4);
121+
}
122+
}
123+
124+
void sx_wrpkmem(void *dst, const void *src, size_t sz)
71125
{
72-
if (IS_SAME_ALIGNMENT(dst, src, tfrblk) && IS_NATURAL_SIZE(sz, tfrblk)) {
73-
memcpy(dst, src, sz);
74-
} else {
75-
volatile char *d = (volatile char *)dst;
76-
volatile const char *s = (volatile const char *)src;
77-
78-
while (sz) {
79-
*d = *s;
80-
d++;
81-
s++;
82-
sz--;
83-
}
126+
#ifdef SX_INSTRUMENT_MMIO_WITH_PRINTFS
127+
printk("sx_wrpkmem(%p, %p, %zu)\r\n", dst, src, sz);
128+
#endif
129+
130+
if ((uintptr_t)dst % 4) {
131+
const uintptr_t dst_addr = (uintptr_t)dst;
132+
const size_t first_byte_pos = dst_addr % 4;
133+
const size_t byte_count = 4 - first_byte_pos;
134+
135+
write_incomplete_word((uint32_t *)(dst_addr & ~3), src, first_byte_pos, byte_count);
136+
*(uint8_t **)&dst += byte_count;
137+
*(const uint8_t **)&src += byte_count;
138+
sz -= byte_count;
84139
}
140+
141+
for (size_t i = 0; i != sz / 4; ++i) {
142+
((uint32_t *)dst)[i] = ((const uint32_t *)src)[i];
143+
}
144+
145+
if (sz % 4) {
146+
write_incomplete_word((uint32_t *)((uint8_t *)dst + (sz & ~3)),
147+
(const uint8_t *)src + (sz & ~3), 0, sz % 4);
148+
}
149+
}
150+
151+
void sx_wrpkmem_byte(void *dst, char input_byte)
152+
{
153+
uintptr_t dst_addr = (uintptr_t)dst;
154+
uint32_t *word_dst = (uint32_t *)(dst_addr & ~3);
155+
uint32_t word = *word_dst;
156+
size_t byte_index = dst_addr % 4;
157+
158+
((uint8_t *)&word)[byte_index] = input_byte;
159+
*word_dst = word;
85160
}
161+
162+
#endif

0 commit comments

Comments
 (0)