123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 |
- /*****************************************************************
- * console.c
- * adapted from MIT xv6 by Zhiyi Huang, [email protected]
- * University of Otago
- *
- ********************************************************************/
- #include "types.h"
- #include "defs.h"
- #include "param.h"
- #include "traps.h"
- #include "spinlock.h"
- #include "fs.h"
- #include "file.h"
- #include "memlayout.h"
- #include "mmu.h"
- #include "proc.h"
- #include "arm.h"
- #define BACKSPACE 0x100
- static int panicked = 0;
- static struct {
- struct spinlock lock;
- int locking;
- } cons;
- uint cursor_x=0, cursor_y=0;
- uint frameheight=768, framewidth=1024, framecolors=16;
- uint fontheight=16, fontwidth=8;
- FBI fbinfo __attribute__ ((aligned (16), nocommon));
- extern u8 font[];
- static uint gpucolour=0xffff;
- void setgpucolour(u16 c)
- {
- gpucolour = c;
- }
- uint initframebuf(uint width, uint height, uint depth)
- {
- fbinfo.width = width;
- fbinfo.height = height;
- fbinfo.v_width = width;
- fbinfo.v_height = height;
- fbinfo.pitch = 0;
- fbinfo.depth = depth;
- fbinfo.x = 0;
- fbinfo.y = 0;
- fbinfo.fbp = 0;
- fbinfo.fbs = 0;
- writemailbox((uint *)&fbinfo, 1);
- return readmailbox(1);
- }
- #define INPUT_BUF 128
- struct {
- struct spinlock lock;
- char buf[INPUT_BUF];
- uint r; // Read index
- uint w; // Write index
- uint e; // Edit index
- } input;
- int
- consolewrite(struct inode *ip, char *buf, int n)
- {
- int i;
- // cprintf("consolewrite is called: ip=%x buf=%x, n=%x", ip, buf, n);
- iunlock(ip);
- acquire(&cons.lock);
- for(i = 0; i < n; i++){
- gpuputc(buf[i] & 0xff);
- uartputc(buf[i] & 0xff);
- }
- release(&cons.lock);
- ilock(ip);
- return n;
- }
- void drawpixel(uint x, uint y)
- {
- u16 *addr;
- if(x >= framewidth || y >= frameheight) return;
- addr = (u16 *) fbinfo.fbp;
- // addr = (u16 *) ((FBI *)FrameBufferInfo)->fbp;
- addr += y*1024 + x;
- *addr = gpucolour;
- return;
- }
- void drawcursor(uint x, uint y)
- {
- u8 row, bit;
- for(row=0; row<15; row++)
- for(bit=0; bit<8; bit++)
- drawpixel(x+bit, y+row);
- }
- void drawcharacter(u8 c, uint x, uint y)
- {
- u8 *faddr;
- u8 row, bit, bits;
- uint tv;
- if(c > 127) return;
- tv = ((uint)c) << 4;
- faddr = font + tv;
- for(row=0; row<15; row++){
- bits = *(faddr+row);
- for(bit=0; bit<8; bit++){
- if((bits>>bit) & 1) drawpixel(x+bit, y+row);
- }
- }
- }
- //static void
- void
- gpuputc(uint c)
- {
- if(c=='\n'){
- cursor_x = 0;
- cursor_y += fontheight;
- if(cursor_y >= frameheight) {
- memmove((u8 *)fbinfo.fbp, (u8 *)fbinfo.fbp+framewidth*fontheight*2, (frameheight - fontheight)*framewidth*2);
- cursor_y = frameheight - fontheight;
- setgpucolour(0);
- while(cursor_x < framewidth) {
- drawcursor(cursor_x, cursor_y);
- cursor_x = cursor_x + fontwidth;
- }
- setgpucolour(0xffff);
- cursor_x = 0;
- }
- } else if(c == BACKSPACE) {
- if (cursor_x > 0) {
- cursor_x -= fontwidth;
- setgpucolour(0);
- drawcursor(cursor_x, cursor_y);
- setgpucolour(0xffff);
- }
- } else {
- setgpucolour(0);
- drawcursor(cursor_x, cursor_y);
- setgpucolour(0xffff);
- if(c!=' ') drawcharacter(c, cursor_x, cursor_y);
- cursor_x = cursor_x + fontwidth;
- if(cursor_x >= framewidth) {
- cursor_x = 0;
- cursor_y += fontheight;
- if(cursor_y >= frameheight) {
- memmove((u8 *)fbinfo.fbp, (u8 *)fbinfo.fbp+framewidth*fontheight*2, (frameheight - fontheight)*framewidth*2);
- cursor_y = frameheight - fontheight;
- setgpucolour(0);
- while(cursor_x < framewidth) {
- drawcursor(cursor_x, cursor_y);
- cursor_x = cursor_x + fontwidth;
- }
- setgpucolour(0xffff);
- cursor_x = 0;
- }
- }
- }
- }
- static void
- printint(int xx, int base, int sign)
- {
- static u8 digits[] = "0123456789abcdef";
- u8 buf[16];
- int i;
- uint x, y, b;
- if(sign && (sign = xx < 0))
- x = -xx;
- else
- x = xx;
- b = base;
- i = 0;
- do{
- y = div(x, b);
- buf[i++] = digits[x - y * b];
- }while((x = y) != 0);
- if(sign)
- buf[i++] = '-';
- while(--i >= 0){
- gpuputc(buf[i]);
- uartputc(buf[i]);
- }
- }
- // Print to the console. only understands %d, %x, %p, %s.
- void
- cprintf(char *fmt, ...)
- {
- int i, c;
- int locking;
- uint *argp;
- char *s;
- locking = cons.locking;
- if(locking)
- acquire(&cons.lock);
- if (fmt == 0)
- panic("null fmt");
- argp = (uint *)(void*)(&fmt + 1);
- for(i = 0; (c = fmt[i] & 0xff) != 0; i++){
- if(c != '%'){
- gpuputc(c);
- uartputc(c);
- continue;
- }
- c = fmt[++i] & 0xff;
- if(c == 0)
- break;
- switch(c){
- case 'd':
- printint(*argp++, 10, 1);
- break;
- case 'x':
- case 'p':
- printint(*argp++, 16, 0);
- break;
- case 's':
- if((s = (char*)*argp++) == 0)
- s = "(null)";
- for(; *s; s++){
- gpuputc(*s);
- uartputc(*s);
- }
- break;
- case '%':
- gpuputc('%');
- uartputc('%');
- break;
- default:
- // Print unknown % sequence to draw attention.
- gpuputc('%');
- uartputc('%');
- gpuputc(c);
- uartputc(c);
- break;
- }
- }
- if(locking)
- release(&cons.lock);
- }
- void
- panic(char *s)
- {
- int i;
- uint pcs[10];
- cprintf("cpu%d: panic: ", 0);
- cprintf(s);
- cprintf("\n");
- getcallerpcs(&s, pcs);
- for(i=0; i<10; i++)
- cprintf(" %p", pcs[i]);
- panicked = 1; // freeze other CPU
- for(;;)
- ;
- }
- #define C(x) ((x)-'@') // Control-x
- void
- consputc(int c)
- {
- if(panicked){
- cli();
- for(;;)
- ;
- }
- if(c == BACKSPACE){
- gpuputc('\b'); gpuputc(' '); gpuputc('\b');
- uartputc('\b'); uartputc(' '); uartputc('\b');
- } else if(c == C('D')) {
- gpuputc('^'); gpuputc('D');
- uartputc('^'); uartputc('D');
- } else {
- gpuputc(c);
- uartputc(c);
- }
- }
- void
- consoleintr(int (*getc)(void))
- {
- int c;
- acquire(&input.lock);
- while((c = getc()) >= 0){
- switch(c){
- case C('P'): // Process listing.
- procdump();
- break;
- case C('U'): // Kill line.
- while(input.e != input.w &&
- input.buf[(input.e-1) % INPUT_BUF] != '\n'){
- input.e--;
- consputc(BACKSPACE);
- }
- break;
- case C('H'): case '\x7f': // Backspace
- if(input.e != input.w){
- input.e--;
- consputc(BACKSPACE);
- }
- break;
- default:
- if(c != 0 && input.e-input.r < INPUT_BUF){
- if(c == 0xa) break;
- c = (c == 0xd) ? '\n' : c;
- input.buf[input.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);
- }
- }
- break;
- }
- }
- release(&input.lock);
- }
- int
- consoleread(struct inode *ip, char *dst, int n)
- {
- uint target;
- int c;
- //cprintf("inside consoleread\n");
- iunlock(ip);
- target = n;
- acquire(&input.lock);
- while(n > 0){
- while(input.r == input.w){
- if(curr_proc->killed){
- release(&input.lock);
- ilock(ip);
- return -1;
- }
- sleep(&input.r, &input.lock);
- }
- c = input.buf[input.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--;
- }
- break;
- }
- *dst++ = c;
- --n;
- if(c == '\n')
- break;
- }
- release(&input.lock);
- ilock(ip);
- return target - n;
- }
- void consoleinit(void)
- {
- uint fbinfoaddr;
- fbinfoaddr = initframebuf(framewidth, frameheight, framecolors);
- if(fbinfoaddr != 0) NotOkLoop();
- initlock(&cons.lock, "console");
- memset(&input, 0, sizeof(input));
- initlock(&input.lock, "input");
- memset(devsw, 0, sizeof(struct devsw)*NDEV);
- devsw[CONSOLE].write = consolewrite;
- devsw[CONSOLE].read = consoleread;
- cons.locking = 1;
- panicked = 0; // must initialize in code since the compiler does not
- cursor_x=cursor_y=0;
- }
|