aboutsummaryrefslogtreecommitdiff
path: root/pk/console.c
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2013-07-13 21:43:57 -0700
committerAndrew Waterman <waterman@cs.berkeley.edu>2013-07-13 21:44:16 -0700
commitcc72987e655578b0529b6c3c8084e810cf40b358 (patch)
treea7a99a9406dfef2d4103e85bc0976cb8d039d7e7 /pk/console.c
parent0bdb8c84092bf7c5eb4c981c620997a5893bfb70 (diff)
downloadriscv-pk-cc72987e655578b0529b6c3c8084e810cf40b358.zip
riscv-pk-cc72987e655578b0529b6c3c8084e810cf40b358.tar.gz
riscv-pk-cc72987e655578b0529b6c3c8084e810cf40b358.tar.bz2
Support Linux ABI and (optionally) virtual memory
Diffstat (limited to 'pk/console.c')
-rw-r--r--pk/console.c147
1 files changed, 147 insertions, 0 deletions
diff --git a/pk/console.c b/pk/console.c
new file mode 100644
index 0000000..cfa58d4
--- /dev/null
+++ b/pk/console.c
@@ -0,0 +1,147 @@
+#include "pk.h"
+#include "file.h"
+#include "syscall.h"
+#include <stdint.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <string.h>
+
+static void vsprintk(char* out, const char* s, va_list vl)
+{
+ bool format = false;
+ bool longarg = false;
+ for( ; *s; s++)
+ {
+ if(format)
+ {
+ switch(*s)
+ {
+ case 'l':
+ longarg = true;
+ break;
+ case 'p':
+ longarg = true;
+ *out++ = '0';
+ *out++ = 'x';
+ case 'x':
+ {
+ long n = longarg ? va_arg(vl,long) : va_arg(vl,int);
+ for(int i = 2*(longarg ? sizeof(long) : sizeof(int))-1; i >= 0; i--)
+ {
+ int d = (n >> (4*i)) & 0xF;
+ *out++ = (d < 10 ? '0'+d : 'a'+d-10);
+ }
+ longarg = false;
+ format = false;
+ break;
+ }
+ case 'd':
+ {
+ long n = longarg ? va_arg(vl,long) : va_arg(vl,int);
+ if(n < 0)
+ {
+ n = -n;
+ *out++ = '-';
+ }
+ long digits = 1;
+ for(long nn = n ; nn /= 10; digits++);
+ for(int i = digits-1; i >= 0; i--)
+ {
+ out[i] = '0' + n%10;
+ n /= 10;
+ }
+ out += digits;
+ longarg = false;
+ format = false;
+ break;
+ }
+ case 's':
+ {
+ const char* s2 = va_arg(vl,const char*);
+ while(*s2)
+ *out++ = *s2++;
+ longarg = false;
+ format = false;
+ break;
+ }
+ case 'c':
+ {
+ *out++ = (char)va_arg(vl,int);
+ longarg = false;
+ format = false;
+ break;
+ }
+ default:
+ panic("bad fmt");
+ }
+ }
+ else if(*s == '%')
+ format = true;
+ else
+ *out++ = *s;
+ }
+ *out++ = '\0';
+}
+
+static void vprintk(const char* s, va_list vl)
+{
+ char out[1024]; // XXX
+ vsprintk(out, s, vl);
+ file_write(stderr, out, strlen(out));
+}
+
+void printk(const char* s, ...)
+{
+ va_list vl;
+ va_start(vl, s);
+
+ vprintk(s, vl);
+
+ va_end(vl);
+}
+
+void sprintk(char* out, const char* s, ...)
+{
+ va_list vl;
+ va_start(vl,s);
+
+ vsprintk(out,s,vl);
+
+ va_end(vl);
+}
+
+void dump_tf(trapframe_t* tf)
+{
+ static const char* regnames[] = {
+ "z ", "ra", "s0", "s1", "s2", "s3", "s4", "s5",
+ "s6", "s7", "s8", "s9", "sA", "sB", "sp", "tp",
+ "v0", "v1", "a0", "a1", "a2", "a3", "a4", "a5",
+ "a6", "a7", "a8", "a9", "aA", "aB", "aC", "aD"
+ };
+
+ tf->gpr[0] = 0;
+
+ for(int i = 0; i < 32; i+=4)
+ {
+ for(int j = 0; j < 4; j++)
+ printk("%s %lx%c",regnames[i+j],tf->gpr[i+j],j < 3 ? ' ' : '\n');
+ }
+ printk("sr %lx pc %lx va %lx insn %x\n",tf->sr,tf->epc,tf->badvaddr,
+ (uint32_t)tf->insn);
+}
+
+void do_panic(const char* s, ...)
+{
+ va_list vl;
+ va_start(vl, s);
+
+ vprintk(s, vl);
+ sys_exit(-1);
+
+ va_end(vl);
+}
+
+void kassert_fail(const char* s)
+{
+ do_panic("assertion failed: %s\n", s);
+}