diff options
| -rw-r--r-- | Notes | 38 | ||||
| -rw-r--r-- | console.c | 180 | ||||
| -rw-r--r-- | defs.h | 2 | ||||
| -rw-r--r-- | fcntl.h | 4 | ||||
| -rw-r--r-- | fs.c | 1 | ||||
| -rw-r--r-- | fs.h | 5 | ||||
| -rw-r--r-- | ide.c | 2 | ||||
| -rw-r--r-- | main.c | 2 | ||||
| -rw-r--r-- | mkfs.c | 2 | ||||
| -rw-r--r-- | spinlock.c | 8 | ||||
| -rw-r--r-- | syscall.c | 1 | ||||
| -rw-r--r-- | trap.c | 16 | ||||
| -rw-r--r-- | userfs.c | 1 | ||||
| -rw-r--r-- | x86.h | 1 | 
14 files changed, 249 insertions, 14 deletions
| @@ -241,3 +241,41 @@ maybe a race; acquire does    cpu = cpu()  what if another acquire calls holding w/ locked = 1 but    before cpu is set? + +if I type a lot (kbd), i get a panic +cpu1 in scheduler: panic "holding locks in scheduler" +cpu0 also in the same panic! +recursive interrupt? +  FL_IF is probably set during interrupt... is that correct? +again: +  olding locks in scheduler +  trap v 33 eip 100ED3 c (that is, interrupt while holding a lock) +  100ed3 is in lapic_write +again: +  trap v 33 eip 102A3C cpu 1 nlock 1 (in acquire) +  panic: interrupt while holding a lock +again: +  trap v 33 eip 102A3C cpu 1 nlock 1 +  panic: interrupt while holding a lock +OR is it the cprintf("kbd overflow")? +  no, get panic even w/o that cprintf +OR a release() at interrupt time turns interrupts back on? +  of course i don't think they were off... +OK, fixing trap.c to make interrupts turn off FL_IF +  that makes it take longer, but still panics +  (maybe b/c release sets FL_IF) + +shouldn't something (PIC?) prevent recursive interrupts of same IRQ? +  or should FL_IF be clear during all interrupts? + +maybe acquire should remember old FL_IF value, release should restore +  if acquire did cli() + +DUH the increment of nlock in acquire() happens before the cli! +  so the panic is probably not a real problem +  test nlock, cli(), then increment? + +BUT now userfs doesn't do the final cat README + +AND w/ cprintf("kbd overflow"), panic holding locks in scheduler +  maybe also simulataneous panic("interrupt while holding a lock") @@ -174,8 +174,186 @@ console_write (int minor, void *buf, int n)    return n;  } + +/* This is i8042reg.h + kbdreg.h from NetBSD. */ +#define	KBSTATP		0x64	/* kbd controller status port(I) */ +#define	 KBS_DIB	0x01	/* kbd data in buffer */ +#define	KBDATAP		0x60	/* kbd data port(I) */ + +#define NO		0 + +#define SHIFT		(1<<0) +#define CTL		(1<<1) +#define ALT		(1<<2) + +#define CAPSLOCK	(1<<3) +#define NUMLOCK		(1<<4) +#define SCROLLLOCK	(1<<5) + +#define E0ESC		(1<<6) + +// Special keycodes +#define KEY_HOME	0xE0 +#define KEY_END		0xE1 +#define KEY_UP		0xE2 +#define KEY_DN		0xE3 +#define KEY_LF		0xE4 +#define KEY_RT		0xE5 +#define KEY_PGUP	0xE6 +#define KEY_PGDN	0xE7 +#define KEY_INS		0xE8 +#define KEY_DEL		0xE9 + +static uchar shiftcode[256] =  +{ +	[0x1D] CTL, +	[0x2A] SHIFT, +	[0x36] SHIFT, +	[0x38] ALT, +	[0x9D] CTL, +	[0xB8] ALT +}; + +static uchar togglecode[256] =  +{ +	[0x3A] CAPSLOCK, +	[0x45] NUMLOCK, +	[0x46] SCROLLLOCK +}; + +static uchar normalmap[256] = +{ +	NO,   0x1B, '1',  '2',  '3',  '4',  '5',  '6',	// 0x00 +	'7',  '8',  '9',  '0',  '-',  '=',  '\b', '\t', +	'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',	// 0x10 +	'o',  'p',  '[',  ']',  '\n', NO,   'a',  's', +	'd',  'f',  'g',  'h',  'j',  'k',  'l',  ';',	// 0x20 +	'\'', '`',  NO,   '\\', 'z',  'x',  'c',  'v', +	'b',  'n',  'm',  ',',  '.',  '/',  NO,   '*',	// 0x30 +	NO,   ' ',  NO,   NO,   NO,   NO,   NO,   NO, +	NO,   NO,   NO,   NO,   NO,   NO,   NO,   '7',	// 0x40 +	'8',  '9',  '-',  '4',  '5',  '6',  '+',  '1', +	'2',  '3',  '0',  '.',  NO,   NO,   NO,   NO,	// 0x50 +	[0x97] KEY_HOME,	[0x9C] '\n' /*KP_Enter*/, +	[0xB5] '/' /*KP_Div*/,	[0xC8] KEY_UP, +	[0xC9] KEY_PGUP,	[0xCB] KEY_LF, +	[0xCD] KEY_RT,		[0xCF] KEY_END, +	[0xD0] KEY_DN,		[0xD1] KEY_PGDN, +	[0xD2] KEY_INS,		[0xD3] KEY_DEL +}; + +static uchar shiftmap[256] =  +{ +	NO,   033,  '!',  '@',  '#',  '$',  '%',  '^',	// 0x00 +	'&',  '*',  '(',  ')',  '_',  '+',  '\b', '\t', +	'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',	// 0x10 +	'O',  'P',  '{',  '}',  '\n', NO,   'A',  'S', +	'D',  'F',  'G',  'H',  'J',  'K',  'L',  ':',	// 0x20 +	'"',  '~',  NO,   '|',  'Z',  'X',  'C',  'V', +	'B',  'N',  'M',  '<',  '>',  '?',  NO,   '*',	// 0x30 +	NO,   ' ',  NO,   NO,   NO,   NO,   NO,   NO, +	NO,   NO,   NO,   NO,   NO,   NO,   NO,   '7',	// 0x40 +	'8',  '9',  '-',  '4',  '5',  '6',  '+',  '1', +	'2',  '3',  '0',  '.',  NO,   NO,   NO,   NO,	// 0x50 +	[0x97] KEY_HOME,	[0x9C] '\n' /*KP_Enter*/, +	[0xB5] '/' /*KP_Div*/,	[0xC8] KEY_UP, +	[0xC9] KEY_PGUP,	[0xCB] KEY_LF, +	[0xCD] KEY_RT,		[0xCF] KEY_END, +	[0xD0] KEY_DN,		[0xD1] KEY_PGDN, +	[0xD2] KEY_INS,		[0xD3] KEY_DEL +}; + +#define C(x) (x - '@') + +static uchar ctlmap[256] =  +{ +	NO,      NO,      NO,      NO,      NO,      NO,      NO,      NO,  +	NO,      NO,      NO,      NO,      NO,      NO,      NO,      NO,  +	C('Q'),  C('W'),  C('E'),  C('R'),  C('T'),  C('Y'),  C('U'),  C('I'), +	C('O'),  C('P'),  NO,      NO,      '\r',    NO,      C('A'),  C('S'), +	C('D'),  C('F'),  C('G'),  C('H'),  C('J'),  C('K'),  C('L'),  NO,  +	NO,      NO,      NO,      C('\\'), C('Z'),  C('X'),  C('C'),  C('V'), +	C('B'),  C('N'),  C('M'),  NO,      NO,      C('/'),  NO,      NO, +	[0x97] KEY_HOME, +	[0xB5] C('/'),		[0xC8] KEY_UP, +	[0xC9] KEY_PGUP,	[0xCB] KEY_LF, +	[0xCD] KEY_RT,		[0xCF] KEY_END, +	[0xD0] KEY_DN,		[0xD1] KEY_PGDN, +	[0xD2] KEY_INS,		[0xD3] KEY_DEL +}; + +static uchar *charcode[4] = { +	normalmap, +	shiftmap, +	ctlmap, +	ctlmap +}; + +#define KBD_BUF 64 +char kbd_buf[KBD_BUF]; +int kbd_r; +int kbd_w; +struct spinlock kbd_lock = { "kbd_lock" }; +  void -console_init () +kbd_intr() +{ +  uint st, data, c; +  static uint shift; + +  st = inb(KBSTATP); +  if ((st & KBS_DIB) == 0){ +    lapic_eoi(); +    return; +  } +  data = inb(KBDATAP); + +  if (data == 0xE0) { +    shift |= E0ESC; +    lapic_eoi(); +    return; +  } else if (data & 0x80) { +    // Key released +    data = (shift & E0ESC ? data : data & 0x7F); +    shift &= ~(shiftcode[data] | E0ESC); +    lapic_eoi(); +    return; +  } else if (shift & E0ESC) { +    // Last character was an E0 escape; or with 0x80 +    data |= 0x80; +    shift &= ~E0ESC; +  } +   +  shift |= shiftcode[data]; +  shift ^= togglecode[data]; +   +  c = charcode[shift & (CTL | SHIFT)][data]; +  if (shift & CAPSLOCK) { +    if ('a' <= c && c <= 'z') +      c += 'A' - 'a'; +    else if ('A' <= c && c <= 'Z') +      c += 'a' - 'A'; +  } +   +  acquire(&kbd_lock); + +  if(((kbd_w + 1) % KBD_BUF) != kbd_r){ +    kbd_buf[kbd_w++] = c; +    if(kbd_w >= KBD_BUF) +      kbd_w = 0; +  } else { +    cprintf("kbd overflow\n"); +  } + +  release(&kbd_lock); + +  lapic_eoi(); +} + +void +console_init()  {    devsw[CONSOLE].d_write = console_write; + +  ioapic_enable (IRQ_KBD, 1);  } @@ -4,8 +4,10 @@ void kfree(char *cp, int len);  void kinit(void);  // console.c +void console_init(void);  void cprintf(char *fmt, ...);  void panic(char *s); +void kbd_intr(void);  // proc.c  struct proc; @@ -0,0 +1,4 @@ +#define O_CREATE  0x200 +#define O_RDONLY  0x000 +#define O_WRONLY  0x001 +#define O_RDWR    0x002 @@ -329,6 +329,7 @@ writei(struct inode *ip, void *addr, uint off, uint n)      return r;    } else {      panic ("writei: unknown type\n"); +    return 0;    }  } @@ -36,8 +36,3 @@ struct dirent {    ushort inum;    char name[DIRSIZ];  }; - -#define O_CREATE  0x200 -#define O_RDONLY  0x000 -#define O_WRONLY  0x001 -#define O_RDWR    0x002 @@ -49,7 +49,7 @@ ide_init(void)    if (ncpu < 2) {      panic ("ide_init: disk interrupt is going to the second  cpu\n");    } -  ioapic_enable (14, 1); // 14 is IRQ # for IDE +  ioapic_enable (IRQ_IDE, 1);    ide_wait_ready(0);    cprintf ("cpu%d: ide_init:done\n", cpu());  } @@ -71,7 +71,7 @@ main0(void)    p->tf->eflags = FL_IF;    setupsegs(p); -  // init disk device +  // initialize I/O devices, let them enable interrupts    console_init();    ide_init();  @@ -75,7 +75,7 @@ main(int argc, char *argv[])    sb.nblocks = xint(nblocks); // so whole disk is size sectors    sb.ninodes = xint(ninodes); -  bitblocks = sb.size/(512*8) + 1;  +  bitblocks = size/(512*8) + 1;     usedblocks = ninodes / IPB + 3 + bitblocks;    freeblock = usedblocks; @@ -30,8 +30,10 @@ acquire(struct spinlock * lock)    if(holding(lock))      panic("acquire"); -	if(cpus[cpu()].nlock++ == 0) -		cli(); +  if(cpus[cpu()].nlock == 0) +    cli(); +  cpus[cpu()].nlock++; +                  	while(cmpxchg(0, 1, &lock->locked) == 1)  		;  	cpuid(0, 0, 0, 0, 0);	// memory barrier @@ -53,6 +55,8 @@ release(struct spinlock * lock)  	lock->locked = 0;  	if(--cpus[cpu()].nlock == 0)  		sti(); +        // xxx we may have just turned interrupts on during +        // an interrupt, is that ok?  }  int @@ -12,6 +12,7 @@  #include "fsvar.h"  #include "elf.h"  #include "fd.h" +#include "fcntl.h"  /*   * User code makes a system call with INT T_SYSCALL. @@ -21,7 +21,7 @@ tvinit(void)    for(i = 0; i < 256; i++){      SETGATE(idt[i], 1, SEG_KCODE << 3, vectors[i], 0);    } -  SETGATE(idt[T_SYSCALL], T_SYSCALL, SEG_KCODE << 3, vectors[48], 3); +  SETGATE(idt[T_SYSCALL], 1, SEG_KCODE << 3, vectors[48], 3);  }  void @@ -40,12 +40,12 @@ trap(struct trapframe *tf)              v, tf->eip, cpu(), cpus[cpu()].nlock);      panic("interrupt while holding a lock");    } -  if((read_eflags() & FL_IF) == 0) -    panic("interrupt but interrupts now disabled");    if(v == T_SYSCALL){      struct proc *cp = curproc[cpu()];      int num = cp->tf->eax; +    if((read_eflags() & FL_IF) == 0) +      panic("syscall but interrupts now disabled");      if(cp == 0)        panic("syscall with no proc");      if(cp->killed) @@ -73,6 +73,9 @@ trap(struct trapframe *tf)      return;    } +  //if(read_eflags() & FL_IF) +  //panic("interrupt but interrupts enabled"); +    if(v == (IRQ_OFFSET + IRQ_TIMER)){      struct proc *cp = curproc[cpu()];      lapic_timerintr(); @@ -97,5 +100,12 @@ trap(struct trapframe *tf)      return;    } +  if(v == (IRQ_OFFSET + IRQ_KBD)){ +    kbd_intr(); +    return; +  } + +  cprintf("trap %d\n", v); +    return;  } @@ -1,6 +1,7 @@  #include "user.h"  #include "types.h"  #include "fs.h" +#include "fcntl.h"  // file system tests @@ -362,6 +362,7 @@ struct trapframe {  #define IRQ_OFFSET      32	// IRQ 0 corresponds to int IRQ_OFFSET +#define IRQ_KBD         1  #define IRQ_IDE         14  #define IRQ_ERROR       19  #define IRQ_SPURIOUS    31 | 
