From bd303ed06096395778c80558e013b64bb47b9e9c Mon Sep 17 00:00:00 2001 From: kaashoek Date: Wed, 28 Jun 2006 16:35:03 +0000 Subject: [PATCH] timer interrupts --- defs.h | 5 +++- main.c | 81 ++++++++++++++++++--------------------------------------- mp.c | 38 ++++++++++++++++++--------- mp.h | 4 +-- trap.c | 13 ++++----- traps.h | 6 +++++ 6 files changed, 70 insertions(+), 77 deletions(-) diff --git a/defs.h b/defs.h index d7cc09b..27cac3d 100644 --- a/defs.h +++ b/defs.h @@ -37,7 +37,10 @@ void pic_init(void); void mp_init(void); int cpu(void); int mp_isbcpu(void); -void lapic_init(int c); +void lapic_init(int); +void lapic_timerinit(void); +void lapic_timerintr(void); +void lapic_enableintr(void); // spinlock.c extern uint32_t kernel_lock; diff --git a/main.c b/main.c index 92b8f24..979048c 100644 --- a/main.c +++ b/main.c @@ -36,11 +36,11 @@ main() cprintf("\nxV6\n\n"); + pic_init(); // initialize PIC---not clear why mp_init(); // multiprocessor kinit(); // physical memory allocator tvinit(); // trap vectors idtinit(); // CPU's idt - pic_init(); // create fake process zero p = &proc[0]; @@ -59,8 +59,9 @@ main() p->ppid = 0; setupsegs(p); - // turn on interrupts - irq_setmask_8259A(0xff); + // turn on interrupts on boot processor + lapic_timerinit(); + lapic_enableintr(); write_eflags(read_eflags() | FL_IF); #if 0 @@ -68,38 +69,8 @@ main() cprintf("sec0.0 %x\n", buf[0] & 0xff); #endif -#if 1 p = newproc(); load_icode(p, _binary_usertests_start, (unsigned) _binary_usertests_size); -#endif - -#if 0 - i = 0; - p->mem[i++] = 0x90; // nop - p->mem[i++] = 0xb8; // mov ..., %eax - p->mem[i++] = SYS_fork; - p->mem[i++] = 0; - p->mem[i++] = 0; - p->mem[i++] = 0; - p->mem[i++] = 0xcd; // int - p->mem[i++] = T_SYSCALL; - p->mem[i++] = 0xb8; // mov ..., %eax - p->mem[i++] = SYS_wait; - p->mem[i++] = 0; - p->mem[i++] = 0; - p->mem[i++] = 0; - p->mem[i++] = 0xcd; // int - p->mem[i++] = T_SYSCALL; - p->mem[i++] = 0xb8; // mov ..., %eax - p->mem[i++] = SYS_exit; - p->mem[i++] = 0; - p->mem[i++] = 0; - p->mem[i++] = 0; - p->mem[i++] = 0xcd; // int - p->mem[i++] = T_SYSCALL; - p->tf->tf_eip = 0; - p->tf->tf_esp = p->sz; -#endif swtch(); @@ -109,32 +80,32 @@ main() void load_icode(struct proc *p, uint8_t *binary, unsigned size) { - int i; - struct Elf *elf; - struct Proghdr *ph; + int i; + struct Elf *elf; + struct Proghdr *ph; - // Check magic number on binary - elf = (struct Elf*) binary; - cprintf("elf %x magic %x\n", elf, elf->e_magic); - if (elf->e_magic != ELF_MAGIC) - panic("load_icode: not an ELF binary"); + // Check magic number on binary + elf = (struct Elf*) binary; + cprintf("elf %x magic %x\n", elf, elf->e_magic); + if (elf->e_magic != ELF_MAGIC) + panic("load_icode: not an ELF binary"); p->tf->tf_eip = elf->e_entry; p->tf->tf_esp = p->sz; - // Map and load segments as directed. - ph = (struct Proghdr*) (binary + elf->e_phoff); - for (i = 0; i < elf->e_phnum; i++, ph++) { - if (ph->p_type != ELF_PROG_LOAD) - continue; - cprintf("va %x memsz %d\n", ph->p_va, ph->p_memsz); - if (ph->p_va + ph->p_memsz < ph->p_va) - panic("load_icode: overflow in elf header segment"); - if (ph->p_va + ph->p_memsz >= p->sz) - panic("load_icode: icode wants to be above UTOP"); + // Map and load segments as directed. + ph = (struct Proghdr*) (binary + elf->e_phoff); + for (i = 0; i < elf->e_phnum; i++, ph++) { + if (ph->p_type != ELF_PROG_LOAD) + continue; + cprintf("va %x memsz %d\n", ph->p_va, ph->p_memsz); + if (ph->p_va + ph->p_memsz < ph->p_va) + panic("load_icode: overflow in elf header segment"); + if (ph->p_va + ph->p_memsz >= p->sz) + panic("load_icode: icode wants to be above UTOP"); - // Load/clear the segment - memcpy(p->mem + ph->p_va, binary + ph->p_offset, ph->p_filesz); - memset(p->mem + ph->p_va + ph->p_filesz, 0, ph->p_memsz - ph->p_filesz); - } + // Load/clear the segment + memcpy(p->mem + ph->p_va, binary + ph->p_offset, ph->p_filesz); + memset(p->mem + ph->p_va + ph->p_filesz, 0, ph->p_memsz - ph->p_filesz); + } } diff --git a/mp.c b/mp.c index f267b8a..ca581e5 100644 --- a/mp.c +++ b/mp.c @@ -4,6 +4,7 @@ #include "memlayout.h" #include "param.h" #include "x86.h" +#include "traps.h" #include "mmu.h" /* @@ -115,12 +116,33 @@ lapic_write(int r, int data) *(lapicaddr+(r/sizeof(*lapicaddr))) = data; } + +void +lapic_timerinit() +{ + cprintf("%d: init timer\n", cpu()); + lapic_write(LAPIC_TDCR, LAPIC_X1); + lapic_write(LAPIC_TIMER, LAPIC_CLKIN | LAPIC_PERIODIC | (IRQ_OFFSET + IRQ_TIMER)); + lapic_write(LAPIC_TCCR, 1000000); + lapic_write(LAPIC_TICR, 1000000); +} + +void +lapic_timerintr() +{ + cprintf("%d: timer interrupt!\n", cpu()); + lapic_write (LAPIC_EOI, 0); +} + void lapic_init(int c) { uint32_t r, lvt; cprintf("lapic_init %d\n", c); + + irq_setmask_8259A(0xFFFF); + lapic_write(LAPIC_DFR, 0xFFFFFFFF); r = (lapic_read(LAPIC_ID)>>24) & 0xFF; lapic_write(LAPIC_LDR, (1<version != 1 && pcmp->version != 4)) return 3; - cprintf("MP spec rev #: %x\n", mp->specrev); + cprintf("Mp spec rev #: %x\n", mp->specrev); return 0; } @@ -348,8 +362,6 @@ mp_init() lapic_init(bcpu-cpus); cprintf("ncpu: %d boot %d\n", ncpu, bcpu-cpus); - lapic_online(); - extern uint8_t _binary_bootother_start[], _binary_bootother_size[]; memmove((void *) APBOOTCODE,_binary_bootother_start, (uint32_t) _binary_bootother_size); diff --git a/mp.h b/mp.h index 21d19c5..f5f4cea 100644 --- a/mp.h +++ b/mp.h @@ -109,7 +109,7 @@ enum { APIC_NMI = 0x00000400, APIC_INIT = 0x00000500, /* INIT/RESET */ APIC_STARTUP = 0x00000600, /* Startup IPI */ - APIC_ExtINT = 0x00000700, + APIC_EXTINT = 0x00000700, APIC_PHYSICAL = 0x00000000, /* [11] Destination Mode (RW) */ APIC_LOGICAL = 0x00000800, @@ -117,7 +117,7 @@ enum { APIC_DELIVS = 0x00001000, /* [12] Delivery Status (RO) */ APIC_HIGH = 0x00000000, /* [13] Interrupt Input Pin Polarity (RW) */ APIC_LOW = 0x00002000, - APIC_RemoteIRR = 0x00004000, /* [14] Remote IRR (RO) */ + APIC_REMOTEIRR = 0x00004000, /* [14] Remote IRR (RO) */ APIC_EDGE = 0x00000000, /* [15] Trigger Mode (RW) */ APIC_LEVEL = 0x00008000, APIC_IMASK = 0x00010000, /* [16] Interrupt Mask */ diff --git a/trap.c b/trap.c index cfa8a57..01c2f14 100644 --- a/trap.c +++ b/trap.c @@ -43,14 +43,15 @@ trap(struct Trapframe *tf) return; } - cprintf("trap %d eip %x:%x\n", tf->tf_trapno, tf->tf_cs, tf->tf_eip); - - if(v == 32){ - // probably clock + if(v == (IRQ_OFFSET + IRQ_TIMER)){ + curproc[cpu()]->tf = tf; + lapic_timerintr(); return; } - while(1) - ; + cprintf("trap %d eip %x:%x\n", tf->tf_trapno, tf->tf_cs, tf->tf_eip); + // XXX probably ought to lgdt on trap return + + return; } diff --git a/traps.h b/traps.h index a81903c..4b2d368 100644 --- a/traps.h +++ b/traps.h @@ -24,3 +24,9 @@ // processor defined exceptions or interrupt vectors. #define T_SYSCALL 48 // system call #define T_DEFAULT 500 // catchall + +#define IRQ_OFFSET 32 // IRQ 0 corresponds to int IRQ_OFFSET + +#define IRQ_TIMER 18 +#define IRQ_ERROR 19 +#define IRQ_SPURIOUS 31