physmap: Implement source-aligned version of mmio_readn()
Implement readn() with explicit alignment of the source pointer.
Change-Id: Ic754c552c826ec06ea209a039c3035265ca61c9a
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/c/flashrom-stable/+/72581
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/hwaccess_physmap.c b/hwaccess_physmap.c
index cfc599e..5f18f8e 100644
--- a/hwaccess_physmap.c
+++ b/hwaccess_physmap.c
@@ -440,6 +440,29 @@
return;
}
+/* Read source-aligned to `align` bytes. `align` should be 4 or 8. */
+void mmio_readn_aligned(const void *addr, uint8_t *dst, size_t len, size_t align)
+{
+ volatile const uint8_t *src = addr;
+
+ /* align */
+ for (; (uintptr_t)src % align && len > 0; --len, ++dst, ++src)
+ *dst = *src;
+
+ /* copy aligned */
+ if (align == 4) {
+ for (; len >= align; len -= align, dst += align, src += align)
+ *(uint32_t *)dst = *(volatile const uint32_t *)src;
+ } else if (align == 8) {
+ for (; len >= align; len -= align, dst += align, src += align)
+ *(uint64_t *)dst = *(volatile const uint64_t *)src;
+ }
+
+ /* residue */
+ for (; len > 0; --len, ++dst, ++src)
+ *dst = *src;
+}
+
void mmio_le_writeb(uint8_t val, void *addr)
{
mmio_writeb(cpu_to_le8(val), addr);
diff --git a/include/hwaccess_physmap.h b/include/hwaccess_physmap.h
index a0a7e74..c330eaf 100644
--- a/include/hwaccess_physmap.h
+++ b/include/hwaccess_physmap.h
@@ -31,6 +31,7 @@
uint16_t mmio_readw(const void *addr);
uint32_t mmio_readl(const void *addr);
void mmio_readn(const void *addr, uint8_t *buf, size_t len);
+void mmio_readn_aligned(const void *addr, uint8_t *dst, size_t len, size_t align);
void mmio_le_writeb(uint8_t val, void *addr);
void mmio_le_writew(uint16_t val, void *addr);
void mmio_le_writel(uint32_t val, void *addr);
@@ -56,4 +57,4 @@
void rmmio_valw(void *addr);
void rmmio_vall(void *addr);
-#endif /* __HWACCESS_PHYSMAP_H__ */
\ No newline at end of file
+#endif /* __HWACCESS_PHYSMAP_H__ */