]> Devi Nivas Git - cs3210-lab1.git/commitdiff
checkpoint
authorrtm <rtm>
Fri, 16 Jun 2006 20:29:25 +0000 (20:29 +0000)
committerrtm <rtm>
Fri, 16 Jun 2006 20:29:25 +0000 (20:29 +0000)
Makefile
defs.h
ide.c [new file with mode: 0644]
main.c
picirq.c [new file with mode: 0644]

index fa93f850374b0c0385cfd10c64aa4c69177f4c15..81241f4db97983983ae83168fe07156040bf95e3 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 OBJS = main.o console.o string.o kalloc.o proc.o trapasm.o trap.o vectors.o \
-       syscall.o
+       syscall.o ide.o picirq.o
 
 CC = i386-jos-elf-gcc
 LD = i386-jos-elf-ld
diff --git a/defs.h b/defs.h
index eea3d0ca8def581cc5a902b775d0a0df3b4acaeb..199ea878088b52fb17da7e6f108c2750f54f7155 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -24,3 +24,7 @@ void * memset(void *dst, int c, unsigned n);
 
 // syscall.c
 void syscall(void);
+
+// picirq.c
+void irq_setmask_8259A(uint16_t mask);
+void pic_init(void);
diff --git a/ide.c b/ide.c
new file mode 100644 (file)
index 0000000..3152f93
--- /dev/null
+++ b/ide.c
@@ -0,0 +1,117 @@
+/*
+ * Minimal PIO-based (non-interrupt-driven) IDE driver code.
+ * For information about what all this IDE/ATA magic means,
+ * see the materials available on the class references page.
+ */
+
+#include "types.h"
+#include "param.h"
+#include "mmu.h"
+#include "proc.h"
+#include "defs.h"
+#include "x86.h"
+
+#define IDE_BSY                0x80
+#define IDE_DRDY       0x40
+#define IDE_DF         0x20
+#define IDE_ERR                0x01
+
+static int diskno = 0;
+
+static int
+ide_wait_ready(int check_error)
+{
+       int r;
+
+       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;
+}
+
+int
+ide_probe_disk1(void)
+{
+       int r, x;
+
+       // wait for Device 0 to be ready
+       ide_wait_ready(0);
+
+       // 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 */;
+
+       // switch back to Device 0
+       outb(0x1F6, 0xE0 | (0<<4));
+
+       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;
+}
+
+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);
+       }
+       
+       return 0;
+}
+
+int
+ide_write(uint32_t secno, const void *src, unsigned nsecs)
+{
+       int r;
+       
+        if(nsecs > 256)
+          panic("ide_write");
+
+       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
+
+       for (; nsecs > 0; nsecs--, src += 512) {
+               if ((r = ide_wait_ready(1)) < 0)
+                       return r;
+               outsl(0x1F0, src, 512/4);
+       }
+
+       return 0;
+}
diff --git a/main.c b/main.c
index 43c8c0260ef82fed14fa532539edb9b6599b957c..2f3b00e54523bbc82746d20726d1076962e4f2c5 100644 (file)
--- a/main.c
+++ b/main.c
@@ -9,6 +9,8 @@
 
 extern char edata[], end[];
 
+char buf[512];
+
 int
 main()
 {
@@ -18,16 +20,11 @@ main()
   // clear BSS
   memset(edata, 0, end - edata);
 
-  // partially initizialize PIC
-  outb(0x20+1, 0xFF); // IO_PIC1
-  outb(0xA0+1, 0xFF); // IO_PIC2
-  outb(0x20, 0x11);
-  outb(0x20+1, 32);
-
   cprintf("\nxV6\n\n");
 
   kinit(); // physical memory allocator
   tinit(); // traps and interrupts
+  pic_init();
 
   // create fake process zero
   p = &proc[0];
@@ -46,6 +43,16 @@ main()
   p->ppid = 0;
   setupsegs(p);
 
+  // turn on interrupts
+  write_eflags(read_eflags() | FL_IF);
+  irq_setmask_8259A(0);
+
+#if 1
+  ide_read(0, buf, 1);
+  cprintf("sec0.0 %x\n", buf[0] & 0xff);
+#endif
+
+#if 0
   p = newproc();
 
   i = 0;
@@ -73,6 +80,7 @@ main()
   p->mem[i++] = T_SYSCALL;
   p->tf->tf_eip = 0;
   p->tf->tf_esp = p->sz;
+#endif
 
   swtch();
 
diff --git a/picirq.c b/picirq.c
new file mode 100644 (file)
index 0000000..5fc90c5
--- /dev/null
+++ b/picirq.c
@@ -0,0 +1,92 @@
+/* See COPYRIGHT for copyright information. */
+
+#include "types.h"
+#include "x86.h"
+#include "defs.h"
+
+#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
+
+// 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);
+}
+
+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");
+}