drivers cleanup

This commit is contained in:
Guokai Chen 2022-04-23 20:51:48 +08:00
parent 5012dfb5b2
commit 36a8e1e2ad
8 changed files with 93 additions and 71 deletions

View File

@ -111,6 +111,18 @@ void custom_handler_reg(uintptr_t code, _Context*(*handler)(_Event, _Context*))
break;
default:
printf("Unrecognized code, custom handler reg ignored\n");
_halt(2);
}
}
void irq_handler_reg(uintptr_t code, _Context*(*handler)(_Event*, _Context*)) {
uintptr_t offset = (code << 1) >> 1;
if (INTR_BIT & code) {
assert(offset < INTERRUPT_CAUSE_SIZE);
interrupt_handler[offset] = handler;
} else {
assert(offset < EXCEPTION_CAUSE_SIZE);
exception_handler[offset] = handler;
}
}

View File

@ -1,6 +1,6 @@
#include <riscv.h>
#include <nemu.h>
// #include <printf.h>
extern void __am_timervec(void);
static void init_machine_exception() {
@ -28,16 +28,16 @@ void __am_init_cte64() {
asm volatile("csrw medeleg, %0" : : "r"(0xfffb));
// set PMP to access all memory in S-mode
asm volatile("csrw pmpaddr8, %0" : : "r"(-1));
asm volatile("csrw pmpcfg2, %0" : : "r"(31));
#include <printf.h>
// asm volatile("csrw pmpaddr8, %0" : : "r"(-1));
// asm volatile("csrw pmpcfg2, %0" : : "r"(31));
init_pmp();
// protect 0x90000000 + 0x10000 for test purpose
enable_pmp(1, 0x90000000, 0x10000, 0, 0);
printf("pmp NA inited\n");
// printf("pmp NA inited\n");
// protect 0xb00000000 + 0x100
enable_pmp_TOR(4, 0xb0000000, 0x100, 0, 0);
printf("pmp TOR inited\n");
//printf("pmp TOR inited\n");
init_machine_exception();
init_timer();

View File

@ -12,13 +12,13 @@ static int vme_enable = 0;
static const _Area segments[] = { // Kernel memory mappings
#if defined(__ARCH_RISCV64_NOOP) || defined(__ARCH_RISCV64_XS)
RANGE_LEN(0x80000000, 0x30000), // PMEM
RANGE_LEN(0xc0000000, 0x100000), // page table
RANGE_LEN(0x80000000, 0x8000000), // PMEM
RANGE_LEN(0x40600000, 0x1000), // uart
RANGE_LEN(CLINT_MMIO, 0x10000), // clint/timer
// RANGE_LEN(FB_ADDR, 0x400000), // vmem
// RANGE_LEN(SCREEN_ADDR,0x1000), // vmem
// RANGE_LEN(0x3c000000, 0x400000), // PLIC
RANGE_LEN(FB_ADDR, 0x400000), // vmem
RANGE_LEN(SCREEN_ADDR,0x1000), // vmem
RANGE_LEN(0x3c000000, 0x4000000), // PLIC
// RANGE_LEN(0xc0000000, 0x100000), // page table test allocates from this position
#else
NEMU_PADDR_SPACE,
#if __riscv_xlen == 64

View File

@ -14,6 +14,12 @@ void init_timer();
void enable_timer();
void set_timer_inc(uintptr_t inc);
// PMP related driver functions
void init_pmp();
void enable_pmp(uintptr_t pmp_reg, uintptr_t pmp_addr, uintptr_t pmp_size, uint8_t lock, uint8_t permission);
void enable_pmp_TOR(uintptr_t pmp_reg, uintptr_t pmp_addr, uintptr_t pmp_size, bool lock, uint8_t permission);
void disable_pmp(uintptr_t pmp_reg);
// plic related driver functions
uint32_t plic_get_claim(uint32_t current_context);
void plic_clear_intr(uint32_t claim);

View File

@ -172,6 +172,10 @@ void init_pmp() {
for (int i = 0; i < PMP_COUNT; i++) {
csr_write_num(PMPADDR_BASE + i, -1L);
}
// set PMP to access all memory in S-mode
// asm volatile("csrw pmpaddr8, %0" : : "r"(-1));
asm volatile("csrw pmpcfg2, %0" : : "r"(31));
asm volatile("sfence.vma");
}
@ -189,11 +193,10 @@ void enable_pmp(uintptr_t pmp_reg, uintptr_t pmp_addr, uintptr_t pmp_size, uint8
uintptr_t set_content = permission | (lock << 7) | (pmp_size == 4 ? 2 : 3) << 3;
uintptr_t cfg_offset = pmp_reg > 7 ? 2 : 0;
uintptr_t cfg_shift = pmp_reg & 0x7;
printf("addr %llx, cfg offset %d, shift %d, set_content %d\n", pmp_addr, cfg_offset, cfg_shift, set_content);
// printf("addr %llx, cfg offset %d, shift %d, set_content %d\n", pmp_addr, cfg_offset, cfg_shift, set_content);
csr_set_num(PMPCFG_BASE + cfg_offset, set_content << (cfg_shift * 8));
asm volatile("sfence.vma");
}
#include <printf.h>
void enable_pmp_TOR(uintptr_t pmp_reg, uintptr_t pmp_addr, uintptr_t pmp_size, bool lock, uint8_t permission) {
// similar interface but different implementation
// pmp reg and pmp reg + 1 will be used
@ -202,13 +205,13 @@ void enable_pmp_TOR(uintptr_t pmp_reg, uintptr_t pmp_addr, uintptr_t pmp_size, b
if (pmp_reg) {
csr_write_num(PMPADDR_BASE + pmp_reg - 1, pmp_addr >> 2);
}
printf("finished writing ADDR\n");
// printf("finished writing ADDR\n");
uintptr_t set_content = permission | (lock << 7) | (1 << 3);
uintptr_t cfg_offset = pmp_reg > 7 ? 2 : 0;
uintptr_t cfg_shift = pmp_reg & 0x7;
printf("addr %llx, cfg offset %d, shift %d, set_content %d\n", pmp_addr, cfg_offset, cfg_shift, set_content);
// printf("addr %llx, cfg offset %d, shift %d, set_content %d\n", pmp_addr, cfg_offset, cfg_shift, set_content);
csr_set_num(PMPCFG_BASE + cfg_offset, set_content << (cfg_shift * 8));
printf("finished writing CFG\n");
// printf("finished writing CFG\n");
asm volatile("sfence.vma");
}

View File

@ -15,61 +15,8 @@ static const char *tests[256] = {
['p'] = "x86 virtual memory test",
};
#define PMP_3
void pmp_test() {
printf("start pmp test\n");
#ifdef PMP_1
volatile int *a = (int *)(0x90000040UL);
*a = 1; // should trigger a fault
#endif
#ifdef PMP_2
int *b = (int *)(0xa0000000UL);
*b = 1; // should not trigger a fault
#endif
#ifdef PMP_3
int *c = (int *)(0xb00000040UL);
*c = 1; // should trigger a fault
#endif
asm volatile("ebreak");
}
static char *sv39_alloc_base = (char *)(0xc0000000UL);
static uintptr_t sv39_alloced_size = 0;
void* sv39_pgalloc(size_t pg_size) {
assert(pg_size == 0x1000);
printf("sv39 pgalloc called\n");
void *ret = (void *)(sv39_alloc_base + sv39_alloced_size);
sv39_alloced_size += pg_size;
return ret;
}
void sv39_pgfree(void *ptr) {
return ;
}
extern _AddressSpace kas;
#include <riscv.h>
void sv39_test() {
printf("start sv39 test\n");
_vme_init(sv39_pgalloc, sv39_pgfree);
printf("sv39 setup done\n");
_map(&kas, (void *)0x900000000UL, (void *)0x80020000, PTE_R | PTE_A | PTE_D);
_map(&kas, (void *)0xa00000000UL, (void *)0x80020000, PTE_W | PTE_R | PTE_A | PTE_D);
_map(&kas, (void *)0xb00000000UL, (void *)0x80020000, PTE_A | PTE_D);
printf("memory map done\n");
char *w_ptr = (char *)(0xa00000000UL);
char *r_ptr = (char *)(0x900000000UL);
char *fault_ptr = (char *)(0xb00000000UL);
*w_ptr = 'a';
printf("sv39 data written\n");
assert(*r_ptr == 'a');
printf("triggering fault\n");
*fault_ptr = 'b';
printf("should not reach here!\n");
}
int main(const char *args) {
char arg = 'e';
char arg = 's';
switch (arg) {
CASE('h', hello);
CASE('i', hello_intr, IOE, CTE(simple_trap), REEH(simple_trap), RCEH(simple_trap));

View File

@ -0,0 +1,20 @@
#include <amtest.h>
#define PMP_1
void pmp_test() {
printf("start pmp test\n");
#ifdef PMP_1
volatile int *a = (int *)(0x90000040UL);
*a = 1; // should trigger a fault
#endif
#ifdef PMP_2
int *b = (int *)(0xa0000000UL);
*b = 1; // should not trigger a fault
#endif
#ifdef PMP_3
int *c = (int *)(0xb00000040UL);
*c = 1; // should trigger a fault
#endif
asm volatile("ebreak");
}

View File

@ -0,0 +1,34 @@
#include <amtest.h>
static char *sv39_alloc_base = (char *)(0xc0000000UL);
static uintptr_t sv39_alloced_size = 0;
void* sv39_pgalloc(size_t pg_size) {
assert(pg_size == 0x1000);
printf("sv39 pgalloc called\n");
void *ret = (void *)(sv39_alloc_base + sv39_alloced_size);
sv39_alloced_size += pg_size;
return ret;
}
void sv39_pgfree(void *ptr) {
return ;
}
extern _AddressSpace kas;
#include <riscv.h>
void sv39_test() {
printf("start sv39 test\n");
_vme_init(sv39_pgalloc, sv39_pgfree);
printf("sv39 setup done\n");
_map(&kas, (void *)0x900000000UL, (void *)0x80020000, PTE_R | PTE_A | PTE_D);
_map(&kas, (void *)0xa00000000UL, (void *)0x80020000, PTE_W | PTE_R | PTE_A | PTE_D);
_map(&kas, (void *)0xb00000000UL, (void *)0x80020000, PTE_A | PTE_D);
printf("memory map done\n");
char *w_ptr = (char *)(0xa00000000UL);
char *r_ptr = (char *)(0x900000000UL);
char *fault_ptr = (char *)(0xb00000000UL);
*w_ptr = 'a';
printf("sv39 data written\n");
assert(*r_ptr == 'a');
printf("triggering fault\n");
*fault_ptr = 'b';
printf("should not reach here!\n");
}