From d7cb08134102b7a2410c48d2a1802193f9031e00 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Sun, 29 May 2022 16:23:41 +0300 Subject: continue documentation efforts --- arch/riscv64/config.h | 46 +++++------ arch/riscv64/gen/asm-offsets.c | 2 +- arch/riscv64/kernel/csr.h | 178 ++++++++++++++++++++++++++++++++--------- arch/riscv64/kernel/pages.h | 8 +- arch/riscv64/kernel/power.c | 20 ++++- arch/riscv64/kernel/regs.h | 68 +++++++++++++++- arch/riscv64/kernel/sbi.h | 65 +++++++++++++-- arch/riscv64/kernel/vmem.c | 16 ++-- 8 files changed, 313 insertions(+), 90 deletions(-) (limited to 'arch') diff --git a/arch/riscv64/config.h b/arch/riscv64/config.h index bdf31ae..3d70248 100644 --- a/arch/riscv64/config.h +++ b/arch/riscv64/config.h @@ -19,19 +19,19 @@ /* --- START ARCH USER CONFIG VALUES --- */ /** Physical address to where the OS image will be loaded. */ -#define RAM_BASE 0x80000000 +#define RAM_BASE 0x80000000 /* --- END ARCH USER CONFIG VALUES --- */ /* don't touch >:( */ /** Physical address to where the kernel proper will be relocated. */ -#define PM_KERN_BASE (RAM_BASE + SZ_512K) +#define PM_KERN_BASE (RAM_BASE + SZ_512K) /** Maximum size of the kernel proper. Largely arbitrary. */ -#define PM_KERN_SIZE (SZ_256K) +#define PM_KERN_SIZE (SZ_256K) /** Highest allowed physical address where kernel stuff may lie. */ -#define PM_KERN_TOP (PM_KERN_BASE + PM_KERN_SIZE) +#define PM_KERN_TOP (PM_KERN_BASE + PM_KERN_SIZE) /** Physical memory stack base. In this case, right after the kernel. */ #define PM_STACK_BASE (PM_KERN_BASE + PM_KERN_SIZE) @@ -40,34 +40,34 @@ #define PM_STACK_SIZE (SZ_256K) /** Top of physical memory stack. */ -#define PM_STACK_TOP (PM_STACK_BASE + PM_STACK_SIZE) +#define PM_STACK_TOP (PM_STACK_BASE + PM_STACK_SIZE) #if defined(riscv64) /* 64bit */ /** Direct map offset. */ -#define VM_DMAP (0xffffffc000000000) /* testing for now */ +#define VM_DMAP (0xffffffc000000000) /* testing for now */ /** Virtual address of kernel proper inside direct mapping. */ -#define VM_KERN (VM_DMAP + SZ_256K) +#define VM_KERN (VM_DMAP + SZ_256K) /** Page reserved for kernel I/O. */ -#define IO_PAGE 511UL +#define IO_PAGE 511UL /** Direct mapping starts from this page. */ -#define KSTART_PAGE 256UL +#define KSTART_PAGE 256UL /** The RPC stack page. */ -#define CSTACK_PAGE 255UL +#define CSTACK_PAGE 255UL /** User virtual memory space start. */ -#define UVMEM_START (SZ_4K) +#define UVMEM_START (SZ_4K) /** User virtual memory space end. */ -#define UVMEM_END (SZ_256G - SZ_1G) +#define UVMEM_END (SZ_256G - SZ_1G) /** RPC stack top. */ -#define RPC_STACK_TOP (SZ_256G) +#define RPC_STACK_TOP (SZ_256G) /** RPC stack base. */ #define RPC_STACK_BASE (SZ_256G - SZ_1G) @@ -76,19 +76,19 @@ /* 32bit */ /* TODO: figure this stuff out */ -#define VM_DMAP (0x000000000) -#define VM_KERN (VM_DMAP + SZ_256K) -#define ROOT_PTE (0UL) -#define ROOT_REGION (SZ_4K) +#define VM_DMAP (0x000000000) +#define VM_KERN (VM_DMAP + SZ_256K) +#define ROOT_PTE (0UL) +#define ROOT_REGION (SZ_4K) -#define IO_PAGE 1023UL -#define KSTART_PAGE 512UL -#define CSTACK_PAGE 511UL +#define IO_PAGE 1023UL +#define KSTART_PAGE 512UL +#define CSTACK_PAGE 511UL -#define UVMEM_START (SZ_4K) -#define UVMEM_END (SZ_4G - SZ_8M) +#define UVMEM_START (SZ_4K) +#define UVMEM_END (SZ_4G - SZ_8M) -#define PROC_STACK_TOP (SZ_4G) +#define PROC_STACK_TOP (SZ_4G) #define PROC_STACK_BASE (SZ_4G - SZ_8M) #endif #endif /* APOS_RISCV_CONFIG_H */ diff --git a/arch/riscv64/gen/asm-offsets.c b/arch/riscv64/gen/asm-offsets.c index dfebb5b..8c31561 100644 --- a/arch/riscv64/gen/asm-offsets.c +++ b/arch/riscv64/gen/asm-offsets.c @@ -31,7 +31,7 @@ * @param n Name of structure. * @param s Structure. */ -#define SIZEOF(n, s) DEFINE(sizeof_##n, sizeof(s)) +#define SIZEOF(n, s) DEFINE(sizeof_##n, sizeof(s)) /** * Generate assembly with calculated offsets and sizes. diff --git a/arch/riscv64/kernel/csr.h b/arch/riscv64/kernel/csr.h index 9cb5799..0af2dbe 100644 --- a/arch/riscv64/kernel/csr.h +++ b/arch/riscv64/kernel/csr.h @@ -3,66 +3,164 @@ /** * @file csr.h - * riscv64-specific header for CSR handling + * riscv64-specific header for CSR handling. */ -#define SATP_MODE_Sv32 0x80000000 -#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 -#define CSR_STVEC 0x105 -#define CSR_SCOUNTEREN 0x106 - -#define CSR_SENVCFG 0x10A - -#define CSR_SSCRATCH 0x140 -#define CSR_SEPC 0x141 -#define CSR_SCAUSE 0x142 -#define CSR_STVAL 0x143 -#define CSR_SIP 0x144 - -#define CSR_SATP 0x180 - -#define CSR_SCONTEXT 0x5A8 - -/* Exception causes */ -#define EXC_INST_MISALIGNED 0 -#define EXC_INST_ACCESS 1 -#define EXC_BREAKPOINT 3 -#define EXC_LOAD_ACCESS 5 -#define EXC_STORE_ACCESS 7 -#define EXC_SYSCALL 8 -#define EXC_INST_PAGE_FAULT 12 -#define EXC_LOAD_PAGE_FAULT 13 +/** @name satp register memory modes. */ +/** @{ */ + +/** Value of Sv32 mode in \c satp register. */ +#define SATP_MODE_Sv32 0x80000000 + +/** Value of Sv39 mode in \c satp register. */ +#define SATP_MODE_Sv39 0x8000000000000000 + +/** Value of Sv48 mode in \c satp register. */ +#define SATP_MODE_Sv48 0x9000000000000000 + +/** @} */ + +/** @name Unprivileged CSR registers. */ +/** @{ */ + +/** Address of \c time CSR. */ +#define CSR_TIME 0xc01 + +/** Address of \c timeh CSR. */ +#define CSR_TIMEH 0xc81 + +/** @} */ + +/** @name Supervisor CSR registers. */ +/** @{ */ + +/** Address of \c sstatus CSR. */ +#define CSR_SSTATUS 0x100 + +/** Address of \c sie CSR. */ +#define CSR_SIE 0x104 + +/** Address of \c stvec CSR. */ +#define CSR_STVEC 0x105 + +/** Address of \c scounteren CSR. */ +#define CSR_SCOUNTEREN 0x106 + +/** Address of \c senvcfg CSR. */ +#define CSR_SENVCFG 0x10A + +/** Address of \c sscratch CSR. */ +#define CSR_SSCRATCH 0x140 + +/** Address of \c sepc CSR. */ +#define CSR_SEPC 0x141 + +/** Address of \c scause CSR. */ +#define CSR_SCAUSE 0x142 + +/** Address of \c stval CSR. */ +#define CSR_STVAL 0x143 + +/** Address of \c sip CSR. */ +#define CSR_SIP 0x144 + +/** Address of \c satp CSR. */ +#define CSR_SATP 0x180 + +/** Address of \c scontext CSR. */ +#define CSR_SCONTEXT 0x5A8 + +/** @} */ + +/** @name Exception causes. */ +/** @{ */ + +/** Misaligned instruction. */ +#define EXC_INST_MISALIGNED 0 + +/** Illegal instruction access. */ +#define EXC_INST_ACCESS 1 + +/** Hardware breakpoint. */ +#define EXC_BREAKPOINT 3 + +/** Illegal load address. */ +#define EXC_LOAD_ACCESS 5 + +/** Illegal store address. */ +#define EXC_STORE_ACCESS 7 + +/** System call. */ +#define EXC_SYSCALL 8 + +/** Instruction page fault. */ +#define EXC_INST_PAGE_FAULT 12 + +/** Load page fault. */ +#define EXC_LOAD_PAGE_FAULT 13 + +/** Store page fault. */ #define EXC_STORE_PAGE_FAULT 15 -/* status CSR bits */ -#define SSTATUS_SUM (1 << 18) -#define SSTATUS_SPP (1 << 8) +/** @} */ + +/** @name Status CSR bits. */ +/** @{ */ + +/** \c sstatus \c SUM bit. */ +#define SSTATUS_SUM (1 << 18) + +/** \c sstatus \c SPP bit. */ +#define SSTATUS_SPP (1 << 8) -/* directly lifted from Linux:/arch/riscv/include/asm/asm.h:9-13 */ +/** @} */ + +/** + * Helper macro for compiler vs. assembler string generation. + * + * Directly lifted from Linux:/arch/riscv/include/asm/asm.h:9-13. + * + * @param x Expression to be stringified. + */ #if defined(__ASSEMBLY__) #define __ASM_STR(x) x #else #define __ASM_STR(x) #x #endif +/** + * Read from CSR. + * + * @param csr Name of CSR. + * @param res Location to where result should be written. + */ #define csr_read(csr, res) \ __asm__ volatile ("csrr %0, " __ASM_STR(csr) : "=r" (res) : : "memory") +/** + * Write to CSR. + * + * @param csr Name of CSR. + * @param val Value to be written. + */ #define csr_write(csr, val) \ __asm__ volatile ("csrw " __ASM_STR(csr) ", %0" : : "r" (val) : "memory") +/** + * Set bits in CSR. + * + * @param csr Name of CSR. + * @param val Mask of bits to set. + */ #define csr_set(csr, val) \ __asm__ volatile ("csrs " __ASM_STR(csr) ", %0" : : "r" (val) : "memory") +/** + * Clear bits in CSR. + * + * @param csr Name of CSR. + * @param val Mask of bits to clear. + */ #define csr_clear(csr, val) \ __asm__ volatile ("csrc " __ASM_STR(csr) ", %0" : : "r" (val) : "memory") diff --git a/arch/riscv64/kernel/pages.h b/arch/riscv64/kernel/pages.h index cb7ca88..887baca 100644 --- a/arch/riscv64/kernel/pages.h +++ b/arch/riscv64/kernel/pages.h @@ -7,16 +7,16 @@ */ /** riscv64 4KiB page, order 0. */ -#define MM_KPAGE MM_O0 +#define MM_KPAGE MM_O0 /** riscv64 2MiB page, order 1. */ -#define MM_MPAGE MM_O1 +#define MM_MPAGE MM_O1 /** riscv64 1GiB page, order 2. */ -#define MM_GPAGE MM_O2 +#define MM_GPAGE MM_O2 /** riscv64 512GiB page, order 3. */ -#define MM_TPAGE MM_O3 +#define MM_TPAGE MM_O3 /** riscv64 4KiB page size. */ #define MM_KPAGE_SIZE SZ_4K diff --git a/arch/riscv64/kernel/power.c b/arch/riscv64/kernel/power.c index b3a48fd..73500bb 100644 --- a/arch/riscv64/kernel/power.c +++ b/arch/riscv64/kernel/power.c @@ -6,14 +6,26 @@ #include #include "sbi.h" -/* shutdown reason */ -#define SBI_NO_REASON 0 +/** + * Shutdown without any particular reason. Only reason kernel is likely to + * need. + */ +#define SBI_NO_REASON 0 + +/** @name Shutdown types. */ +/** @{ */ -/* shutdown type */ -#define SBI_SHUTDOWN 0 +/** Regular shutdown. */ +#define SBI_SHUTDOWN 0 + +/** Cold reboot. */ #define SBI_COLD_REBOOT 1 + +/** Warm reboot. */ #define SBI_WARM_REBOOT 2 +/** @} */ + stat_t poweroff(enum poweroff_type type) { /* TODO: this only shuts down the cpu itself, but may leave the SOC diff --git a/arch/riscv64/kernel/regs.h b/arch/riscv64/kernel/regs.h index f2bf336..bda3c1d 100644 --- a/arch/riscv64/kernel/regs.h +++ b/arch/riscv64/kernel/regs.h @@ -10,9 +10,73 @@ * @todo Implement sacing floating point, vector, etc. registers. */ +/** + * Structure containing registers that should always be saved. + * Essentially all base ISA registers. + */ struct riscv_regs { - long ra, sp, gp, tp, t0, t1, t2, s0, s1, a0, a1, a2, a3, a4, a5, a6, a7, - s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, t3, t4, t5, t6; + /** Return address. */ + long ra, + /** Stack pointer. */ + sp, + /** Global pointer. */ + gp, + /** Thread pointer. */ + tp, + /** Temporary 0. */ + t0, + /** Temporary 1. */ + t1, + /** Temporary 2. */ + t2, + /** Caller-save 0. */ + s0, + /** Caller-save 1. */ + s1, + /** Argument 0. */ + a0, + /** Argument 1. */ + a1, + /** Argument 2. */ + a2, + /** Argument 3. */ + a3, + /** Argument 4. */ + a4, + /** Argument 5. */ + a5, + /** Argument 6. */ + a6, + /** Argument 7. */ + a7, + /** Caller-save 2. */ + s2, + /** Caller-save 3. */ + s3, + /** Caller-save 4. */ + s4, + /** Caller-save 5. */ + s5, + /** Caller-save 6. */ + s6, + /** caller-save 7. */ + s7, + /** Caller-save 8. */ + s8, + /** Caller-save 9. */ + s9, + /** Caller-save 10. */ + s10, + /** Caller-save 11. */ + s11, + /** Temporary 3. */ + t3, + /** Temporary 4. */ + t4, + /** Temporary 5. */ + t5, + /** Temporary 6. */ + t6; }; #endif /* APOS_RISCV_REGS_H */ diff --git a/arch/riscv64/kernel/sbi.h b/arch/riscv64/kernel/sbi.h index 44eec4f..3ffac05 100644 --- a/arch/riscv64/kernel/sbi.h +++ b/arch/riscv64/kernel/sbi.h @@ -8,36 +8,71 @@ #include +/** Return structure of SBI calls. */ struct sbiret { + /** Error code. \see sbi_ecodes */ long error; + /** Value. */ long value; }; -enum { +/** SBI error codes. */ +enum sbi_ecodes { + /** Succesful call. */ SBI_SUCCESS = 0, + /** Unsuccesful call. */ SBI_ERR_FAILED = -1, + /** Not supported. */ SBI_ERR_NOT_SUPPORTED = -2, + /** Invalid parameter. */ SBI_ERR_INVALID_PARAM = -3, + /** Access denied. */ SBI_ERR_DENIED = -4, + /** Invalid address. */ SBI_ERR_INVALID_ADDRESS = -5, + /** Already available. */ SBI_ERR_ALREADY_AVAILABLE = -6, + /** Already started. */ SBI_ERR_ALREADY_STARTED = -7, - SBI_ERR_ALREADY_STOPEED = -8, + /** Already stopped. */ + SBI_ERR_ALREADY_STOPPED = -8, }; -/* TODO: query which extensions are available */ +/** + * Do an SBI call. + * + * @param ext \c EXT field of call. + * @param fid \c FID field of call. + * @param arg0 Argument 0. + * @param arg1 Argument 1. + * @param arg2 Argument 2. + * @param arg3 Argument 3. + * @param arg4 Argument 4. + * @param arg5 Argument 5. + * @return SBI call return. \see sbiret. + * @todo Query which extensions are available. + */ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5); -#define EID_TIME 0x54494D45 +/** Timer extension ID. */ +#define EID_TIME 0x54494D45 + +/** Function ID of sbi_set_timer(). */ #define FID_SET_TIMER 0 + +/** + * Start timer. IRQs have to be enabled for the timer to trigger. + * + * @param stime_value Absolute timepoint in ticks. + * @return SBI call return. \see sbiret. + * @todo Read timebase from fdt, seems to be clocks/sec for accurate timers. + */ static inline struct sbiret sbi_set_timer(uint64_t stime_value) { - /* TODO: read timebase from fdt, seems to be clocks/sec for accurate - * timers */ -#if __riscv_xlen == 32 +#if defined(riscv32) return sbi_ecall(EID_TIME, FID_SET_TIMER, stime_value, stime_value >> 32, 0, 0, 0, 0); #else @@ -45,8 +80,22 @@ static inline struct sbiret sbi_set_timer(uint64_t stime_value) #endif } -#define EID_SRST 0x53525354 +/** System reset extension ID. */ +#define EID_SRST 0x53525354 + +/** Function ID of sbi_system_reset(). */ #define FID_RESET 0 + +/** + * Reset system. + * + * @param reset_type Type of reset. \see SBI_SHUTDOWN, SBI_COLD_REBOOT, + * SBI_WARM_REBOOT. + * @param reset_reason Reason for reset. Optional, probably won't be used by the + * kernel. + * @return SBI call return \see sbiret. + * @todo Should \ref SBI_SHUTDOWN etc. be defined in this file instead? + */ static inline struct sbiret sbi_system_reset(uint32_t reset_type, uint32_t reset_reason) { diff --git a/arch/riscv64/kernel/vmem.c b/arch/riscv64/kernel/vmem.c index 73db4dc..1c825e1 100644 --- a/arch/riscv64/kernel/vmem.c +++ b/arch/riscv64/kernel/vmem.c @@ -12,15 +12,15 @@ #include "pages.h" #include "csr.h" -#define pte_ppn(pte) (((pm_t)(pte)) >> 10) -#define pte_flags(pte) (((pm_t)(pte)) & 0xff) -#define to_pte(p, f) ((pm_to_pnum(p) << 10) | (f)) -#define pte_addr(pte) __va(pnum_to_paddr(pte_ppn(pte))) -#define pte_paddr(pte) (pnum_to_paddr(pte_ppn(pte))) +#define pte_ppn(pte) (((pm_t)(pte)) >> 10) +#define pte_flags(pte) (((pm_t)(pte)) & 0xff) +#define to_pte(p, f) ((pm_to_pnum(p) << 10) | (f)) +#define pte_addr(pte) __va(pnum_to_pm(pte_ppn(pte))) +#define pte_paddr(pte) (pnum_to_pm(pte_ppn(pte))) #define vm_to_index(a, o) (pm_to_index(a, o)) -#define is_active(pte) (pte_flags(pte) & VM_V) -#define is_leaf(pte) (is_active(pte) && (pte_flags(pte) & ~VM_V)) -#define is_branch(pte) (is_active(pte) && !(pte_flags(pte) & ~VM_V)) +#define is_active(pte) (pte_flags(pte) & VM_V) +#define is_leaf(pte) (is_active(pte) && (pte_flags(pte) & ~VM_V)) +#define is_branch(pte) (is_active(pte) && !(pte_flags(pte) & ~VM_V)) static pm_t *__find_vmem(struct vmem *b, vm_t v, enum mm_order *o) { -- cgit v1.3