diff options
author | kaashoek <kaashoek> | 2006-06-28 16:35:03 +0000 |
---|---|---|
committer | kaashoek <kaashoek> | 2006-06-28 16:35:03 +0000 |
commit | bd303ed06096395778c80558e013b64bb47b9e9c (patch) | |
tree | 4bcd3d7ae05c85f414c98037a7baef51455acc33 | |
parent | c41f1de5d41a527a3fa2d1e94215766130eac456 (diff) | |
download | xv6-labs-bd303ed06096395778c80558e013b64bb47b9e9c.tar.gz xv6-labs-bd303ed06096395778c80558e013b64bb47b9e9c.tar.bz2 xv6-labs-bd303ed06096395778c80558e013b64bb47b9e9c.zip |
timer interrupts
-rw-r--r-- | defs.h | 5 | ||||
-rw-r--r-- | main.c | 83 | ||||
-rw-r--r-- | mp.c | 38 | ||||
-rw-r--r-- | mp.h | 4 | ||||
-rw-r--r-- | trap.c | 13 | ||||
-rw-r--r-- | traps.h | 6 |
6 files changed, 71 insertions, 78 deletions
@@ -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; @@ -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"); - - // 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); - } + // 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); + } } @@ -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<<r)<<24); @@ -152,19 +174,11 @@ lapic_init(int c) while(lapic_read(LAPIC_ICRLO) & APIC_DELIVS) ; - /* - * Do not allow acceptance of interrupts until all initialisation - * for this processor is done. For the bootstrap processor this can be - * early duing initialisation. For the application processors this should - * be after the bootstrap processor has lowered priority and is accepting - * interrupts. - */ - lapic_write(LAPIC_TPR, 0); cprintf("Done init of an apic\n"); } -static void -lapic_online(void) +void +lapic_enableintr(void) { lapic_write(LAPIC_TPR, 0); } @@ -274,7 +288,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\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); @@ -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 */ @@ -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; } @@ -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 |