summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorAditya Naik2021-01-31 06:05:55 -0500
committerAditya Naik2021-01-31 06:05:55 -0500
commit951e300c10613c8500705d7b54467169be53a7f5 (patch)
tree0ea92fc4b6f75e6c6bb96e37bf26ffe371135f08 /kernel
parent077323a8f0b3440fcc3d082096a2d83fe5461d70 (diff)
With only RISCV64-I extension
Diffstat (limited to 'kernel')
-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
6 files changed, 57 insertions, 13 deletions
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();