aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>2010-07-21 20:12:09 -0700
committerAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>2010-07-21 20:12:09 -0700
commitb24c0f1a1eafa6fe18164d0df81512d3ff42bc1f (patch)
treec05b70f43b22f2dd649ae2fa3cba7bc45acbc93d
parent263c2ff7d8ae261fc2ee2dbf740ba048df9c956d (diff)
downloadpk-b24c0f1a1eafa6fe18164d0df81512d3ff42bc1f.zip
pk-b24c0f1a1eafa6fe18164d0df81512d3ff42bc1f.tar.gz
pk-b24c0f1a1eafa6fe18164d0df81512d3ff42bc1f.tar.bz2
[pk,sim] first cut of appserver communication link
-rw-r--r--Makefile4
-rw-r--r--atomic.h43
-rw-r--r--cop0.h11
-rw-r--r--file.c52
-rw-r--r--file.h5
-rw-r--r--frontend.c26
-rw-r--r--frontend.h8
7 files changed, 133 insertions, 16 deletions
diff --git a/Makefile b/Makefile
index 1ae112e..b73bf20 100644
--- a/Makefile
+++ b/Makefile
@@ -5,8 +5,8 @@ TARGETS := pk
all: $(TARGETS)
-pk: boot.o entry.o pk.o syscall.o file.o pk.ld
- $(CC) -o pk entry.o pk.o syscall.o file.o -T pk.ld
+pk: boot.o entry.o pk.o syscall.o file.o frontend.o pk.ld
+ $(CC) -o pk entry.o pk.o syscall.o file.o frontend.o -T pk.ld
%.o: %.c *.h
$(CC) -c $<
diff --git a/atomic.h b/atomic.h
new file mode 100644
index 0000000..3294b6c
--- /dev/null
+++ b/atomic.h
@@ -0,0 +1,43 @@
+#ifndef _RISCV_ATOMIC_H
+#define _RISCV_ATOMIC_H
+
+typedef struct { long val; } atomic_t;
+typedef struct { atomic_t lock; } spinlock_t;
+#define SPINLOCK_INIT {{0}}
+
+static inline long atomic_add(atomic_t* a, long inc)
+{
+ long old = a->val;
+ a->val += inc;
+ return old;
+}
+
+static inline long atomic_swap(atomic_t* a, long val)
+{
+ long old = a->val;
+ a->val = val;
+ return old;
+}
+
+static inline void atomic_set(atomic_t* a, long val)
+{
+ a->val = val;
+}
+
+static inline long atomic_read(atomic_t* a)
+{
+ return a->val;
+}
+
+static inline void spinlock_lock(spinlock_t* lock)
+{
+ while(atomic_read(&lock->lock))
+ while(atomic_swap(&lock->lock,-1));
+}
+
+static inline void spinlock_unlock(spinlock_t* lock)
+{
+ atomic_set(&lock->lock,0);
+}
+
+#endif
diff --git a/cop0.h b/cop0.h
new file mode 100644
index 0000000..29456a0
--- /dev/null
+++ b/cop0.h
@@ -0,0 +1,11 @@
+#ifndef _RISCV_COP0_H
+#define _RISCV_COP0_H
+
+#define dmtc0(val,reg) ({ long __tmp = (long)(val); \
+ asm volatile ("dmtc0 %0,$%1"::"r"(__tmp),"i"(reg)); })
+
+#define dmfc0(reg) ({ long __tmp; \
+ asm volatile ("dmfc0 %0,$%1" : "=r"(__tmp) : "i"(reg)); \
+ __tmp; })
+
+#endif
diff --git a/file.c b/file.c
index b52ec47..7907bd3 100644
--- a/file.c
+++ b/file.c
@@ -1,31 +1,45 @@
#include <string.h>
+#include <errno.h>
#include "file.h"
#include "pk.h"
+#include "frontend.h"
#define MAX_FDS 1000
file_t* fds[MAX_FDS];
#define MAX_FILES 1000
-file_t files[MAX_FILES];
+file_t files[MAX_FILES] = {[0 ... MAX_FILES-1] = {-1,{0}}};
file_t *stdout, *stdin, *stderr;
static void file_incref(file_t* f)
{
- f->refcnt++;
+ atomic_add(&f->refcnt,1);
}
static void file_decref(file_t* f)
{
- f->refcnt--;
+ if(atomic_add(&f->refcnt,-1) == 2)
+ {
+ if(f->kfd != -1)
+ {
+ frontend_syscall(SYS_close,f->kfd,0,0,0);
+ f->kfd = -1;
+ }
+ atomic_add(&f->refcnt,-1); // I think this could just be atomic_set(..,0)
+ }
}
static file_t* file_get_free()
{
for(int i = 0; i < MAX_FILES; i++)
{
- if(files[i].refcnt == 0)
+ if(atomic_read(&files[i].refcnt) == 0)
{
- files[i].refcnt = 1;
- return &files[i];
+ if(atomic_add(&files[i].refcnt,1) == 0)
+ {
+ atomic_add(&files[i].refcnt,1);
+ return &files[i];
+ }
+ file_decref(&files[i]);
}
}
return NULL;
@@ -41,10 +55,10 @@ static int fd_get_free()
int file_dup(file_t* f)
{
- file_incref(f);
int fd = fd_get_free();
if(fd == -1)
return -1;
+ file_incref(f);
fds[fd] = f;
return fd;
}
@@ -70,9 +84,22 @@ file_t* file_get(int fd)
return fd < 0 || fd >= MAX_FDS ? NULL : fds[fd];
}
-file_t* file_open(const char* fn)
+sysret_t file_open(const char* fn, int mode)
{
- return NULL;
+ file_t* f = file_get_free();
+ if(!f)
+ return (sysret_t){-1,ENOMEM};
+
+ sysret_t ret = frontend_syscall(SYS_open,(long)fn,mode,0,0);
+ if(ret.result != -1)
+ {
+ f->kfd = ret.result;
+ ret.result = (long)f;
+ }
+ else
+ file_decref(f);
+
+ return ret;
}
int fd_close(int fd)
@@ -93,9 +120,10 @@ static void putch(int c)
sysret_t file_write(file_t* f, const void* buf, size_t size)
{
- for(int i = 0; i < size; i++)
- putch(((char*)buf)[i]);
- return (sysret_t){0,0};
+ return frontend_syscall(SYS_write,f->kfd,(long)buf,size,0);
+ //for(int i = 0; i < size; i++)
+ // putch(((char*)buf)[i]);
+ //return (sysret_t){0,0};
}
sysret_t file_stat(file_t* f, struct stat* s)
diff --git a/file.h b/file.h
index 0a26ba6..2a18e00 100644
--- a/file.h
+++ b/file.h
@@ -3,17 +3,18 @@
#include <sys/stat.h>
#include <machine/syscall.h>
+#include "atomic.h"
typedef struct file
{
int kfd; // file descriptor on the appserver side
- int refcnt;
+ atomic_t refcnt;
} file_t;
extern file_t *stdin, *stdout, *stderr;
file_t* file_get(int fd);
-file_t* file_open(const char* fn);
+sysret_t file_open(const char* fn, int mode);
int file_dup(file_t*);
sysret_t file_write(file_t* f, const void* buf, size_t n);
diff --git a/frontend.c b/frontend.c
new file mode 100644
index 0000000..b57c9a2
--- /dev/null
+++ b/frontend.c
@@ -0,0 +1,26 @@
+#include "pk.h"
+#include "atomic.h"
+#include "frontend.h"
+#include "cop0.h"
+
+sysret_t frontend_syscall(long n, long a0, long a1, long a2, long a3)
+{
+ static volatile long magic_mem[8];
+
+ static spinlock_t lock = SPINLOCK_INIT;
+ spinlock_lock(&lock);
+
+ magic_mem[0] = n;
+ magic_mem[1] = a0;
+ magic_mem[2] = a1;
+ magic_mem[3] = a2;
+ magic_mem[4] = a3;
+
+ dmtc0(magic_mem,16);
+ while(dmfc0(17));
+
+ sysret_t ret = {magic_mem[0],magic_mem[1]};
+
+ spinlock_unlock(&lock);
+ return ret;
+}
diff --git a/frontend.h b/frontend.h
new file mode 100644
index 0000000..86a8917
--- /dev/null
+++ b/frontend.h
@@ -0,0 +1,8 @@
+#ifndef _RISCV_FRONTEND_H
+#define _RISCV_FRONTEND_H
+
+#include <machine/syscall.h>
+
+sysret_t frontend_syscall(long n, long a0, long a1, long a2, long a3);
+
+#endif