diff options
| -rw-r--r-- | TODO.txt | 6 | ||||
| -rw-r--r-- | arch/riscv64/include/csr.h | 4 | ||||
| -rw-r--r-- | arch/riscv64/kernel/timer.c | 35 | ||||
| -rw-r--r-- | common/timer.c | 3 | ||||
| -rw-r--r-- | common/uapi/ipc.c | 15 | ||||
| -rw-r--r-- | common/uapi/mem.c | 6 | ||||
| -rw-r--r-- | common/vmem.c | 7 | ||||
| -rw-r--r-- | include/apos/debug.h | 120 | ||||
| -rw-r--r-- | include/apos/sp_tree.h | 4 | ||||
| -rw-r--r-- | include/apos/vmem.h | 9 | ||||
| -rw-r--r-- | include/libfdt.h | 7 |
11 files changed, 187 insertions, 29 deletions
@@ -46,7 +46,11 @@ under a common process ID. (sort of done, not sure if linked lists even + Timers should use the sp_tree thing sorted by time of completion, and then each timer interrupt just pops the smallest value off and jumps to the associated program. Easy. (started) -+ Add more flags to memory regions, for example MR_SHARED and MR_OWNED? ++ Add more flags to memory regions, for example MR_SHARED and MR_OWNED? done ++ DOCUMENTATION ++ Start working on proper context swaps and RPC swaps. (which thread ID should + be visible from cur_tcb() when in an RPC? should I use some kind + of effective tid instead of cur_tcb()?) !!! FUTURE: + Cache locality? diff --git a/arch/riscv64/include/csr.h b/arch/riscv64/include/csr.h index 39e8dc9..ae0763b 100644 --- a/arch/riscv64/include/csr.h +++ b/arch/riscv64/include/csr.h @@ -5,6 +5,10 @@ #define SATP_MODE_Sv39 0x8000000000000000 #define SATP_MODE_Sv48 0x9000000000000000 +/* unprivileged CSR registers */ +#define CSR_TIME 0xc01 +#define CSR_TIMEH 0xc81 + /* supervisor CSR registers */ #define CSR_SSTATUS 0x100 #define CSR_SIE 0x104 diff --git a/arch/riscv64/kernel/timer.c b/arch/riscv64/kernel/timer.c index 02f080c..1f79c5b 100644 --- a/arch/riscv64/kernel/timer.c +++ b/arch/riscv64/kernel/timer.c @@ -1,20 +1,45 @@ #include <arch/timer.h> +#include <libfdt.h> +#include <csr.h> #include <sbi.h> ticks_t stat_timer(const void *fdt) { - /* TODO: read from fdt */ - return 0; + int cpu_offset = fdt_path_offset(fdt, "/cpus"); + uint8_t *tf_reg = (uint8_t *)fdt_getprop(fdt, cpu_offset, + "timebase-frequency", NULL); + return (ticks_t)fdt_load_int32_ptr(tf_reg); } void set_timer(ticks_t ticks) { - /* TODO */ sbi_set_timer(ticks); } +#if __riscv_xlen == 64 +static ticks_t get_ticks64() +{ + ticks_t ticks = 0; + csr_read(CSR_TIME, ticks); + return ticks; +} +#else +static ticks_t get_ticks64() +{ + ticks_t ticksh, ticksl, check; + + /* avoid overflow between reading high and low */ + do { + csr_read(CSR_TIMEH, ticksh); + csr_read(CSR_TIME, ticksl); + csr_read(CSR_TIMEH, check); + } while (ticksh != check); + + return (ticksh << 32) | ticksl; +} +#endif + ticks_t current_ticks() { - /* TODO */ - return 0; + return get_ticks64(); } diff --git a/common/timer.c b/common/timer.c index da4fd11..0442c44 100644 --- a/common/timer.c +++ b/common/timer.c @@ -3,6 +3,7 @@ #include <apos/nodes.h> #include <apos/utils.h> #include <apos/timer.h> +#include <apos/debug.h> #include <arch/timer.h> #include <arch/cpu.h> @@ -27,6 +28,8 @@ static struct sp_root *__cpu_timers() void init_timer(const void *fdt) { ticks_per_sec = stat_timer(fdt); + info("ticks_per_sec: %" PRIu64 "\n", ticks_per_sec); + info("current ticks: %" PRIu64 "\n", current_ticks()); init_nodes(&node_root, sizeof(struct timer_node)); } diff --git a/common/uapi/ipc.c b/common/uapi/ipc.c index 7181490..bef9665 100644 --- a/common/uapi/ipc.c +++ b/common/uapi/ipc.c @@ -11,17 +11,16 @@ SYSCALL_DEFINE1(ipc_server)(sys_arg_t callback) return (struct sys_ret){ OK, 0 }; } -SYSCALL_DEFINE4(ipc_req) -(sys_arg_t pid, sys_arg_t d0, sys_arg_t d1, sys_arg_t d2) +SYSCALL_DEFINE3(ipc_req)(sys_arg_t tid, sys_arg_t d0, sys_arg_t d1) { - struct tcb *t = get_tcb(pid); - /* something like jump_to_callback(t, d0, d1, d2) */ - return (struct sys_ret){ OK, 0 }; + struct tcb *r = get_tcb(tid); + /* something like jump_to_callback(t, d0, d1) */ + return (struct sys_ret){ d0, d1 }; } -SYSCALL_DEFINE3(ipc_resp)(sys_arg_t pid, sys_arg_t ret, sys_arg_t val) +SYSCALL_DEFINE3(ipc_resp)(sys_arg_t tid, sys_arg_t d0, sys_arg_t d1) { - struct tcb *r = get_tcb(pid); + struct tcb *r = get_tcb(tid); /* something like return_from_callback(t, r) */ - return (struct sys_ret){ ret, val }; + return (struct sys_ret){ d0, d1 }; } diff --git a/common/uapi/mem.c b/common/uapi/mem.c index ace40b9..7526152 100644 --- a/common/uapi/mem.c +++ b/common/uapi/mem.c @@ -50,7 +50,7 @@ SYSCALL_DEFINE2(req_sharedmem) if ((start = alloc_shared_uvmem(t, size, flags))) return (struct sys_ret){ ERR_OOMEM, 0 }; - return (struct sys_ret){ OK, start}; + return (struct sys_ret){ OK, start }; } /* add a syscall like ref_sharedmem that adds a reference to an existing shared @@ -61,7 +61,7 @@ SYSCALL_DEFINE3(ref_sharedmem)(sys_arg_t tid, sys_arg_t va, sys_arg_t flags) struct tcb *t2 = get_tcb(tid); vm_t start = 0; if ((start = ref_shared_uvmem(t1, t2, va, flags))) - return (struct sys_ret){ERR_OOMEM, 0}; + return (struct sys_ret){ ERR_OOMEM, 0 }; - return (struct sys_ret) {OK, start}; + return (struct sys_ret){ OK, start }; } diff --git a/common/vmem.c b/common/vmem.c index 89e1140..989029a 100644 --- a/common/vmem.c +++ b/common/vmem.c @@ -21,12 +21,11 @@ vm_t alloc_fixed_uvmem(struct tcb *t, vm_t start, size_t size, vmflags_t flags) } /* free_shared_uvmem shouldn't be needed, likely to work with free_uvmem */ -vm_t alloc_shared_uvmem(struct tcb *t, size_t size, - vmflags_t flags) +vm_t alloc_shared_uvmem(struct tcb *t, size_t size, vmflags_t flags) { /* TODO: proper error handling */ vm_t v = alloc_region(&t->sp_r, size, &size, - flags | MR_SHARED | MR_OWNED); + flags | MR_SHARED | MR_OWNED); return map_shared_region(t->b_r, v, size, flags); } @@ -81,7 +80,7 @@ stat_t alloc_uvmem_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr, } stat_t alloc_shared_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr, - vmflags_t flags, enum mm_order order) + vmflags_t flags, enum mm_order order) { if (order != MM_O0) return REGION_TRY_AGAIN; diff --git a/include/apos/debug.h b/include/apos/debug.h index d9d668c..25ea132 100644 --- a/include/apos/debug.h +++ b/include/apos/debug.h @@ -5,6 +5,126 @@ #include <apos/pmem.h> #include <arch/vmem.h> +#if _LP64 +/* approximate, but probably good enough */ +#define __PRI64_PREFIX "l" +#define __PRIPTR_PREFIX "l" +#else +#define __PRI64_PREFIX "ll" +#define __PRIPTR_PREFIX +#endif + +/* Decimal notation. */ +#define PRId8 "d" +#define PRId16 "d" +#define PRId32 "d" +#define PRId64 __PRI64_PREFIX "d" + +#define PRIdLEAST8 "d" +#define PRIdLEAST16 "d" +#define PRIdLEAST32 "d" +#define PRIdLEAST64 __PRI64_PREFIX "d" + +#define PRIdFAST8 "d" +#define PRIdFAST16 __PRIPTR_PREFIX "d" +#define PRIdFAST32 __PRIPTR_PREFIX "d" +#define PRIdFAST64 __PRI64_PREFIX "d" + +#define PRIi8 "i" +#define PRIi16 "i" +#define PRIi32 "i" +#define PRIi64 __PRI64_PREFIX "i" + +#define PRIiLEAST8 "i" +#define PRIiLEAST16 "i" +#define PRIiLEAST32 "i" +#define PRIiLEAST64 __PRI64_PREFIX "i" + +#define PRIiFAST8 "i" +#define PRIiFAST16 __PRIPTR_PREFIX "i" +#define PRIiFAST32 __PRIPTR_PREFIX "i" +#define PRIiFAST64 __PRI64_PREFIX "i" + +/* Octal notation. */ +#define PRIo8 "o" +#define PRIo16 "o" +#define PRIo32 "o" +#define PRIo64 __PRI64_PREFIX "o" + +#define PRIoLEAST8 "o" +#define PRIoLEAST16 "o" +#define PRIoLEAST32 "o" +#define PRIoLEAST64 __PRI64_PREFIX "o" + +#define PRIoFAST8 "o" +#define PRIoFAST16 __PRIPTR_PREFIX "o" +#define PRIoFAST32 __PRIPTR_PREFIX "o" +#define PRIoFAST64 __PRI64_PREFIX "o" + +/* Unsigned integers. */ +#define PRIu8 "u" +#define PRIu16 "u" +#define PRIu32 "u" +#define PRIu64 __PRI64_PREFIX "u" + +#define PRIuLEAST8 "u" +#define PRIuLEAST16 "u" +#define PRIuLEAST32 "u" +#define PRIuLEAST64 __PRI64_PREFIX "u" + +#define PRIuFAST8 "u" +#define PRIuFAST16 __PRIPTR_PREFIX "u" +#define PRIuFAST32 __PRIPTR_PREFIX "u" +#define PRIuFAST64 __PRI64_PREFIX "u" + +/* lowercase hexadecimal notation. */ +#define PRIx8 "x" +#define PRIx16 "x" +#define PRIx32 "x" +#define PRIx64 __PRI64_PREFIX "x" + +#define PRIxLEAST8 "x" +#define PRIxLEAST16 "x" +#define PRIxLEAST32 "x" +#define PRIxLEAST64 __PRI64_PREFIX "x" + +#define PRIxFAST8 "x" +#define PRIxFAST16 __PRIPTR_PREFIX "x" +#define PRIxFAST32 __PRIPTR_PREFIX "x" +#define PRIxFAST64 __PRI64_PREFIX "x" + +/* Binary notation */ +#define PRIX8 "X" +#define PRIX16 "X" +#define PRIX32 "X" +#define PRIX64 __PRI64_PREFIX "X" + +#define PRIXLEAST8 "X" +#define PRIXLEAST16 "X" +#define PRIXLEAST32 "X" +#define PRIXLEAST64 __PRI64_PREFIX "X" + +#define PRIXFAST8 "X" +#define PRIXFAST16 __PRIPTR_PREFIX "X" +#define PRIXFAST32 __PRIPTR_PREFIX "X" +#define PRIXFAST64 __PRI64_PREFIX "X" + +/* Macros for printing `intmax_t' and `uintmax_t'. */ +#define PRIdMAX __PRI64_PREFIX "d" +#define PRIiMAX __PRI64_PREFIX "i" +#define PRIoMAX __PRI64_PREFIX "o" +#define PRIuMAX __PRI64_PREFIX "u" +#define PRIxMAX __PRI64_PREFIX "x" +#define PRIXMAX __PRI64_PREFIX "X" + +/* Macros for printing `intptr_t' and `uintptr_t'. */ +#define PRIdPTR __PRIPTR_PREFIX "d" +#define PRIiPTR __PRIPTR_PREFIX "i" +#define PRIoPTR __PRIPTR_PREFIX "o" +#define PRIuPTR __PRIPTR_PREFIX "u" +#define PRIxPTR __PRIPTR_PREFIX "x" +#define PRIXPTR __PRIPTR_PREFIX "X" + #if defined(DEBUG) enum serial_dev { /* only the NS16550A and compatible at the moment */ diff --git a/include/apos/sp_tree.h b/include/apos/sp_tree.h index fe02e91..65e4e89 100644 --- a/include/apos/sp_tree.h +++ b/include/apos/sp_tree.h @@ -1,6 +1,8 @@ #ifndef SP_TREE_H #define SP_TREE_H +#include <apos/types.h> + #define sp_root(r) ((r)->sp_r) #define sp_left(n) ((n)->left) #define sp_right(n) ((n)->right) @@ -11,7 +13,7 @@ #define sp_has_gparen(n) (sp_paren(n) && sp_gparen(n)) struct sp_node { - short hint; + int_fast16_t hint; struct sp_node *left; struct sp_node *right; struct sp_node *parent; diff --git a/include/apos/vmem.h b/include/apos/vmem.h index 5b5037d..17f998d 100644 --- a/include/apos/vmem.h +++ b/include/apos/vmem.h @@ -8,8 +8,7 @@ vm_t alloc_uvmem(struct tcb *r, size_t size, vmflags_t flags); vm_t alloc_fixed_uvmem(struct tcb *r, vm_t start, size_t size, vmflags_t flags); -vm_t alloc_shared_uvmem(struct tcb *r, size_t size, - vmflags_t flags); +vm_t alloc_shared_uvmem(struct tcb *r, size_t size, vmflags_t flags); vm_t ref_shared_uvmem(struct tcb *r1, struct tcb *r2, vm_t va, vmflags_t flags); stat_t free_uvmem(struct tcb *r, vm_t a); @@ -18,17 +17,17 @@ stat_t init_uvmem(struct tcb *r, vm_t base, vm_t top); stat_t alloc_uvmem_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr, vmflags_t flags, enum mm_order order); stat_t alloc_shared_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr, - vmflags_t flags, enum mm_order order); + vmflags_t flags, enum mm_order order); stat_t free_uvmem_wrapper(struct vm_branch *b, pm_t *offset, vm_t vaddr, vmflags_t flags, enum mm_order order); #define map_allocd_region(b, start, bytes, flags) \ map_fill_region(b, &alloc_uvmem_wrapper, 0, start, bytes, flags) -#define map_shared_region(b, start, bytes, flags)\ +#define map_shared_region(b, start, bytes, flags) \ map_fill_region(b, &alloc_shared_wrapper, 0, start, bytes, flags) -#define unmap_freed_region(b, start, bytes, flags) \ +#define unmap_freed_region(b, start, bytes, flags) \ map_fill_region(b, &free_uvmem_wrapper, 0, start, bytes, flags) #define vm_flags(x) ((x) & ~0xff) diff --git a/include/libfdt.h b/include/libfdt.h index ffe979d..63e96fd 100644 --- a/include/libfdt.h +++ b/include/libfdt.h @@ -20,8 +20,11 @@ void __dbg_fdt(const void *fdt, int node_offset, int depth); #define dbg_fdt(...) #endif +#define fdt_load_int32_ptr(p) fdt32_to_cpu(get_unaligned((uint32_t *)p)) + +#define fdt_load_int64_ptr(p) fdt64_to_cpu(get_unaligned((uint64_t *)p)) + #define fdt_load_int_ptr(c, p) \ - ((c) == 2 ? fdt64_to_cpu(get_unaligned((uint64_t *)p)) : \ - fdt32_to_cpu(get_unaligned((uint32_t *)p))) + ((c) == 2 ? fdt_load_int64_ptr(p) : fdt_load_int32_ptr(p)) #endif |
