// SPDX-License-Identifier: BSD-3-Clause // LittleFS freestanding configuration for Rumpk unikernel. // // Replaces lfs_util.h entirely via -DLFS_CONFIG=lfs_rumpk.h. // Provides minimal stubs using kernel-provided malloc/free/memcpy/memset. #ifndef LFS_RUMPK_H #define LFS_RUMPK_H #include #include #include #ifdef __cplusplus extern "C" { #endif // --- NULL (freestanding stddef.h may not always provide it) --- #ifndef NULL #define NULL ((void *)0) #endif // --- Logging: all disabled in freestanding kernel --- #define LFS_TRACE(...) #define LFS_DEBUG(...) #define LFS_WARN(...) #define LFS_ERROR(...) // --- Assertions: disabled --- #define LFS_ASSERT(test) ((void)(test)) // --- Memory functions (provided by clib.c / libc_shim.zig) --- extern void *malloc(unsigned long size); extern void free(void *ptr); extern void *memcpy(void *dest, const void *src, unsigned long n); extern void *memset(void *s, int c, unsigned long n); extern int memcmp(const void *s1, const void *s2, unsigned long n); extern unsigned long strlen(const char *s); // strchr — needed by lfs.c for path parsing static inline char *strchr(const char *s, int c) { while (*s) { if (*s == (char)c) return (char *)s; s++; } return (c == '\0') ? (char *)s : NULL; } static inline void *lfs_malloc(unsigned long size) { return malloc(size); } static inline void lfs_free(void *p) { free(p); } // --- Builtins --- static inline uint32_t lfs_max(uint32_t a, uint32_t b) { return (a > b) ? a : b; } static inline uint32_t lfs_min(uint32_t a, uint32_t b) { return (a < b) ? a : b; } static inline uint32_t lfs_aligndown(uint32_t a, uint32_t alignment) { return a - (a % alignment); } static inline uint32_t lfs_alignup(uint32_t a, uint32_t alignment) { return lfs_aligndown(a + alignment - 1, alignment); } static inline uint32_t lfs_npw2(uint32_t a) { #if defined(__GNUC__) || defined(__clang__) return 32 - __builtin_clz(a - 1); #else uint32_t r = 0, s; a -= 1; s = (a > 0xffff) << 4; a >>= s; r |= s; s = (a > 0xff ) << 3; a >>= s; r |= s; s = (a > 0xf ) << 2; a >>= s; r |= s; s = (a > 0x3 ) << 1; a >>= s; r |= s; return (r | (a >> 1)) + 1; #endif } static inline uint32_t lfs_ctz(uint32_t a) { #if defined(__GNUC__) || defined(__clang__) return __builtin_ctz(a); #else return lfs_npw2((a & -a) + 1) - 1; #endif } static inline uint32_t lfs_popc(uint32_t a) { #if defined(__GNUC__) || defined(__clang__) return __builtin_popcount(a); #else a = a - ((a >> 1) & 0x55555555); a = (a & 0x33333333) + ((a >> 2) & 0x33333333); return (((a + (a >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24; #endif } static inline int lfs_scmp(uint32_t a, uint32_t b) { return (int)(unsigned)(a - b); } // --- Endianness (RISC-V / ARM64 / x86_64 are all little-endian) --- static inline uint32_t lfs_fromle32(uint32_t a) { return a; } static inline uint32_t lfs_tole32(uint32_t a) { return a; } static inline uint32_t lfs_frombe32(uint32_t a) { return __builtin_bswap32(a); } static inline uint32_t lfs_tobe32(uint32_t a) { return __builtin_bswap32(a); } // --- CRC-32 (implementation in lfs.c) --- uint32_t lfs_crc(uint32_t crc, const void *buffer, unsigned long size); #ifdef __cplusplus } #endif #endif // LFS_RUMPK_H