diff options
| -rw-r--r-- | arch/riscv64/kernel/cpu.c | 5 | ||||
| -rw-r--r-- | arch/riscv64/kernel/proc.c | 2 | ||||
| -rw-r--r-- | arch/riscv64/kernel/timer.c | 5 | ||||
| -rw-r--r-- | arch/riscv64/kernel/vmem.c | 88 | ||||
| -rw-r--r-- | common/debug.c | 226 | ||||
| -rw-r--r-- | common/pmem.c | 175 | ||||
| -rw-r--r-- | common/proc.c | 2 | ||||
| -rw-r--r-- | include/apos/attrs.h | 4 | ||||
| -rw-r--r-- | include/apos/debug.h | 2 | ||||
| -rw-r--r-- | include/arch/cpu.h | 11 | ||||
| -rw-r--r-- | include/arch/timer.h | 3 | ||||
| -rw-r--r-- | lib/ubsan.c | 3 |
12 files changed, 478 insertions, 48 deletions
diff --git a/arch/riscv64/kernel/cpu.c b/arch/riscv64/kernel/cpu.c index 91b39b6..966dfec 100644 --- a/arch/riscv64/kernel/cpu.c +++ b/arch/riscv64/kernel/cpu.c @@ -6,6 +6,11 @@ #include <apos/tcb.h> #include <arch/cpu.h> +void cpu_assign(struct tcb *t) +{ + __asm__ volatile ("mv tp, %0\n" : : "r" (t) :); +} + id_t cpu_id() { /* yes, slightly weird situation where cur_tcb() call cpu_id() which diff --git a/arch/riscv64/kernel/proc.c b/arch/riscv64/kernel/proc.c index a85ae6f..efbf7df 100644 --- a/arch/riscv64/kernel/proc.c +++ b/arch/riscv64/kernel/proc.c @@ -8,9 +8,9 @@ #include "regs.h" #include "csr.h" -/** \todo actually map fdt into the target address space */ stat_t run_init(struct tcb *t, void *fdt) { + /** \todo actually map fdt into the target address space */ csr_write(CSR_SSCRATCH, t); __asm__ volatile ("mv sp, %0\n" : : "r" (t->thread_stack_top) : "memory"); __asm__ volatile ("mv a0, %0\n" : : "r" (fdt) : ); diff --git a/arch/riscv64/kernel/timer.c b/arch/riscv64/kernel/timer.c index 36760c4..e529e55 100644 --- a/arch/riscv64/kernel/timer.c +++ b/arch/riscv64/kernel/timer.c @@ -21,6 +21,11 @@ void set_timer(ticks_t ticks) sbi_set_timer(ticks); } +/** + * Get current ticks. + * + * @return Current ticks. + */ #if __riscv_xlen == 64 static ticks_t get_ticks64() { diff --git a/arch/riscv64/kernel/vmem.c b/arch/riscv64/kernel/vmem.c index 6d0b60c..1677103 100644 --- a/arch/riscv64/kernel/vmem.c +++ b/arch/riscv64/kernel/vmem.c @@ -12,16 +12,88 @@ #include "pages.h" #include "csr.h" +/** + * Get page table entry physical page number. + * + * @param pte Page table entry. + * @return Corresponding physical page number. + */ #define pte_ppn(pte) (((pm_t)(pte)) >> 10) + +/** + * Get page table entry flags. + * + * @param pte Page table entry. + * @return Corresponding flags. + */ #define pte_flags(pte) (((pm_t)(pte)) & 0xff) + +/** + * Convert physical memory address to page table entry. + * + * @param p Physical memory address. + * @param f Flags to use. + * @return Corresponding page table entry. + */ #define to_pte(p, f) ((pm_to_pnum(p) << 10) | (f)) + +/** + * Get virtual address in page table entry. + * + * @param pte Page table entry. + * @return Corresponding virtual address. + */ #define pte_addr(pte) __va(pnum_to_pm(pte_ppn(pte))) + +/** + * Get physical address in page table entry. + * + * @param pte Page table entry. + * @return Corresponding physical address. + */ #define pte_paddr(pte) (pnum_to_pm(pte_ppn(pte))) + +/** + * Virtual memory address to page order index. + * + * @param a Virtual address. + * @param o Order of page. + * @return Corresponding page index. + */ #define vm_to_index(a, o) (pm_to_index(a, o)) + +/** + * Check if page table entry is active. + * + * @param pte Page table entry. + * @return \c 0 if entry is not active, non-zero otherwise. + */ #define is_active(pte) (pte_flags(pte) & VM_V) + +/** + * Check if page table entry is a leaf. + * + * @param pte Page table entry. + * @return \c 0 if entry is not leaf, non-zero otherwise. + */ #define is_leaf(pte) (is_active(pte) && (pte_flags(pte) & ~VM_V)) + +/** + * Check if page table entry is a branch. + * + * @param pte Page table entry. + * @return \c 0 if entry is not branch, non-zero otherwise. + */ #define is_branch(pte) (is_active(pte) && !(pte_flags(pte) & ~VM_V)) +/** + * Find page table entry corresponding to virtual address. + * + * @param b Virtual memory to work in. + * @param v Virtual address to look for. + * @param o Address where to return page order to. + * @return Physical address of page. + */ static pm_t *__find_vmem(struct vmem *b, vm_t v, enum mm_order *o) { enum mm_order top = __mm_max_order; @@ -84,6 +156,11 @@ stat_t stat_vpage(struct vmem *branch, vm_t vaddr, pm_t *paddr, return ERR_NF; } +/** + * Create virtual memory leaf page table. + * + * @return New virtual memory leaf page table. + */ static struct vmem *__create_leaf() { pm_t new_leaf = alloc_page(MM_KPAGE, 0); @@ -91,6 +168,11 @@ static struct vmem *__create_leaf() return (struct vmem *)to_pte((pm_t)__pa(new_leaf), VM_V); } +/** + * Destroy virtual memory page table branch. + * + * @param b Virtual memory to work in. + */ static void __destroy_branch(struct vmem *b) { if (!b) @@ -150,6 +232,12 @@ void flush_tlb_all() __asm__ volatile ("sfence.vma\n" ::: "memory"); } +/** + * Jump into virtual memory. + * + * @param branch Virtual memory address space to jump into. + * @param m Riscv memory mode to use. + */ static void __use_vmem(struct vmem *branch, enum mm_mode m) { branch = (struct vmem *)__pa(branch); diff --git a/common/debug.c b/common/debug.c index 2bcdf7f..924c0dd 100644 --- a/common/debug.c +++ b/common/debug.c @@ -14,10 +14,18 @@ #include <stdarg.h> #if defined(DEBUG) -static struct dbg_info { + +/** Debug context structure. */ +struct dbg_info { + /** Address of serial device in memory. */ pm_t dbg_ptr; + + /** Type of serial device. */ enum serial_dev dev; -} dbg_info = (struct dbg_info){ 0 }; +}; + +/** Static debugging information. */ +static struct dbg_info dbg_info = (struct dbg_info){ 0 }; /* forward declarations. */ static void __setup_dbg(pm_t pt, enum serial_dev dev); @@ -43,43 +51,78 @@ void setup_io_dbg(struct vmem *b) * try to implement some kind of basic driver subsystem, but this is good enough * for now. */ +/** NS16550A and compatible serial drivers. */ struct __packed ns16550a { - union { - struct { - uint8_t data; - uint8_t irq; - }; + /** Receiver buffer/transmitter holding register. */ + uint8_t data; - struct { - uint8_t lsbr; - uint8_t msbr; - }; - }; + /** Interrupt enable register. */ + uint8_t irq; + /** Interrupt identity/FIFO control register. */ uint8_t irq_id; + + /** Line control register. */ uint8_t lcr; + + /** Modem control register. */ uint8_t mcr; + + /** Line status register. */ uint8_t lsr; + + /** Modem status register. */ uint8_t msr; + + /** Scratch register. */ uint8_t scr; }; +/** Line status data ready. */ #define LSR_DR (1 << 0) + +/** Line status overrun error. */ #define LSR_OE (1 << 1) + +/** Line status parity error. */ #define LSR_PE (1 << 2) + +/** Line status framing error. */ #define LSR_FE (1 << 3) + +/** Line status break interrupt. */ #define LSR_BI (1 << 4) + +/** Line status transmitter holding register. */ #define LSR_THRE (1 << 5) + +/** Line status transmitter empty. */ #define LSR_TEMT (1 << 6) + +/** Line status error in RCVR FIFO. */ #define LSR_ERR (1 << 7) +/** + * Address of ns16550a port. If other serial drivers are added, this should + * maybe be made a void *. + */ static struct ns16550a *port = 0; +/** + * Serial transmitter empty. + * + * @return \c 0 if not empty, non-zero otherwise. + */ static int __serial_tx_empty() { return port->lsr & LSR_THRE; } +/** + * Put character out onto serial lines. + * + * @param c Character to output. + */ static void __putchar(char c) { if (!port) @@ -91,6 +134,12 @@ static void __putchar(char c) port->data = c; } +/** + * Convert serial device name (from FDT) to serial device enumerator. + * + * @param dev_name Device name string. + * @return Corresponding enumerator value. + */ static enum serial_dev __serial_dev_enum(const char *dev_name) { if (strncmp("ns16550", dev_name, 7) == 0) @@ -99,6 +148,12 @@ static enum serial_dev __serial_dev_enum(const char *dev_name) return -1; } +/** + * Get debugging info from FDT. + * + * @param fdt Global FDT pointer. + * @return Filled \ref dbg_info structure. + */ static struct dbg_info __dbg_from_fdt(const void *fdt) { int chosen_offset = fdt_path_offset(fdt, "/chosen"); @@ -122,6 +177,12 @@ static struct dbg_info __dbg_from_fdt(const void *fdt) return (struct dbg_info){ dbg_ptr, dev }; } +/** + * Set static port. + * + * @param pt Address of memory mapped serial device. + * @param dev Chosen device. + */ void __setup_dbg(vm_t pt, enum serial_dev dev) { switch (dev) { @@ -134,29 +195,71 @@ void __setup_dbg(vm_t pt, enum serial_dev dev) * defaults (set by U-boot) seem to work alright */ } +/** Printf formatting left align flag. */ #define LEFT_FLAG (1 << 0) + +/** Printf formatting explicit sign flag. */ #define SIGN_FLAG (1 << 1) + +/** Printf formatting hash sign flag. */ #define HASH_FLAG (1 << 2) + +/** Printf formatting zero padding flag. */ #define ZERO_FLAG (1 << 3) + +/** Printf formatting ' flag. */ #define FMT_FLAG (1 << 4) + +/** Printf formatting space flag. */ #define SPACE_FLAG (1 << 5) + +/** Printf formatting long specifier flag. */ #define LONG_FLAG (1 << 6) + +/** Printf formatting long long specifier flag. */ #define LLONG_FLAG (1 << 7) + +/** Printf formatting short flag. */ #define SHORT_FLAG (1 << 8) + +/** Printf formatting char flag. */ #define CHAR_FLAG (1 << 9) + +/** Printf precision flag. */ #define PRECS_FLAG (1 << 11) + +/** Printf unsigned flag. */ #define UNSIGN_FLAG (1 << 12) + +/** Printf width flag. */ #define WIDTH_FLAG (1 << 13) + +/** Printf padding flag. */ #define PAD_FLAG (1 << 14) +/** Printf continue flag. */ #define CONT 1 + +/** Printf stop flag. */ #define STOP 0 +/** + * Check if character is ASCII decimal digit. + * + * @param c Character to check. + * @return \c true if character is ASCII decimal digit, \c false otherwise. + */ static bool __is_digit(char c) { return (c >= '0') && (c <= '9'); } +/** + * Convert string to corresponding number (assuming int). + * + * @param s Number string. + * @return Corresponding number. + */ static int __atoi(const char *s) { unsigned int i = 0; @@ -167,6 +270,25 @@ static int __atoi(const char *s) return i; } +/** + * Calculate signed char from value using type interpretation. + * + * @param x Type to interpret value as. + * @param value Value to interpret. + * @param base Base to interpret value in. + */ +#define handle_type(x, value, base) \ + c = (x)value % (x)base; \ + value = (x)value / (x)base; +/** + * Convert number to string length. + * + * @param value Number to print. + * @param base Base to print in. + * @param flags Flags to output. + * @param print Print number as well. + * @return Length of corresponding string. + */ static size_t __integral_val(ssize_t value, size_t base, size_t flags, bool print) { @@ -174,22 +296,19 @@ static size_t __integral_val(ssize_t value, size_t base, size_t flags, size_t ret = 0; signed char c = 0; -#define handle_type(x) \ - c = (x)value % (x)base; \ - value = (x)value / (x)base; if (!is_set(flags, UNSIGN_FLAG)) { /* signed values, only with i format */ if (is_set(flags, LLONG_FLAG)) { - handle_type(signed long long); + handle_type(signed long long, value, base); } else if (is_set(flags, LONG_FLAG)) { - handle_type(signed long); + handle_type(signed long, value, base); } else if (is_set(flags, SHORT_FLAG)) { - handle_type(signed short); + handle_type(signed short, value, base); } else if (is_set(flags, CHAR_FLAG)) { - handle_type(signed char); + handle_type(signed char, value, base); } else { - handle_type(signed int); + handle_type(signed int, value, base); } /* convert negative results into actual characters */ @@ -198,20 +317,18 @@ static size_t __integral_val(ssize_t value, size_t base, size_t flags, } else { /* unsigned values, everything else */ if (is_set(flags, LLONG_FLAG)) { - handle_type(unsigned long long); + handle_type(unsigned long long, value, base); } else if (is_set(flags, LONG_FLAG)) { - handle_type(unsigned long); + handle_type(unsigned long, value, base); } else if (is_set(flags, SHORT_FLAG)) { - handle_type(unsigned short); + handle_type(unsigned short, value, base); } else if (is_set(flags, CHAR_FLAG)) { - handle_type(unsigned char); + handle_type(unsigned char, value, base); } else { - handle_type(unsigned int); + handle_type(unsigned int, value, base); } } -#undef handle_type - if (base == 16) c += c > 9 ? 'a' - 10 : '0'; else @@ -226,6 +343,12 @@ static size_t __integral_val(ssize_t value, size_t base, size_t flags, return ret + 1; } +/** + * Print prefix corresponding to \c base. + * + * @param base Base to integer. + * @return Length of prefix as string. + */ static size_t __print_prefix(size_t base) { size_t i = 0; @@ -252,6 +375,13 @@ static size_t __print_prefix(size_t base) return i; } +/** + * Print padding. + * + * @param pad Number of characters to print. + * @param pad_char Character to use as padding. + * @return Number of characters printed. + */ static size_t __print_padding(size_t pad, char pad_char) { size_t i = 0; @@ -262,6 +392,13 @@ static size_t __print_padding(size_t pad, char pad_char) return i; } +/** + * Print signed value. + * + * @param value Value to print. + * @param flags Flags to printing. + * @return Number of characters written. + */ static size_t __print_sign(ssize_t value, size_t flags) { if (is_set(flags, LLONG_FLAG)) @@ -286,12 +423,38 @@ static size_t __print_sign(ssize_t value, size_t flags) return 0; } +/** + * Length of integral value as string. + * + * @param value Value to convert to string. + * @param base Base to interpret value as. + * @param flags Formatting flags. + * @return \see __integral_val(). + */ +#define __integral_len(value, base, flags) __integral_val((value), (base), (flags), false) + +/** + * Print integral value as string. + * + * @param value Value to convert to string. + * @param base Base to interpret value as. + * @param flags Formatting flags. + * @return \see __integral_val(). + */ +#define __integral_print(value, base, flags) __integral_val((value), (base), (flags), true) + +/** + * Print integral value. + * + * @param value Value to print. + * @param base Base to print value in. + * @param flags Flags to printing. + * @param width Minimum width of printing. + * @return Number of characters written. + */ static size_t __print_integral(ssize_t value, size_t base, size_t flags, size_t width) { -#define __integral_len(a, b, c) __integral_val((a), (b), (c), false) -#define __integral_print(a, b, c) __integral_val((a), (b), (c), true) - size_t ret = 0; size_t raw_len = __integral_len(value, base, flags); ssize_t pad = is_set(flags, PAD_FLAG) ? width - raw_len : 0; @@ -338,9 +501,6 @@ static size_t __print_integral(ssize_t value, size_t base, size_t flags, } return ret; - -#undef __integral_len -#undef __integral_print } void dbg(const char *fmt, ...) diff --git a/common/pmem.c b/common/pmem.c index dae26ea..fdde12a 100644 --- a/common/pmem.c +++ b/common/pmem.c @@ -33,53 +33,122 @@ #include <apos/bits.h> /* is_nset etc */ #include <libfdt.h> -/* NOTE: these are all for pnum_t, i.e. O0_SHIFT is from 0 */ +/** + * Loop through all page usage bits in current bitmap. + * + * @param var Memory leaf or branch containing bitmap. + * @param start Start looking from this index. + * @param end Stop looking before this index. + * @param attr Attribute name of bitmap. + * @param neg Negate whether we're looking for full or empty pages. + * + * \note These are all for pnum_t, i.e. O0_SHIFT is from 0 + */ #define __foreach_page(var, start, end, attr, neg) \ for (pnum_t page = start; page < end; ++page) \ if (neg (bitmap_is_set(var->attr, page))) continue; \ else \ +/** Easier to read negation. */ #define NEG ! -#define foreach_full_page(var, start, order) \ + +/** + * Loop through all full pages. + * + * @param var Memory leaf or branch containing bitmap. + * @param start Start looking from this index. + */ +#define foreach_full_page(var, start) \ __foreach_page(var, start, var->entries, full, NEG) -#define foreach_not_full_page(var, start, order) \ +/** + * Loop through all not full pages. + * + * @param var Memory leaf or branch containing bitmap. + * @param start Start looking from this index. + */ +#define foreach_not_full_page(var, start) \ __foreach_page(var, start, var->entries, full, ) -#define foreach_used_page(var, start, order) \ +/** + * Loop through all used pages. + * + * @param var Memory leaf or branch containing bitmap. + * @param start Start looking from this index. + */ +#define foreach_used_page(var, start) \ __foreach_page(var, start, var->entries, used, NEG) -#define foreach_not_used_page(var, start, order) \ +/** + * Loop through all not used pages. + * + * @param var Memory leaf or branch containing bitmap. + * @param start Start looking from this index. + */ +#define foreach_not_used_page(var, start) \ __foreach_page(var, start, var->entries, used, ) /* curiously, all my optimisation efforts were in vain, and eight bits is the * best alternative. */ + +/** Memory bitmap base size. */ typedef uint8_t mm_info_t; + +/** Beauty typedef for void *, used for bitmaps in this file. */ typedef void mm_node_t; +/** Memory page leaf. */ struct mm_leaf { + /** Number of entries in leaf. */ pnum_t entries; + + /** Bitmap of used pages. */ mm_info_t *used; }; +/** Memory page branch. */ struct mm_branch { + /** Number of entries in branch. */ pnum_t entries; + + /** Bitmap of full nodes. */ mm_info_t *full; + + /** Pointer to array of next order indexes. */ mm_node_t **next; }; +/** Order map. */ struct mm_omap { + /** Base address of map. */ pm_t base; + + /** Pointer to array of nodes. */ mm_node_t **orders; + + /** Order of map. */ enum mm_order order; }; +/** Physical map. */ struct mm_pmap { - struct mm_omap *omap[9]; + /** Order map, one per order up to maximum order. */ + struct mm_omap *omap[NUM_ORDERS]; }; +/** Static physical map address. \note If I support NUMA, this should not be + * static, rather one physical map per NUMA region. */ static struct mm_pmap *pmap = 0; +/** + * Helper function for marking a page used. + * + * @param op Order node pointer. + * @param pnum Physical page number to mark free. + * @param tgt Target order. + * @param src Source order. + * @param dst Destination order. + */ static void __mark_free(mm_node_t *op, pnum_t pnum, enum mm_order tgt, enum mm_order src, enum mm_order dst) { @@ -99,9 +168,9 @@ static void __mark_free(mm_node_t *op, pnum_t pnum, enum mm_order tgt, bitmap_clear(o->full, idx); } -/* this could probably use an int for status, but eh */ void free_page(enum mm_order order, pm_t paddr) { + /** \todo This could probably use an int for status, but eh */ for (size_t i = MM_O0; i <= __mm_max_order; ++i) { if (!pmap->omap[i]) continue; @@ -119,6 +188,16 @@ void free_page(enum mm_order order, pm_t paddr) } } +/** + * Helper function for marking a page used. + * + * @param op Order node pointer. + * @param pnum Page number to mark used. + * @param tgt Target order. + * @param src Source order. + * @param dst Destination order. + * @return \ref true if order is filled, \ref false otherwise. + */ static bool __mark_used(mm_node_t *op, pnum_t pnum, enum mm_order tgt, enum mm_order src, enum mm_order dst) { @@ -173,6 +252,15 @@ void mark_used(enum mm_order order, pm_t paddr) } } +/** + * Look for next free page. + * + * @param op Operand node pointer. + * @param offset Offset to where to start looking for available pages from. + * @param src Source order. + * @param dst Destination order. + * @return Page number of found index. + */ static pnum_t __enum_order(mm_node_t *op, pnum_t offset, enum mm_order src, enum mm_order dst) { @@ -180,7 +268,7 @@ static pnum_t __enum_order(mm_node_t *op, pnum_t offset, enum mm_order src, if (src == dst) { struct mm_leaf *o = (struct mm_leaf *)op; - foreach_not_used_page(o, idx, src) + foreach_not_used_page(o, idx) { return page << order_offset(src); } @@ -189,7 +277,7 @@ static pnum_t __enum_order(mm_node_t *op, pnum_t offset, enum mm_order src, } struct mm_branch *o = (struct mm_branch *)op; - foreach_not_full_page(o, idx, src) + foreach_not_full_page(o, idx) { /* if the suggested search index is full, the following level * would get an incorrect offset if trying to follow the original @@ -237,10 +325,20 @@ pm_t alloc_page(enum mm_order order, pm_t offset) return paddr; } -/* unfortunate that populating the mm info is so complicated */ +/** + * Populate order node map. + * + * @param op Address to where to write order node pointer. + * @param cont Physical address where to continue writing data to. + * @param src Source order. + * @param dst Destination order. + * @param num Number of nodes in this order to populate. + * @return Physical address to continue from. + */ static pm_t __populate_order(mm_node_t **op, pm_t cont, enum mm_order src, enum mm_order dst, size_t num) { + /* unfortunate that populating the mm info is so complicated */ if (src == dst) { struct mm_leaf *o = (struct mm_leaf *)move_forward( cont, sizeof(struct mm_leaf)); @@ -272,6 +370,15 @@ static pm_t __populate_order(mm_node_t **op, pm_t cont, enum mm_order src, return cont; } +/** + * Probe order node map. + * + * @param cont Number of bytes written so far. + * @param src Source order. + * @param dst Destination order. + * @param num Number of nodes in this order to calculate. + * @return Number of bytes written so far. + */ static pm_t __probe_order(pm_t cont, enum mm_order src, enum mm_order dst, size_t num) { @@ -292,6 +399,15 @@ static pm_t __probe_order(pm_t cont, enum mm_order src, enum mm_order dst, return cont; } +/** Populate order map. + * + * @param omap Address where to write order map pointer. + * @param cont Address where to continue writing map data. + * @param base Base of order map. + * @param entries Number of order node entries in order map. + * @param order Order of this order map. + * @return Address to continue writing data to. + */ static pm_t __populate_omap(struct mm_omap **omap, pm_t cont, pm_t base, size_t entries, enum mm_order order) { @@ -314,6 +430,14 @@ static pm_t __populate_omap(struct mm_omap **omap, pm_t cont, pm_t base, return cont; } +/** + * Probe order map. + * + * @param cont Number of bytes written so far. + * @param entries Number of order node entries in this order map. + * @param order Order of this order map. + * @return Number of bytes written so far. + */ static pm_t __probe_omap(pm_t cont, size_t entries, enum mm_order order) { cont += sizeof(struct mm_omap); @@ -375,6 +499,12 @@ pm_t probe_pmap(pm_t ram_base, size_t ram_size) return cont; } +/** + * Helper function for marking area used. + * + * @param base Base address of area. + * @param top Top address of top. + */ static void __mark_area_used(pm_t base, pm_t top) { size_t area_left = top - base; @@ -389,6 +519,11 @@ static void __mark_area_used(pm_t base, pm_t top) mark_used(BASE_PAGE, runner); } +/** + * Mark reserved memory region used, to avoid it getting accidentally allocated. + * + * @param fdt Global FDT pointer. + */ static void __mark_reserved_mem(void *fdt) { int rmem_offset = fdt_path_offset(fdt, "/reserved-memory/mmode_resv0"); @@ -407,6 +542,12 @@ static void __mark_reserved_mem(void *fdt) __mark_area_used((pm_t)__va(base), (pm_t)__va(top)); } +/** + * Read top of RAM from FDT. + * + * @param fdt Global FDT pointer. + * @return Physical address of top of RAM. + */ static pm_t __get_ramtop(void *fdt) { struct cell_info ci = get_reginfo(fdt, "/memory"); @@ -423,12 +564,26 @@ static pm_t __get_ramtop(void *fdt) return (pm_t)fdt_load_int_ptr(ci.size_cells, mem_reg) + base; } +/** + * Read top of FDT. + * + * @param fdt Global FDT pointer. + * @return Physical address of top of FDT. + */ static pm_t __get_fdttop(void *fdt) { const char *b = (const char *)fdt; return (pm_t)(b + fdt_totalsize(fdt)); } +/** + * Return base of FDT. + * + * Technically pretty useless, but here mainly for cohesion. + * + * @param fdt Global FDT pointer. + * @return \c fdt. + */ static pm_t __get_fdtbase(void *fdt) { /* lol */ diff --git a/common/proc.c b/common/proc.c index 001e127..6de22c1 100644 --- a/common/proc.c +++ b/common/proc.c @@ -10,6 +10,7 @@ #include <apos/initrd.h> #include <arch/arch.h> #include <arch/proc.h> +#include <arch/cpu.h> stat_t prepare_proc(struct tcb *t, vm_t bin, vm_t interp) { @@ -33,6 +34,7 @@ stat_t init_proc(void *fdt) return ERR_OOMEM; /* set current tcb */ + cpu_assign(t); use_tcb(t); use_vmem(t->proc.vmem); diff --git a/include/apos/attrs.h b/include/apos/attrs.h index 76ef39f..0cb167c 100644 --- a/include/apos/attrs.h +++ b/include/apos/attrs.h @@ -33,6 +33,10 @@ */ #define __fmt(x, y) __attribute__((format(__printf__, x, y))) + +/** Printf formatting attribute to not confuse doxygen. */ +#define __printf __fmt(1, 2) + /** * Align object. * diff --git a/include/apos/debug.h b/include/apos/debug.h index 6263ea2..f703974 100644 --- a/include/apos/debug.h +++ b/include/apos/debug.h @@ -326,7 +326,7 @@ enum serial_dev { * * @param fmt Format string. Integer subset of normal printf formatting. */ -void dbg(const char *fmt, ...) __fmt(1, 2); +void __printf dbg(const char *fmt, ...); /** * Initialize debugging, set up serial driver etc. diff --git a/include/arch/cpu.h b/include/arch/cpu.h index 8913b85..4fe0c99 100644 --- a/include/arch/cpu.h +++ b/include/arch/cpu.h @@ -8,6 +8,7 @@ */ #include <apos/types.h> +#include <apos/tcb.h> #if defined(riscv64) #include "../../arch/riscv64/include/cpu.h" @@ -24,6 +25,14 @@ */ id_t cpu_id(); -/** \todo add more cpu handling functions */ +/** + * Assign tcb to current cpu. + * + * @param t \ref tcb to assign to current cpu. + */ +void cpu_assign(struct tcb *t); + +/** \todo Should init be assigned one thread per core, or how should I handle + * giving out CPU IDs? */ #endif /* APOS_CPU_H */ diff --git a/include/arch/timer.h b/include/arch/timer.h index 71f878a..7f12100 100644 --- a/include/arch/timer.h +++ b/include/arch/timer.h @@ -18,9 +18,10 @@ /** * Get hardware timer frequency. * + * @param fdt Global FDT pointer. * @return Hardware timer frequency, ticks/sec. */ -ticks_t stat_timer(); +ticks_t stat_timer(const void *fdt); /** * Set up timer interrupt for absolute ticks. diff --git a/lib/ubsan.c b/lib/ubsan.c index d3e363e..191787a 100644 --- a/lib/ubsan.c +++ b/lib/ubsan.c @@ -226,7 +226,8 @@ void __ubsan_handle_pointer_overflow(const struct overflow_data *data) * * @param data Out of bounds information, generated by the compiler. */ -void __ubsan_handle_shift_out_of_bounds(const struct shift_out_of_bounds_data *data) +void __ubsan_handle_shift_out_of_bounds( + const struct shift_out_of_bounds_data *data) { print_location("shift out of bounds", data->location); } |
