aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO.txt6
-rw-r--r--arch/riscv64/include/csr.h4
-rw-r--r--arch/riscv64/kernel/timer.c35
-rw-r--r--common/timer.c3
-rw-r--r--common/uapi/ipc.c15
-rw-r--r--common/uapi/mem.c6
-rw-r--r--common/vmem.c7
-rw-r--r--include/apos/debug.h120
-rw-r--r--include/apos/sp_tree.h4
-rw-r--r--include/apos/vmem.h9
-rw-r--r--include/libfdt.h7
11 files changed, 187 insertions, 29 deletions
diff --git a/TODO.txt b/TODO.txt
index 8eb8ec9..20f86a3 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -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