diff options
| -rw-r--r-- | TODO.txt | 1 | ||||
| -rw-r--r-- | arch/riscv/common/vmem.c | 51 | ||||
| -rw-r--r-- | arch/riscv/conf/init-link.S | 2 | ||||
| -rw-r--r-- | arch/riscv/conf/kernel-link.S | 2 | ||||
| -rw-r--r-- | arch/riscv/config.h | 2 | ||||
| -rw-r--r-- | arch/riscv/include/csr.h | 18 | ||||
| -rw-r--r-- | arch/riscv/include/pages.h | 6 | ||||
| -rw-r--r-- | arch/riscv/include/vmap.h | 15 | ||||
| -rw-r--r-- | arch/riscv/include/vmem.h | 29 | ||||
| -rw-r--r-- | arch/riscv/init/init.c | 135 | ||||
| -rw-r--r-- | arch/riscv/kernel/main.c | 13 | ||||
| -rw-r--r-- | arch/riscv/source.mk | 4 | ||||
| -rw-r--r-- | common/mem.c | 40 | ||||
| -rw-r--r-- | common/pmem.c | 165 | ||||
| -rw-r--r-- | include/apos/mem.h | 126 | ||||
| -rw-r--r-- | include/apos/pmem.h | 1 |
16 files changed, 369 insertions, 241 deletions
@@ -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 { |
