From 70056864f7402b5f8fabe8955bcf2528ceec8531 Mon Sep 17 00:00:00 2001 From: Zihao Yu Date: Sat, 7 Mar 2020 20:28:52 +0800 Subject: [PATCH] riscv64-noop: reuse cte and vme from riscv64-nemu --- am/arch/riscv64-noop.mk | 32 +++--- am/include/arch/riscv64-noop.h | 25 +---- am/src/nemu/include/nemu.h | 4 +- am/src/nemu/isa/riscv/cte64.c | 8 +- am/src/nemu/isa/riscv/vme.c | 12 +- am/src/{riscv64/noop => noop/common}/input.c | 3 +- am/src/noop/common/timer.c | 36 ++++++ .../{riscv64/noop => noop/common}/uartlite.c | 2 +- .../{riscv64/noop => noop/isa/riscv}/instr.c | 8 +- .../{riscv64/noop => noop/isa/riscv}/perf.c | 0 am/src/{riscv64/noop => noop/isa/riscv}/trm.c | 10 +- am/src/riscv64/noop/cte.c | 99 ---------------- am/src/riscv64/noop/trap.S | 54 --------- am/src/riscv64/noop/vme.c | 106 ------------------ 14 files changed, 92 insertions(+), 307 deletions(-) rename am/src/{riscv64/noop => noop/common}/input.c (96%) create mode 100644 am/src/noop/common/timer.c rename am/src/{riscv64/noop => noop/common}/uartlite.c (97%) rename am/src/{riscv64/noop => noop/isa/riscv}/instr.c (95%) rename am/src/{riscv64/noop => noop/isa/riscv}/perf.c (100%) rename am/src/{riscv64/noop => noop/isa/riscv}/trm.c (81%) delete mode 100644 am/src/riscv64/noop/cte.c delete mode 100644 am/src/riscv64/noop/trap.S delete mode 100644 am/src/riscv64/noop/vme.c diff --git a/am/arch/riscv64-noop.mk b/am/arch/riscv64-noop.mk index cba13923..534b201a 100644 --- a/am/arch/riscv64-noop.mk +++ b/am/arch/riscv64-noop.mk @@ -1,21 +1,25 @@ include $(AM_HOME)/am/arch/isa/riscv64.mk -AM_SRCS := $(ISA)/noop/trm.c \ - $(ISA)/noop/uartlite.c \ - $(ISA)/noop/perf.c \ - $(ISA)/noop/cte.c \ - $(ISA)/noop/trap.S \ - $(ISA)/noop/instr.c \ - $(ISA)/noop/vme.c \ - nemu-common/ioe.c \ - $(ISA)/noop/input.c \ - nemu-common/nemu-timer.c \ - nemu-common/nemu-video.c \ +AM_SRCS := noop/isa/riscv/trm.c \ + noop/isa/riscv/perf.c \ + noop/common/uartlite.c \ + nemu/isa/riscv/cte.c \ + nemu/isa/riscv/trap.S \ + nemu/isa/riscv/cte64.c \ + nemu/isa/riscv/mtime.S \ + nemu/isa/riscv/vme.c \ + nemu/common/ioe.c \ + noop/common/input.c \ + noop/common/timer.c \ + nemu/common/video.c \ + noop/isa/riscv/instr.c \ dummy/mpe.c \ - $(ISA)/nemu/boot/start.S + nemu/isa/riscv/boot/start.S -LDFLAGS += -L $(AM_HOME)/am/src/nemu-common -LDFLAGS += -T $(AM_HOME)/am/src/$(ISA)/nemu/boot/loader.ld +CFLAGS += -I$(AM_HOME)/am/src/nemu/include -DISA_H=\"riscv.h\" + +LDFLAGS += -L $(AM_HOME)/am/src/nemu/ldscript +LDFLAGS += -T $(AM_HOME)/am/src/nemu/isa/riscv/boot/loader64.ld image: @echo + LD "->" $(BINARY_REL).elf diff --git a/am/include/arch/riscv64-noop.h b/am/include/arch/riscv64-noop.h index 335c6e33..bdb51290 100644 --- a/am/include/arch/riscv64-noop.h +++ b/am/include/arch/riscv64-noop.h @@ -1,23 +1,5 @@ #ifndef __ARCH_H__ -#define __ARCH_H__ - -#include - -struct _Context { - union { - struct _AddressSpace *as; - uint64_t gpr[32]; - }; - uint64_t mcause; - uint64_t mstatus; - uint64_t mepc; -}; - -#define GPR1 gpr[17] // a7 -#define GPR2 gpr[10] // a0 -#define GPR3 gpr[11] // a1 -#define GPR4 gpr[12] // a2 -#define GPRx gpr[10] // a0 +#include "riscv64-nemu.h" #define MAP(c, f) c(f) @@ -32,7 +14,10 @@ enum { }; typedef struct { - R64 cnts[NR_PERFCNT]; + union { + struct { uint32_t lo, hi; }; + int64_t val; + } cnts[NR_PERFCNT]; } PerfCntSet; void __am_perfcnt_read(PerfCntSet *t); diff --git a/am/src/nemu/include/nemu.h b/am/src/nemu/include/nemu.h index 58b63284..db52ed13 100644 --- a/am/src/nemu/include/nemu.h +++ b/am/src/nemu/include/nemu.h @@ -20,10 +20,10 @@ # define FB_ADDR 0x40000000 #elif defined(__ARCH_RISCV64_NOOP) # define KBD_ADDR 0x40900000 -# define RTC_ADDR 0x4070bff8 +# define RTC_ADDR 0x4800bff8 # define SCREEN_ADDR 0x40800000 # define SYNC_ADDR 0x40800004 -# define FB_ADDR 0x40000000 +# define FB_ADDR 0x41000000 #else # define SERIAL_PORT 0xa10003f8 # define KBD_ADDR 0xa1000060 diff --git a/am/src/nemu/isa/riscv/cte64.c b/am/src/nemu/isa/riscv/cte64.c index edebc18b..74a92072 100644 --- a/am/src/nemu/isa/riscv/cte64.c +++ b/am/src/nemu/isa/riscv/cte64.c @@ -1,8 +1,14 @@ #include +#ifdef __ARCH_RISCV64_NOOP +#define CLINT_MMIO 0x48000000 +#define TIME_INC 0x80000 +#else #define CLINT_MMIO 0xa2000000 -#define CLINT_MTIMECMP (CLINT_MMIO + 0x4000) #define TIME_INC 0x800 +#endif + +#define CLINT_MTIMECMP (CLINT_MMIO + 0x4000) extern void __am_timervec(void); diff --git a/am/src/nemu/isa/riscv/vme.c b/am/src/nemu/isa/riscv/vme.c index 779d9919..94b93753 100644 --- a/am/src/nemu/isa/riscv/vme.c +++ b/am/src/nemu/isa/riscv/vme.c @@ -6,10 +6,20 @@ static void* (*pgalloc_usr)(size_t) = NULL; static void (*pgfree_usr)(void*) = NULL; static int vme_enable = 0; +#define RANGE_LEN(start, len) RANGE((start), (start + len)) + static const _Area segments[] = { // Kernel memory mappings +#ifdef __ARCH_RISCV64_NOOP + RANGE_LEN(0x80000000, 0x8000000), // PMEM + RANGE_LEN(0x40600000, 0x1000), // uart + RANGE_LEN(0x48000000, 0x10000), // clint/timer + RANGE_LEN(0x41000000, 0x400000), // vmem + RANGE_LEN(0x40800000, 0x1000), // vmem +#else NEMU_PADDR_SPACE, #if __riscv_xlen == 64 - RANGE(0xa2000000, 0xa2000000 + 0x10000), // clint + RANGE_LEN(0xa2000000, 0x10000), // clint +#endif #endif }; diff --git a/am/src/riscv64/noop/input.c b/am/src/noop/common/input.c similarity index 96% rename from am/src/riscv64/noop/input.c rename to am/src/noop/common/input.c index a3b8fb69..e67b81b7 100644 --- a/am/src/riscv64/noop/input.c +++ b/am/src/noop/common/input.c @@ -40,8 +40,9 @@ size_t __am_input_read(uintptr_t reg, void *buf, size_t size) { timestamp = uptime(); } else { int _k = __am_uartlite_getchar(); + if (_k == 255) _k = 0; assert(_k < 128 && _k >= 0); - int key = am_keycode[_k]; + int key = (_k == -1 ? _KEY_NONE : am_keycode[_k]); if (key == _KEY_NONE) { if (last_key != _KEY_NONE) { unsigned long now = uptime(); diff --git a/am/src/noop/common/timer.c b/am/src/noop/common/timer.c new file mode 100644 index 00000000..174377c7 --- /dev/null +++ b/am/src/noop/common/timer.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include + +static unsigned long boot_time = 0; +static inline uint32_t read_time(void) { + return ind(RTC_ADDR) / 1000; // unit: ms +} + +size_t __am_timer_read(uintptr_t reg, void *buf, size_t size) { + switch (reg) { + case _DEVREG_TIMER_UPTIME: { + _DEV_TIMER_UPTIME_t *uptime = (_DEV_TIMER_UPTIME_t *)buf; + uptime->hi = 0; + uptime->lo = read_time() - boot_time; +// printf("lo = %d\n", uptime->lo); + return sizeof(_DEV_TIMER_UPTIME_t); + } + case _DEVREG_TIMER_DATE: { + _DEV_TIMER_DATE_t *rtc = (_DEV_TIMER_DATE_t *)buf; + rtc->second = 0; + rtc->minute = 0; + rtc->hour = 0; + rtc->day = 0; + rtc->month = 0; + rtc->year = 2018; + return sizeof(_DEV_TIMER_DATE_t); + } + } + return 0; +} + +void __am_timer_init() { + boot_time = read_time(); +} diff --git a/am/src/riscv64/noop/uartlite.c b/am/src/noop/common/uartlite.c similarity index 97% rename from am/src/riscv64/noop/uartlite.c rename to am/src/noop/common/uartlite.c index 3a60058e..3b37498e 100644 --- a/am/src/riscv64/noop/uartlite.c +++ b/am/src/noop/common/uartlite.c @@ -1,4 +1,4 @@ -#include +#include #define UARTLITE_MMIO 0x40600000 #define UARTLITE_RX_FIFO 0x0 diff --git a/am/src/riscv64/noop/instr.c b/am/src/noop/isa/riscv/instr.c similarity index 95% rename from am/src/riscv64/noop/instr.c rename to am/src/noop/isa/riscv/instr.c index 766f4c41..5e24fc41 100644 --- a/am/src/riscv64/noop/instr.c +++ b/am/src/noop/isa/riscv/instr.c @@ -1,6 +1,8 @@ #include -#include +#include #include +#include + //TODO: have not done riscv64 software mul/div static uint32_t mul(uint32_t a, uint32_t b, int sign, int hi) { if (a == 0x80000000 && b == 0x80000000) { @@ -83,7 +85,7 @@ int __am_illegal_instr(_Context *c) { }; uint32_t val; } instr; - instr.val = *(uint32_t *)(c->mepc); + instr.val = *(uint32_t *)(c->sepc); if (instr.opcode == 0x33 && instr.func2 == 1) { // M extension @@ -99,7 +101,7 @@ int __am_illegal_instr(_Context *c) { } } - printf("invalid instruction at pc = %x\n", c->mepc); + printf("invalid instruction at pc = %x\n", c->sepc); _halt(1); return false; } diff --git a/am/src/riscv64/noop/perf.c b/am/src/noop/isa/riscv/perf.c similarity index 100% rename from am/src/riscv64/noop/perf.c rename to am/src/noop/isa/riscv/perf.c diff --git a/am/src/riscv64/noop/trm.c b/am/src/noop/isa/riscv/trm.c similarity index 81% rename from am/src/riscv64/noop/trm.c rename to am/src/noop/isa/riscv/trm.c index fbb98415..c7d0c46c 100644 --- a/am/src/riscv64/noop/trm.c +++ b/am/src/noop/isa/riscv/trm.c @@ -1,16 +1,16 @@ #include -#include +#include #include extern char _heap_start; -extern char _heap_end; +extern char _pmem_end; int main(const char *args); void __am_init_uartlite(void); void __am_uartlite_putchar(char ch); _Area _heap = { .start = &_heap_start, - .end = &_heap_end, + .end = &_pmem_end, }; void _putc(char ch) { @@ -29,7 +29,7 @@ void _halt(int code) { void _trm_init() { __am_init_uartlite(); - extern const char _mainargs; - int ret = main(&_mainargs); + const char *mainargs = ""; + int ret = main(mainargs); _halt(ret); } diff --git a/am/src/riscv64/noop/cte.c b/am/src/riscv64/noop/cte.c deleted file mode 100644 index 61d13f9e..00000000 --- a/am/src/riscv64/noop/cte.c +++ /dev/null @@ -1,99 +0,0 @@ -#include -#include -#include - -#define CLINT_MMIO 0x40700000 -#define CLINT_MTIME (CLINT_MMIO + 0xbff8) -#define CLINT_MTIMECMP (CLINT_MMIO + 0x4000) -#define TIME_INC 10 -static inline void inc_mtimecmp(uint64_t this) { - outd(CLINT_MTIMECMP, this + TIME_INC); -} - -static _Context* (*user_handler)(_Event, _Context*) = NULL; - -void __am_get_cur_as(_Context *c); -void __am_switch(_Context *c); - -int __am_illegal_instr(_Context *c); - -#define INTR_BIT (1ULL << 63) - -_Context* __am_irq_handle(_Context *c) { - __am_get_cur_as(c); - - _Context *next = c; - if (user_handler) { - _Event ev = {0}; - switch (c->mcause) { - case 2: - if (__am_illegal_instr(c)) c->mepc += 4; - break; - case (0x7 | INTR_BIT): - inc_mtimecmp(ind(CLINT_MTIME)); - ev.event = _EVENT_IRQ_TIMER; - break; - case (0xb | INTR_BIT): - ev.event = _EVENT_IRQ_IODEV; - break; - case 11: - ev.event = (c->GPR1 == -1) ? _EVENT_YIELD : _EVENT_SYSCALL; - c->mepc += 4; - break; - default: ev.event = _EVENT_ERROR; break; - } - - next = user_handler(ev, c); - if (next == NULL) { - next = c; - } - } - - __am_switch(next); - - return next; -} - -extern void __am_asm_trap(void); - -int _cte_init(_Context*(*handler)(_Event, _Context*)) { - // initialize exception entry - asm volatile("csrw mtvec, %0" : : "r"(__am_asm_trap)); - - // register event handler - user_handler = handler; - - inc_mtimecmp(0); - asm volatile("csrw mie, %0" : : "r"((1 << 7) | (1 << 11))); - - return 0; -} - -_Context *_kcontext(_Area stack, void (*entry)(void *), void *arg) { - _Context *c = (_Context*)stack.end - 1; - - c->mepc = (uintptr_t)entry; - c->mstatus = 0x000c1880; - return c; -} - -void _yield() { - asm volatile("li a7, -1; ecall"); -} - -int _intr_read() { - uintptr_t mstatus; - asm volatile("csrr %0, mstatus" : "=r"(mstatus)); - return (mstatus & 0x8) != 0; -} - -void _intr_write(int enable) { - uintptr_t mstatus; - asm volatile("csrr %0, mstatus" : "=r"(mstatus)); - if (enable) { - mstatus |= 0x8; - } else { - mstatus &= ~0x8; - } - asm volatile("csrw mstatus, %0" : : "r"(mstatus)); -} diff --git a/am/src/riscv64/noop/trap.S b/am/src/riscv64/noop/trap.S deleted file mode 100644 index bf6b826a..00000000 --- a/am/src/riscv64/noop/trap.S +++ /dev/null @@ -1,54 +0,0 @@ -// unmodified for cputest - -#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 ((31 + 4) * 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, mcause - csrr t1, mstatus - csrr t2, mepc - - sd t0, OFFSET_CAUSE(sp) - sd t1, OFFSET_STATUS(sp) - sd t2, OFFSET_EPC(sp) - - mv a0, sp - jal __am_irq_handle - - mv sp, a0 - - ld t1, OFFSET_STATUS(sp) - ld t2, OFFSET_EPC(sp) - csrw mstatus, t1 - csrw mepc, t2 - - MAP(REGS, POP) - - addi sp, sp, CONTEXT_SIZE - - mret diff --git a/am/src/riscv64/noop/vme.c b/am/src/riscv64/noop/vme.c deleted file mode 100644 index 81fcbe50..00000000 --- a/am/src/riscv64/noop/vme.c +++ /dev/null @@ -1,106 +0,0 @@ -#include -#include -#include - -#define PG_ALIGN __attribute((aligned(PGSIZE))) - -static _AddressSpace kas; // Kernel address space -static void* (*pgalloc_usr)(size_t) = NULL; -static void (*pgfree_usr)(void*) = NULL; -static int vme_enable = 0; - -static _Area segments[] = { // Kernel memory mappings - {.start = (void*)0x80000000u, .end = (void*)(0x80000000u + 0x3000000)}, //PMEM_SIZE)}, - {.start = (void*)0x40600000u, .end = (void*)(0x40600000u + 0x1000)}, // uart - {.start = (void*)0x40700000u, .end = (void*)(0x40700000u + 0x1000)}, // clint/timer - {.start = (void*)0x40000000u, .end = (void*)(0x40000000u + 0x400000)}, // vmem - {.start = (void*)0x40800000u, .end = (void*)(0x40800000u + 0x1000)} // vga ctrl -}; - -#define NR_KSEG_MAP (sizeof(segments) / sizeof(segments[0])) - -static inline void set_satp(void *pdir) { - uintptr_t mode = 8ull << 60; - asm volatile("csrw satp, %0" : : "r"(mode | PN(pdir))); -} - -int _vme_init(void* (*pgalloc_f)(size_t), void (*pgfree_f)(void*)) { - pgalloc_usr = pgalloc_f; - pgfree_usr = pgfree_f; - - kas.ptr = pgalloc_f(1); - // make all PTEs invalid - memset(kas.ptr, 0, PGSIZE); - - int i; - for (i = 0; i < NR_KSEG_MAP; 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 0; -} - -int _protect(_AddressSpace *as) { - PTE *updir = (PTE *)(pgalloc_usr(1)); - as->ptr = updir; - // map kernel space - memcpy(updir, kas.ptr, PGSIZE); - - return 0; -} - -void _unprotect(_AddressSpace *as) { -} - -static _AddressSpace *cur_as = NULL; -void __am_get_cur_as(_Context *c) { - c->as = cur_as; -} - -void __am_switch(_Context *c) { - if (vme_enable) { - set_satp(c->as->ptr); - cur_as = c->as; - } -} - -int _map(_AddressSpace *as, void *va, void *pa, int prot) { - PTE *pg_base = as->ptr; - PTE *pte; - int level; - for (level = PTW_LEVEL - 1; level >= 0; level --) { - pte = &pg_base[VPNi((uintptr_t)va, level)]; - pg_base = (PTE *)PTE_ADDR(*pte); - if (level != 0 && !(*pte & PTE_V)) { - pg_base = pgalloc_usr(1); - *pte = PTE_V | (PN(pg_base) << 10); - } - } - - if (!(*pte & PTE_V)) { - *pte = PTE_V | PTE_R | PTE_W | PTE_X | (PN(pa) << 10); - } else { -#define ptr_to_u32(p) ((uint32_t)(uintptr_t)p) - printf("remap: ptr = 0x%08x, vpn = 0x%08x, old ppn = 0x%08x, new ppn = 0x%08x\nSomething may be wrong.", - ptr_to_u32(as->ptr), PN(va), PN(PTE_ADDR(*pte)), PN(pa)); - assert(0); - } - - return 0; -} - -_Context *_ucontext(_AddressSpace *as, _Area ustack, _Area kstack, void *entry, void *args) { - _Context *c = (_Context*)ustack.end - 1; - c->gpr[10] = c->gpr[11] = 0; - - c->as = as; - c->mepc = (uintptr_t)entry; - c->mstatus = 0x000c1880; - return c; -}