|
5 | 5 | */ |
6 | 6 |
|
7 | 7 | #include <stdint.h> |
8 | | -#include <string.h> |
9 | 8 | #include <silexpk/iomem.h> |
10 | 9 |
|
| 10 | +#ifndef CONFIG_SOC_NRF54L20 |
| 11 | + |
11 | 12 | #define PTR_ALIGNMENT(ptr, type) (((uintptr_t)ptr) & (sizeof(type) - 1)) |
12 | 13 | #define IS_NATURAL_ALIGNED(ptr, type) !PTR_ALIGNMENT(ptr, type) |
13 | 14 | #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) |
67 | 68 | memcpy((char *)d, (char *)s, sz); |
68 | 69 | } |
69 | 70 |
|
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) |
71 | 125 | { |
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; |
84 | 139 | } |
| 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; |
85 | 160 | } |
| 161 | + |
| 162 | +#endif |
0 commit comments