add riscv64-nemu
This commit is contained in:
parent
e4e5d03fa6
commit
11059d5b6f
11 changed files with 227 additions and 2 deletions
15
am/include/arch/riscv64-nemu.h
Normal file
15
am/include/arch/riscv64-nemu.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef ARCH_H__
|
||||||
|
#define ARCH_H__
|
||||||
|
|
||||||
|
struct Context {
|
||||||
|
uintptr_t epc, cause, gpr[32], status;
|
||||||
|
void *pdir;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define GPR1 gpr[17] // a7
|
||||||
|
#define GPR2 gpr[0]
|
||||||
|
#define GPR3 gpr[0]
|
||||||
|
#define GPR4 gpr[0]
|
||||||
|
#define GPRx gpr[0]
|
||||||
|
|
||||||
|
#endif
|
|
@ -9,7 +9,7 @@
|
||||||
# define nemu_trap(code) asm volatile (".byte 0xd6" : :"a"(code))
|
# define nemu_trap(code) asm volatile (".byte 0xd6" : :"a"(code))
|
||||||
#elif defined(__ISA_MIPS32__)
|
#elif defined(__ISA_MIPS32__)
|
||||||
# define nemu_trap(code) asm volatile ("move $v0, %0; .word 0xf0000000" : :"r"(code))
|
# define nemu_trap(code) asm volatile ("move $v0, %0; .word 0xf0000000" : :"r"(code))
|
||||||
#elif defined(__ISA_RISCV32__)
|
#elif defined(__ISA_RISCV32__) || defined(__ISA_RISCV64__)
|
||||||
# define nemu_trap(code) asm volatile("mv a0, %0; .word 0x0000006b" : :"r"(code))
|
# define nemu_trap(code) asm volatile("mv a0, %0; .word 0x0000006b" : :"r"(code))
|
||||||
#elif
|
#elif
|
||||||
# error unsupported ISA __ISA__
|
# error unsupported ISA __ISA__
|
||||||
|
|
4
am/src/nemu/isa/riscv64/boot/loader.ld
Normal file
4
am/src/nemu/isa/riscv64/boot/loader.ld
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
_pmem_start = 0x80000000;
|
||||||
|
|
||||||
|
/* at $(AM_HOME)/am/src/nemu/scripts/section.ld */
|
||||||
|
INCLUDE "section.ld"
|
8
am/src/nemu/isa/riscv64/boot/start.S
Normal file
8
am/src/nemu/isa/riscv64/boot/start.S
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
.section entry, "ax"
|
||||||
|
.globl _start
|
||||||
|
.type _start, @function
|
||||||
|
|
||||||
|
_start:
|
||||||
|
mv s0, zero
|
||||||
|
la sp, _stack_pointer
|
||||||
|
jal _trm_init
|
46
am/src/nemu/isa/riscv64/cte.c
Normal file
46
am/src/nemu/isa/riscv64/cte.c
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#include <am.h>
|
||||||
|
#include <nemu.h>
|
||||||
|
#include <klib.h>
|
||||||
|
|
||||||
|
static Context* (*user_handler)(Event, Context*) = NULL;
|
||||||
|
|
||||||
|
Context* __am_irq_handle(Context *c) {
|
||||||
|
if (user_handler) {
|
||||||
|
Event ev = {0};
|
||||||
|
switch (c->cause) {
|
||||||
|
default: ev.event = EVENT_ERROR; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = user_handler(ev, c);
|
||||||
|
assert(c != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void __am_asm_trap(void);
|
||||||
|
|
||||||
|
bool cte_init(Context*(*handler)(Event, Context*)) {
|
||||||
|
// initialize exception entry
|
||||||
|
asm volatile("csrw stvec, %0" : : "r"(__am_asm_trap));
|
||||||
|
|
||||||
|
// register event handler
|
||||||
|
user_handler = handler;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Context *kcontext(Area kstack, void (*entry)(void *), void *arg) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void yield() {
|
||||||
|
asm volatile("li a7, -1; ecall");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ienabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void iset(bool enable) {
|
||||||
|
}
|
51
am/src/nemu/isa/riscv64/trap.S
Normal file
51
am/src/nemu/isa/riscv64/trap.S
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
|
||||||
|
#define concat_temp(x, y) x ## y
|
||||||
|
#define concat(x, y) concat_temp(x, y)
|
||||||
|
#define MAP(c, f) c(f)
|
||||||
|
|
||||||
|
#define REGS(f) \
|
||||||
|
f( 1) f( 3) f( 4) f( 5) f( 6) f( 7) f( 8) f( 9) \
|
||||||
|
f(10) f(11) f(12) f(13) f(14) f(15) f(16) f(17) f(18) f(19) \
|
||||||
|
f(20) f(21) f(22) f(23) f(24) f(25) f(26) f(27) f(28) f(29) \
|
||||||
|
f(30) f(31)
|
||||||
|
|
||||||
|
#define PUSH(n) sd concat(x, n), (n * 8)(sp);
|
||||||
|
#define POP(n) ld concat(x, n), (n * 8)(sp);
|
||||||
|
|
||||||
|
#define CONTEXT_SIZE ((32 + 3) * 8)
|
||||||
|
#define OFFSET_SP ( 2 * 8)
|
||||||
|
#define OFFSET_CAUSE (32 * 8)
|
||||||
|
#define OFFSET_STATUS (33 * 8)
|
||||||
|
#define OFFSET_EPC (34 * 8)
|
||||||
|
|
||||||
|
.globl __am_asm_trap
|
||||||
|
__am_asm_trap:
|
||||||
|
addi sp, sp, -CONTEXT_SIZE
|
||||||
|
|
||||||
|
MAP(REGS, PUSH)
|
||||||
|
|
||||||
|
mv t0, sp
|
||||||
|
addi t0, t0, CONTEXT_SIZE
|
||||||
|
sd t0, OFFSET_SP(sp)
|
||||||
|
|
||||||
|
csrr t0, scause
|
||||||
|
csrr t1, sstatus
|
||||||
|
csrr t2, sepc
|
||||||
|
|
||||||
|
sd t0, OFFSET_CAUSE(sp)
|
||||||
|
sd t1, OFFSET_STATUS(sp)
|
||||||
|
sd t2, OFFSET_EPC(sp)
|
||||||
|
|
||||||
|
mv a0, sp
|
||||||
|
jal __am_irq_handle
|
||||||
|
|
||||||
|
ld t1, OFFSET_STATUS(sp)
|
||||||
|
ld t2, OFFSET_EPC(sp)
|
||||||
|
csrw sstatus, t1
|
||||||
|
csrw sepc, t2
|
||||||
|
|
||||||
|
MAP(REGS, POP)
|
||||||
|
|
||||||
|
addi sp, sp, CONTEXT_SIZE
|
||||||
|
|
||||||
|
sret
|
74
am/src/nemu/isa/riscv64/vme.c
Normal file
74
am/src/nemu/isa/riscv64/vme.c
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
#include <am.h>
|
||||||
|
#include <nemu.h>
|
||||||
|
#include <klib.h>
|
||||||
|
|
||||||
|
static AddrSpace kas = {};
|
||||||
|
static void* (*pgalloc_usr)(int) = NULL;
|
||||||
|
static void (*pgfree_usr)(void*) = NULL;
|
||||||
|
static int vme_enable = 0;
|
||||||
|
|
||||||
|
static Area segments[] = { // Kernel memory mappings
|
||||||
|
NEMU_PADDR_SPACE
|
||||||
|
};
|
||||||
|
|
||||||
|
#define USER_SPACE RANGE(0x40000000, 0x80000000)
|
||||||
|
|
||||||
|
static inline void set_satp(void *pdir) {
|
||||||
|
uintptr_t mode = 8ull << 60;
|
||||||
|
asm volatile("csrw satp, %0" : : "r"(mode | ((uintptr_t)pdir >> 12)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uintptr_t get_satp() {
|
||||||
|
uintptr_t satp;
|
||||||
|
asm volatile("csrr %0, satp" : "=r"(satp));
|
||||||
|
return satp << 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vme_init(void* (*pgalloc_f)(int), void (*pgfree_f)(void*)) {
|
||||||
|
pgalloc_usr = pgalloc_f;
|
||||||
|
pgfree_usr = pgfree_f;
|
||||||
|
|
||||||
|
kas.ptr = pgalloc_f(PGSIZE);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < LENGTH(segments); i ++) {
|
||||||
|
void *va = segments[i].start;
|
||||||
|
for (; va < segments[i].end; va += PGSIZE) {
|
||||||
|
map(&kas, va, va, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set_satp(kas.ptr);
|
||||||
|
vme_enable = 1;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void protect(AddrSpace *as) {
|
||||||
|
PTE *updir = (PTE*)(pgalloc_usr(PGSIZE));
|
||||||
|
as->ptr = updir;
|
||||||
|
as->area = USER_SPACE;
|
||||||
|
as->pgsize = PGSIZE;
|
||||||
|
// map kernel space
|
||||||
|
memcpy(updir, kas.ptr, PGSIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unprotect(AddrSpace *as) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void __am_get_cur_as(Context *c) {
|
||||||
|
c->pdir = (vme_enable ? (void *)get_satp() : NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __am_switch(Context *c) {
|
||||||
|
if (vme_enable && c->pdir != NULL) {
|
||||||
|
set_satp(c->pdir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void map(AddrSpace *as, void *va, void *pa, int prot) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Context *ucontext(AddrSpace *as, Area kstack, void *entry) {
|
||||||
|
return NULL;
|
||||||
|
}
|
|
@ -12,6 +12,6 @@ int cpu_current() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int atomic_xchg(int *addr, intptr_t newval) {
|
int atomic_xchg(int *addr, int newval) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
20
am/src/riscv64.h
Normal file
20
am/src/riscv64.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef RISCV64_H__
|
||||||
|
#define RISCV64_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
static inline uint8_t inb(uintptr_t addr) { return *(volatile uint8_t *)addr; }
|
||||||
|
static inline uint16_t inw(uintptr_t addr) { return *(volatile uint16_t *)addr; }
|
||||||
|
static inline uint32_t inl(uintptr_t addr) { return *(volatile uint32_t *)addr; }
|
||||||
|
|
||||||
|
static inline void outb(uintptr_t addr, uint8_t data) { *(volatile uint8_t *)addr = data; }
|
||||||
|
static inline void outw(uintptr_t addr, uint16_t data) { *(volatile uint16_t *)addr = data; }
|
||||||
|
static inline void outl(uintptr_t addr, uint32_t data) { *(volatile uint32_t *)addr = data; }
|
||||||
|
|
||||||
|
#define PTE_V 0x01
|
||||||
|
#define PTE_R 0x02
|
||||||
|
#define PTE_W 0x04
|
||||||
|
#define PTE_X 0x08
|
||||||
|
#define PTE_U 0x10
|
||||||
|
|
||||||
|
#endif
|
5
scripts/isa/riscv64.mk
Normal file
5
scripts/isa/riscv64.mk
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
CROSS_COMPILE := riscv64-linux-gnu-
|
||||||
|
COMMON_FLAGS := -fno-pic -march=rv64g -mcmodel=medany
|
||||||
|
CFLAGS += $(COMMON_FLAGS) -static
|
||||||
|
ASFLAGS += $(COMMON_FLAGS) -O0
|
||||||
|
LDFLAGS += -melf64lriscv
|
2
scripts/riscv64-nemu.mk
Normal file
2
scripts/riscv64-nemu.mk
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
include $(AM_HOME)/scripts/isa/riscv64.mk
|
||||||
|
include $(AM_HOME)/scripts/platform/nemu.mk
|
Loading…
Add table
Reference in a new issue