timer interrupts
disk interrupts (assuming bochs has a bug)
This commit is contained in:
parent
8b4e2a08fe
commit
b22d898297
9 changed files with 185 additions and 138 deletions
6
defs.h
6
defs.h
|
@ -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);
|
||||||
|
|
121
ide.c
121
ide.c
|
@ -21,97 +21,104 @@ static int diskno = 0;
|
||||||
static int
|
static int
|
||||||
ide_wait_ready(int check_error)
|
ide_wait_ready(int check_error)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
while (((r = inb(0x1F7)) & (IDE_BSY|IDE_DRDY)) != IDE_DRDY)
|
while (((r = inb(0x1F7)) & (IDE_BSY|IDE_DRDY)) != IDE_DRDY)
|
||||||
/* do nothing */;
|
/* do nothing */;
|
||||||
|
|
||||||
if (check_error && (r & (IDE_DF|IDE_ERR)) != 0)
|
if (check_error && (r & (IDE_DF|IDE_ERR)) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
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)
|
||||||
{
|
{
|
||||||
int r, x;
|
int r, x;
|
||||||
|
|
||||||
// wait for Device 0 to be ready
|
// wait for Device 0 to be ready
|
||||||
ide_wait_ready(0);
|
ide_wait_ready(0);
|
||||||
|
|
||||||
// switch to Device 1
|
// switch to Device 1
|
||||||
outb(0x1F6, 0xE0 | (1<<4));
|
outb(0x1F6, 0xE0 | (1<<4));
|
||||||
|
|
||||||
// check for Device 1 to be ready for a while
|
// check for Device 1 to be ready for a while
|
||||||
for (x = 0; x < 1000 && (r = inb(0x1F7)) == 0; x++)
|
for (x = 0; x < 1000 && (r = inb(0x1F7)) == 0; x++)
|
||||||
/* do nothing */;
|
/* do nothing */;
|
||||||
|
|
||||||
// switch back to Device 0
|
// switch back to Device 0
|
||||||
outb(0x1F6, 0xE0 | (0<<4));
|
outb(0x1F6, 0xE0 | (0<<4));
|
||||||
|
|
||||||
cprintf("Device 1 presence: %d\n", (x < 1000));
|
cprintf("Device 1 presence: %d\n", (x < 1000));
|
||||||
return (x < 1000);
|
return (x < 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ide_set_disk(int d)
|
ide_set_disk(int d)
|
||||||
{
|
{
|
||||||
if (d != 0 && d != 1)
|
if (d != 0 && d != 1)
|
||||||
panic("bad disk number");
|
panic("bad disk number");
|
||||||
diskno = d;
|
diskno = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ide_read(uint32_t secno, void *dst, unsigned nsecs)
|
ide_read(uint32_t secno, void *dst, unsigned nsecs)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if(nsecs > 256)
|
if(nsecs > 256)
|
||||||
panic("ide_read");
|
panic("ide_read");
|
||||||
|
|
||||||
ide_wait_ready(0);
|
ide_wait_ready(0);
|
||||||
|
|
||||||
outb(0x3f6, 0);
|
outb(0x3f6, 0);
|
||||||
outb(0x1F2, nsecs);
|
outb(0x1F2, nsecs);
|
||||||
outb(0x1F3, secno & 0xFF);
|
outb(0x1F3, secno & 0xFF);
|
||||||
outb(0x1F4, (secno >> 8) & 0xFF);
|
outb(0x1F4, (secno >> 8) & 0xFF);
|
||||||
outb(0x1F5, (secno >> 16) & 0xFF);
|
outb(0x1F5, (secno >> 16) & 0xFF);
|
||||||
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) {
|
||||||
|
if ((r = ide_wait_ready(1)) < 0)
|
||||||
for (; nsecs > 0; nsecs--, dst += 512) {
|
return r;
|
||||||
if ((r = ide_wait_ready(1)) < 0)
|
insl(0x1F0, dst, 512/4);
|
||||||
return r;
|
}
|
||||||
insl(0x1F0, dst, 512/4);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ide_write(uint32_t secno, const void *src, unsigned nsecs)
|
ide_write(uint32_t secno, const void *src, unsigned nsecs)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if(nsecs > 256)
|
if(nsecs > 256)
|
||||||
panic("ide_write");
|
panic("ide_write");
|
||||||
|
|
||||||
ide_wait_ready(0);
|
ide_wait_ready(0);
|
||||||
|
|
||||||
outb(0x1F2, nsecs);
|
outb(0x1F2, nsecs);
|
||||||
outb(0x1F3, secno & 0xFF);
|
outb(0x1F3, secno & 0xFF);
|
||||||
outb(0x1F4, (secno >> 8) & 0xFF);
|
outb(0x1F4, (secno >> 8) & 0xFF);
|
||||||
outb(0x1F5, (secno >> 16) & 0xFF);
|
outb(0x1F5, (secno >> 16) & 0xFF);
|
||||||
outb(0x1F6, 0xE0 | ((diskno&1)<<4) | ((secno>>24)&0x0F));
|
outb(0x1F6, 0xE0 | ((diskno&1)<<4) | ((secno>>24)&0x0F));
|
||||||
outb(0x1F7, 0x30); // CMD 0x30 means write sector
|
outb(0x1F7, 0x30); // CMD 0x30 means write sector
|
||||||
|
|
||||||
for (; nsecs > 0; nsecs--, src += 512) {
|
for (; nsecs > 0; nsecs--, src += 512) {
|
||||||
if ((r = ide_wait_ready(1)) < 0)
|
if ((r = ide_wait_ready(1)) < 0)
|
||||||
return r;
|
return r;
|
||||||
outsl(0x1F0, src, 512/4);
|
outsl(0x1F0, src, 512/4);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
6
main.c
6
main.c
|
@ -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
61
mp.c
|
@ -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:
|
||||||
|
|
111
picirq.c
111
picirq.c
|
@ -4,80 +4,85 @@
|
||||||
#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
|
||||||
|
outb(IO_PIC1+1, 0xFF);
|
||||||
|
outb(IO_PIC2+1, 0xFF);
|
||||||
|
|
||||||
// mask all interrupts
|
// Set up master (8259A-1)
|
||||||
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);
|
||||||
|
|
||||||
// ICW1: 0001g0hi
|
// ICW2: Vector offset
|
||||||
// g: 0 = edge triggering, 1 = level triggering
|
outb(IO_PIC1+1, IRQ_OFFSET);
|
||||||
// h: 0 = cascaded PICs, 1 = master only
|
|
||||||
// i: 0 = no ICW4, 1 = ICW4 required
|
|
||||||
outb(IO_PIC1, 0x11);
|
|
||||||
|
|
||||||
// ICW2: Vector offset
|
// ICW3: bit mask of IR lines connected to slave PICs (master PIC),
|
||||||
outb(IO_PIC1+1, IRQ_OFFSET);
|
// 3-bit No of IR line at which slave connects to master(slave PIC).
|
||||||
|
outb(IO_PIC1+1, 1<<IRQ_SLAVE);
|
||||||
|
|
||||||
// ICW3: bit mask of IR lines connected to slave PICs (master PIC),
|
// ICW4: 000nbmap
|
||||||
// 3-bit No of IR line at which slave connects to master(slave PIC).
|
// n: 1 = special fully nested mode
|
||||||
outb(IO_PIC1+1, 1<<IRQ_SLAVE);
|
// 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);
|
||||||
|
|
||||||
// ICW4: 000nbmap
|
// Set up slave (8259A-2)
|
||||||
// n: 1 = special fully nested mode
|
outb(IO_PIC2, 0x11); // ICW1
|
||||||
// b: 1 = buffered mode
|
outb(IO_PIC2+1, IRQ_OFFSET + 8); // ICW2
|
||||||
// m: 0 = slave PIC, 1 = master PIC
|
outb(IO_PIC2+1, IRQ_SLAVE); // ICW3
|
||||||
// (ignored when b is 0, as the master/slave role
|
// NB Automatic EOI mode doesn't tend to work on the slave.
|
||||||
// can be hardwired).
|
// Linux source code says it's "to be investigated".
|
||||||
// a: 1 = Automatic EOI mode
|
outb(IO_PIC2+1, 0x3); // ICW4
|
||||||
// p: 0 = MCS-80/85 mode, 1 = intel x86 mode
|
|
||||||
outb(IO_PIC1+1, 0x3);
|
|
||||||
|
|
||||||
// Set up slave (8259A-2)
|
// OCW3: 0ef01prs
|
||||||
outb(IO_PIC2, 0x11); // ICW1
|
// ef: 0x = NOP, 10 = clear specific mask, 11 = set specific mask
|
||||||
outb(IO_PIC2+1, IRQ_OFFSET + 8); // ICW2
|
// p: 0 = no polling, 1 = polling mode
|
||||||
outb(IO_PIC2+1, IRQ_SLAVE); // ICW3
|
// rs: 0x = NOP, 10 = read IRR, 11 = read ISR
|
||||||
// NB Automatic EOI mode doesn't tend to work on the slave.
|
outb(IO_PIC1, 0x68); /* clear specific mask */
|
||||||
// Linux source code says it's "to be investigated".
|
outb(IO_PIC1, 0x0a); /* read IRR by default */
|
||||||
outb(IO_PIC2+1, 0x01); // ICW4
|
|
||||||
|
|
||||||
// OCW3: 0ef01prs
|
outb(IO_PIC2, 0x68); /* OCW3 */
|
||||||
// ef: 0x = NOP, 10 = clear specific mask, 11 = set specific mask
|
outb(IO_PIC2, 0x0a); /* OCW3 */
|
||||||
// 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 */
|
if (irq_mask_8259A != 0xFFFF)
|
||||||
outb(IO_PIC2, 0x0a); /* OCW3 */
|
irq_setmask_8259A(irq_mask_8259A);
|
||||||
|
|
||||||
if (irq_mask_8259A != 0xFFFF)
|
|
||||||
irq_setmask_8259A(irq_mask_8259A);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
irq_setmask_8259A(uint16_t mask)
|
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++)
|
|
||||||
if (~mask & (1<<i))
|
for (i = 0; i < 16; i++)
|
||||||
cprintf(" %d", i);
|
if (~mask & (1<<i))
|
||||||
cprintf("\n");
|
cprintf(" %d", i);
|
||||||
|
cprintf("\n");
|
||||||
}
|
}
|
||||||
|
|
1
proc.h
1
proc.h
|
@ -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()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
11
string.c
11
string.c
|
@ -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
1
trap.c
|
@ -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
5
x86.h
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue