diff --git a/kernel/kernel.cpp b/kernel/kernel.cpp index 2a85a1e..a9acc34 100644 --- a/kernel/kernel.cpp +++ b/kernel/kernel.cpp @@ -4,165 +4,165 @@ #include #define read_csr(csr) \ - ({ \ - unsigned long __v; \ - asm volatile ("csrr %0, " csr : "=r"(__v) : : "memory");\ - __v;\ - }) + ({ \ + unsigned long __v; \ + asm volatile ("csrr %0, " csr : "=r"(__v) : : "memory");\ + __v;\ + }) #define write_csr(csr, v) \ - ({ \ - unsigned long __v = (v); \ - asm volatile ("csrw " csr ", %0" : : "r"(__v) : "memory");\ - }) + ({ \ + unsigned long __v = (v); \ + asm volatile ("csrw " csr ", %0" : : "r"(__v) : "memory");\ + }) #define set_csr_bits(csr, bits) \ - ({ \ - unsigned long __v = (bits); \ - asm volatile ("csrs " csr ", %0" : : "r"(__v) : "memory");\ - }) + ({ \ + unsigned long __v = (bits); \ + asm volatile ("csrs " csr ", %0" : : "r"(__v) : "memory");\ + }) #define clear_csr_bits(csr, bits) \ - ({ \ - unsigned long __v = (bits); \ - asm volatile ("csrc " csr ", %0" : : "r"(__v) : "memory");\ - }) + ({ \ + unsigned long __v = (bits); \ + asm volatile ("csrc " csr ", %0" : : "r"(__v) : "memory");\ + }) typedef unsigned long sbi_word; /* void sbi_call1(int ext, int func, sbi_word arg0) { - register sbi_word rExt asm("a7") = ext; - register sbi_word rFunc asm("a6") = func; - register sbi_word rArg0 asm("a0") = arg0; - register sbi_word rArg1 asm("a1"); - asm volatile("ecall" : "+r"(rArg0), "=r"(rArg1) : "r"(rExt), "r"(rFunc)); - if(rArg0) - __builtin_trap(); + register sbi_word rExt asm("a7") = ext; + register sbi_word rFunc asm("a6") = func; + register sbi_word rArg0 asm("a0") = arg0; + register sbi_word rArg1 asm("a1"); + asm volatile("ecall" : "+r"(rArg0), "=r"(rArg1) : "r"(rExt), "r"(rFunc)); + if(rArg0) + __builtin_trap(); } void sbi_call2(int ext, int func, sbi_word arg0, sbi_word arg1) { - register sbi_word rExt asm("a7") = ext; - register sbi_word rFunc asm("a6") = func; - register sbi_word rArg0 asm("a0") = arg0; - register sbi_word rArg1 asm("a1") = arg1; - asm volatile("ecall" : "+r"(rArg0), "+r"(rArg1) : "r"(rExt), "r"(rFunc)); - if(rArg0) - __builtin_trap(); + register sbi_word rExt asm("a7") = ext; + register sbi_word rFunc asm("a6") = func; + register sbi_word rArg0 asm("a0") = arg0; + register sbi_word rArg1 asm("a1") = arg1; + asm volatile("ecall" : "+r"(rArg0), "+r"(rArg1) : "r"(rExt), "r"(rFunc)); + if(rArg0) + __builtin_trap(); } */ void fmt(const char *f, ...) { - va_list va; - va_start(va, f); - while(*f) { - if(*f != '{') { + va_list va; + va_start(va, f); + while(*f) { + if(*f != '{') { drivers::opensbi::call(1, 0, *(f++)); - continue; - } - f++; + continue; + } + f++; - while(*f != '}') { - if(!(*f)) - return; - f++; - } - f++; + while(*f != '}') { + if(!(*f)) + return; + f++; + } + f++; - unsigned long v = va_arg(va, unsigned long); - for(int i = 0; i < 16; ++i) { - const char *digits = "0123456789abcdef"; - int d = (v >> (60 - i * 4)) & 0xF; + unsigned long v = va_arg(va, unsigned long); + for(int i = 0; i < 16; ++i) { + const char *digits = "0123456789abcdef"; + int d = (v >> (60 - i * 4)) & 0xF; drivers::opensbi::call(1, 0, digits[d]); - } - } - va_end(va); + } + } + va_end(va); } enum { - pte_valid = 1 << 0, - pte_r = 1 << 1, - pte_w = 1 << 2, - pte_x = 1 << 3, - pte_user = 1 << 4, - pte_access = 1 << 6, - pte_dirty = 1 << 7, + pte_valid = 1 << 0, + pte_r = 1 << 1, + pte_w = 1 << 2, + pte_x = 1 << 3, + pte_user = 1 << 4, + pte_access = 1 << 6, + pte_dirty = 1 << 7, }; enum { - pte_ppn_shift = 10 + pte_ppn_shift = 10 }; struct pt_t { - unsigned long ptes[512]; + unsigned long ptes[512]; } __attribute__((aligned(4096))); enum { - satp_sv48 = 9UL << 60 + satp_sv48 = 9UL << 60 }; const char *exception_strings[] = { - "instruction misaligned", - "instruction access fault", - "illegal instruction", - "breakpoint", - "load misaligned", - "load access fault", - "store misaligned", - "store access fault", - "u-mode ecall", - "s-mode ecall", - "reserved (10)", - "reserved (11)", - "instruction page fault", - "load page fault", - "reserved (14)", - "store page fault", + "instruction misaligned", + "instruction access fault", + "illegal instruction", + "breakpoint", + "load misaligned", + "load access fault", + "store misaligned", + "store access fault", + "u-mode ecall", + "s-mode ecall", + "reserved (10)", + "reserved (11)", + "instruction page fault", + "load page fault", + "reserved (14)", + "store page fault", }; enum { - sie_s_software = (1 << 1), - sie_s_timer = (1 << 5) + sie_s_software = (1 << 1), + sie_s_timer = (1 << 5) }; enum { - sstatus_sie = (1 << 1) + sstatus_sie = (1 << 1) }; void cli() { - clear_csr_bits("sstatus", sstatus_sie); + clear_csr_bits("sstatus", sstatus_sie); } void sti() { - set_csr_bits("sstatus", sstatus_sie); + set_csr_bits("sstatus", sstatus_sie); } typedef struct { - void *sp; + void *sp; } continuation_t; struct task_t; struct isr_frame_t { - task_t *task; - isr_frame_t *next; - unsigned long ra; // Offset 0x10. - unsigned long a[8]; // Offset 0x18. - unsigned long t[7]; // Offset 0x58. - unsigned long s1; // Offset 0x90. - unsigned long sstatus; // Offset 0x98. - unsigned long sepc; // Offset 0xA0. + task_t *task; + isr_frame_t *next; + unsigned long ra; // Offset 0x10. + unsigned long a[8]; // Offset 0x18. + unsigned long t[7]; // Offset 0x58. + unsigned long s1; // Offset 0x90. + unsigned long sstatus; // Offset 0x98. + unsigned long sepc; // Offset 0xA0. }; enum { - kernel_stack_size = 0x10000 + kernel_stack_size = 0x10000 }; struct task_t { - continuation_t cont; - isr_frame_t isr_frames[2]; - isr_frame_t *next_isr; - char kernel_stack[kernel_stack_size]; + continuation_t cont; + isr_frame_t isr_frames[2]; + isr_frame_t *next_isr; + char kernel_stack[kernel_stack_size]; }; task_t task1; @@ -170,80 +170,80 @@ task_t task2; task_t *current_task; continuation_t prepare_stack(void *s_top, void (*mainfn)(continuation_t)) { - void *sp = (void *)((uintptr_t)s_top - 0x78); - *((uint64_t *)((uintptr_t)sp + 0x70)) = (uint64_t)mainfn; - return (continuation_t){.sp = sp}; + void *sp = (void *)((uintptr_t)s_top - 0x78); + *((uint64_t *)((uintptr_t)sp + 0x70)) = (uint64_t)mainfn; + return (continuation_t){.sp = sp}; } extern "C" void save_stack(void (*f)(void *, continuation_t), void *ctx); extern "C" void restore_stack(continuation_t c); void create_task(task_t *task, void (*mainfn)(continuation_t)) { - task->isr_frames[0].task = task; - task->isr_frames[1].task = task; - task->isr_frames[0].next = &task->isr_frames[1]; - task->isr_frames[1].next = 0; - task->next_isr = &task->isr_frames[0]; + task->isr_frames[0].task = task; + task->isr_frames[1].task = task; + task->isr_frames[0].next = &task->isr_frames[1]; + task->isr_frames[1].next = 0; + task->next_isr = &task->isr_frames[0]; - task->cont = prepare_stack((void *)(task->kernel_stack + kernel_stack_size), mainfn); + task->cont = prepare_stack((void *)(task->kernel_stack + kernel_stack_size), mainfn); } void switch_task(void *ctx, continuation_t c) { - task_t *task = (task_t *)ctx; - if(task) { - task->next_isr = (isr_frame_t *)read_csr("sscratch"); - task->cont = c; - } + task_t *task = (task_t *)ctx; + if(task) { + task->next_isr = (isr_frame_t *)read_csr("sscratch"); + task->cont = c; + } - task_t *next; - if(task == &task1) { - next = &task2; - }else{ - next = &task1; - } - current_task = next; + task_t *next; + if(task == &task1) { + next = &task2; + }else{ + next = &task1; + } + current_task = next; - write_csr("sscratch", (unsigned long)next->next_isr); + write_csr("sscratch", (unsigned long)next->next_isr); - restore_stack(next->cont); + restore_stack(next->cont); } extern "C" void isr(); extern "C" void handle_isr(isr_frame_t *frame) { - unsigned long cause = read_csr("scause"); - unsigned long code = cause & ~(1UL << 63); - if(cause & (1UL << 63)) { - if(code == 1) { - fmt("it's an IPI\n"); - clear_csr_bits("sip", sie_s_software); - }else if(code == 5) { // Timer interrupt. - //clear_csr_bits("sie", sie_s_timer); - unsigned long time = read_csr("time"); + unsigned long cause = read_csr("scause"); + unsigned long code = cause & ~(1UL << 63); + if(cause & (1UL << 63)) { + if(code == 1) { + fmt("it's an IPI\n"); + clear_csr_bits("sip", sie_s_software); + }else if(code == 5) { // Timer interrupt. + //clear_csr_bits("sie", sie_s_timer); + unsigned long time = read_csr("time"); drivers::opensbi::call(0x54494D45, 0, time + 100000); - save_stack(switch_task, current_task); - }else{ - fmt("it's an unhandled interrupt, code: {}\n", code); - } - }else{ - if(code == 8) { // Syscall. + save_stack(switch_task, current_task); + }else{ + fmt("it's an unhandled interrupt, code: {}\n", code); + } + }else{ + if(code == 8) { // Syscall. drivers::opensbi::call(1, 0, frame->a[0]); - }else{ - unsigned long sepc = read_csr("sepc"); - fmt("it's an exception at {}\n", sepc); - const char *s = exception_strings[cause]; - while(*s) - drivers::opensbi::call(1, 0, *(s++)); - while(1) - ; - } - } + }else{ + unsigned long sepc = read_csr("sepc"); + fmt("it's an exception at {}\n", sepc); + const char *s = exception_strings[cause]; + while(*s) + drivers::opensbi::call(1, 0, *(s++)); + while(1) + ; + } + } } extern "C" void isr_frame_overflow() { - fmt("isr frame overflow\n"); - while(1) - ; + fmt("isr frame overflow\n"); + while(1) + ; } pt_t pml4; @@ -251,37 +251,37 @@ pt_t pml4; extern "C" void enter_umode(void *entry); void syscall(int n, unsigned long arg0) { - register sbi_word rArg0 asm("a0") = arg0; - register sbi_word rN asm("a7") = n; - asm volatile("ecall" : "+r"(rArg0) : "r"(rN) : "memory"); - if(rArg0) - __builtin_trap(); + register sbi_word rArg0 asm("a0") = arg0; + register sbi_word rN asm("a7") = n; + asm volatile("ecall" : "+r"(rArg0) : "r"(rN) : "memory"); + if(rArg0) + __builtin_trap(); } void task1_umode() { - while(1) - syscall(0, '!'); + while(1) + syscall(0, '!'); } void task1_main(continuation_t c) { - fmt("hello from task1\n"); + fmt("hello from task1\n"); sti(); - //syscall(0, '!'); - //enter_umode((void *)task1_umode); + //syscall(0, '!'); + //enter_umode((void *)task1_umode); } void task2_main(continuation_t c) { - fmt("hello from task2\n"); - sti(); - //while(1) - //fmt("."); + fmt("hello from task2\n"); + sti(); + //while(1) + //fmt("."); } isr_frame_t global_isr_frames[2]; extern "C" void kmain(unsigned long hart, void *dtb) { - (void)hart; - (void)dtb; + (void)hart; + (void)dtb; fmt("test\n"); @@ -296,21 +296,21 @@ extern "C" void kmain(unsigned long hart, void *dtb) { while(1); - cli(); + cli(); - global_isr_frames[0].next = &global_isr_frames[1]; - write_csr("sscratch", (unsigned long)&global_isr_frames[0]); - write_csr("stvec", ((unsigned long)&isr)); + global_isr_frames[0].next = &global_isr_frames[1]; + write_csr("sscratch", (unsigned long)&global_isr_frames[0]); + write_csr("stvec", ((unsigned long)&isr)); - const char *s; + const char *s; - set_csr_bits("sie", sie_s_software | sie_s_timer); + set_csr_bits("sie", sie_s_software | sie_s_timer); - // Self-IPI. + // Self-IPI. drivers::opensbi::call(0x735049, 0, 1 << hart, 0); - sti(); - cli(); + sti(); + cli(); unsigned long time; //volatile uint32_t *meme = (uint32_t *)0x6011010; @@ -320,37 +320,37 @@ extern "C" void kmain(unsigned long hart, void *dtb) { //*meme = *meme | (0xA57 << 1) | (1 << 0); //} - // Identity map the first 512GiB. - pml4.ptes[0] = ((0UL >> 12) << pte_ppn_shift) | pte_valid - | pte_r | pte_w | pte_x | pte_access | pte_dirty | pte_user; - // Map 512GiB -> 0. - pml4.ptes[1] = ((0UL >> 12) << pte_ppn_shift) | pte_valid - | pte_r | pte_w | pte_x | pte_access | pte_dirty | pte_user; + // Identity map the first 512GiB. + pml4.ptes[0] = ((0UL >> 12) << pte_ppn_shift) | pte_valid + | pte_r | pte_w | pte_x | pte_access | pte_dirty | pte_user; + // Map 512GiB -> 0. + pml4.ptes[1] = ((0UL >> 12) << pte_ppn_shift) | pte_valid + | pte_r | pte_w | pte_x | pte_access | pte_dirty | pte_user; fmt("Writing paging memes\n"); - unsigned long pml4p = (unsigned long)&pml4; + unsigned long pml4p = (unsigned long)&pml4; fmt("pml4p @ {}\n", pml4p); fmt("Setting SStatus\n"); - set_csr_bits("sstatus", 1 << 18); + set_csr_bits("sstatus", 1 << 18); fmt("Setting Satp\n"); - write_csr("satp", (pml4p >> 12) | satp_sv48); + write_csr("satp", (pml4p >> 12) | satp_sv48); fmt("Paging might work?...\n"); - s = "paging works!\n"; - s += 512UL * 1024 * 1024 * 1024; - while(*s) - drivers::opensbi::call(1, 0, *(s++)); + s = "paging works!\n"; + s += 512UL * 1024 * 1024 * 1024; + while(*s) + drivers::opensbi::call(1, 0, *(s++)); - create_task(&task1, task1_main); - create_task(&task2, task2_main); + create_task(&task1, task1_main); + create_task(&task2, task2_main); - time = read_csr("time"); + time = read_csr("time"); drivers::opensbi::call(0x54494D45, 0, time + 100000); - save_stack(switch_task, 0); + save_stack(switch_task, 0); drivers::opensbi::call(8, 0, 0); - while(1); + while(1); }