aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/riscv64/config.h46
-rw-r--r--arch/riscv64/gen/asm-offsets.c2
-rw-r--r--arch/riscv64/kernel/csr.h164
-rw-r--r--arch/riscv64/kernel/pages.h8
-rw-r--r--arch/riscv64/kernel/power.c20
-rw-r--r--arch/riscv64/kernel/regs.h68
-rw-r--r--arch/riscv64/kernel/sbi.h65
-rw-r--r--arch/riscv64/kernel/vmem.c16
8 files changed, 306 insertions, 83 deletions
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
+/** @name satp register memory modes. */
+/** @{ */
-/* unprivileged CSR registers */
-#define CSR_TIME 0xc01
-#define CSR_TIMEH 0xc81
+/** Value of Sv32 mode in \c satp register. */
+#define SATP_MODE_Sv32 0x80000000
-/* supervisor CSR registers */
-#define CSR_SSTATUS 0x100
-#define CSR_SIE 0x104
-#define CSR_STVEC 0x105
-#define CSR_SCOUNTEREN 0x106
+/** Value of Sv39 mode in \c satp register. */
+#define SATP_MODE_Sv39 0x8000000000000000
-#define CSR_SENVCFG 0x10A
+/** Value of Sv48 mode in \c satp register. */
+#define SATP_MODE_Sv48 0x9000000000000000
-#define CSR_SSCRATCH 0x140
-#define CSR_SEPC 0x141
-#define CSR_SCAUSE 0x142
-#define CSR_STVAL 0x143
-#define CSR_SIP 0x144
+/** @} */
-#define CSR_SATP 0x180
+/** @name Unprivileged CSR registers. */
+/** @{ */
-#define CSR_SCONTEXT 0x5A8
+/** Address of \c time CSR. */
+#define CSR_TIME 0xc01
-/* 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
+/** 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)
+/** @} */
-/* directly lifted from Linux:/arch/riscv/include/asm/asm.h:9-13 */
+/** @name Status CSR bits. */
+/** @{ */
+
+/** \c sstatus \c SUM bit. */
+#define SSTATUS_SUM (1 << 18)
+
+/** \c sstatus \c SPP bit. */
+#define SSTATUS_SPP (1 << 8)
+
+/** @} */
+
+/**
+ * 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 <apos/power.h>
#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 <apos/types.h>
+/** 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)
{