From 12be40e22aae582cca9abbd151031edaab800cae Mon Sep 17 00:00:00 2001 From: Kimplul Date: Mon, 23 May 2022 23:00:55 +0300 Subject: start writing documentation --- include/apos/lock.h | 24 +++++++++++++++-- include/apos/timer.h | 73 +++++++++++++++++++++++++++++++++++++++++++++++----- include/arch/timer.h | 19 +++++++++++--- include/libfdt.h | 59 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 164 insertions(+), 11 deletions(-) (limited to 'include') 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 #include + +/** + * 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 +#include +/** + * 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 -/* 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 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)) -- cgit v1.3