timer interrupts

disk interrupts (assuming bochs has a bug)
This commit is contained in:
kaashoek 2006-07-05 20:00:14 +00:00
parent 8b4e2a08fe
commit b22d898297
9 changed files with 185 additions and 138 deletions

6
defs.h
View file

@ -25,11 +25,13 @@ void * memcpy(void *dst, void *src, unsigned n);
void * memset(void *dst, int c, unsigned n); void * memset(void *dst, int c, unsigned n);
int memcmp(const void *v1, const void *v2, unsigned n); int memcmp(const void *v1, const void *v2, unsigned n);
void *memmove(void *dst, const void *src, unsigned n); void *memmove(void *dst, const void *src, unsigned n);
int strncmp(const char *p, const char *q, unsigned n);
// syscall.c // syscall.c
void syscall(void); void syscall(void);
// picirq.c // picirq.c
extern uint16_t irq_mask_8259A;
void irq_setmask_8259A(uint16_t mask); void irq_setmask_8259A(uint16_t mask);
void pic_init(void); void pic_init(void);
@ -66,3 +68,7 @@ struct fd * fd_alloc();
void fd_close(struct fd *); void fd_close(struct fd *);
int fd_read(struct fd *fd, char *addr, int n); int fd_read(struct fd *fd, char *addr, int n);
int fd_write(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);

11
ide.c
View file

@ -31,6 +31,15 @@ ide_wait_ready(int check_error)
return 0; 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 int
ide_probe_disk1(void) ide_probe_disk1(void)
{ {
@ -79,8 +88,6 @@ ide_read(uint32_t secno, void *dst, unsigned nsecs)
outb(0x1F6, 0xE0 | ((diskno&1)<<4) | ((secno>>24)&0x0F)); outb(0x1F6, 0xE0 | ((diskno&1)<<4) | ((secno>>24)&0x0F));
outb(0x1F7, 0x20); // CMD 0x20 means read sector outb(0x1F7, 0x20); // CMD 0x20 means read sector
sleep(0);
for (; nsecs > 0; nsecs--, dst += 512) { for (; nsecs > 0; nsecs--, dst += 512) {
if ((r = ide_wait_ready(1)) < 0) if ((r = ide_wait_ready(1)) < 0)
return r; return r;

6
main.c
View file

@ -36,7 +36,7 @@ main()
cprintf("\nxV6\n\n"); cprintf("\nxV6\n\n");
pic_init(); // initialize PIC---not clear why pic_init(); // initialize PIC
mp_init(); // multiprocessor mp_init(); // multiprocessor
kinit(); // physical memory allocator kinit(); // physical memory allocator
tvinit(); // trap vectors tvinit(); // trap vectors
@ -59,12 +59,14 @@ main()
p->ppid = 0; p->ppid = 0;
setupsegs(p); setupsegs(p);
write_eflags(read_eflags() | FL_IF);
// turn on interrupts on boot processor // turn on interrupts on boot processor
lapic_timerinit(); lapic_timerinit();
lapic_enableintr(); lapic_enableintr();
write_eflags(read_eflags() | FL_IF);
#if 0 #if 0
ide_init();
ide_read(0, buf, 1); ide_read(0, buf, 1);
cprintf("sec0.0 %x\n", buf[0] & 0xff); cprintf("sec0.0 %x\n", buf[0] & 0xff);
#endif #endif

61
mp.c
View file

@ -92,6 +92,28 @@ enum { /* LAPIC_TDCR */
LAPIC_X1 = 0x0000000B, /* divide by 1 */ 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 #define APBOOTCODE 0x7000 // XXX hack
static struct MP* mp; // The MP floating point structure static struct MP* mp; // The MP floating point structure
@ -126,7 +148,7 @@ lapic_timerinit()
void void
lapic_timerintr() lapic_timerintr()
{ {
// cprintf("%d: timer interrupt!\n", cpu()); cprintf("%d: timer interrupt!\n", cpu());
lapic_write (LAPIC_EOI, 0); lapic_write (LAPIC_EOI, 0);
} }
@ -137,23 +159,17 @@ lapic_init(int c)
cprintf("lapic_init %d\n", 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); // in virtual wire mode, set up the LINT0 and LINT1 as follows:
r = (lapic_read(LAPIC_ID)>>24) & 0xFF; lapic_write(LAPIC_LINT0, APIC_IMASK | APIC_EXTINT);
lapic_write(LAPIC_LDR, (1<<r)<<24); lapic_write(LAPIC_LINT1, APIC_IMASK | APIC_NMI);
lapic_write(LAPIC_TPR, 0xFF);
lapic_write(LAPIC_SVR, LAPIC_ENABLE|(IRQ_OFFSET+IRQ_SPURIOUS));
/* lapic_write(LAPIC_EOI, 0); // acknowledge any outstanding interrupts.
* 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);
lvt = (lapic_read(LAPIC_VER)>>16) & 0xFF; lvt = (lapic_read(LAPIC_VER)>>16) & 0xFF;
if(lvt >= 4) if(lvt >= 4)
@ -290,7 +306,7 @@ mp_detect(void)
if(sum || (pcmp->version != 1 && pcmp->version != 4)) if(sum || (pcmp->version != 1 && pcmp->version != 4))
return 3; 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; return 0;
} }
@ -308,8 +324,10 @@ mp_init()
uint8_t *p, *e; uint8_t *p, *e;
struct MPCTB *mpctb; struct MPCTB *mpctb;
struct MPPE *proc; struct MPPE *proc;
struct MPBE *bus;
int c; int c;
extern int main(); extern int main();
int i;
ncpu = 0; ncpu = 0;
if ((r = mp_detect()) != 0) return; if ((r = mp_detect()) != 0) return;
@ -332,8 +350,6 @@ mp_init()
case MPPROCESSOR: case MPPROCESSOR:
proc = (struct MPPE *) p; proc = (struct MPPE *) p;
cpus[ncpu].apicid = proc->apicid; 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); cprintf("a processor %x\n", cpus[ncpu].apicid);
if (proc->flags & MPBP) { if (proc->flags & MPBP) {
bcpu = &cpus[ncpu]; bcpu = &cpus[ncpu];
@ -342,6 +358,12 @@ mp_init()
p += sizeof(struct MPPE); p += sizeof(struct MPPE);
continue; continue;
case MPBUS: 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); p += sizeof(struct MPBE);
continue; continue;
case MPIOAPIC: case MPIOAPIC:
@ -349,6 +371,7 @@ mp_init()
p += sizeof(struct MPIOAPIC); p += sizeof(struct MPIOAPIC);
continue; continue;
case MPIOINTR: case MPIOINTR:
cprintf("an I/O intr\n");
p += sizeof(struct MPIE); p += sizeof(struct MPIE);
continue; continue;
default: default:

View file

@ -4,17 +4,20 @@
#include "x86.h" #include "x86.h"
#include "defs.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. // Current IRQ mask.
// Initial IRQ mask has interrupt 2 enabled (for slave 8259A). // Initial IRQ mask has interrupt 2 enabled (for slave 8259A).
uint16_t irq_mask_8259A = 0xFFFF & ~(1<<IRQ_SLAVE); uint16_t irq_mask_8259A = 0xFFFF & ~(1<<IRQ_SLAVE);
static int didinit;
/* Initialize the 8259A interrupt controllers. */ /* Initialize the 8259A interrupt controllers. */
void void
pic_init(void) pic_init(void)
{ {
didinit = 1;
// mask all interrupts // mask all interrupts
outb(IO_PIC1+1, 0xFF); outb(IO_PIC1+1, 0xFF);
outb(IO_PIC2+1, 0xFF); outb(IO_PIC2+1, 0xFF);
@ -50,7 +53,7 @@ pic_init(void)
outb(IO_PIC2+1, IRQ_SLAVE); // ICW3 outb(IO_PIC2+1, IRQ_SLAVE); // ICW3
// NB Automatic EOI mode doesn't tend to work on the slave. // NB Automatic EOI mode doesn't tend to work on the slave.
// Linux source code says it's "to be investigated". // Linux source code says it's "to be investigated".
outb(IO_PIC2+1, 0x01); // ICW4 outb(IO_PIC2+1, 0x3); // ICW4
// OCW3: 0ef01prs // OCW3: 0ef01prs
// ef: 0x = NOP, 10 = clear specific mask, 11 = set specific mask // ef: 0x = NOP, 10 = clear specific mask, 11 = set specific mask
@ -64,6 +67,7 @@ pic_init(void)
if (irq_mask_8259A != 0xFFFF) if (irq_mask_8259A != 0xFFFF)
irq_setmask_8259A(irq_mask_8259A); irq_setmask_8259A(irq_mask_8259A);
} }
void void
@ -71,11 +75,12 @@ irq_setmask_8259A(uint16_t mask)
{ {
int i; int i;
irq_mask_8259A = mask; irq_mask_8259A = mask;
if (!didinit)
return;
outb(IO_PIC1+1, (char)mask); outb(IO_PIC1+1, (char)mask);
outb(IO_PIC2+1, (char)(mask >> 8)); outb(IO_PIC2+1, (char)(mask >> 8));
cprintf("enabled interrupts:");
cprintf("%d: enabled interrupts:", cpu());
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
if (~mask & (1<<i)) if (~mask & (1<<i))
cprintf(" %d", i); cprintf(" %d", i);

1
proc.h
View file

@ -42,7 +42,6 @@ extern struct proc *curproc[NCPU];
struct cpu { struct cpu {
uint8_t apicid; // Local APIC ID 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() char mpstack[MPSTACK]; // per-cpu start-up stack, only used to get into main()
}; };

View file

@ -58,3 +58,14 @@ memmove(void *dst, const void *src, unsigned n)
return dst; 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);
}

1
trap.c
View file

@ -61,7 +61,6 @@ trap(struct Trapframe *tf)
return; 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 // XXX probably ought to lgdt on trap return

5
x86.h
View file

@ -352,11 +352,6 @@ struct Trapframe {
#define MAX_IRQS 16 // Number of IRQs #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_OFFSET 32 // IRQ 0 corresponds to int IRQ_OFFSET
#define IRQ_ERROR 19 #define IRQ_ERROR 19