aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO.txt1
-rw-r--r--arch/riscv/common/vmem.c51
-rw-r--r--arch/riscv/conf/init-link.S2
-rw-r--r--arch/riscv/conf/kernel-link.S2
-rw-r--r--arch/riscv/config.h2
-rw-r--r--arch/riscv/include/csr.h18
-rw-r--r--arch/riscv/include/pages.h6
-rw-r--r--arch/riscv/include/vmap.h15
-rw-r--r--arch/riscv/include/vmem.h29
-rw-r--r--arch/riscv/init/init.c135
-rw-r--r--arch/riscv/kernel/main.c13
-rw-r--r--arch/riscv/source.mk4
-rw-r--r--common/mem.c40
-rw-r--r--common/pmem.c165
-rw-r--r--include/apos/mem.h126
-rw-r--r--include/apos/pmem.h1
16 files changed, 369 insertions, 241 deletions
diff --git a/TODO.txt b/TODO.txt
index 012fba9..5176f0a 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -12,3 +12,4 @@
init from vmem when jumping to vmem
+ Figure out best way to tell the init how large out kernel is
+ Make code more robust, error checking etc
++ Make all physical memory addresses use the same typedef
diff --git a/arch/riscv/common/vmem.c b/arch/riscv/common/vmem.c
new file mode 100644
index 0000000..17db777
--- /dev/null
+++ b/arch/riscv/common/vmem.c
@@ -0,0 +1,51 @@
+#include <apos/string.h>
+#include <apos/pmem.h>
+#include <pages.h>
+#include <vmem.h>
+
+extern const size_t mm_shifts[10];
+extern const size_t mm_widths[10];
+extern const size_t mm_sizes[10];
+
+#define pte_ppn(pte) (((paddr_t)(pte)) >> 10)
+#define pte_flags(pte) (((paddr_t)(pte)) & 0xff)
+#define to_pte(p, f) ((paddr_to_pnum(p) << 10) + (f))
+#define pte_addr(pte) (pnum_to_paddr(pte_ppn(pte)))
+
+/* probably not actually this simple, right? */
+void map_vmem(struct vm_branch_t *branch,
+ paddr_t paddr, vaddr_t vaddr,
+ uint8_t flags, enum mm_order_t order)
+{
+ enum mm_order_t top = MAX_ORDER;
+ while(top != order){
+ size_t idx = paddr_to_index(vaddr, top);
+
+ if(!branch->leaf[idx]){
+ paddr_t new_leaf = alloc_page(MM_KPAGE, 0);
+ branch->leaf[idx] = (struct vm_branch_t *)to_pte(new_leaf, VM_V);
+ memset((void *)new_leaf, 0, sizeof(struct vm_branch_t));
+ }
+
+ branch = (struct vm_branch_t *)pte_addr(branch->leaf[idx]);
+ top--;
+ }
+
+ size_t idx = paddr_to_index(vaddr, top);
+ branch->leaf[idx] = (struct vm_branch_t *)to_pte(paddr, flags);
+}
+
+void unmap_vmem(struct vm_branch_t *branch,
+ vaddr_t vaddr, enum mm_order_t order)
+{
+ while(order){
+ size_t idx = paddr_to_index(vaddr, order);
+ branch = (struct vm_branch_t *)pte_addr(branch->leaf[idx]);
+ }
+
+ size_t idx = paddr_to_index(vaddr, order);
+ if(branch->leaf[idx])
+ free_page(order, pte_addr(branch->leaf[idx]));
+
+ branch->leaf[idx] = 0;
+}
diff --git a/arch/riscv/conf/init-link.S b/arch/riscv/conf/init-link.S
index 86e692e..c9a6da2 100644
--- a/arch/riscv/conf/init-link.S
+++ b/arch/riscv/conf/init-link.S
@@ -1,5 +1,3 @@
-#include <vmap.h>
-
OUTPUT_ARCH(riscv)
ENTRY(_start)
diff --git a/arch/riscv/conf/kernel-link.S b/arch/riscv/conf/kernel-link.S
index 1ccdc77..d3b1223 100644
--- a/arch/riscv/conf/kernel-link.S
+++ b/arch/riscv/conf/kernel-link.S
@@ -1,5 +1,3 @@
-#include <vmap.h>
-
OUTPUT_ARCH(riscv)
ENTRY(main)
diff --git a/arch/riscv/config.h b/arch/riscv/config.h
index 9db8d8f..13e166b 100644
--- a/arch/riscv/config.h
+++ b/arch/riscv/config.h
@@ -2,7 +2,7 @@
#define PM_KERN 0x83800000
#define PM_STACK_BASE (PM_KERN + SZ_2M)
#define PM_STACK_TOP (PM_STACK_BASE + SZ_2M - 2)
-#define VM_KERN ((-1) - SZ_1G)
+#define VM_KERN ((-1) - SZ_1G + 1)
#define MAX_ORDER 3
#define PAGE_SHIFT 12
diff --git a/arch/riscv/include/csr.h b/arch/riscv/include/csr.h
index 694000b..5da0882 100644
--- a/arch/riscv/include/csr.h
+++ b/arch/riscv/include/csr.h
@@ -1,8 +1,22 @@
#ifndef APOS_CSR_H
#define APOS_CSR_H
-#define csr_write(csr, val)
-
#define SATP_MODE_39 0x8000000000000000
+#define SATP_MODE_48 0x9000000000000000
+
+#define CSR_SATP 0x180
+
+/* directly lifted from Linux:/arch/riscv/include/asm/asm.h:9-13 */
+#ifdef __ASSEMBLY__
+#define __ASM_STR(x) x
+#else
+#define __ASM_STR(x) #x
+#endif
+
+#define csr_read(csr, res)\
+ __asm__ ("csrr %0, " __ASM_STR(csr) : "=r" (res) : : "memory")
+
+#define csr_write(csr, val)\
+ __asm__ ("csrw " __ASM_STR(csr) ", %0" : : "rK" (val) : "memory")
#endif /* APOS_CSR_H */
diff --git a/arch/riscv/include/pages.h b/arch/riscv/include/pages.h
index 82ce6c7..8ca396a 100644
--- a/arch/riscv/include/pages.h
+++ b/arch/riscv/include/pages.h
@@ -2,10 +2,6 @@
#define APOS_RISCV_PAGES_H
#include <apos/types.h>
-#include <apos/pmem.h>
-
-/* assume riscv64 for now */
-typedef uint64_t pm_t;
#define MM_KPAGE MM_O0
#define MM_MPAGE MM_O1
@@ -17,4 +13,6 @@ typedef uint64_t pm_t;
#define MM_GPAGE_SIZE SZ_1G
#define MM_TPAGE_SIZE SZ_512G
+typedef uint64_t paddr_t;
+
#endif /* APOS_RISCV_PAGES_H */
diff --git a/arch/riscv/include/vmap.h b/arch/riscv/include/vmap.h
deleted file mode 100644
index aee3725..0000000
--- a/arch/riscv/include/vmap.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef APOS_RISCV_VMAP_H
-#define APOS_RISCV_VMAP_H
-
-#include <apos/sizes.h>
-
-#define VM_V (1 << 0)
-#define VM_R (1 << 1)
-#define VM_W (1 << 2)
-#define VM_X (1 << 3)
-#define VM_U (1 << 4)
-#define VM_G (1 << 5)
-#define VM_A (1 << 6)
-#define VM_D (1 << 7)
-
-#endif /* APOS_RISCV_VMAP_H */
diff --git a/arch/riscv/include/vmem.h b/arch/riscv/include/vmem.h
new file mode 100644
index 0000000..3c27c7b
--- /dev/null
+++ b/arch/riscv/include/vmem.h
@@ -0,0 +1,29 @@
+#ifndef APOS_RISCV_VMAP_H
+#define APOS_RISCV_VMAP_H
+
+#include <apos/sizes.h>
+#include <apos/types.h>
+#include <apos/attrs.h>
+
+#define VM_V (1 << 0)
+#define VM_R (1 << 1)
+#define VM_W (1 << 2)
+#define VM_X (1 << 3)
+#define VM_U (1 << 4)
+#define VM_G (1 << 5)
+#define VM_A (1 << 6)
+#define VM_D (1 << 7)
+
+typedef size_t vaddr_t;
+struct __packed vm_branch_t {
+ struct vm_branch_t *leaf[512];
+};
+
+void map_vmem(struct vm_branch_t *branch,
+ paddr_t paddr, vaddr_t vaddr,
+ uint8_t flags, enum mm_order_t order);
+
+void unmap_vmem(struct vm_branch_t *branch, vaddr_t vaddr, enum mm_order_t order);
+
+
+#endif /* APOS_RISCV_VMAP_H */
diff --git a/arch/riscv/init/init.c b/arch/riscv/init/init.c
index ca04bcd..1e04d34 100644
--- a/arch/riscv/init/init.c
+++ b/arch/riscv/init/init.c
@@ -7,12 +7,12 @@
#include <apos/utils.h>
#include <libfdt.h>
#include <pages.h>
+#include <vmem.h>
#include <csr.h>
-#include <vmap.h>
struct pmem_layout {
- pm_t base;
- pm_t top;
+ paddr_t base;
+ paddr_t top;
};
struct cell_info {
@@ -55,7 +55,7 @@ static struct pmem_layout get_memlayout(void *fdt)
/* if riscv128 comes around we will probably see addr_cells == 4, but
* I'm not too concerned about it at the moment */
- pm_t base = (pm_t)fdt_load_int_ptr(ci.addr_cells, mem_reg);
+ paddr_t base = (paddr_t)fdt_load_int_ptr(ci.addr_cells, mem_reg);
if(ci.addr_cells == 2)
mem_reg += sizeof(fdt64_t);
@@ -63,7 +63,7 @@ static struct pmem_layout get_memlayout(void *fdt)
mem_reg += sizeof(fdt32_t);
/* -1 because base is a legitimate memory address */
- pm_t top = (pm_t)fdt_load_int_ptr(ci.size_cells, mem_reg) + base - 1;
+ paddr_t top = (paddr_t)fdt_load_int_ptr(ci.size_cells, mem_reg) + base - 1;
return (struct pmem_layout){base, top};
}
@@ -79,6 +79,7 @@ static enum serial_dev_t serial_dev_enum(const char *dev_name)
return -1;
}
+static void* uart_ptr_glbl = 0;
static void init_debug(void *fdt)
{
int chosen_offset = fdt_path_offset(fdt, "/chosen");
@@ -98,7 +99,8 @@ static void init_debug(void *fdt)
void *reg_ptr = (void *)fdt_getprop(fdt, stdout_offset, "reg", NULL);
void *uart_ptr = 0;
- uart_ptr = (void *)(pm_t)fdt_load_int_ptr(ci.addr_cells, reg_ptr);
+ uart_ptr = (void *)(paddr_t)fdt_load_int_ptr(ci.addr_cells, reg_ptr);
+ uart_ptr_glbl = uart_ptr;
dbg_init(uart_ptr, dev);
}
@@ -107,16 +109,16 @@ static void init_debug(void *fdt)
#define init_debug(...)
#endif
-static pm_t get_kerneltop()
+static paddr_t get_kerneltop()
{
/* interesting, for some reason if I define these to be just char
* pointers I get some wacky values. Not sure why that would be, but
* this works. */
extern char __init_end, __kernel_size;
- return (pm_t)&__init_end + (pm_t)&__kernel_size;
+ return (paddr_t)&__init_end + (paddr_t)&__kernel_size;
}
-static pm_t get_initrdtop(void *fdt)
+static paddr_t get_initrdtop(void *fdt)
{
int chosen_offset = fdt_path_offset(fdt, "/chosen");
struct cell_info ci = get_cellinfo(fdt, chosen_offset);
@@ -124,10 +126,10 @@ static pm_t get_initrdtop(void *fdt)
void *initrd_end_ptr = (void *)fdt_getprop(fdt, chosen_offset,
"linux,initrd-end", NULL);
- return (pm_t)fdt_load_int_ptr(ci.addr_cells, initrd_end_ptr);
+ return (paddr_t)fdt_load_int_ptr(ci.addr_cells, initrd_end_ptr);
}
-static pm_t get_initrdbase(void *fdt)
+static paddr_t get_initrdbase(void *fdt)
{
int chosen_offset = fdt_path_offset(fdt, "/chosen");
struct cell_info ci = get_cellinfo(fdt, chosen_offset);
@@ -135,43 +137,26 @@ static pm_t get_initrdbase(void *fdt)
void *initrd_base_ptr = (void *)fdt_getprop(fdt, chosen_offset,
"linux,initrd-start", NULL);
- return (pm_t)fdt_load_int_ptr(ci.addr_cells, initrd_base_ptr);
+ return (paddr_t)fdt_load_int_ptr(ci.addr_cells, initrd_base_ptr);
}
-static pm_t get_fdttop(void *fdt)
+static paddr_t get_fdttop(void *fdt)
{
const char *b = (const char *)fdt;
- return (pm_t)(b + fdt_totalsize(fdt));
+ return (paddr_t)(b + fdt_totalsize(fdt));
}
-static pm_t get_fdtbase(void *fdt)
+static paddr_t get_fdtbase(void *fdt)
{
/* lol */
- return (pm_t)fdt;
+ return (paddr_t)fdt;
}
-static void mark_area_used(pm_t base, pm_t top)
+static void mark_area_used(paddr_t base, paddr_t top)
{
size_t area_left = top - base;
- while(area_left >= MM_TPAGE_SIZE){
- mark_used(MM_TPAGE, base);
- area_left -= MM_TPAGE_SIZE;
- base += MM_TPAGE_SIZE;
- }
-
- while(area_left >= MM_GPAGE_SIZE){
- mark_used(MM_GPAGE, base);
- area_left -= MM_GPAGE_SIZE;
- base += MM_GPAGE_SIZE;
- }
-
- while(area_left >= MM_MPAGE_SIZE){
- mark_used(MM_MPAGE, base);
- area_left -= MM_MPAGE_SIZE;
- base += MM_MPAGE_SIZE;
- }
-
-
+ /* TODO: add in a method to make sure that we use as large mappings as
+ * possible. */
while(area_left >= MM_KPAGE_SIZE){
mark_used(base, MM_KPAGE);
area_left -= MM_KPAGE_SIZE;
@@ -182,15 +167,32 @@ static void mark_area_used(pm_t base, pm_t top)
mark_used(base, MM_KPAGE_SIZE);
}
+static void mark_reserved_mem(void *fdt)
+{
+ int rmem_offset = fdt_path_offset(fdt, "/reserved-memory/mmode_resv0");
+ struct cell_info ci = get_reginfo(fdt, "/reserved-memory/mmode_resv0");
+ uint8_t *rmem_reg = (uint8_t *)fdt_getprop(fdt, rmem_offset, "reg", NULL);
+
+ paddr_t base = (paddr_t)fdt_load_int_ptr(ci.addr_cells, rmem_reg);
+
+ if(ci.addr_cells == 2)
+ rmem_reg += sizeof(fdt64_t);
+ else
+ rmem_reg += sizeof(fdt32_t);
+
+ paddr_t top = (paddr_t)fdt_load_int_ptr(ci.size_cells, rmem_reg) + base - 1;
+ mark_area_used(base, top);
+}
+
static void setup_pmem(void *fdt)
{
struct pmem_layout pmem = get_memlayout(fdt);
- pm_t initrd_top = get_initrdtop(fdt);
- pm_t kernel_top = get_kerneltop();
- pm_t fdt_top = get_fdttop(fdt);
+ paddr_t initrd_top = get_initrdtop(fdt);
+ paddr_t kernel_top = get_kerneltop();
+ paddr_t fdt_top = get_fdttop(fdt);
- pm_t top = MAX3(kernel_top, initrd_top, fdt_top);
+ paddr_t top = MAX3(kernel_top, initrd_top, fdt_top);
dbg("initrd_top:\t%#lx\n", initrd_top);
dbg("kernel_top:\t%#lx\n", kernel_top);
dbg("fdt_top:\t%#lx\n", fdt_top);
@@ -200,7 +202,7 @@ static void setup_pmem(void *fdt)
size_t probe_size = probe_pmap(pmem.base, pmem.top - pmem.base);
/* riscv handles two byte boundaries better than one byte, so align
* upwards */
- pm_t pmap_base = align_up(top + 1, 2);
+ paddr_t pmap_base = align_up(top + 1, 2);
size_t actual_size = populate_pmap(pmem.base, pmem.top - pmem.base,
pmap_base);
@@ -223,6 +225,51 @@ static void setup_pmem(void *fdt)
/* mark pmap */
mark_area_used(pmap_base, pmap_base + actual_size);
+
+ /* mark reserved mem */
+ mark_reserved_mem(fdt);
+}
+
+paddr_t move_kernel()
+{
+ extern char __init_end, __kernel_size;
+ paddr_t dst = alloc_page(MM_MPAGE, 0);
+ memmove((void *)dst, &__init_end, (size_t)&__kernel_size);
+
+ return dst;
+}
+
+struct vm_branch_t *prepare_vmem()
+{
+ paddr_t kernel_dst = move_kernel();
+
+ /* TODO: check if this actually works */
+ struct vm_branch_t *branch = (struct vm_branch_t *)alloc_page(MM_KPAGE, 0);
+ memset(branch, 0, sizeof(struct vm_branch_t));
+
+ /* TODO: check mapping flags, also iron out possible bugs etc in
+ * map_vmem */
+ /* map kernel */
+ map_vmem(branch, kernel_dst, VM_KERN, VM_R | VM_W | VM_G | VM_X | VM_V, MM_MPAGE);
+
+ /* map init */
+ map_vmem(branch, PM_KERN, PM_KERN, VM_R | VM_W | VM_X | VM_V, MM_MPAGE);
+
+ /* map stack */
+ map_vmem(branch, PM_STACK_BASE, PM_STACK_BASE, VM_R | VM_W | VM_V, MM_MPAGE);
+
+ /* map debug VERY UGLY GLOBALS BAH */
+ map_vmem(branch, (paddr_t)uart_ptr_glbl, (paddr_t)uart_ptr_glbl, VM_R | VM_W | VM_V, MM_KPAGE);
+
+ /* TODO: map more stuff */
+
+ return branch;
+}
+
+void start_vmem(struct vm_branch_t *branch)
+{
+ /* assume Sv48 and ASID 0*/
+ csr_write(CSR_SATP, SATP_MODE_48 | (((paddr_t)(branch)) >> 12));
}
void init(void *fdt)
@@ -231,6 +278,10 @@ void init(void *fdt)
dbg_fdt(fdt);
setup_pmem(fdt);
+ struct vm_branch_t *branch = prepare_vmem();
+ start_vmem(branch);
+
/* update_pmap(TODO: figure out where to place pmap in vmem); */
- /* TODO: jump to kernel */
+ void (*main)(void *uart) = (void (*)(void *))VM_KERN;
+ main(uart_ptr_glbl);
}
diff --git a/arch/riscv/kernel/main.c b/arch/riscv/kernel/main.c
index 9334fb3..510ea42 100644
--- a/arch/riscv/kernel/main.c
+++ b/arch/riscv/kernel/main.c
@@ -1,13 +1,8 @@
-#include <pages.h>
#include <apos/main.h>
+#include <apos/debug.h>
-void yeet()
+void __main main(void *uart)
{
- int a = 23;
-}
-
-void __main main(struct mm_ptinfo *pageinfo)
-{
- yeet();
- while(1){};
+ dbg_init(uart, NS16550A);
+ dbg("Hello from (hopefully) virtual memory!\n");
}
diff --git a/arch/riscv/source.mk b/arch/riscv/source.mk
index 2d79625..4733efa 100644
--- a/arch/riscv/source.mk
+++ b/arch/riscv/source.mk
@@ -1,7 +1,7 @@
-KERNEL_LOCAL != echo arch/riscv/kernel/*.[cS]
+KERNEL_LOCAL != echo arch/riscv/kernel/*.[cS] arch/riscv/common/*.[cS]
KERNEL_SOURCES += $(KERNEL_LOCAL)
-INIT_LOCAL != echo arch/riscv/init/*.[cS]
+INIT_LOCAL != echo arch/riscv/init/*.[cS] arch/riscv/common/*.[cS]
INIT_FDT != echo lib/fdt*.c
INIT_SOURCES += $(INIT_LOCAL) $(INIT_FDT)
diff --git a/common/mem.c b/common/mem.c
new file mode 100644
index 0000000..420f6f4
--- /dev/null
+++ b/common/mem.c
@@ -0,0 +1,40 @@
+#include <apos/types.h>
+#include <apos/mem.h>
+
+const size_t mm_shifts[10] = {
+ MM_O0_SHIFT,
+ MM_O1_SHIFT,
+ MM_O2_SHIFT,
+ MM_O3_SHIFT,
+ MM_O4_SHIFT,
+ MM_O6_SHIFT,
+ MM_O7_SHIFT,
+ MM_O8_SHIFT,
+ MM_O9_SHIFT,
+};
+
+const size_t mm_widths[10] = {
+ MM_O0_WIDTH,
+ MM_O1_WIDTH,
+ MM_O2_WIDTH,
+ MM_O3_WIDTH,
+ MM_O4_WIDTH,
+ MM_O5_WIDTH,
+ MM_O6_WIDTH,
+ MM_O7_WIDTH,
+ MM_O8_WIDTH,
+ MM_O9_WIDTH,
+};
+
+const size_t mm_sizes[10] = {
+ MM_O0_SIZE,
+ MM_O1_SIZE,
+ MM_O2_SIZE,
+ MM_O3_SIZE,
+ MM_O4_SIZE,
+ MM_O5_SIZE,
+ MM_O6_SIZE,
+ MM_O7_SIZE,
+ MM_O8_SIZE,
+ MM_O9_SIZE,
+};
diff --git a/common/pmem.c b/common/pmem.c
index ff19c95..68632ae 100644
--- a/common/pmem.c
+++ b/common/pmem.c
@@ -3,131 +3,6 @@
#include <apos/bits.h> /* __is_nset etc */
/* NOTE: these are all for pnum_t, i.e. O0_SHIFT is from 0 */
-#if defined(O0_WIDTH)
-#define MM_O0_SHIFT (0)
-#define MM_O0_WIDTH (1UL << (O0_WIDTH))
-#define MM_O0_SIZE (1UL << MM_O0_SHIFT << PAGE_SHIFT)
-#else
-#define MM_O0_SHIFT 0
-#define MM_O0_WIDTH 0
-#define MM_O0_SIZE 0
-#endif
-
-#if defined(O1_WIDTH)
-#define MM_O1_SHIFT (MM_O0_SHIFT + (O0_WIDTH))
-#define MM_O1_WIDTH (1UL << (O1_WIDTH))
-#define MM_O1_SIZE (1UL << MM_O1_SHIFT << PAGE_SHIFT)
-#else
-#define MM_O1_SHIFT 0
-#define MM_O1_SHIFT 0
-#define MM_O1_SIZE 0
-#endif
-
-#if defined(O2_WIDTH)
-#define MM_O2_SHIFT (MM_O1_SHIFT + (O1_WIDTH))
-#define MM_O2_WIDTH (1UL << (O2_WIDTH))
-#define MM_O2_SIZE (1UL << MM_O2_SHIFT << PAGE_SHIFT)
-#else
-#define MM_O2_SHIFT 0
-#define MM_O2_WIDTH 0
-#define MM_O2_SIZE 0
-#endif
-
-#if defined(O3_WIDTH)
-#define MM_O3_SHIFT (MM_O2_SHIFT + (O2_WIDTH))
-#define MM_O3_WIDTH (1UL << (O3_WIDTH))
-#define MM_O3_SIZE (1UL << MM_O3_SHIFT << PAGE_SHIFT)
-#else
-#define MM_O3_SHIFT 0
-#define MM_O3_WIDTH 0
-#define MM_O3_SIZE 0
-#endif
-
-#if defined(O4_WIDTH)
-#define MM_O4_SHIFT (MM_O3_SHIFT + (O3_WIDTH))
-#define MM_O4_SHIFT (1UL << (O4_WIDTH))
-#define MM_O4_SIZE (1UL << MM_O4_SHIFT << PAGE_SHIFT)
-#else
-#define MM_O4_SHIFT 0
-#define MM_O4_WIDTH 0
-#define MM_O4_SIZE 0
-#endif
-
-#if defined(O5_WIDTH)
-#define MM_O5_SHIFT (MM_O4_SHIFT + (O4_WIDTH))
-#define MM_O5_WIDTH (1UL << (O5_WIDTH))
-#define MM_O5_SIZE (1UL << MM_O5_SHIFT << PAGE_SHIFT)
-#else
-#define MM_O5_SHIFT 0
-#define MM_O5_WIDTH 0
-#define MM_O5_SIZE 0
-#endif
-
-#if defined(O6_WIDTH)
-#define MM_O6_SHIFT (MM_O5_SHIFT + (O5_WIDTH))
-#define MM_O6_WIDTH (1UL << (O6_WIDTH))
-#define MM_O6_SIZE (1UL << MM_O6_SHIFT << PAGE_SHIFT)
-#else
-#define MM_O6_SHIFT 0
-#define MM_O6_WIDTH 0
-#define MM_O6_SIZE 0
-#endif
-
-#if defined(O7_WIDTH)
-#define MM_O7_SHIFT (MM_O6_SHIFT + (O6_WIDTH))
-#define MM_O7_WIDTH (1UL << (O7_WIDTH))
-#define MM_O7_SIZE (1UL << MM_O7_SHIFT << PAGE_SHIFT)
-#else
-#define MM_O7_SHIFT 0
-#define MM_O7_WIDTH 0
-#define MM_O7_SIZE 0
-#endif
-
-#if defined(O8_WIDTH)
-#define MM_O8_SHIFT (MM_O7_SHIFT + (O7_WIDTH))
-#define MM_O8_WIDTH (1UL << (O8_WIDTH))
-#define MM_O8_SIZE (1UL << MM_O8_SHIFT << PAGE_SHIFT)
-#else
-#define MM_O8_SHIFT 0
-#define MM_O8_WIDTH 0
-#define MM_O8_SIZE 0
-#endif
-
-#if defined(O9_WIDTH)
-#define MM_O9_SHIFT (MM_O8_SHIFT + (O8_WIDTH))
-#define MM_O9_WIDTH (1UL << (O9_WIDTH))
-#define MM_O9_SIZE (1UL << MM_O9_SHIFT << PAGE_SHIFT)
-#else
-#define MM_O9_SHIFT 0
-#define MM_O9_WIDTH 0
-#define MM_O9_SIZE 0
-#endif
-
-#define MM_OINFO_WIDTH (sizeof(mm_info_t) * 8)
-
-#define pnum_to_index(pnum, order) (((pnum) >> __o_offset(order)) & (__o_width(order) - 1))
-#define paddr_to_pnum(paddr) ((paddr) >> PAGE_SHIFT)
-#define pnum_to_paddr(pnum) ((pnum) << PAGE_SHIFT)
-
-#define move_forward(var, num) (((var) += (num)) - (num))
-
-#define move_paddr(paddr, base, offset) ((((paddr_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)
-
-#define __o_offset(order) (mm_shifts[order])
-#define __o_width(order) (mm_widths[order])
-#define __o_elems(order) (mm_widths[order] / MM_OINFO_WIDTH)
-
-#define __o_container(idx) ((idx) / MM_OINFO_WIDTH)
-#define __o_bit(idx) ((idx) & (MM_OINFO_WIDTH - 1))
-
-#define MIN(x, y) ((x) < (y) ? (x) : (y))
-
#define __foreach_page(var, start, end, attr, neg)\
for(size_t i = num_indexes(start); i < num_elems(end); ++i)\
if(var->attr[i] == (mm_info_t)(-1)) continue;\
@@ -149,43 +24,9 @@
#define foreach_not_used_page(var, start, order)\
__foreach_page(var, start, var->entries, used, NEG)
-static const size_t mm_shifts[] = {
- MM_O0_SHIFT,
- MM_O1_SHIFT,
- MM_O2_SHIFT,
- MM_O3_SHIFT,
- MM_O4_SHIFT,
- MM_O6_SHIFT,
- MM_O7_SHIFT,
- MM_O8_SHIFT,
- MM_O9_SHIFT,
-};
-
-static const size_t mm_widths[] = {
- MM_O0_WIDTH,
- MM_O1_WIDTH,
- MM_O2_WIDTH,
- MM_O3_WIDTH,
- MM_O4_WIDTH,
- MM_O5_WIDTH,
- MM_O6_WIDTH,
- MM_O7_WIDTH,
- MM_O8_WIDTH,
- MM_O9_WIDTH,
-};
-
-static const size_t mm_sizes[] = {
- MM_O0_SIZE,
- MM_O1_SIZE,
- MM_O2_SIZE,
- MM_O3_SIZE,
- MM_O4_SIZE,
- MM_O5_SIZE,
- MM_O6_SIZE,
- MM_O7_SIZE,
- MM_O8_SIZE,
- MM_O9_SIZE,
-};
+extern const size_t mm_shifts[10];
+extern const size_t mm_widths[10];
+extern const size_t mm_sizes[10];
typedef uint32_t mm_info_t;
typedef void mm_node_t;
diff --git a/include/apos/mem.h b/include/apos/mem.h
index 6b209c5..158ac5e 100644
--- a/include/apos/mem.h
+++ b/include/apos/mem.h
@@ -1,4 +1,130 @@
#ifndef APOS_MEM_H
#define APOS_MEM_H
+#include <apos/utils.h>
+#include <pages.h>
+
+#if defined(O0_WIDTH)
+#define MM_O0_SHIFT (0)
+#define MM_O0_WIDTH (1UL << (O0_WIDTH))
+#define MM_O0_SIZE (1UL << MM_O0_SHIFT << PAGE_SHIFT)
+#else
+#define MM_O0_SHIFT 0
+#define MM_O0_WIDTH 0
+#define MM_O0_SIZE 0
+#endif
+
+#if defined(O1_WIDTH)
+#define MM_O1_SHIFT (MM_O0_SHIFT + (O0_WIDTH))
+#define MM_O1_WIDTH (1UL << (O1_WIDTH))
+#define MM_O1_SIZE (1UL << MM_O1_SHIFT << PAGE_SHIFT)
+#else
+#define MM_O1_SHIFT 0
+#define MM_O1_SHIFT 0
+#define MM_O1_SIZE 0
+#endif
+
+#if defined(O2_WIDTH)
+#define MM_O2_SHIFT (MM_O1_SHIFT + (O1_WIDTH))
+#define MM_O2_WIDTH (1UL << (O2_WIDTH))
+#define MM_O2_SIZE (1UL << MM_O2_SHIFT << PAGE_SHIFT)
+#else
+#define MM_O2_SHIFT 0
+#define MM_O2_WIDTH 0
+#define MM_O2_SIZE 0
+#endif
+
+#if defined(O3_WIDTH)
+#define MM_O3_SHIFT (MM_O2_SHIFT + (O2_WIDTH))
+#define MM_O3_WIDTH (1UL << (O3_WIDTH))
+#define MM_O3_SIZE (1UL << MM_O3_SHIFT << PAGE_SHIFT)
+#else
+#define MM_O3_SHIFT 0
+#define MM_O3_WIDTH 0
+#define MM_O3_SIZE 0
+#endif
+
+#if defined(O4_WIDTH)
+#define MM_O4_SHIFT (MM_O3_SHIFT + (O3_WIDTH))
+#define MM_O4_SHIFT (1UL << (O4_WIDTH))
+#define MM_O4_SIZE (1UL << MM_O4_SHIFT << PAGE_SHIFT)
+#else
+#define MM_O4_SHIFT 0
+#define MM_O4_WIDTH 0
+#define MM_O4_SIZE 0
+#endif
+
+#if defined(O5_WIDTH)
+#define MM_O5_SHIFT (MM_O4_SHIFT + (O4_WIDTH))
+#define MM_O5_WIDTH (1UL << (O5_WIDTH))
+#define MM_O5_SIZE (1UL << MM_O5_SHIFT << PAGE_SHIFT)
+#else
+#define MM_O5_SHIFT 0
+#define MM_O5_WIDTH 0
+#define MM_O5_SIZE 0
+#endif
+
+#if defined(O6_WIDTH)
+#define MM_O6_SHIFT (MM_O5_SHIFT + (O5_WIDTH))
+#define MM_O6_WIDTH (1UL << (O6_WIDTH))
+#define MM_O6_SIZE (1UL << MM_O6_SHIFT << PAGE_SHIFT)
+#else
+#define MM_O6_SHIFT 0
+#define MM_O6_WIDTH 0
+#define MM_O6_SIZE 0
+#endif
+
+#if defined(O7_WIDTH)
+#define MM_O7_SHIFT (MM_O6_SHIFT + (O6_WIDTH))
+#define MM_O7_WIDTH (1UL << (O7_WIDTH))
+#define MM_O7_SIZE (1UL << MM_O7_SHIFT << PAGE_SHIFT)
+#else
+#define MM_O7_SHIFT 0
+#define MM_O7_WIDTH 0
+#define MM_O7_SIZE 0
+#endif
+
+#if defined(O8_WIDTH)
+#define MM_O8_SHIFT (MM_O7_SHIFT + (O7_WIDTH))
+#define MM_O8_WIDTH (1UL << (O8_WIDTH))
+#define MM_O8_SIZE (1UL << MM_O8_SHIFT << PAGE_SHIFT)
+#else
+#define MM_O8_SHIFT 0
+#define MM_O8_WIDTH 0
+#define MM_O8_SIZE 0
+#endif
+
+#if defined(O9_WIDTH)
+#define MM_O9_SHIFT (MM_O8_SHIFT + (O8_WIDTH))
+#define MM_O9_WIDTH (1UL << (O9_WIDTH))
+#define MM_O9_SIZE (1UL << MM_O9_SHIFT << PAGE_SHIFT)
+#else
+#define MM_O9_SHIFT 0
+#define MM_O9_WIDTH 0
+#define MM_O9_SIZE 0
+#endif
+
+#define MM_OINFO_WIDTH (sizeof(mm_info_t) * 8)
+
+#define pnum_to_index(pnum, order) (((pnum) >> __o_offset(order)) & (__o_width(order) - 1))
+#define paddr_to_index(paddr, order) (pnum_to_index(paddr_to_pnum(paddr), (order)))
+#define paddr_to_pnum(paddr) ((paddr) >> PAGE_SHIFT)
+#define pnum_to_paddr(pnum) ((pnum) << PAGE_SHIFT)
+
+#define move_forward(var, num) (((var) += (num)) - (num))
+
+#define move_paddr(paddr, base, offset) ((((paddr_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)
+
+#define __o_offset(order) (mm_shifts[order])
+#define __o_width(order) (mm_widths[order])
+#define __o_elems(order) (mm_widths[order] / MM_OINFO_WIDTH)
+
+#define __o_container(idx) ((idx) / MM_OINFO_WIDTH)
+#define __o_bit(idx) ((idx) & (MM_OINFO_WIDTH - 1))
#endif /* APOS_MEM_H */
diff --git a/include/apos/pmem.h b/include/apos/pmem.h
index 826ae14..884cf5c 100644
--- a/include/apos/pmem.h
+++ b/include/apos/pmem.h
@@ -1,6 +1,7 @@
#ifndef APOS_PMEM_H
#define APOS_PMEM_H
+#include <apos/mem.h>
#include <apos/types.h>
enum mm_order_t {