[Add] laos base boot
This commit is contained in:
28
laos/src/kernel/console.c
Normal file
28
laos/src/kernel/console.c
Normal 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;
|
||||
|
||||
|
||||
@@ -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
116
laos/src/kernel/kprintf.c
Normal 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;
|
||||
}
|
||||
@@ -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
24
laos/src/kernel/proc.c
Normal 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;
|
||||
}
|
||||
54
laos/src/kernel/spinlock.c
Normal file
54
laos/src/kernel/spinlock.c
Normal 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;
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
Reference in New Issue
Block a user