[Add] laos base boot

This commit is contained in:
bLueriVerLHR
2023-05-21 00:48:04 +08:00
parent 5d31bf294c
commit 029a8823f4
34 changed files with 927 additions and 18 deletions

28
laos/src/kernel/console.c Normal file
View File

@@ -0,0 +1,28 @@
#include "console.h"
#include "memio.h"
#include "memlayout.h"
#include "spinlock.h"
void consputc(int c) {
if (c == '\b') {
memb(SERIAL_ADDR) = '\b';
memb(SERIAL_ADDR) = ' ';
memb(SERIAL_ADDR) = '\b';
return;
}
memb(SERIAL_ADDR) = c;
}
struct {
struct spinlock lock;
// input
#define INPUT_BUF_SIZE 128
char buf[INPUT_BUF_SIZE];
uint r; // Read index
uint w; // Write index
uint e; // Edit index
} cons;

View File

@@ -8,13 +8,13 @@ _entry:
# with a 4096-byte stack per CPU.
# sp = stack0 + (hartid * 4096)
la.global $sp, stack0
lu12i.w $a0, (1024*4 >> 12) & 0xfffff
addi.w $a0, $a0, 1024*4 & 0xfff
csrrd $a1, CPUID
addi.w $a1, $a1, 1
mul.w $a0, $a0, $a1
add.w $sp, $sp, $a0
lu12i.w $a0, (1024*4 >> 12) & 0xfffff
addi.w $a0, $a0, 1024*4 & 0xfff
csrrd $a1, CPUID
addi.w $a1, $a1, 1
mul.w $a0, $a0, $a1
add.w $sp, $sp, $a0
# jump to start() in start.c
bl start
bl start
spin:
b spin

116
laos/src/kernel/kprintf.c Normal file
View File

@@ -0,0 +1,116 @@
#include <stdarg.h>
#include "latype.h"
#include "console.h"
#include "kprintf.h"
#include "spinlock.h"
volatile int panicked = 0;
// lock to avoid interleaving concurrent printf's.
static struct {
struct spinlock lock;
int locking;
} pr;
static char digits[] = "0123456789abcdef";
static void print_int(int xx, int base, int sign) {
char buf[32];
int i;
uint x;
if (sign && (sign = xx < 0)) {
x = -xx;
} else {
x = xx;
}
i = 0;
do {
buf[i++] = digits[x % base];
} while ((x /= base) != 0);
if(sign) {
buf[i++] = '-';
}
while(--i >= 0)
consputc(buf[i]);
}
static void print_ptr(intptr_t x) {
consputc('0');
consputc('x');
for (int i = 0; i < (sizeof(intptr_t) * 2); i++, x <<= 4)
consputc(digits[x >> (sizeof(intptr_t) * 8 - 4)]);
}
void kprintf(char *fmt, ...) {
va_list ap;
int i, c, locking;
char *s;
locking = pr.locking;
if(locking)
acquire(&pr.lock);
if (fmt == 0)
panic("null fmt");
va_start(ap, fmt);
for (i = 0; (c = fmt[i] & 0xff) != 0; i++) {
if (c != '%') {
consputc(c);
continue;
}
c = fmt[++i] & 0xff;
if (c == 0) {
break;
}
switch (c) {
case 'd':
print_int(va_arg(ap, int), 10, 1);
break;
case 'x':
print_int(va_arg(ap, int), 16, 1);
break;
case 'p':
print_ptr(va_arg(ap, intptr_t));
break;
case 's':
if((s = va_arg(ap, char*)) == 0)
s = "(null)";
for(; *s; s++)
consputc(*s);
break;
case '%':
consputc('%');
break;
default:
// Print unknown % sequence to draw attention.
consputc('%');
consputc(c);
break;
}
}
va_end(ap);
if(locking)
release(&pr.lock);
}
void panic(char *s) {
pr.locking = 0;
kprintf("panic: ");
kprintf(s);
kprintf("\n");
panicked = 1; // freeze serial output from other CPUs
for(;;)
;
}
void kprintf_init(void) {
initlock(&pr.lock, "pr");
pr.locking = 1;
}

View File

@@ -1,3 +1,25 @@
#include "la32r.h"
#include "spinlock.h"
volatile static int started = 0;
void main() {
struct spinlock lck[1];
initlock(lck, "main");
acquire(lck);
if (r_cpuid() == 0) {
synchronize();
started = 1;
} else {
// 当前假定只有一个 hart
while (started == 0)
;
synchronize();
}
}

24
laos/src/kernel/proc.c Normal file
View File

@@ -0,0 +1,24 @@
#include "proc.h"
#include "la32r.h"
#include "latype.h"
struct cpu cpus[NCPU];
struct proc proc[NPROC];
struct proc *initproc;
int nextpid = 1;
struct spinlock pid_lock;
// helps ensure that wakeups of wait()ing
// parents are not lost. helps obey the
// memory model when using p->parent.
// must be acquired before any p->lock.
struct spinlock wait_lock;
struct cpu *mycpu() {
int id = r_cpuid();
struct cpu *c = &cpus[id];
return c;
}

View File

@@ -0,0 +1,54 @@
#include "spinlock.h"
#include "la32r.h"
#include "defs.h"
#include "kprintf.h"
#include "proc.h"
void initlock(struct spinlock *lck, char *name) {
lck->name = name;
lck->locked = 0;
lck->cpu = 0;
}
void acquire(struct spinlock *lck) {
if(holding(lck)) {
panic("acquire");
}
do {
// 如果已经上锁了,就等待
while (llw((intptr_t)&lck->locked) == 1)
;
// 此时没有上锁,那就开始抢锁
// 没有抢成功就进入新的循环
} while (scw(1, (intptr_t)&lck->locked) != 1);
synchronize();
lck->cpu = mycpu();
}
void release(struct spinlock *lck) {
if (holding(lck) != 1) {
panic("release");
}
lck->cpu = NULL;
synchronize();
do {
// 标记上
llw((intptr_t)&lck->locked);
// 此时没有 hart 动,那就安全的释放
// 否则重新循环
} while (scw(0, (intptr_t)&lck->locked) != 1);
}
int holding(struct spinlock *lck) {
int r;
r = (lck->locked && lck->cpu == mycpu());
return r;
}

View File

@@ -1,7 +1,20 @@
#include "common.h"
#include "kernel.h"
#include "la32r.h"
__attribute__ ((aligned (16))) char stack0[4096 * NCPU];
void start() {
// 设置特权等级
volatile u32 crmd_info = r_crmd();
crmd_info = crmd_info & 0xfffffffc;
w_crmd(crmd_info);
// ERTN 返回地址
w_eentry((intptr_t)main);
// 设置 tp
int id = r_cpuid();
w_tp(id);
asm volatile("ertn");
}