drivers cleanup
This commit is contained in:
parent
5012dfb5b2
commit
36a8e1e2ad
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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");
|
||||
}
|
|
@ -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");
|
||||
}
|
Loading…
Reference in New Issue