aboutsummaryrefslogtreecommitdiff
path: root/include/apos/mem.h
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2022-05-29 16:23:41 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2022-05-29 16:23:41 +0300
commitd7cb08134102b7a2410c48d2a1802193f9031e00 (patch)
tree711498836d6679ca2fc3b4ba9369b7fe53d7a3fa /include/apos/mem.h
parente148f38dc937c34b222ba8df8612b3fa2b6bc349 (diff)
downloadkmi-d7cb08134102b7a2410c48d2a1802193f9031e00.tar.gz
kmi-d7cb08134102b7a2410c48d2a1802193f9031e00.zip
continue documentation efforts
Diffstat (limited to 'include/apos/mem.h')
-rw-r--r--include/apos/mem.h281
1 files changed, 242 insertions, 39 deletions
diff --git a/include/apos/mem.h b/include/apos/mem.h
index af0ac89..a0f32f5 100644
--- a/include/apos/mem.h
+++ b/include/apos/mem.h
@@ -9,82 +9,285 @@
#include <apos/utils.h>
#include <apos/types.h>
+/** Helper macro for getting bit width of \ref mm_info_t. */
#define MM_OINFO_WIDTH (sizeof(mm_info_t) * 8)
+/**
+ * Extract index of page order \c order from base page index \c pnum.
+ *
+ * @param pnum Base page order index.
+ * @param order Order page index to convert to.
+ * @return Index of page order \c order.
+ */
#define pnum_to_index(pnum, order) \
- (((pnum) >> __o_offset(order)) & (__o_width(order) - 1))
-#define pm_to_index(paddr, \
- order) (pnum_to_index(pm_to_pnum(paddr), (order)))
-#define pm_to_pnum(paddr) ((paddr) >> __mm_page_shift)
-#define pnum_to_paddr(pnum) ((pnum) << __mm_page_shift)
+ (((pnum) >> order_offset(order)) & (order_width(order) - 1))
-#define move_forward(var, num) (((var) += (num)) - (num))
+/**
+ * Convert physical memory address \c paddr to index of page order \c order.
+ *
+ * @param paddr Physical memory address.
+ * @param order Order page index to convert to.
+ * @return Index of page order \c order.
+ */
+#define pm_to_index(paddr, order) \
+ (pnum_to_index(pm_to_pnum(paddr), (order)))
-#define move_paddr(paddr, base, offset) ((((pm_t)(paddr)) - (base)) + (offset))
-#define num_elems(num) (((num) + MM_OINFO_WIDTH - 1) / \
- MM_OINFO_WIDTH)
-#define num_indexes(num) ((num) / MM_OINFO_WIDTH)
-#define index_elems(num) ((num) / MM_OINFO_WIDTH)
-#define state_elems(num) (sizeof(mm_info_t) * (num_elems(num)))
-#define next_elems(num) (sizeof(void *) * (num))
-#define max_index(order) (__o_width(order) - 1)
+/**
+ * Convert physical memory address \c paddr to corresponding page number.
+ *
+ * @param paddr Physical memory address.
+ * @return Corresponding page number.
+ */
+#define pm_to_pnum(paddr) ((paddr) >> __mm_page_shift)
-#define __o_offset(order) (__mm_shifts[order])
-#define __o_width(order) (__mm_widths[order])
-#define __o_size(order) (__mm_sizes[order])
-#define __o_elems(order) (__mm_widths[order] / MM_OINFO_WIDTH)
+/**
+ * Convert page number to physical address.
+ * Note that since a page number is the base page an address lies in,
+ * @code pnum_to_pm(pm_to_pnum(p)) != p @endcode
+ *
+ * @param pnum Page number.
+ * @return Corresponding physical address.
+ */
+#define pnum_to_pm(pnum) ((pnum) << __mm_page_shift)
+
+/**
+ * Add \c num to \c var and return value before addition.
+ *
+ * @param var Variable to add \c num to.
+ * @param num Number to add to \c var.
+ * @return Value of \c var before addition.
+ */
+#define move_forward(var, num) (((var) += (num)) - (num))
-#define __o_container(idx) ((idx) / MM_OINFO_WIDTH)
-#define __o_bit(idx) ((idx) & (MM_OINFO_WIDTH - 1))
+/**
+ * Helper for calculating highest index of elements in order info map.
+ * Since the number of entries is stored with the granularity of \c MM_OINFO_WIDTH,
+ * the highest index element is \c num rounded up to the nearest index multiple
+ * of \c MM_OINFO_WIDTH. This is due to some data access optimizations over in
+ * common/pmem.c.
+ *
+ * @param num Number of entries in map.
+ * @return Highest index of element in map.
+ */
+#define num_elems(num) \
+ (((num) + MM_OINFO_WIDTH - 1) / MM_OINFO_WIDTH)
+/**
+ * Helper for calculating starting index of element.
+ *
+ * @param num Number of starting entry.
+ * @return Index of starting element in which entry resides.
+ */
+#define num_indexes(num) ((num) / MM_OINFO_WIDTH)
+
+/**
+ * Helper for calculating index of element from entry number.
+ *
+ * @param num Entry number.
+ * @return Index of element in which entry resides.
+ */
+#define index_elems(num) ((num) / MM_OINFO_WIDTH)
+
+/**
+ * Helper for calculating size of state for storing elements in.
+ *
+ * @param num Number of entries.
+ * @return Size of element state buffer.
+ */
+#define state_elems(num) (sizeof(mm_info_t) * (num_elems(num)))
-#define __va(x) (void *)(((uintptr_t)(x)) + VM_DMAP - \
- RAM_BASE)
-#define __pa(x) (void *)(((uintptr_t)(x)) - VM_DMAP + \
- RAM_BASE)
-#define __page(x) ((x) / BASE_PAGE_SIZE)
-#define __addr(x) ((x)*BASE_PAGE_SIZE)
+/**
+ * Helper for calculating size of pointer buffer.
+ *
+ * @param num Number of entries.
+ * @return Size of pointer buffer.
+ */
+#define next_elems(num) (sizeof(void *) * (num))
+
+/**
+ * Get highest possible index in an order.
+ *
+ * @param order Order to query.
+ * @return Highest possible index in the order \c order.
+ */
+#define max_index(order) (order_width(order) - 1)
+
+/**
+ * Get starting offset of order bits in address.
+ *
+ * @param order Order to query.
+ * @return Starting offset of order bits.
+ */
+#define order_offset(order) (__mm_shifts[order])
+
+/**
+ * Get number of order bits in an address.
+ *
+ * @param order Order to query.
+ * @return Width in bits of order bits.
+ */
+#define order_width(order) (__mm_widths[order])
+
+/**
+ * Get size of order, as in how many pages of one order lower it can contain.
+ *
+ * @param order Order to query.
+ * @return Number of pages of one order lower this order can contain.
+ */
+#define order_size(order) (__mm_sizes[order])
+
+/**
+ * Get number of elements needed to represent this order.
+ *
+ * @param order Order to query.
+ * @return Number of elements needed to represent this order.
+ */
+#define order_elems(order) (__mm_widths[order] / MM_OINFO_WIDTH)
+
+/**
+ * Entry index to element index that contains the entry.
+ *
+ * @param idx Index of entry.
+ * @return Index of element.
+ */
+#define order_container(idx) ((idx) / MM_OINFO_WIDTH)
+
+/**
+ * Entry index within the element that contains it.
+ *
+ * @param idx Index of entry.
+ * @return Index of entry within its containing element.
+ */
+#define order_bit(idx) ((idx) & (MM_OINFO_WIDTH - 1))
+
+/**
+ * Convert physical address to virtual address in direct mapping.
+ *
+ * @param x Physical address.
+ * @return Corresponding virtual address.
+ */
+#define __va(x) (void *)(((uintptr_t)(x)) + VM_DMAP - RAM_BASE)
+
+/**
+ * Convert virtual address to physical address in direct mapping.
+ *
+ * @param x Virtual address.
+ * @return Corresponding physical address.
+ */
+#define __pa(x) (void *)(((uintptr_t)(x)) - VM_DMAP + RAM_BASE)
+
+/**
+ * Get page number of physical address.
+ *
+ * @todo Isn't this the same as \ref pnum_to_pm()?
+ *
+ * @param x Physical address.
+ * @return Corresponding page number.
+ */
+#define __page(x) ((x) / BASE_PAGE_SIZE)
+
+/**
+ * Get physical address of page number.
+ *
+ * @param x Page number.
+ * @return Corresponding physical address.
+ */
+#define __addr(x) ((x) * BASE_PAGE_SIZE)
+
+/**
+ * Convert bytes to number of base pages.
+ *
+ * @param x Number of bytes.
+ * @return Corresponding number of page pages.
+ */
#define __pages(x) \
(is_aligned((x), BASE_PAGE_SIZE) ? __page((x)) : \
__page((x) + BASE_PAGE_SIZE))
-#define __bytes(x) (__addr(x))
+
+/** @name Memory region flags. */
+/** @{ */
/** Memory region is used. */
-#define MR_USED (1 << 8)
+#define MR_USED (1 << 8)
/** Memory region is shared. */
-#define MR_SHARED (1 << 9)
+#define MR_SHARED (1 << 9)
/** Owner of shared region. */
-#define MR_OWNED (1 << 10)
+#define MR_OWNED (1 << 10)
/** Copy on write. */
-#define MR_COW (1 << 11)
+#define MR_COW (1 << 11)
/** Don't free memory on flush. */
-#define MR_KEEP (1 << 12)
+#define MR_KEEP (1 << 12)
+
+/** @} */
-extern size_t __mm_shifts[10];
-extern size_t __mm_widths[10];
-extern size_t __mm_sizes[10];
+/** Maximum number of page orders allowed. Likely massively overkill. */
+#define NUM_ORDERS 10
+
+/** Gives access to global page order shift information. \global */
+extern size_t __mm_shifts[NUM_ORDERS];
+
+/** Gives access to global page order width information. \global */
+extern size_t __mm_widths[NUM_ORDERS];
+/** Gives access to global page order size information. \global */
+extern size_t __mm_sizes[NUM_ORDERS];
+
+/** Gives access to global base page shift. \global */
extern size_t __mm_page_shift;
+
+/** Gives access to global maximum order size. \global */
extern size_t __mm_max_order;
-#define NUM_ORDERS 10
+/** Give names to page orders. */
enum mm_order {
+ /** Base order. */
MM_O0,
+
+ /** Order 1. */
MM_O1,
+
+ /** Order 2. */
MM_O2,
+
+ /** Order 3. */
MM_O3,
+
+ /** Order 4. */
MM_O4,
+
+ /** Order 5. */
MM_O5,
+
+ /** Order 6. */
MM_O6,
+
+ /** Order 7. */
MM_O7,
+
+ /** Order 8. */
MM_O8,
+
+ /** Order 9. */
MM_O9,
};
+/** Page number. */
typedef ssize_t pnum_t;
+
+/**
+ * Initialize memory subsystem data. Populates __mm_* with data given.
+ *
+ * @param max_order Maximum order the current system supports.
+ * @param shifts Offsets to start of each memory order in address.
+ * @param page_shift Width in bits of base page size.
+ * @todo Should likely also be stat_t?
+ */
void init_mem(size_t max_order, size_t shifts[10], size_t page_shift);
-enum mm_mode get_mmode(void *fdt);
-#define BASE_PAGE_SIZE (__o_size(BASE_PAGE))
-#define BASE_PAGE (MM_O0)
+
+/** Base page size. */
+#define BASE_PAGE_SIZE (order_size(BASE_PAGE))
+
+/** Base page order. */
+#define BASE_PAGE (MM_O0)
#endif /* APOS_MEM_H */