From ae6e8aa730fa410118c0532938d4a9e62b08bbe8 Mon Sep 17 00:00:00 2001 From: rtm Date: Fri, 16 Jun 2006 20:29:25 +0000 Subject: [PATCH] checkpoint --- Makefile | 2 +- defs.h | 4 ++ ide.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.c | 20 +++++++--- picirq.c | 92 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 228 insertions(+), 7 deletions(-) create mode 100644 ide.c create mode 100644 picirq.c diff --git a/Makefile b/Makefile index fa93f85..81241f4 100644 --- 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 eea3d0c..199ea87 100644 --- 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 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 43c8c02..2f3b00e 100644 --- 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 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<> 8)); + cprintf("enabled interrupts:"); + for (i = 0; i < 16; i++) + if (~mask & (1<