aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/arch/mem.h21
-rw-r--r--include/arch/pmem.h3
-rw-r--r--include/kmi/assert.h14
-rw-r--r--include/kmi/mem.h8
-rw-r--r--include/kmi/utils.h245
5 files changed, 160 insertions, 131 deletions
diff --git a/include/arch/mem.h b/include/arch/mem.h
new file mode 100644
index 0000000..a70637c
--- /dev/null
+++ b/include/arch/mem.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: copyleft-next-0.3.1 */
+/* Copyright 2024, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */
+
+#ifndef KMI_ARCH_MEM_H
+#define KMI_ARCH_MEM_H
+
+/**
+ * @file mem.h
+ *
+ * Arch-specific stuff generic to all memory.
+ */
+
+#if defined(__riscv)
+# if __riscv_xlen == 64
+#include "../../arch/riscv64/include/pmem.h"
+# else
+#include "../../arch/riscv32/include/pmem.h"
+# endif
+#endif
+
+#endif /* KMI_ARCH_MEM_H */
diff --git a/include/arch/pmem.h b/include/arch/pmem.h
index 6a17449..9abbe8b 100644
--- a/include/arch/pmem.h
+++ b/include/arch/pmem.h
@@ -10,8 +10,8 @@
* arch/whatever/kernel/pmem.c
*/
-#include <kmi/mem.h> /* NUM_ORDERS */
#include <kmi/types.h>
+#include <kmi/mem.h> /* NUM_ORDERS */
#if defined(__riscv)
# if __riscv_xlen == 64
@@ -21,6 +21,7 @@
# endif
#endif
+
/**
* Get physical memory parameters.
*
diff --git a/include/kmi/assert.h b/include/kmi/assert.h
index 3120edc..ecf5272 100644
--- a/include/kmi/assert.h
+++ b/include/kmi/assert.h
@@ -30,13 +30,13 @@
*
* @param x Condition to check for.
*/
-#define assert(x) \
- do { \
- if (unlikely(!(x))) { \
- error("assertion failed: " QUOTE(x) "\n"); \
- while (1) { \
- } \
- } \
+#define assert(x) \
+ do { \
+ if (unlikely(!(x))) { \
+ error("assertion failed: " #x "\n"); \
+ while (1) { \
+ } \
+ } \
} while (0);
#else
diff --git a/include/kmi/mem.h b/include/kmi/mem.h
index bf55c61..e840683 100644
--- a/include/kmi/mem.h
+++ b/include/kmi/mem.h
@@ -11,6 +11,7 @@
#include <kmi/utils.h>
#include <kmi/types.h>
+#include <arch/mem.h>
/**
* Convert physical memory address \c paddr to index of page order \c order.
@@ -224,6 +225,7 @@ void set_ram_base(pm_t base);
/** @param size Set RAM size. */
void set_ram_size(size_t size);
+/** @param addr Set load address. */
void set_load_addr(pm_t addr);
/**
@@ -243,10 +245,14 @@ pm_t get_ram_base();
*/
size_t get_ram_size();
+/** @return Load address. */
pm_t get_load_addr();
-/** Base page size. */
+/** Base page size. Can be overridden by arch if we know it to be some constant
+ * value. */
+#ifndef BASE_PAGE_SIZE
#define BASE_PAGE_SIZE (order_size(BASE_PAGE))
+#endif
/** Base page order. */
#define BASE_PAGE (MM_O0)
diff --git a/include/kmi/utils.h b/include/kmi/utils.h
index 914d456..a37f4bb 100644
--- a/include/kmi/utils.h
+++ b/include/kmi/utils.h
@@ -4,6 +4,8 @@
#ifndef KMI_UTILS_H
#define KMI_UTILS_H
+#include <kmi/bits.h>
+
/**
* @file utils.h
* Misc utils and helpers.
@@ -238,269 +240,271 @@
/* clang-format doesn't like _Generic, but I guess that's fine.
* Uncrustify just ignores it, as far as I can tell. */
+
/**
- * Align value upwards.
+ * Align value downwards.
* Type is deduced from \c x.
*
- * @param x Value to align up.
+ * @param x Value to align.
* @param y Value to align to.
- * @return \c x aligned to \c y.
+ * @return \c x aligned to down \c y.
*/
-#define align_up(x, y) \
- _Generic((x), signed char \
- : align_up_c, signed short \
- : align_up_s, signed int \
- : align_up_i, signed long \
- : align_up_l, signed long long \
- : align_up_ll, \
- \
- unsigned char \
- : align_up_uc, unsigned short \
- : align_up_us, unsigned int \
- : align_up_ui, unsigned long \
- : align_up_ul, unsigned long long \
- : align_up_ull)((x), (y))
+#define align_down(x, y) \
+ _Generic((x), signed char \
+ : align_down_c, signed short \
+ : align_down_s, signed int \
+ : align_down_i, signed long \
+ : align_down_l, signed long long \
+ : align_down_ll, \
+ \
+ unsigned char \
+ : align_down_uc, unsigned short \
+ : align_down_us, unsigned int \
+ : align_down_ui, unsigned long \
+ : align_down_ul, unsigned long long \
+ : align_down_ull)((x), (y))
/**
* Helper macro for defining type specific aligning.
+ * Treats 0 as if it was 1, i.e. returns the value as it is.
*
* @param name Name of type in function name.
* @param type Actual type.
*/
-#define DEFINE_ALIGN_UP(name, type) \
- static inline type align_up_##name(type val, type a) \
- { \
- if (!a) { \
- return val; \
- } \
- \
- type rem = val % a; \
- \
- if (rem == 0) { \
- return val; \
- } \
- \
- return val + a - rem; \
+#define DEFINE_ALIGN_DOWN(name, type) \
+ static inline type align_down_##name(type val, type a) \
+ { \
+ if (a == 0) { \
+ return val; \
+ } \
+ \
+ /* a branch is likely a bit faster than a rem */ \
+ if (likely(is_powerof2(a))) { \
+ return val & ~(a - 1); \
+ } \
+ \
+ return val - (val % a); \
}
/**
- * Align signed char up.
+ * Align signed char down.
*
* @param val Value to align.
* @param a Value to align to.
- * @return \c val aligned up to nearest multiple of \c a.
+ * @return \c val aligned down to nearest multiple of \c a.
*/
-DEFINE_ALIGN_UP(c, signed char);
+DEFINE_ALIGN_DOWN(c, signed char);
/**
- * Align signed short up.
+ * Align signed short down.
*
* @param val Value to align.
* @param a Value to align to.
- * @return \c val aligned up to nearest multiple of \c a.
+ * @return \c val aligned down to nearest multiple of \c a.
*/
-DEFINE_ALIGN_UP(s, signed short);
+DEFINE_ALIGN_DOWN(s, signed short);
/**
- * Align signed int up.
+ * Align signed int down.
*
* @param val Value to align.
* @param a Value to align to.
- * @return \c val aligned up to nearest multiple of \c a.
+ * @return \c val aligned down to nearest multiple of \c a.
*/
-DEFINE_ALIGN_UP(i, signed int);
+DEFINE_ALIGN_DOWN(i, signed int);
/**
- * Align signed long up.
+ * Align signed long down.
*
* @param val Value to align.
* @param a Value to align to.
- * @return \c val aligned up to nearest multiple of \c a.
+ * @return \c val aligned down to nearest multiple of \c a.
*/
-DEFINE_ALIGN_UP(l, signed long);
+DEFINE_ALIGN_DOWN(l, signed long);
/**
- * Align signed long long up.
+ * Align signed long long down.
*
* @param val Value to align.
* @param a Value to align to.
- * @return \c val aligned up to nearest multiple of \c a.
+ * @return \c val aligned down to nearest multiple of \c a.
*/
-DEFINE_ALIGN_UP(ll, signed long long);
+DEFINE_ALIGN_DOWN(ll, signed long long);
/**
- * Align unsigned char up.
+ * Align unsigned char down.
*
* @param val Value to align.
* @param a Value to align to.
- * @return \c val aligned up to nearest multiple of \c a.
+ * @return \c val aligned down to nearest multiple of \c a.
*/
-DEFINE_ALIGN_UP(uc, unsigned char);
+DEFINE_ALIGN_DOWN(uc, unsigned char);
/**
- * Align unsigned short up.
+ * Align unsigned short down.
*
* @param val Value to align.
* @param a Value to align to.
- * @return \c val aligned up to nearest multiple of \c a.
+ * @return \c val aligned down to nearest multiple of \c a.
*/
-DEFINE_ALIGN_UP(us, unsigned short);
+DEFINE_ALIGN_DOWN(us, unsigned short);
/**
- * Align unsigned int up.
+ * Align unsigned int down.
*
* @param val Value to align.
* @param a Value to align to.
- * @return \c val aligned up to nearest multiple of \c a.
+ * @return \c val aligned down to nearest multiple of \c a.
*/
-DEFINE_ALIGN_UP(ui, unsigned int);
+DEFINE_ALIGN_DOWN(ui, unsigned int);
/**
- * Align unsigned long up.
+ * Align unsigned long down.
*
* @param val Value to align.
* @param a Value to align to.
- * @return \c val aligned up to nearest multiple of \c a.
+ * @return \c val aligned down to nearest multiple of \c a.
*/
-DEFINE_ALIGN_UP(ul, unsigned long);
+DEFINE_ALIGN_DOWN(ul, unsigned long);
/**
- * Align unsigned long long up.
+ * Align unsigned long long down.
*
* @param val Value to align.
* @param a Value to align to.
- * @return \c val aligned up to nearest multiple of \c a.
+ * @return \c val aligned down to nearest multiple of \c a.
*/
-DEFINE_ALIGN_UP(ull, unsigned long long);
-
+DEFINE_ALIGN_DOWN(ull, unsigned long long);
/**
- * Align value downwards.
+ * Align value upwards.
* Type is deduced from \c x.
*
- * @param x Value to align.
+ * @param x Value to align up.
* @param y Value to align to.
- * @return \c x aligned to down \c y.
+ * @return \c x aligned to \c y.
*/
-#define align_down(x, y) \
- _Generic((x), signed char \
- : align_down_c, signed short \
- : align_down_s, signed int \
- : align_down_i, signed long \
- : align_down_l, signed long long \
- : align_down_ll, \
- \
- unsigned char \
- : align_down_uc, unsigned short \
- : align_down_us, unsigned int \
- : align_down_ui, unsigned long \
- : align_down_ul, unsigned long long \
- : align_down_ull)((x), (y))
+#define align_up(x, y) \
+ _Generic((x), signed char \
+ : align_up_c, signed short \
+ : align_up_s, signed int \
+ : align_up_i, signed long \
+ : align_up_l, signed long long \
+ : align_up_ll, \
+ \
+ unsigned char \
+ : align_up_uc, unsigned short \
+ : align_up_us, unsigned int \
+ : align_up_ui, unsigned long \
+ : align_up_ul, unsigned long long \
+ : align_up_ull)((x), (y))
/**
* Helper macro for defining type specific aligning.
+ * Treats 0 as 1, i.e. lowest possible alignment.
*
* @param name Name of type in function name.
* @param type Actual type.
*/
-#define DEFINE_ALIGN_DOWN(name, type) \
- static inline type align_down_##name(type val, type a) \
- { \
- if (!a) { \
- return val; \
- } \
- \
- return val - (val % a); \
+#define DEFINE_ALIGN_UP(name, type) \
+ static inline type align_up_##name(type val, type a) \
+ { \
+ type new = align_down(val, a); \
+ if (new == val) { \
+ return val; \
+ } \
+ \
+ return new + a; \
}
/**
- * Align signed char down.
+ * Align signed char up.
*
* @param val Value to align.
* @param a Value to align to.
- * @return \c val aligned down to nearest multiple of \c a.
+ * @return \c val aligned up to nearest multiple of \c a.
*/
-DEFINE_ALIGN_DOWN(c, signed char);
+DEFINE_ALIGN_UP(c, signed char);
/**
- * Align signed short down.
+ * Align signed short up.
*
* @param val Value to align.
* @param a Value to align to.
- * @return \c val aligned down to nearest multiple of \c a.
+ * @return \c val aligned up to nearest multiple of \c a.
*/
-DEFINE_ALIGN_DOWN(s, signed short);
+DEFINE_ALIGN_UP(s, signed short);
/**
- * Align signed int down.
+ * Align signed int up.
*
* @param val Value to align.
* @param a Value to align to.
- * @return \c val aligned down to nearest multiple of \c a.
+ * @return \c val aligned up to nearest multiple of \c a.
*/
-DEFINE_ALIGN_DOWN(i, signed int);
+DEFINE_ALIGN_UP(i, signed int);
/**
- * Align signed long down.
+ * Align signed long up.
*
* @param val Value to align.
* @param a Value to align to.
- * @return \c val aligned down to nearest multiple of \c a.
+ * @return \c val aligned up to nearest multiple of \c a.
*/
-DEFINE_ALIGN_DOWN(l, signed long);
+DEFINE_ALIGN_UP(l, signed long);
/**
- * Align signed long long down.
+ * Align signed long long up.
*
* @param val Value to align.
* @param a Value to align to.
- * @return \c val aligned down to nearest multiple of \c a.
+ * @return \c val aligned up to nearest multiple of \c a.
*/
-DEFINE_ALIGN_DOWN(ll, signed long long);
+DEFINE_ALIGN_UP(ll, signed long long);
/**
- * Align unsigned char down.
+ * Align unsigned char up.
*
* @param val Value to align.
* @param a Value to align to.
- * @return \c val aligned down to nearest multiple of \c a.
+ * @return \c val aligned up to nearest multiple of \c a.
*/
-DEFINE_ALIGN_DOWN(uc, unsigned char);
+DEFINE_ALIGN_UP(uc, unsigned char);
/**
- * Align unsigned short down.
+ * Align unsigned short up.
*
* @param val Value to align.
* @param a Value to align to.
- * @return \c val aligned down to nearest multiple of \c a.
+ * @return \c val aligned up to nearest multiple of \c a.
*/
-DEFINE_ALIGN_DOWN(us, unsigned short);
+DEFINE_ALIGN_UP(us, unsigned short);
/**
- * Align unsigned int down.
+ * Align unsigned int up.
*
* @param val Value to align.
* @param a Value to align to.
- * @return \c val aligned down to nearest multiple of \c a.
+ * @return \c val aligned up to nearest multiple of \c a.
*/
-DEFINE_ALIGN_DOWN(ui, unsigned int);
+DEFINE_ALIGN_UP(ui, unsigned int);
/**
- * Align unsigned long down.
+ * Align unsigned long up.
*
* @param val Value to align.
* @param a Value to align to.
- * @return \c val aligned down to nearest multiple of \c a.
+ * @return \c val aligned up to nearest multiple of \c a.
*/
-DEFINE_ALIGN_DOWN(ul, unsigned long);
+DEFINE_ALIGN_UP(ul, unsigned long);
/**
- * Align unsigned long long down.
+ * Align unsigned long long up.
*
* @param val Value to align.
* @param a Value to align to.
- * @return \c val aligned down to nearest multiple of \c a.
+ * @return \c val aligned up to nearest multiple of \c a.
*/
-DEFINE_ALIGN_DOWN(ull, unsigned long long);
+DEFINE_ALIGN_UP(ull, unsigned long long);
/**
* Check if value is aligned.
@@ -533,11 +537,8 @@ DEFINE_ALIGN_DOWN(ull, unsigned long long);
#define DEFINE_ALIGNED(name, type) \
static inline bool is_aligned_##name(type val, type a) \
{ \
- if (!a) { \
- return true; \
- } \
- \
- return val % a == 0; \
+ type new = align_down(val, a); \
+ return new == val; \
}
/**