diff options
| -rw-r--r-- | arch/riscv64/include/vmem.h | 32 | ||||
| -rw-r--r-- | common/timer.c | 4 | ||||
| -rw-r--r-- | docs/doxygen.conf | 6 | ||||
| -rw-r--r-- | include/apos/lock.h | 24 | ||||
| -rw-r--r-- | include/apos/timer.h | 73 | ||||
| -rw-r--r-- | include/arch/timer.h | 19 | ||||
| -rw-r--r-- | include/libfdt.h | 59 | ||||
| -rw-r--r-- | lib/ubsan.c | 2 |
8 files changed, 203 insertions, 16 deletions
diff --git a/arch/riscv64/include/vmem.h b/arch/riscv64/include/vmem.h index a557513..fc3df00 100644 --- a/arch/riscv64/include/vmem.h +++ b/arch/riscv64/include/vmem.h @@ -11,28 +11,60 @@ #include <apos/types.h> #include <apos/attrs.h> +/** + * Number of entries in one page table, depends on if we're running riscv32 or + * riscv64. + */ #if __riscv_xlen == 64 + /** When running riscv64, each page table has 512 8byte entries. */ #define RISCV_NUM_LEAVES 512 #else + /** When running riscv32, each page table has 1024 4byte entries. */ #define RISCV_NUM_LEAVES 1024 #endif +/** Page is active. */ #define VM_V (1 << 0) + +/** Page is readable. */ #define VM_R (1 << 1) + +/** Page is writable. */ #define VM_W (1 << 2) + +/** Page is executable. */ #define VM_X (1 << 3) + +/** Page is user-accessible. */ #define VM_U (1 << 4) + +/** Page is global. */ #define VM_G (1 << 5) + +/** Page has been accessed. */ #define VM_A (1 << 6) + +/** Page is dirty. */ #define VM_D (1 << 7) +/** Memory mode of cpu. Currently only Sv39 is supported. */ enum mm_mode { + /** 48bit effective addresses on 64bit systems. */ Sv48, + /** 39bit effective addresses on 64bit systems. */ Sv39, + /** 32bit effective addresses on 32bit systems. */ Sv32, }; +/** + * Virtual memory. + * + * On riscv, all page tables are luckily identical, so we can + * use this without much trickery. + */ struct vmem { + /** RISCV_NUM_LEAVES pointers to other page tables. */ struct vmem *leaf[RISCV_NUM_LEAVES]; }; diff --git a/common/timer.c b/common/timer.c index 0a11dc8..f36c90d 100644 --- a/common/timer.c +++ b/common/timer.c @@ -133,13 +133,15 @@ struct timer *find_timer(id_t cid) return 0; } -void remove_timer(struct timer *t) +stat_t remove_timer(struct timer *t) { if (!t) return; struct sp_node *n = &timer_node_container(t)->sp_n; sp_remove(&sp_root(__cpu_timers()), n); + + return OK; } ticks_t nsecs_to_ticks(tunit_t nsecs) diff --git a/docs/doxygen.conf b/docs/doxygen.conf index cc0d07c..d113ff4 100644 --- a/docs/doxygen.conf +++ b/docs/doxygen.conf @@ -509,7 +509,7 @@ EXTRACT_PACKAGE = NO # included in the documentation. # The default value is: NO. -EXTRACT_STATIC = NO +EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined # locally in source files will be included in the documentation. If set to NO, @@ -2094,7 +2094,7 @@ MAN_LINKS = NO # captures the structure of the code including all documentation. # The default value is: NO. -GENERATE_XML = NO +GENERATE_XML = YES # The XML_OUTPUT tag is used to specify where the XML pages will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of @@ -2254,7 +2254,7 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = +PREDEFINED = DEBUG # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The diff --git a/include/apos/lock.h b/include/apos/lock.h index 2fac160..f874399 100644 --- a/include/apos/lock.h +++ b/include/apos/lock.h @@ -3,16 +3,31 @@ /** * @file lock.h - * Atomic locks, currently only \ref spin_lock and \ref spin_unlock. Mutex is + * Atomic locks, currently only \ref spin_lock() and \ref spin_unlock(). Mutex is * probably overkill for this project. */ #include <apos/atomic.h> #include <apos/irq.h> + +/** + * Typedef for atomic_int. + * + * In apos, spinlocks are implemented with compiler-intrinsic atomic integers, + * that essentially just contain some flags. Currently all spinlocks + * enable/disable irqs. + * + * \todo irq contexts? + */ typedef atomic_int spinlock_t; -#include <lock.h> +#include <arch/lock.h> +/** + * Lock a spinlock. + * + * @param lck Pointer to lock. + */ static inline void spin_lock(spinlock_t *lck) { disable_irq(); @@ -23,6 +38,11 @@ static inline void spin_lock(spinlock_t *lck) } while (atomic_exchange_explicit(lck, 1, memory_order_acq_rel)); } +/** + * Unlock a spinlock. + * + * @param lck Pointer to lock. + */ static inline void spin_unlock(spinlock_t *lck) { atomic_store_explicit(lck, 0, memory_order_release); diff --git a/include/apos/timer.h b/include/apos/timer.h index 85cd5bc..b21a182 100644 --- a/include/apos/timer.h +++ b/include/apos/timer.h @@ -4,21 +4,38 @@ /** * @file timer.h * Timer handling. + * + * \todo Document exceptions and return values better. */ #include <apos/types.h> -/* GCC will compile uint64_t even on 32bit platforms, just with some runtime +/** + * ticks_t typedef, use unsigned 64bit integer on all platforms. + * + * GCC will compile uint64_t even on 32bit platforms, just with some runtime * overhead, should be fine. This will allow us to have a reasonable time range - * even with nanosecond clocks. (138 years with ~4.2 Hz clock) */ + * even with nanosecond clocks. (138 years with ~4.2 Hz clock) + */ typedef uint64_t ticks_t; -/* whichever time unit we're dealing with */ + + +/** + * tunit_t typedef, whichever time unit we're dealing with. + */ typedef size_t tunit_t; +/** + * Timer structure. + */ struct timer { + /** tid. Thread ID of whoever scheduled the timer. */ id_t tid; + /** cid. Control ID, used to differentiate timers. */ id_t cid; + /** ticks. Absolute number of ticks, essentially a timepoint for when + * the timer should trigger. */ ticks_t ticks; }; @@ -47,26 +64,70 @@ id_t new_rel_timer(id_t tid, ticks_t ticks); */ id_t new_abs_timer(id_t tid, ticks_t ticks); +/** + * Return a pointer to the newest timer, i.e. the one that is closest to + * triggering. + * + * @return Pointer to a timer or NULL if queue is empty. + */ struct timer *newest_timer(); + +/** + * Find a timer associated with a specific control ID. + * + * @param cid Control ID to find. + * @return Pointer to associated timer if found, else NULL. + */ struct timer *find_timer(id_t cid); -void remove_timer(struct timer *); +/** + * Remove a timer. + * + * @param timer Pointer to timer to remove. + * @return OK on success. + */ +stat_t remove_timer(struct timer *timer); + +/** + * Convert nanoseconds to ticks. + * + * @param nsecs Number of nanoseconds to represent as ticks. + * @return Equivalent ticks to nsecs. + */ ticks_t nsecs_to_ticks(tunit_t nsecs); +/** + * Convert microseconds to ticks. + * + * @param usecs Number of microseconds to represent as ticks. + * @return Equivalent ticks to usecs. + */ static inline ticks_t usecs_to_ticks(tunit_t usecs) { return nsecs_to_ticks(usecs * 1000); } +/** + * Convert milliseconds to ticks. + * + * @param msecs Number of milliseconds to represent as ticks. + * @return Equivalent ticks to msecs. + */ static inline ticks_t msecs_to_ticks(tunit_t msecs) { return usecs_to_ticks(msecs * 1000); } -/* TODO: likely not a problem on 64bit systems, not sure how to handle situation on - * 32bit */ +/** + * Convert seconds to ticks. + * + * @param secs Number of seconds to represent as ticks. + * @return Equivalent ticks to secs. + */ static inline ticks_t secs_to_ticks(tunit_t secs) { + /* TODO: likely not a problem on 64bit systems, not sure how to handle situation on + * 32bit */ return msecs_to_ticks(secs * 1000); } diff --git a/include/arch/timer.h b/include/arch/timer.h index a94fda4..71f878a 100644 --- a/include/arch/timer.h +++ b/include/arch/timer.h @@ -15,13 +15,26 @@ #include "../../arch/riscv32/include/timer.h" #endif -/* return hardware timer frequency */ +/** + * Get hardware timer frequency. + * + * @return Hardware timer frequency, ticks/sec. + */ ticks_t stat_timer(); -/* set up timer interrupt for absolute ticks */ +/** + * Set up timer interrupt for absolute ticks. + * + * @param ticks Time point for timer to trigger. + * \todo Should maybe be stat_t? + */ void set_timer(ticks_t ticks); -/* current ticks */ +/** + * Get current ticks. + * + * @return Current tick count. + */ ticks_t current_ticks(); #endif /* APOS_ARCH_TIMER_H */ diff --git a/include/libfdt.h b/include/libfdt.h index 33ce0fb..a1266c9 100644 --- a/include/libfdt.h +++ b/include/libfdt.h @@ -11,25 +11,84 @@ #include <apos/types.h> /* apos additions, implementation can be found in common/fdt.c */ + +/** + * FDT cell info. + */ struct cell_info { + /** Value size of cell. */ uint32_t size_cells; + /** Address size of cell. */ uint32_t addr_cells; }; +/** + * Get information about a cell. + * + * @param fdt Pointer to the global FDT. + * @param offset Offset of cell to poke. + * @return Cell information. + */ struct cell_info get_cellinfo(const void *fdt, const int offset); + +/** + * Get information about a register. + * + * @param fdt Pointer to the global fdt. + * @param path Path to be searched. + * @return Register information. + */ struct cell_info get_reginfo(const void *fdt, const char *path); #if defined(DEBUG) +/** + * Print FDT node at specified location. + * + * @param fdt Pointer to global FDT. + * @param node_offset Offset of node. + * @param depth Depth of node. + */ void __dbg_fdt(const void *fdt, int node_offset, int depth); + +/** + * Convenience wrapper around \ref __dbg_fdt(), used to print whole tree. + */ #define dbg_fdt(fdt) __dbg_fdt(fdt, 0, 0) #else +/** + * Debugging is disabled when in release mode, so all calls to dbg_fdt need to + * be erased. + */ #define dbg_fdt(...) #endif +/** + * Load int32 from FDT at location specified by pointer. Integers inside the FDT + * may be unaligned, and accessing them should preferably be done through this + * and \ref fdt_load_int64_ptr(). + * + * @param p Pointer to int32 inside the global FDT. + */ #define fdt_load_int32_ptr(p) fdt32_to_cpu(get_unaligned((uint32_t *)p)) +/** + * Load int64 from FDT at location specified by pointer. + * + * @param p Pointer to int64 inside the global FDT. + * @return Value of int32 at location p. + * + * See \ref fdt_load_int32_ptr() + */ #define fdt_load_int64_ptr(p) fdt64_to_cpu(get_unaligned((uint64_t *)p)) +/** + * Load int{32,64} from FDT at location specified by pointer. + * + * @param c Size of int, where 2 == int64 and everything else int32. Query int + * size from FDT with \ref get_cellinfo() and \ref get_reginfo(). + * @param p Pointer to int{32,64} inside the global FDT. + * @return Value of integer at location p. + */ #define fdt_load_int_ptr(c, p) \ ((c) == 2 ? fdt_load_int64_ptr(p) : fdt_load_int32_ptr(p)) diff --git a/lib/ubsan.c b/lib/ubsan.c index 0d92fb7..f1b46d4 100644 --- a/lib/ubsan.c +++ b/lib/ubsan.c @@ -3,7 +3,7 @@ * Tiny undefined behaviour sanitizer, mostly lifted from * https://github.com/Abb1x/tinyubsan/blob/master/src/tinyubsan.c * - * \todo: Add in more runtime info. + * \todo Add in more runtime info. */ #include <apos/types.h> |
