From 383e55e6bb725a01f652a9fb74f6103b2c789793 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Wed, 8 Dec 2021 13:31:20 +0200 Subject: Added some C11 atomic operations Mainly to be used in spinlocks etc. --- arch/riscv/include/lock.h | 1 + arch/riscv/kernel/main.c | 1 + arch/riscv/mm.txt | 83 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 arch/riscv/include/lock.h create mode 100644 arch/riscv/mm.txt (limited to 'arch/riscv') diff --git a/arch/riscv/include/lock.h b/arch/riscv/include/lock.h new file mode 100644 index 0000000..4f71344 --- /dev/null +++ b/arch/riscv/include/lock.h @@ -0,0 +1 @@ +#define optional_pause() diff --git a/arch/riscv/kernel/main.c b/arch/riscv/kernel/main.c index 207b0bc..aaf828c 100644 --- a/arch/riscv/kernel/main.c +++ b/arch/riscv/kernel/main.c @@ -2,6 +2,7 @@ #include #include #include +#include #ifdef DEBUG diff --git a/arch/riscv/mm.txt b/arch/riscv/mm.txt new file mode 100644 index 0000000..fa06180 --- /dev/null +++ b/arch/riscv/mm.txt @@ -0,0 +1,83 @@ +Ideas for actually working virtual mappings: + +1. Define sensible memory areas, to start with for Sv39 and then that can +probably be extended to Sv48 etc. + +Something like this for Sv39: + +Offset | Size | Purpose +------------------------------------------------ +-242 GiB | 256 GiB | Userspace +------------------------------------------------ +-246 GiB | 4 GiB | Direct mapping +-254 GiB | 8 GiB | vmemmap +-255 GiB | 1 GiB | Kernel IO +-256 GiB | 1 GiB | Kernel + +Sv48: + +Offset | Size | Purpose +------------------------------------------------ +-58368 GiB | 65536 GiB | Userspace +------------------------------------------------ +-60416 GiB | 2048 GiB | Direct mapping +-64512 GiB | 4096 GiB | vmemmap +-65024 GiB | 512 GiB | Kernel IO +-65536 GiB | 512 GiB | Kernel + +Note that tera/giga/etc pages have to be aligned to their corresponding size. +This means that these areas will probably have to be mapped with 2M pages, which +is fine but would've been cool to use top-level PTE's to keep context switch +latencies down. + +(Note: Direct mapping can be something like + inline static __va(pm_t pa) + { + if (__dma_bottom >= pa || __dma_top <= pa) + remap_dma(pa); + return pa + __dma_bottom; + } + ...) + +PTE's can be kept in vmemmap, and the Direct mapping can overlap. + +2. Come up with a somewhat sensible virtual memory management system. Linux uses +rb_trees, which might be a good idea, although I should figure out how to handle +both acuiring and freeing them quickly. + +Maybe keep two separate trees, one for free and one for mapped regions? Free +regions should be ordered by size, to quickly find the best suitable size. +Used/mapped regions should be ordered by address, to quickly find the correct +region. + +struct rb_free_node { + union { + size_t size; + vm_t address; + }; + + struct rb_free_node *pair; + struct rb_free_node *left; + struct rb_free_node *right; +}; + +struct rb_used_node { + vm_t address; + size_t size; + + struct rb_used_node *left; + struct rb_used_node *right; +}; + +My idea: Have two trees made of rb_free_node, one ordered by size and one +ordered by address, with the *pair pointer pointing to the corresponding node in +the other tree. + +When allocating, search up the most suitable free area in the tree ordered by +size, and do the required node modifications. +(remove node completely, split area one or twice, mirror in other tree) + +When freeing, search up the address in the used area, after which insert it into +the free trees and remove it from the used tree. After that, merge adjacent +memory areas in the free trees? Could be done reasonably efficiently, should +start up a test implementation, like with pmem. -- cgit v1.3