summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2019-07-27 03:49:03 -0400
committerRobert Morris <[email protected]>2019-07-27 03:49:03 -0400
commit281d450a088b348b898f2e23f6951e6d4f1efac0 (patch)
tree7dc504a77980ffb2c7cf2fe742952dadc9b1e737
parent734faa27acfe136f4cab3ea06e70193c0ecc5402 (diff)
downloadxv6-labs-281d450a088b348b898f2e23f6951e6d4f1efac0.tar.gz
xv6-labs-281d450a088b348b898f2e23f6951e6d4f1efac0.tar.bz2
xv6-labs-281d450a088b348b898f2e23f6951e6d4f1efac0.zip
split printf into a separate file, to make console.c more like a driver
-rw-r--r--Makefile1
-rw-r--r--kernel/console.c158
-rw-r--r--kernel/defs.h8
-rw-r--r--kernel/main.c1
-rw-r--r--kernel/printf.c134
5 files changed, 168 insertions, 134 deletions
diff --git a/Makefile b/Makefile
index 7f6d032..c6360fd 100644
--- a/Makefile
+++ b/Makefile
@@ -5,6 +5,7 @@ OBJS = \
$K/entry.o \
$K/start.o \
$K/console.o \
+ $K/printf.o \
$K/uart.o \
$K/kalloc.o \
$K/spinlock.o \
diff --git a/kernel/console.c b/kernel/console.c
index fe21405..8023405 100644
--- a/kernel/console.c
+++ b/kernel/console.c
@@ -1,6 +1,7 @@
-// Console input and output.
-// Input is from the keyboard or serial port.
-// Output is written to the screen and serial port.
+//
+// Console input and output, to the uart.
+// Implements erase/kill processing.
+//
#include <stdarg.h>
@@ -15,122 +16,13 @@
#include "defs.h"
#include "proc.h"
-static void consputc(int);
-
-static volatile int panicked = 0;
-
-static struct {
- struct spinlock lock;
- int locking;
-} cons;
-
-static char digits[] = "0123456789abcdef";
-
-static void
-printint(int xx, int base, int sign)
-{
- char buf[16];
- int i;
- uint x;
-
- if(sign && (sign = xx < 0))
- x = -xx;
- else
- x = xx;
-
- i = 0;
- do{
- buf[i++] = digits[x % base];
- }while((x /= base) != 0);
-
- if(sign)
- buf[i++] = '-';
-
- while(--i >= 0)
- consputc(buf[i]);
-}
-
-static void
-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)]);
-}
-
-// Print to the console. only understands %d, %x, %p, %s.
-void
-printf(char *fmt, ...)
-{
- va_list ap;
- int i, c, locking;
- char *s;
-
- locking = cons.locking;
- if(locking)
- acquire(&cons.lock);
-
- if (fmt == 0)
- panic("null fmt");
-
- va_start(ap, fmt);
- for(i = 0; (c = fmt[i] & 0xff) != 0; i++){
- if(c != '%'){
- consputc(c);
- continue;
- }
- c = fmt[++i] & 0xff;
- if(c == 0)
- break;
- switch(c){
- case 'd':
- printint(va_arg(ap, int), 10, 1);
- break;
- case 'x':
- printint(va_arg(ap, int), 16, 1);
- break;
- case 'p':
- printptr(va_arg(ap, uint64));
- break;
- case 's':
- if((s = va_arg(ap, char*)) == 0)
- s = "(null)";
- for(; *s; s++)
- consputc(*s);
- break;
- case '%':
- consputc('%');
- break;
- default:
- // Print unknown % sequence to draw attention.
- consputc('%');
- consputc(c);
- break;
- }
- }
-
- if(locking)
- release(&cons.lock);
-}
-
-void
-panic(char *s)
-{
- cons.locking = 0;
- printf("panic: ");
- printf(s);
- printf("\n");
- panicked = 1; // freeze other CPU
- for(;;)
- ;
-}
-
#define BACKSPACE 0x100
void
consputc(int c)
{
+ extern volatile int panicked; // from printf.c
+
if(panicked){
for(;;)
;
@@ -142,13 +34,16 @@ consputc(int c)
uartputc(c);
}
-#define INPUT_BUF 128
struct {
+ struct spinlock lock;
+
+ // input
+#define INPUT_BUF 128
char buf[INPUT_BUF];
uint r; // Read index
uint w; // Write index
uint e; // Edit index
-} input;
+} cons;
#define C(x) ((x)-'@') // Contro
@@ -162,19 +57,19 @@ consoleread(int user_dst, uint64 dst, int n)
target = n;
acquire(&cons.lock);
while(n > 0){
- while(input.r == input.w){
+ while(cons.r == cons.w){
if(myproc()->killed){
release(&cons.lock);
return -1;
}
- sleep(&input.r, &cons.lock);
+ sleep(&cons.r, &cons.lock);
}
- c = input.buf[input.r++ % INPUT_BUF];
+ c = cons.buf[cons.r++ % INPUT_BUF];
if(c == C('D')){ // EOF
if(n < target){
// Save ^D for next time, to make sure
// caller gets a 0-byte result.
- input.r--;
+ cons.r--;
}
break;
}
@@ -221,26 +116,26 @@ consoleintr(int c)
doprocdump = 1;
break;
case C('U'): // Kill line.
- while(input.e != input.w &&
- input.buf[(input.e-1) % INPUT_BUF] != '\n'){
- input.e--;
+ while(cons.e != cons.w &&
+ cons.buf[(cons.e-1) % INPUT_BUF] != '\n'){
+ cons.e--;
consputc(BACKSPACE);
}
break;
case C('H'): case '\x7f': // Backspace
- if(input.e != input.w){
- input.e--;
+ if(cons.e != cons.w){
+ cons.e--;
consputc(BACKSPACE);
}
break;
default:
- if(c != 0 && input.e-input.r < INPUT_BUF){
+ if(c != 0 && cons.e-cons.r < INPUT_BUF){
c = (c == '\r') ? '\n' : c;
- input.buf[input.e++ % INPUT_BUF] = c;
+ cons.buf[cons.e++ % INPUT_BUF] = c;
consputc(c);
- if(c == '\n' || c == C('D') || input.e == input.r+INPUT_BUF){
- input.w = input.e;
- wakeup(&input.r);
+ if(c == '\n' || c == C('D') || cons.e == cons.r+INPUT_BUF){
+ cons.w = cons.e;
+ wakeup(&cons.r);
}
}
break;
@@ -255,9 +150,8 @@ consoleintr(int c)
void
consoleinit(void)
{
- initlock(&cons.lock, "console");
+ initlock(&cons.lock, "cons");
devsw[CONSOLE].write = consolewrite;
devsw[CONSOLE].read = consoleread;
- cons.locking = 1;
}
diff --git a/kernel/defs.h b/kernel/defs.h
index fa9dd13..52fca8e 100644
--- a/kernel/defs.h
+++ b/kernel/defs.h
@@ -17,9 +17,8 @@ void bwrite(struct buf*);
// console.c
void consoleinit(void);
-void printf(char*, ...);
void consoleintr(int);
-void panic(char*) __attribute__((noreturn));
+void consputc(int);
// exec.c
int exec(char*, char**);
@@ -74,6 +73,11 @@ void pipeclose(struct pipe*, int);
int piperead(struct pipe*, uint64, int);
int pipewrite(struct pipe*, uint64, int);
+// printf.c
+void printf(char*, ...);
+void panic(char*) __attribute__((noreturn));
+void printfinit(void);
+
// proc.c
int cpuid(void);
void exit(void);
diff --git a/kernel/main.c b/kernel/main.c
index 17bd5d1..09580e0 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -13,6 +13,7 @@ main()
if(cpuid() == 0){
uartinit(); // serial port
consoleinit();
+ printfinit();
printf("hart %d starting\n", cpuid());
kinit(); // physical page allocator
kvminit(); // create kernel page table
diff --git a/kernel/printf.c b/kernel/printf.c
new file mode 100644
index 0000000..777cc5f
--- /dev/null
+++ b/kernel/printf.c
@@ -0,0 +1,134 @@
+//
+// formatted console output -- printf, panic.
+//
+
+#include <stdarg.h>
+
+#include "types.h"
+#include "param.h"
+#include "spinlock.h"
+#include "sleeplock.h"
+#include "fs.h"
+#include "file.h"
+#include "memlayout.h"
+#include "riscv.h"
+#include "defs.h"
+#include "proc.h"
+
+volatile int panicked = 0;
+
+// lock to avoid interleaving concurrent printf's.
+static struct {
+ struct spinlock lock;
+ int locking;
+} pr;
+
+static char digits[] = "0123456789abcdef";
+
+static void
+printint(int xx, int base, int sign)
+{
+ char buf[16];
+ int i;
+ uint x;
+
+ if(sign && (sign = xx < 0))
+ x = -xx;
+ else
+ x = xx;
+
+ i = 0;
+ do {
+ buf[i++] = digits[x % base];
+ } while((x /= base) != 0);
+
+ if(sign)
+ buf[i++] = '-';
+
+ while(--i >= 0)
+ consputc(buf[i]);
+}
+
+static void
+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)]);
+}
+
+// Print to the console. only understands %d, %x, %p, %s.
+void
+printf(char *fmt, ...)
+{
+ va_list ap;
+ int i, c, locking;
+ char *s;
+
+ locking = pr.locking;
+ if(locking)
+ acquire(&pr.lock);
+
+ if (fmt == 0)
+ panic("null fmt");
+
+ va_start(ap, fmt);
+ for(i = 0; (c = fmt[i] & 0xff) != 0; i++){
+ if(c != '%'){
+ consputc(c);
+ continue;
+ }
+ c = fmt[++i] & 0xff;
+ if(c == 0)
+ break;
+ switch(c){
+ case 'd':
+ printint(va_arg(ap, int), 10, 1);
+ break;
+ case 'x':
+ printint(va_arg(ap, int), 16, 1);
+ break;
+ case 'p':
+ printptr(va_arg(ap, uint64));
+ break;
+ case 's':
+ if((s = va_arg(ap, char*)) == 0)
+ s = "(null)";
+ for(; *s; s++)
+ consputc(*s);
+ break;
+ case '%':
+ consputc('%');
+ break;
+ default:
+ // Print unknown % sequence to draw attention.
+ consputc('%');
+ consputc(c);
+ break;
+ }
+ }
+
+ if(locking)
+ release(&pr.lock);
+}
+
+void
+panic(char *s)
+{
+ pr.locking = 0;
+ printf("panic: ");
+ printf(s);
+ printf("\n");
+ panicked = 1; // freeze other CPUs
+ for(;;)
+ ;
+}
+
+void
+printfinit(void)
+{
+ initlock(&pr.lock, "pr");
+ pr.locking = 1;
+}