summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile27
-rw-r--r--kernel/entry.S9
-rw-r--r--kernel/main.c2
-rw-r--r--kernel/param.h2
-rw-r--r--kernel/printf.c43
-rw-r--r--kernel/proc.c3
-rw-r--r--kernel/spinlock.c11
-rw-r--r--user/printf.c35
9 files changed, 99 insertions, 34 deletions
diff --git a/.gitignore b/.gitignore
index 07216f3..4a146fb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,4 @@ mkfs
kernel/kernel
user/usys.S
.gdbinit
+TAGS \ No newline at end of file
diff --git a/Makefile b/Makefile
index 328f9c6..add9c30 100644
--- a/Makefile
+++ b/Makefile
@@ -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++] = '-';