diff options
| -rw-r--r-- | TCB.txt | 16 | ||||
| -rw-r--r-- | TODO.txt | 16 | ||||
| -rwxr-xr-x | arch/riscv/conf/init | bin | 1040 -> 968 bytes | |||
| -rw-r--r-- | arch/riscv/conf/initrd | bin | 1536 -> 1536 bytes | |||
| -rw-r--r-- | arch/riscv/conf/s.S | 5 | ||||
| -rw-r--r-- | arch/riscv/kernel/irq.c | 10 | ||||
| -rw-r--r-- | arch/riscv/kernel/vmem.c | 2 | ||||
| -rw-r--r-- | common/main.c | 1 | ||||
| -rw-r--r-- | common/pmem.c | 8 | ||||
| -rw-r--r-- | common/uapi/mem.c | 10 | ||||
| -rw-r--r-- | include/apos/attrs.h | 1 | ||||
| -rw-r--r-- | include/apos/debug.h | 12 |
12 files changed, 70 insertions, 11 deletions
@@ -0,0 +1,16 @@ +Alright, so my general idea of creating/killing threads is as follows: + +When a new thread is spawned, it happens through fork, so the new thread gets a +new thread ID but keeps the process ID of the parent process. The new thread is +added to a doubly linked list of thread IDs with the same common process ID. +When a thread is promoted to a process, the process ID becomes that thread ID +(helps with finding threads and corresponding process IDs). Should check that no +other process is using that ID, but it should be exeedingly rare if not +impossible. (can't think of how you would launch 4B threads on one machine but I +guess that's not impossible?) + +All threads share a common (struct vm_branch), and only when a thread is +elevated to a process is a new one allocated. Only when the last thread in a +process is released is the memory released. Will still need to figure out +exactly how device memory should be freed, since it's handled globally instead +of per thread atm. @@ -29,3 +29,19 @@ assume all devices are below the first NUMA node? No clue. + The dev interface can be abused, if a program decides to spam through all memory addresses the system will probably run out of memory. Not sure if it's worh doing anything to. + ++ TLS. Can this be done completely in userspace? + +!!! CURRENT: + ++ Separate vmem and devmem to have a common 'backend', like mem_nodes or +whatever, would probably make it a bit more clean-feeling. ++ Add in interrupt handling and start testing jumping back and forth. ++ Add in better tcb handling, mainly creating linked lists with all threads +under a common process ID. + +!!! FUTURE: ++ Cache locality? ++ When mapping some other address space into your own, I could keep a maximum +used address of the guest address space and only map so many pages, which could +be better for cache locality. diff --git a/arch/riscv/conf/init b/arch/riscv/conf/init Binary files differindex 43a179c..f05254f 100755 --- a/arch/riscv/conf/init +++ b/arch/riscv/conf/init diff --git a/arch/riscv/conf/initrd b/arch/riscv/conf/initrd Binary files differindex e3704f2..90344c1 100644 --- a/arch/riscv/conf/initrd +++ b/arch/riscv/conf/initrd diff --git a/arch/riscv/conf/s.S b/arch/riscv/conf/s.S index e6997ac..80a3a11 100644 --- a/arch/riscv/conf/s.S +++ b/arch/riscv/conf/s.S @@ -1,7 +1,4 @@ .text .global _start _start: -li a1, 1 -loop: -add a0, a0, a1 -jal loop +ecall diff --git a/arch/riscv/kernel/irq.c b/arch/riscv/kernel/irq.c index ed97c00..f844dd1 100644 --- a/arch/riscv/kernel/irq.c +++ b/arch/riscv/kernel/irq.c @@ -1,13 +1,21 @@ #include <apos/irq.h> +#include <apos/attrs.h> +#include <apos/debug.h> #include <csr.h> void init_irq(void *fdt) { UNUSED(fdt); + csr_write(CSR_STVEC, &handle_irq); + + long s = 0; + csr_read(CSR_SIE, s); + info("CSR_SIE: %lx\n", s); } -void handle_irq() +__aligned(4) void handle_irq() { + while(1); } /* very simple for now */ diff --git a/arch/riscv/kernel/vmem.c b/arch/riscv/kernel/vmem.c index c862cea..1f1f44a 100644 --- a/arch/riscv/kernel/vmem.c +++ b/arch/riscv/kernel/vmem.c @@ -177,6 +177,6 @@ int setup_kernel_io(struct vm_branch *b, vm_t paddr) /* assume Sv39 for now */ pm_t gigapage = paddr / MM_GPAGE_SIZE; b->leaf[IO_PAGE] = (struct vm_branch *)to_pte(gigapage, VM_V | VM_R | VM_W); - return 0; + return -SZ_1G + paddr - (gigapage * MM_GPAGE_SIZE); } #endif diff --git a/common/main.c b/common/main.c index f91fc22..52987d1 100644 --- a/common/main.c +++ b/common/main.c @@ -41,7 +41,6 @@ void __main main(void *fdt) arch_setup(fdt); init_pmem(fdt); - init_mem_blocks(); struct vm_branch *b = init_vmem(fdt); /* start up debugging in kernel IO */ diff --git a/common/pmem.c b/common/pmem.c index c919204..ae01175 100644 --- a/common/pmem.c +++ b/common/pmem.c @@ -1,3 +1,4 @@ +#include <apos/mem_nodes.h> #include <apos/pmem.h> #include <apos/dev.h> #include <apos/debug.h> @@ -426,7 +427,7 @@ void init_pmem(void *fdt) size_t actual_size = populate_pmap(ram_base, ram_size, pmap_base); if(probe_size != actual_size) - dbg("BUG! probe_size (%#lx) != actual_size (%#lx)\n", + bug("probe_size (%#lx) != actual_size (%#lx)\n", probe_size, actual_size); /* mark init stack, this should be unmapped once we get to executing @@ -434,7 +435,8 @@ void init_pmem(void *fdt) mark_area_used((pm_t)__va(PM_STACK_BASE), (pm_t)__va(PM_STACK_TOP)); /* mark kernel */ - mark_area_used((pm_t)__va(PM_KERN_BASE), (pm_t)__va(PM_KERN_TOP)); + /* this could be made more explicit, I suppose. */ + mark_area_used(VM_KERN, VM_KERN + PM_KERN_SIZE); /* mark fdt and initrd */ mark_area_used(get_initrdbase(fdt), initrd_top); @@ -446,5 +448,7 @@ void init_pmem(void *fdt) /* mark reserved mem */ mark_reserved_mem(fdt); + init_mem_blocks(); + init_devmem((pm_t)__pa(ram_base), (pm_t)__pa(ram_base + ram_size)); } diff --git a/common/uapi/mem.c b/common/uapi/mem.c index 34ddda2..8c63a87 100644 --- a/common/uapi/mem.c +++ b/common/uapi/mem.c @@ -1,3 +1,4 @@ +#include <apos/dev.h> #include <apos/uapi.h> #include <apos/utils.h> #include <apos/vmem.h> @@ -21,7 +22,11 @@ vm_t sys_free_mem(vm_t start, vm_t u0, vm_t u1, vm_t u2) { UNUSED(u0); UNUSED(u1); UNUSED(u2); struct tcb *r = cur_tcb(); - free_uvmem(r, start); + if(start > __pre_top && start < __post_base) + free_uvmem(r, start); + else + free_devmem(r, start); + return 0; } @@ -33,7 +38,8 @@ vm_t sys_req_pmem(vm_t paddr, vm_t size, vm_t flags, vm_t u0) * outside the RAM area, and I'll probably have to implement some method * that keeps track of used regions outside of RAM. We'll see. */ - return 0; + struct tcb *r = cur_tcb(); + return alloc_devmem(r, paddr, size, flags); } vm_t sys_req_sharedmem(vm_t pid, vm_t start, vm_t size, vm_t flags) diff --git a/include/apos/attrs.h b/include/apos/attrs.h index 64ec27d..0a731cc 100644 --- a/include/apos/attrs.h +++ b/include/apos/attrs.h @@ -2,6 +2,7 @@ #define __section(section) __attribute__((__section__(section))) #define __fmt(x, y) __attribute__((format (__printf__, x, y))) +#define __aligned(a) __attribute__((aligned(a))) #define __noinline __attribute__((noinline)) #define __noreturn __attribute__((noreturn)) #define __packed __attribute__((packed)) diff --git a/include/apos/debug.h b/include/apos/debug.h index 1a3265f..9aa132f 100644 --- a/include/apos/debug.h +++ b/include/apos/debug.h @@ -19,12 +19,24 @@ void __fmt(1, 2) dbg(const char *fmt, ...); void setup_dbg(pm_t pt, enum serial_dev dev); struct dbg_info dbg_from_fdt(void *fdt); +#define COMMON_FORMAT "[%s] %s:%d\n\t" +#define COMMON_ARGS(s) s, __FILE__, __LINE__ +#define bug(fmt, ...) dbg(COMMON_FORMAT fmt, COMMON_ARGS("BUG"), __VA_ARGS__) +#define warn(fmt, ...) dbg(COMMON_FORMAT fmt, COMMON_ARGS("WARN"), __VA_ARGS__) +#define info(fmt, ...) dbg(COMMON_FORMAT fmt, COMMON_ARGS("INFO"), __VA_ARGS__) +#define error(fmt, ...) dbg(COMMON_FORMAT fmt, COMMON_ARGS("ERROR"), __VA_ARGS__) + #else #define dbg(...) #define dbg_init(...) #define dbg_from_fdt(...) +#define bug(...) +#define warn(...) +#define info(...) +#define error(...) + #endif /* DEBUG */ #endif /* APOS_DEBUG_H */ |
