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  | 
