]> Devi Nivas Git - cs3210-lab0.git/commitdiff
timer interrupts
authorkaashoek <kaashoek>
Wed, 5 Jul 2006 20:00:14 +0000 (20:00 +0000)
committerkaashoek <kaashoek>
Wed, 5 Jul 2006 20:00:14 +0000 (20:00 +0000)
disk interrupts (assuming bochs has a bug)

defs.h
ide.c
main.c
mp.c
picirq.c
proc.h
string.c
trap.c
x86.h

diff --git a/defs.h b/defs.h
index e627a4c18bd5b7784704b39c2d5b7faefa5acecb..d1025a60ebcaf0e933bb54b34e91ebc656dc13d4 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -25,11 +25,13 @@ void * memcpy(void *dst, void *src, unsigned n);
 void * memset(void *dst, int c, unsigned n);
 int memcmp(const void *v1, const void *v2, unsigned n);
 void *memmove(void *dst, const void *src, unsigned n);
+int strncmp(const char *p, const char *q, unsigned n);
 
 // syscall.c
 void syscall(void);
 
 // picirq.c
+extern uint16_t irq_mask_8259A;
 void irq_setmask_8259A(uint16_t mask);
 void pic_init(void);
 
@@ -66,3 +68,7 @@ struct fd * fd_alloc();
 void fd_close(struct fd *);
 int fd_read(struct fd *fd, char *addr, int n);
 int fd_write(struct fd *fd, char *addr, int n);
+
+// ide.c
+void ide_init(void);
+int ide_read(uint32_t secno, void *dst, unsigned nsecs);
diff --git a/ide.c b/ide.c
index 3152f93772c0d7551f67f37ed4cfbb9bacca6b28..0e63a865b1b76cf66e64e1fffba6ad229b5292f2 100644 (file)
--- a/ide.c
+++ b/ide.c
@@ -21,97 +21,104 @@ static int diskno = 0;
 static int
 ide_wait_ready(int check_error)
 {
-       int r;
+  int r;
 
-       while (((r = inb(0x1F7)) & (IDE_BSY|IDE_DRDY)) != IDE_DRDY)
-               /* do nothing */;
+  while (((r = inb(0x1F7)) & (IDE_BSY|IDE_DRDY)) != IDE_DRDY)
+    /* do nothing */;
 
-       if (check_error && (r & (IDE_DF|IDE_ERR)) != 0)
-               return -1;
-       return 0;
+  if (check_error && (r & (IDE_DF|IDE_ERR)) != 0)
+    return -1;
+  return 0;
 }
 
+void
+ide_init(void)
+{
+  cprintf("ide_init: enable IRQ 14\n");
+  irq_setmask_8259A(irq_mask_8259A & ~(1<<14));
+  ide_wait_ready(0);
+}
+
+
 int
 ide_probe_disk1(void)
 {
-       int r, x;
+  int r, x;
 
-       // wait for Device 0 to be ready
-       ide_wait_ready(0);
+  // wait for Device 0 to be ready
+  ide_wait_ready(0);
 
-       // switch to Device 1
-       outb(0x1F6, 0xE0 | (1<<4));
+  // switch to Device 1
+  outb(0x1F6, 0xE0 | (1<<4));
 
-       // check for Device 1 to be ready for a while
-       for (x = 0; x < 1000 && (r = inb(0x1F7)) == 0; x++)
-               /* do nothing */;
+  // check for Device 1 to be ready for a while
+  for (x = 0; x < 1000 && (r = inb(0x1F7)) == 0; x++)
+    /* do nothing */;
 
-       // switch back to Device 0
-       outb(0x1F6, 0xE0 | (0<<4));
+  // switch back to Device 0
+  outb(0x1F6, 0xE0 | (0<<4));
 
-       cprintf("Device 1 presence: %d\n", (x < 1000));
-       return (x < 1000);
+  cprintf("Device 1 presence: %d\n", (x < 1000));
+  return (x < 1000);
 }
 
 void
 ide_set_disk(int d)
 {
-       if (d != 0 && d != 1)
-               panic("bad disk number");
-       diskno = d;
+  if (d != 0 && d != 1)
+    panic("bad disk number");
+  diskno = d;
 }
 
 int
 ide_read(uint32_t secno, void *dst, unsigned nsecs)
 {
-       int r;
-
-        if(nsecs > 256)
-          panic("ide_read");
-
-       ide_wait_ready(0);
-
-        outb(0x3f6, 0);
-       outb(0x1F2, nsecs);
-       outb(0x1F3, secno & 0xFF);
-       outb(0x1F4, (secno >> 8) & 0xFF);
-       outb(0x1F5, (secno >> 16) & 0xFF);
-       outb(0x1F6, 0xE0 | ((diskno&1)<<4) | ((secno>>24)&0x0F));
-       outb(0x1F7, 0x20);      // CMD 0x20 means read sector
-        
-        sleep(0);
-
-       for (; nsecs > 0; nsecs--, dst += 512) {
-               if ((r = ide_wait_ready(1)) < 0)
-                       return r;
-               insl(0x1F0, dst, 512/4);
-       }
+  int r;
+
+  if(nsecs > 256)
+    panic("ide_read");
+
+  ide_wait_ready(0);
+
+  outb(0x3f6, 0);
+  outb(0x1F2, nsecs);
+  outb(0x1F3, secno & 0xFF);
+  outb(0x1F4, (secno >> 8) & 0xFF);
+  outb(0x1F5, (secno >> 16) & 0xFF);
+  outb(0x1F6, 0xE0 | ((diskno&1)<<4) | ((secno>>24)&0x0F));
+  outb(0x1F7, 0x20);   // CMD 0x20 means read sector
+   
+  for (; nsecs > 0; nsecs--, dst += 512) {
+    if ((r = ide_wait_ready(1)) < 0)
+      return r;
+    insl(0x1F0, dst, 512/4);
+  }
        
-       return 0;
+  return 0;
 }
 
 int
 ide_write(uint32_t secno, const void *src, unsigned nsecs)
 {
-       int r;
+  int r;
        
-        if(nsecs > 256)
-          panic("ide_write");
+  if(nsecs > 256)
+    panic("ide_write");
 
-       ide_wait_ready(0);
+  ide_wait_ready(0);
 
-       outb(0x1F2, nsecs);
-       outb(0x1F3, secno & 0xFF);
-       outb(0x1F4, (secno >> 8) & 0xFF);
-       outb(0x1F5, (secno >> 16) & 0xFF);
-       outb(0x1F6, 0xE0 | ((diskno&1)<<4) | ((secno>>24)&0x0F));
-       outb(0x1F7, 0x30);      // CMD 0x30 means write sector
+  outb(0x1F2, nsecs);
+  outb(0x1F3, secno & 0xFF);
+  outb(0x1F4, (secno >> 8) & 0xFF);
+  outb(0x1F5, (secno >> 16) & 0xFF);
+  outb(0x1F6, 0xE0 | ((diskno&1)<<4) | ((secno>>24)&0x0F));
+  outb(0x1F7, 0x30);   // CMD 0x30 means write sector
 
-       for (; nsecs > 0; nsecs--, src += 512) {
-               if ((r = ide_wait_ready(1)) < 0)
-                       return r;
-               outsl(0x1F0, src, 512/4);
-       }
+  for (; nsecs > 0; nsecs--, src += 512) {
+    if ((r = ide_wait_ready(1)) < 0)
+      return r;
+    outsl(0x1F0, src, 512/4);
+  }
 
-       return 0;
+  return 0;
 }
diff --git a/main.c b/main.c
index 4c2a2f97aa80d4ea9c0dcb0e8a7c1e7b827732a9..296d00f5012847396ff584411227b9ed7037dd0d 100644 (file)
--- a/main.c
+++ b/main.c
@@ -36,7 +36,7 @@ main()
 
   cprintf("\nxV6\n\n");
 
-  pic_init(); // initialize PIC---not clear why
+  pic_init(); // initialize PIC
   mp_init(); // multiprocessor
   kinit(); // physical memory allocator
   tvinit(); // trap vectors
@@ -59,12 +59,14 @@ main()
   p->ppid = 0;
   setupsegs(p);
 
+  write_eflags(read_eflags() | FL_IF);
+
   // turn on interrupts on boot processor
   lapic_timerinit();
   lapic_enableintr();
-  write_eflags(read_eflags() | FL_IF);
 
 #if 0
+  ide_init();
   ide_read(0, buf, 1);
   cprintf("sec0.0 %x\n", buf[0] & 0xff);
 #endif
diff --git a/mp.c b/mp.c
index 57b887d4fdd51d48403da70f960d2bd62da2ce91..a0d51bf399261b484834c8487f0456c42c96c86a 100644 (file)
--- a/mp.c
+++ b/mp.c
@@ -92,6 +92,28 @@ enum {                                       /* LAPIC_TDCR */
   LAPIC_X1 = 0x0000000B,       /* divide by 1 */
 };
 
+static char* buses[] = {
+       "CBUSI ",
+       "CBUSII",
+       "EISA  ",
+       "FUTURE",
+       "INTERN",
+       "ISA   ",
+       "MBI   ",
+       "MBII  ",
+       "MCA   ",
+       "MPI   ",
+       "MPSA  ",
+       "NUBUS ",
+       "PCI   ",
+       "PCMCIA",
+       "TC    ",
+       "VL    ",
+       "VME   ",
+       "XPRESS",
+       0,
+};
+
 #define APBOOTCODE 0x7000 // XXX hack
 
 static struct MP* mp;  // The MP floating point structure
@@ -126,7 +148,7 @@ lapic_timerinit()
 void
 lapic_timerintr()
 {
-  // cprintf("%d: timer interrupt!\n", cpu());
+  cprintf("%d: timer interrupt!\n", cpu());
   lapic_write (LAPIC_EOI, 0);
 }
 
@@ -137,23 +159,17 @@ lapic_init(int c)
 
   cprintf("lapic_init %d\n", c);
 
-  irq_setmask_8259A(0xFFFF);
+  lapic_write(LAPIC_DFR, 0xFFFFFFFF); // set destination format register
+  r = (lapic_read(LAPIC_ID)>>24) & 0xFF; // read APIC ID
+  lapic_write(LAPIC_LDR, (1<<r)<<24);  // set logical destination register to r
+  lapic_write(LAPIC_TPR, 0xFF);  // no interrupts for now
+  lapic_write(LAPIC_SVR, LAPIC_ENABLE|(IRQ_OFFSET+IRQ_SPURIOUS));  // enable APIC
 
-  lapic_write(LAPIC_DFR, 0xFFFFFFFF);
-  r = (lapic_read(LAPIC_ID)>>24) & 0xFF;
-  lapic_write(LAPIC_LDR, (1<<r)<<24);
-  lapic_write(LAPIC_TPR, 0xFF);
-  lapic_write(LAPIC_SVR, LAPIC_ENABLE|(IRQ_OFFSET+IRQ_SPURIOUS));
+  // in virtual wire mode, set up the LINT0 and LINT1 as follows:
+  lapic_write(LAPIC_LINT0, APIC_IMASK | APIC_EXTINT);
+  lapic_write(LAPIC_LINT1, APIC_IMASK | APIC_NMI);
 
-  /*
-   * Set the local interrupts. It's likely these should just be
-   * masked off for SMP mode as some Pentium Pros have problems if
-   * LINT[01] are set to ExtINT.
-   * Acknowledge any outstanding interrupts.
-   */
-  lapic_write(LAPIC_LINT0, cpus[c].lintr[0]);
-  lapic_write(LAPIC_LINT1, cpus[c].lintr[1]);
-  lapic_write(LAPIC_EOI, 0);
+  lapic_write(LAPIC_EOI, 0); // acknowledge any outstanding interrupts.
 
   lvt = (lapic_read(LAPIC_VER)>>16) & 0xFF;
   if(lvt >= 4)
@@ -290,7 +306,7 @@ mp_detect(void)
   if(sum || (pcmp->version != 1 && pcmp->version != 4))
     return 3;
 
-  cprintf("Mp spec rev #: %x\n", mp->specrev);
+  cprintf("Mp spec rev #: %x imcrp 0x%x\n", mp->specrev, mp->imcrp);
   return 0;
 }
 
@@ -308,8 +324,10 @@ mp_init()
   uint8_t *p, *e;
   struct MPCTB *mpctb;
   struct MPPE *proc;
+  struct MPBE *bus;
   int c;
   extern int main();
+  int i;
 
   ncpu = 0;
   if ((r = mp_detect()) != 0) return;
@@ -332,8 +350,6 @@ mp_init()
     case MPPROCESSOR:
       proc = (struct MPPE *) p;
       cpus[ncpu].apicid = proc->apicid;
-      cpus[ncpu].lintr[0] = APIC_IMASK;
-      cpus[ncpu].lintr[1] = APIC_IMASK;
       cprintf("a processor %x\n", cpus[ncpu].apicid);
       if (proc->flags & MPBP) {
        bcpu = &cpus[ncpu];
@@ -342,6 +358,12 @@ mp_init()
       p += sizeof(struct MPPE);
       continue;
     case MPBUS:
+      bus = (struct MPBE *) p;
+      for(i = 0; buses[i]; i++){
+       if(strncmp(buses[i], bus->string, sizeof(bus->string)) == 0)
+         break;
+      }
+      cprintf("a bus %d\n", i);
       p += sizeof(struct MPBE);
       continue;
     case MPIOAPIC:
@@ -349,6 +371,7 @@ mp_init()
       p += sizeof(struct MPIOAPIC);
       continue;
     case MPIOINTR:
+      cprintf("an I/O intr\n");
       p += sizeof(struct MPIE);
       continue;
     default:
index ba131a3297af160c174faad2dc16250bf5b92a41..9c3ea0c37d265fab60e3337a54cac03d00ffbcff 100644 (file)
--- a/picirq.c
+++ b/picirq.c
@@ -4,80 +4,85 @@
 #include "x86.h"
 #include "defs.h"
 
+// I/O Addresses of the two 8259A programmable interrupt controllers
+#define IO_PIC1                0x20    // Master (IRQs 0-7)
+#define IO_PIC2                0xA0    // Slave (IRQs 8-15)
+
+#define IRQ_SLAVE       2      // IRQ at which slave connects to master
+
 // Current IRQ mask.
 // Initial IRQ mask has interrupt 2 enabled (for slave 8259A).
 uint16_t irq_mask_8259A = 0xFFFF & ~(1<<IRQ_SLAVE);
-static int didinit;
 
 /* Initialize the 8259A interrupt controllers. */
 void
 pic_init(void)
 {
-       didinit = 1;
-
-       // mask all interrupts
-       outb(IO_PIC1+1, 0xFF);
-       outb(IO_PIC2+1, 0xFF);
-
-       // Set up master (8259A-1)
-
-       // ICW1:  0001g0hi
-       //    g:  0 = edge triggering, 1 = level triggering
-       //    h:  0 = cascaded PICs, 1 = master only
-       //    i:  0 = no ICW4, 1 = ICW4 required
-       outb(IO_PIC1, 0x11);
-
-       // ICW2:  Vector offset
-       outb(IO_PIC1+1, IRQ_OFFSET);
-
-       // ICW3:  bit mask of IR lines connected to slave PICs (master PIC),
-       //        3-bit No of IR line at which slave connects to master(slave PIC).
-       outb(IO_PIC1+1, 1<<IRQ_SLAVE);
-
-       // ICW4:  000nbmap
-       //    n:  1 = special fully nested mode
-       //    b:  1 = buffered mode
-       //    m:  0 = slave PIC, 1 = master PIC
-       //        (ignored when b is 0, as the master/slave role
-       //        can be hardwired).
-       //    a:  1 = Automatic EOI mode
-       //    p:  0 = MCS-80/85 mode, 1 = intel x86 mode
-       outb(IO_PIC1+1, 0x3);
-
-       // Set up slave (8259A-2)
-       outb(IO_PIC2, 0x11);                    // ICW1
-       outb(IO_PIC2+1, IRQ_OFFSET + 8);        // ICW2
-       outb(IO_PIC2+1, IRQ_SLAVE);             // ICW3
-       // NB Automatic EOI mode doesn't tend to work on the slave.
-       // Linux source code says it's "to be investigated".
-       outb(IO_PIC2+1, 0x01);                  // ICW4
-
-       // OCW3:  0ef01prs
-       //   ef:  0x = NOP, 10 = clear specific mask, 11 = set specific mask
-       //    p:  0 = no polling, 1 = polling mode
-       //   rs:  0x = NOP, 10 = read IRR, 11 = read ISR
-       outb(IO_PIC1, 0x68);             /* clear specific mask */
-       outb(IO_PIC1, 0x0a);             /* read IRR by default */
-
-       outb(IO_PIC2, 0x68);               /* OCW3 */
-       outb(IO_PIC2, 0x0a);               /* OCW3 */
-
-       if (irq_mask_8259A != 0xFFFF)
-               irq_setmask_8259A(irq_mask_8259A);
+  // mask all interrupts
+  outb(IO_PIC1+1, 0xFF);
+  outb(IO_PIC2+1, 0xFF);
+
+  // Set up master (8259A-1)
+
+  // ICW1:  0001g0hi
+  //    g:  0 = edge triggering, 1 = level triggering
+  //    h:  0 = cascaded PICs, 1 = master only
+  //    i:  0 = no ICW4, 1 = ICW4 required
+  outb(IO_PIC1, 0x11);
+
+  // ICW2:  Vector offset
+  outb(IO_PIC1+1, IRQ_OFFSET);
+
+  // ICW3:  bit mask of IR lines connected to slave PICs (master PIC),
+  //        3-bit No of IR line at which slave connects to master(slave PIC).
+  outb(IO_PIC1+1, 1<<IRQ_SLAVE);
+
+  // ICW4:  000nbmap
+  //    n:  1 = special fully nested mode
+  //    b:  1 = buffered mode
+  //    m:  0 = slave PIC, 1 = master PIC
+  //     (ignored when b is 0, as the master/slave role
+  //     can be hardwired).
+  //    a:  1 = Automatic EOI mode
+  //    p:  0 = MCS-80/85 mode, 1 = intel x86 mode
+  outb(IO_PIC1+1, 0x3);
+
+  // Set up slave (8259A-2)
+  outb(IO_PIC2, 0x11);                 // ICW1
+  outb(IO_PIC2+1, IRQ_OFFSET + 8);     // ICW2
+  outb(IO_PIC2+1, IRQ_SLAVE);          // ICW3
+  // NB Automatic EOI mode doesn't tend to work on the slave.
+  // Linux source code says it's "to be investigated".
+  outb(IO_PIC2+1, 0x3);                        // ICW4
+
+  // OCW3:  0ef01prs
+  //   ef:  0x = NOP, 10 = clear specific mask, 11 = set specific mask
+  //    p:  0 = no polling, 1 = polling mode
+  //   rs:  0x = NOP, 10 = read IRR, 11 = read ISR
+  outb(IO_PIC1, 0x68);             /* clear specific mask */
+  outb(IO_PIC1, 0x0a);             /* read IRR by default */
+
+  outb(IO_PIC2, 0x68);               /* OCW3 */
+  outb(IO_PIC2, 0x0a);               /* OCW3 */
+
+  if (irq_mask_8259A != 0xFFFF)
+    irq_setmask_8259A(irq_mask_8259A);
+
 }
 
 void
 irq_setmask_8259A(uint16_t mask)
 {
-       int i;
-       irq_mask_8259A = mask;
-       if (!didinit)
-               return;
-       outb(IO_PIC1+1, (char)mask);
-       outb(IO_PIC2+1, (char)(mask >> 8));
-       cprintf("enabled interrupts:");
-       for (i = 0; i < 16; i++)
-               if (~mask & (1<<i))
-                       cprintf(" %d", i);
-       cprintf("\n");
+  int i;
+  irq_mask_8259A = mask;
+
+  outb(IO_PIC1+1, (char)mask);
+  outb(IO_PIC2+1, (char)(mask >> 8));
+
+  cprintf("%d: enabled interrupts:", cpu());
+
+  for (i = 0; i < 16; i++)
+    if (~mask & (1<<i))
+      cprintf(" %d", i);
+  cprintf("\n");
 }
diff --git a/proc.h b/proc.h
index e371f7dbb575bbffc19e16f83f80943b9118c8bc..0c748aa5244697fee73f09b21f268332b2632ab1 100644 (file)
--- a/proc.h
+++ b/proc.h
@@ -42,7 +42,6 @@ extern struct proc *curproc[NCPU];
 
 struct cpu {
   uint8_t apicid;       // Local APIC ID
-  int lintr[2];                // Local APIC
   char mpstack[MPSTACK]; // per-cpu start-up stack, only used to get into main()
 };
 
index 54f4ba832eb2f9abdb767153e31bc3be7a7f7d7c..c88e7de252010edfe441b02d9f3e8b1894cccc12 100644 (file)
--- a/string.c
+++ b/string.c
@@ -58,3 +58,14 @@ memmove(void *dst, const void *src, unsigned n)
 
   return dst;
 }
+
+int
+strncmp(const char *p, const char *q, unsigned n)
+{
+       while (n > 0 && *p && *p == *q)
+               n--, p++, q++;
+       if (n == 0)
+               return 0;
+       else
+               return (int) ((unsigned char) *p - (unsigned char) *q);
+}
diff --git a/trap.c b/trap.c
index e36540da6f2820f1d1e081ee8aa1e4ed18138dbd..045958315d43ed0c349ba4621702aa615d32f457 100644 (file)
--- a/trap.c
+++ b/trap.c
@@ -61,7 +61,6 @@ trap(struct Trapframe *tf)
     return;
   }
 
-  cprintf("trap %d eip %x:%x\n", tf->tf_trapno, tf->tf_cs, tf->tf_eip);
 
   // XXX probably ought to lgdt on trap return
 
diff --git a/x86.h b/x86.h
index 7bc677fe69896b10ce03f2ed5dd2bf98a25311a0..00638265e68e839073b13d51aa27487596ca2786 100644 (file)
--- a/x86.h
+++ b/x86.h
@@ -352,11 +352,6 @@ struct Trapframe {
 
 #define MAX_IRQS       16      // Number of IRQs
 
-// I/O Addresses of the two 8259A programmable interrupt controllers
-#define IO_PIC1                0x20    // Master (IRQs 0-7)
-#define IO_PIC2                0xA0    // Slave (IRQs 8-15)
-
-#define IRQ_SLAVE       2      // IRQ at which slave connects to master
 #define IRQ_OFFSET      32     // IRQ 0 corresponds to int IRQ_OFFSET
 
 #define IRQ_ERROR       19