diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Makefile | 27 | ||||
| -rw-r--r-- | kernel/entry.S | 9 | ||||
| -rw-r--r-- | kernel/main.c | 2 | ||||
| -rw-r--r-- | kernel/param.h | 2 | ||||
| -rw-r--r-- | kernel/printf.c | 43 | ||||
| -rw-r--r-- | kernel/proc.c | 3 | ||||
| -rw-r--r-- | kernel/spinlock.c | 11 | ||||
| -rw-r--r-- | user/printf.c | 35 |
9 files changed, 99 insertions, 34 deletions
@@ -15,3 +15,4 @@ mkfs kernel/kernel user/usys.S .gdbinit +TAGS
\ No newline at end of file @@ -32,21 +32,7 @@ OBJS = \ # riscv64-unknown-elf- or riscv64-linux-gnu- # perhaps in /opt/riscv/bin -#TOOLPREFIX = - -# Try to infer the correct TOOLPREFIX if not set -ifndef TOOLPREFIX -TOOLPREFIX := $(shell if riscv64-unknown-elf-objdump -i 2>&1 | grep 'elf64-big' >/dev/null 2>&1; \ - then echo 'riscv64-unknown-elf-'; \ - elif riscv64-linux-gnu-objdump -i 2>&1 | grep 'elf64-big' >/dev/null 2>&1; \ - then echo 'riscv64-linux-gnu-'; \ - elif riscv64-unknown-linux-gnu-objdump -i 2>&1 | grep 'elf64-big' >/dev/null 2>&1; \ - then echo 'riscv64-unknown-linux-gnu-'; \ - else echo "***" 1>&2; \ - echo "*** Error: Couldn't find a riscv64 version of GCC/binutils." 1>&2; \ - echo "*** To turn off this error, run 'gmake TOOLPREFIX= ...'." 1>&2; \ - echo "***" 1>&2; exit 1; fi) -endif +TOOLPREFIX = /home/aditya/dev/os/riscv-gnu-toolchain/bin/bin/riscv64-unknown-linux-gnu- QEMU = qemu-system-riscv64 @@ -57,7 +43,7 @@ OBJCOPY = $(TOOLPREFIX)objcopy OBJDUMP = $(TOOLPREFIX)objdump CFLAGS = -Wall -Werror -O -fno-omit-frame-pointer -ggdb -CFLAGS += -MD +CFLAGS += -MD -march=rv64i -mabi=lp64 CFLAGS += -mcmodel=medany CFLAGS += -ffreestanding -fno-common -nostdlib -mno-relax CFLAGS += -I. @@ -128,11 +114,13 @@ UPROGS=\ $U/_rm\ $U/_sh\ $U/_stressfs\ - $U/_usertests\ - $U/_grind\ $U/_wc\ $U/_zombie\ +# These two need the M extension + # $U/_grind\ + # $U/_usertests\ + fs.img: mkfs/mkfs README $(UPROGS) mkfs/mkfs fs.img README $(UPROGS) @@ -152,8 +140,9 @@ GDBPORT = $(shell expr `id -u` % 5000 + 25000) QEMUGDB = $(shell if $(QEMU) -help | grep -q '^-gdb'; \ then echo "-gdb tcp::$(GDBPORT)"; \ else echo "-s -p $(GDBPORT)"; fi) + ifndef CPUS -CPUS := 3 +CPUS := 1 endif QEMUOPTS = -machine virt -bios none -kernel $K/kernel -m 128M -smp $(CPUS) -nographic diff --git a/kernel/entry.S b/kernel/entry.S index b72ddbc..8d3bd30 100644 --- a/kernel/entry.S +++ b/kernel/entry.S @@ -12,7 +12,14 @@ _entry: li a0, 1024*4 csrr a1, mhartid addi a1, a1, 1 - mul a0, a0, a1 + + addi t0, a1, 0 + addi t1, a0, 0 +mul: + add a0, a0, t1 + addi t0, t0, -1 + bne t0, zero, mul + add sp, sp, a0 # jump to start() in start.c call start diff --git a/kernel/main.c b/kernel/main.c index 5d7ad49..f486533 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -41,5 +41,5 @@ main() plicinithart(); // ask PLIC for device interrupts } - scheduler(); + scheduler(); } diff --git a/kernel/param.h b/kernel/param.h index b5fdcb2..7852ddb 100644 --- a/kernel/param.h +++ b/kernel/param.h @@ -1,5 +1,5 @@ #define NPROC 64 // maximum number of processes -#define NCPU 8 // maximum number of CPUs +#define NCPU 1 // maximum number of CPUs #define NOFILE 16 // open files per process #define NFILE 100 // open files per system #define NINODE 50 // maximum number of active i-nodes diff --git a/kernel/printf.c b/kernel/printf.c index e1347de..6312689 100644 --- a/kernel/printf.c +++ b/kernel/printf.c @@ -2,6 +2,8 @@ // formatted console output -- printf, panic. // +// TODO Printf to not use mul/div/mod and all that and send stuff to hw-implemented UART + #include <stdarg.h> #include "types.h" @@ -25,13 +27,43 @@ static struct { static char digits[] = "0123456789abcdef"; +int mul(int x, int y) +{ + int ret = x; + for (int tmp = y-1; tmp > 0; tmp--) { + // Add higher and lower 16 bits seperately + // apparently gcc uses muldi3 builtin while adding long long ints + int rettmp = ret; + ret = (((uint16)(x>>16))+((uint16)(rettmp>>16))); + ret += (((uint16)(x&0xffff))+((uint16)(rettmp&0xffff))); + } + return ret; +} + +int mod(int x, int y) +{ + int idx = 0; + for (idx = 0; mul(idx, y) <= x; idx++); + idx = x-mul((idx-1), y); + return idx; +} + +int div(int x, int y) +{ + if (y >= x) + return 0; + int ret = 1; + for (; (x=x-y) >= y; ret++); + return ret; +} + static void printint(int xx, int base, int sign) { char buf[16]; int i; uint x; - + if(sign && (sign = xx < 0)) x = -xx; else @@ -39,8 +71,9 @@ printint(int xx, int base, int sign) i = 0; do { - buf[i++] = digits[x % base]; - } while((x /= base) != 0); + buf[i++] = digits[mod(x, base)]; + x = div(x, base); + } while(x != 0); if(sign) buf[i++] = '-'; @@ -55,8 +88,8 @@ printptr(uint64 x) int i; consputc('0'); consputc('x'); - for (i = 0; i < (sizeof(uint64) * 2); i++, x <<= 4) - consputc(digits[x >> (sizeof(uint64) * 8 - 4)]); + for (i = 0; i < (mul(sizeof(uint64), 2)); i++, x <<= 4) + consputc(digits[x >> (mul(sizeof(uint64), 8) - 4)]); } // Print to the console. only understands %d, %x, %p, %s. diff --git a/kernel/proc.c b/kernel/proc.c index 22e7ce4..35097f5 100644 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -439,12 +439,11 @@ scheduler(void) { struct proc *p; struct cpu *c = mycpu(); - + c->proc = 0; for(;;){ // Avoid deadlock by ensuring that devices can interrupt. intr_on(); - for(p = proc; p < &proc[NPROC]; p++) { acquire(&p->lock); if(p->state == RUNNABLE) { diff --git a/kernel/spinlock.c b/kernel/spinlock.c index 9840302..9603578 100644 --- a/kernel/spinlock.c +++ b/kernel/spinlock.c @@ -25,18 +25,23 @@ acquire(struct spinlock *lk) if(holding(lk)) panic("acquire"); + // TODO This depends on a macro that is only available in the Atomic extension that is + // not being implemented. Fix this. + // When NCPU is set to 1 (as is currently the case), disabling this shouldn't make a difference. + // On RISC-V, sync_lock_test_and_set turns into an atomic swap: // a5 = 1 // s1 = &lk->locked // amoswap.w.aq a5, a5, (s1) - while(__sync_lock_test_and_set(&lk->locked, 1) != 0) - ; + while (lk->locked == 1); + lk->locked = 1; + /* while(__sync_lock_test_and_set(&lk->locked, 1) != 0); */ // Tell the C compiler and the processor to not move loads or stores // past this point, to ensure that the critical section's memory // references happen strictly after the lock is acquired. // On RISC-V, this emits a fence instruction. - __sync_synchronize(); + /* __sync_synchronize(); */ // Record info about lock acquisition for holding() and debugging. lk->cpu = mycpu(); diff --git a/user/printf.c b/user/printf.c index 5c5c782..2b9cd06 100644 --- a/user/printf.c +++ b/user/printf.c @@ -12,6 +12,36 @@ putc(int fd, char c) write(fd, &c, 1); } +int mul(int x, int y) +{ + int ret = x; + for (int tmp = y-1; tmp > 0; tmp--) { + // Add higher and lower 16 bits seperately + // apparently gcc uses muldi3 builtin while adding long long ints + int rettmp = ret; + ret = (((uint16)(x>>16))+((uint16)(rettmp>>16))); + ret += (((uint16)(x&0xffff))+((uint16)(rettmp&0xffff))); + } + return ret; +} + +int mod(int x, int y) +{ + int idx = 0; + for (idx = 0; mul(idx, y) <= x; idx++); + idx = x-mul((idx-1), y); + return idx; +} + +int div(int x, int y) +{ + if (y >= x) + return 0; + int ret = 1; + for (; (x=x-y) >= y; ret++); + return ret; +} + static void printint(int fd, int xx, int base, int sgn) { @@ -29,8 +59,9 @@ printint(int fd, int xx, int base, int sgn) i = 0; do{ - buf[i++] = digits[x % base]; - }while((x /= base) != 0); + buf[i++] = digits[mod(x, base)]; + x = div(x, base); + }while(x != 0); if(neg) buf[i++] = '-'; |
