[arch][riscv] start of FPU support

Add build system support for at least being aware of the FPU on
the architecture, not building code to use it.

At the moment, only sets up the FPU into Initial state prior to
entering user space and then ignores it.
This commit is contained in:
Travis Geiselbrecht
2021-04-13 02:39:34 -07:00
parent 1772e7e890
commit 035a15325a
4 changed files with 58 additions and 6 deletions

View File

@@ -134,6 +134,10 @@ void arch_enter_uspace(vaddr_t entry_point, vaddr_t user_stack_top) {
status = RISCV_CSR_XSTATUS_PIE |
RISCV_CSR_XSTATUS_SUM;
#if RISCV_FPU
status |= (1ul << RISCV_CSR_XSTATUS_FS_SHIFT); // mark fpu state 'initial'
#endif
printf("user sstatus %#lx\n", status);
arch_disable_ints();
@@ -145,7 +149,49 @@ void arch_enter_uspace(vaddr_t entry_point, vaddr_t user_stack_top) {
// the exception code will recover it when coming from user space
((uintptr_t *)kernel_stack_top)[-1] = (uintptr_t)riscv_get_percpu();
asm volatile(
#if RISCV_FPU
// zero out the fpu state
"csrw fcsr, 0\n"
// TODO: figure out how to do this more cleanly
// without 'fd' in the march line the assembler wont let us emit a direct
// fpu opcode. Tried unsuccessfully to use the .insn operand. below is a
// series of fmv.d.x fN, zero instructions to wipe out the complete state.
".word 0xf2000053\n" // fmv.d.x f0, zero
".word 0xf20000d3\n" // fmv.d.x f1, zero
".word 0xf2000153\n" // ...
".word 0xf20001d3\n"
".word 0xf2000253\n"
".word 0xf20002d3\n"
".word 0xf2000353\n"
".word 0xf20003d3\n"
".word 0xf2000453\n"
".word 0xf20004d3\n"
".word 0xf2000553\n"
".word 0xf20005d3\n"
".word 0xf2000653\n"
".word 0xf20006d3\n"
".word 0xf2000753\n"
".word 0xf20007d3\n"
".word 0xf2000853\n"
".word 0xf20008d3\n"
".word 0xf2000953\n"
".word 0xf20009d3\n"
".word 0xf2000a53\n"
".word 0xf2000ad3\n"
".word 0xf2000b53\n"
".word 0xf2000bd3\n"
".word 0xf2000c53\n"
".word 0xf2000cd3\n"
".word 0xf2000d53\n"
".word 0xf2000dd3\n"
".word 0xf2000e53\n"
".word 0xf2000ed3\n"
".word 0xf2000f53\n"
".word 0xf2000fd3\n" // fmv.d.x f31, zero
#endif
// set the user stack pointer
"mv sp, %0\n"
// zero out the rest of the integer state
"li a0, 0\n"
"li a1, 0\n"
"li a2, 0\n"

View File

@@ -63,6 +63,8 @@
#define RISCV_CSR_XSTATUS_SPP (1ul << 8)
#define RISCV_CSR_XSTATUS_SUM (1ul << 18)
#define RISCV_CSR_XSTATUS_MXR (1ul << 19)
#define RISCV_CSR_XSTATUS_FS_SHIFT (13)
#define RISCV_CSR_XSTATUS_FS_MASK (3ul << RISCV_CSR_XSTATUS_FS_SHIFT)
#define RISCV_CSR_XIE_SIE (1ul << (RISCV_XMODE_OFFSET + 0))
#define RISCV_CSR_XIE_TIE (1ul << (RISCV_XMODE_OFFSET + 4))

View File

@@ -18,17 +18,20 @@ MODULE_CFLAGS += -Wno-override-init
SMP_MAX_CPUS ?= 1
RISCV_MMU ?= none
RISCV_FPU ?= false
SUBARCH ?= 32
RISCV_MODE ?= machine
GLOBAL_DEFINES += SMP_MAX_CPUS=$(SMP_MAX_CPUS)
GLOBAL_DEFINES += PLATFORM_HAS_DYNAMIC_TIMER=1
ifeq ($(WITH_SMP),1)
ifeq (true,$(call TOBOOL,$(WITH_SMP)))
GLOBAL_DEFINES += WITH_SMP=1
endif
SUBARCH ?= 32
RISCV_MODE ?= machine
ifeq (true,$(call TOBOOL,$(RISCV_FPU)))
GLOBAL_DEFINES += RISCV_FPU=1
endif
ifeq ($(strip $(RISCV_MODE)),machine)
$(info RISCV: Machine Mode)
@@ -87,7 +90,7 @@ else
$(error Unknown RISCV_MMU: "$(strip $(RISCV_MMU))" (valid values are "none", "sv32", "sv39", "sv48"))
endif
ifeq ($(WITH_KERNEL_VM),1)
ifeq (true,$(call TOBOOL,$(WITH_KERNEL_VM)))
GLOBAL_DEFINES += \
ARCH_HAS_MMU=1 \