From b22d898297a2496ba4cfd31d445769fbebc0a46d Mon Sep 17 00:00:00 2001 From: kaashoek Date: Wed, 5 Jul 2006 20:00:14 +0000 Subject: [PATCH] timer interrupts disk interrupts (assuming bochs has a bug) --- defs.h | 6 +++ ide.c | 121 +++++++++++++++++++++++++++++-------------------------- main.c | 6 ++- mp.c | 61 +++++++++++++++++++--------- picirq.c | 111 ++++++++++++++++++++++++++------------------------ proc.h | 1 - string.c | 11 +++++ trap.c | 1 - x86.h | 5 --- 9 files changed, 185 insertions(+), 138 deletions(-) diff --git a/defs.h b/defs.h index e627a4c..d1025a6 100644 --- 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 3152f93..0e63a86 100644 --- 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; + int r; - if(nsecs > 256) - panic("ide_read"); + if(nsecs > 256) + panic("ide_read"); - ide_wait_ready(0); + 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); - } + 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 4c2a2f9..296d00f 100644 --- 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 57b887d..a0d51bf 100644 --- 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<>24) & 0xFF; - lapic_write(LAPIC_LDR, (1<>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: diff --git a/picirq.c b/picirq.c index ba131a3..9c3ea0c 100644 --- 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<> 8)); - cprintf("enabled interrupts:"); - for (i = 0; i < 16; i++) - if (~mask & (1<> 8)); + + cprintf("%d: enabled interrupts:", cpu()); + + for (i = 0; i < 16; i++) + if (~mask & (1< 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 e36540d..0459583 100644 --- 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 7bc677f..0063826 100644 --- 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