Kernel: tabs -> spaces

This commit is contained in:
Thomas Muller 2022-01-05 02:50:14 -05:00
parent d5d92555ae
commit 94fbea02ca
Signed by: thomas
GPG key ID: AF006EB730564952

View file

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