aboutsummaryrefslogtreecommitdiffstats
path: root/src/arch/riscv/include/bits/string.h
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2024-09-15 10:54:04 +0100
committerMichael Brown <mcb30@ipxe.org>2024-09-15 22:34:10 +0100
commitc215048ddaac75969c22c018871295a5748a47e8 (patch)
tree1e47dce485579135c16c130778a810aaeb912d9c /src/arch/riscv/include/bits/string.h
parent68db9a3cb3d73aae83ee4b7a0cbe9c69d7f32482 (diff)
downloadipxe-c215048ddaac75969c22c018871295a5748a47e8.tar.gz
[riscv] Add support for the RISC-V CPU architecture
Add support for building iPXE as a 64-bit or 32-bit RISC-V binary, for either UEFI or Linux userspace platforms. For example: # RISC-V 64-bit UEFI make CROSS=riscv64-linux-gnu- bin-riscv64-efi/ipxe.efi # RISC-V 32-bit UEFI make CROSS=riscv64-linux-gnu- bin-riscv32-efi/ipxe.efi # RISC-V 64-bit Linux make CROSS=riscv64-linux-gnu- bin-riscv64-linux/tests.linux qemu-riscv64 -L /usr/riscv64-linux-gnu/sys-root \ ./bin-riscv64-linux/tests.linux # RISC-V 32-bit Linux make CROSS=riscv64-linux-gnu- SYSROOT=/usr/riscv32-linux-gnu/sys-root \ bin-riscv32-linux/tests.linux qemu-riscv32 -L /usr/riscv32-linux-gnu/sys-root \ ./bin-riscv32-linux/tests.linux Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/arch/riscv/include/bits/string.h')
-rw-r--r--src/arch/riscv/include/bits/string.h89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/arch/riscv/include/bits/string.h b/src/arch/riscv/include/bits/string.h
new file mode 100644
index 000000000..3f78b351d
--- /dev/null
+++ b/src/arch/riscv/include/bits/string.h
@@ -0,0 +1,89 @@
+#ifndef _BITS_STRING_H
+#define _BITS_STRING_H
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+/** @file
+ *
+ * String functions
+ *
+ */
+
+extern void riscv_bzero ( void *dest, size_t len );
+extern void riscv_memset ( void *dest, size_t len, int character );
+extern void riscv_memcpy ( void *dest, const void *src, size_t len );
+extern void riscv_memmove_forwards ( void *dest, const void *src, size_t len );
+extern void riscv_memmove_backwards ( void *dest, const void *src, size_t len );
+extern void riscv_memmove ( void *dest, const void *src, size_t len );
+
+/**
+ * Fill memory region
+ *
+ * @v dest Destination region
+ * @v character Fill character
+ * @v len Length
+ * @ret dest Destination region
+ */
+static inline __attribute__ (( always_inline )) void *
+memset ( void *dest, int character, size_t len ) {
+
+ /* For zeroing larger or non-constant lengths, use the
+ * optimised variable-length zeroing code.
+ */
+ if ( __builtin_constant_p ( character ) && ( character == 0 ) ) {
+ riscv_bzero ( dest, len );
+ return dest;
+ }
+
+ /* Not necessarily zeroing: use basic variable-length code */
+ riscv_memset ( dest, len, character );
+ return dest;
+}
+
+/**
+ * Copy memory region
+ *
+ * @v dest Destination region
+ * @v src Source region
+ * @v len Length
+ * @ret dest Destination region
+ */
+static inline __attribute__ (( always_inline )) void *
+memcpy ( void *dest, const void *src, size_t len ) {
+
+ /* Otherwise, use variable-length code */
+ riscv_memcpy ( dest, src, len );
+ return dest;
+}
+
+/**
+ * Copy (possibly overlapping) memory region
+ *
+ * @v dest Destination region
+ * @v src Source region
+ * @v len Length
+ * @ret dest Destination region
+ */
+static inline __attribute__ (( always_inline )) void *
+memmove ( void *dest, const void *src, size_t len ) {
+ ssize_t offset = ( dest - src );
+
+ /* If required direction of copy is known at build time, then
+ * use the appropriate forwards/backwards copy directly.
+ */
+ if ( __builtin_constant_p ( offset ) ) {
+ if ( offset <= 0 ) {
+ riscv_memmove_forwards ( dest, src, len );
+ return dest;
+ } else {
+ riscv_memmove_backwards ( dest, src, len );
+ return dest;
+ }
+ }
+
+ /* Otherwise, use ambidirectional copy */
+ riscv_memmove ( dest, src, len );
+ return dest;
+}
+
+#endif /* _BITS_STRING_H */