diff options
| author | Frans Kaashoek <kaashoek@Frans-Kaashoeks-MacBook-Pro.local> | 2010-07-23 07:41:13 -0400 | 
|---|---|---|
| committer | Frans Kaashoek <kaashoek@Frans-Kaashoeks-MacBook-Pro.local> | 2010-07-23 07:41:13 -0400 | 
| commit | 4714c20521a047fba652854e5bf59158b5d85a4e (patch) | |
| tree | 236507e7a400cc93db3a25d2aba3837d6176184f | |
| parent | 74c82bc1584dda4cee6b0788055a52c32a10b2e0 (diff) | |
| download | xv6-labs-4714c20521a047fba652854e5bf59158b5d85a4e.tar.gz xv6-labs-4714c20521a047fba652854e5bf59158b5d85a4e.tar.bz2 xv6-labs-4714c20521a047fba652854e5bf59158b5d85a4e.zip | |
Checkpoint page-table version for SMP
Includes code for TLB shootdown (which actually seems unnecessary for xv6)
| -rw-r--r-- | defs.h | 3 | ||||
| -rw-r--r-- | exec.c | 6 | ||||
| -rw-r--r-- | lapic.c | 40 | ||||
| -rw-r--r-- | main.c | 23 | ||||
| -rw-r--r-- | proc.c | 1 | ||||
| -rw-r--r-- | trap.c | 4 | ||||
| -rw-r--r-- | traps.h | 3 | ||||
| -rw-r--r-- | x86.h | 5 | 
8 files changed, 65 insertions, 20 deletions
| @@ -73,6 +73,7 @@ int             cpunum(void);  extern volatile uint*    lapic;  void            lapiceoi(void);  void            lapicinit(int); +void            lapic_tlbflush(uint);  void            lapicstartap(uchar, uint);  void            microdelay(int); @@ -156,6 +157,8 @@ void            uartputc(int);  #define PGROUNDUP(sz)  ((sz+PGSIZE-1) & ~(PGSIZE-1))  void            pminit(void);  void            ksegment(void); +void            kvmalloc(void); +void            loadkvm(void);  void            vminit(void);  void            jkstack();  void            printstack(void); @@ -95,14 +95,10 @@ exec(char *path, char **argv)    proc->tf->eip = elf.entry;  // main    proc->tf->esp = sp; -  // printstack(); - -  loadvm(proc); +  loadvm(proc);     freevm(oldpgdir); -  // printstack();  -    return 0;   bad: @@ -20,8 +20,11 @@    #define STARTUP    0x00000600   // Startup IPI    #define DELIVS     0x00001000   // Delivery status    #define ASSERT     0x00004000   // Assert interrupt (vs deassert) +  #define DEASSERT   0x00000000    #define LEVEL      0x00008000   // Level triggered    #define BCAST      0x00080000   // Send to all APICs, including self. +  #define BUSY       0x00001000 +  #define FIXED      0x00000000  #define ICRHI   (0x0310/4)   // Interrupt Command [63:32]  #define TIMER   (0x0320/4)   // Local Vector Table 0 (TIMER)    #define X1         0x0000000B   // divide counts by 1 @@ -44,6 +47,27 @@ lapicw(int index, int value)    lapic[ID];  // wait for write to finish, by reading  } +static uint +lapicr(uint off) +{ +  return lapic[off]; +} + +static int +apic_icr_wait() +{ +    uint i = 100000; +    while ((lapicr(ICRLO) & BUSY) != 0) { +        nop_pause(); +        i--; +        if (i == 0) { +            cprintf("apic_icr_wait: wedged?\n"); +            return -1; +        } +    } +    return 0; +} +  //PAGEBREAK!  void  lapicinit(int c) @@ -128,6 +152,22 @@ microdelay(int us)  } +// Send IPI +void +lapic_ipi(int cpu, int ino) +{ +  lapicw(ICRHI, cpu << 24); +  lapicw(ICRLO, FIXED | DEASSERT | ino); +  if (apic_icr_wait() < 0) +    panic("lapic_ipi: icr_wait failure"); +} + +void +lapic_tlbflush(uint cpu) +{ +  lapic_ipi(cpu, T_TLBFLUSH); +} +  #define IO_RTC  0x70  // Start additional processor running bootstrap code at addr. @@ -6,13 +6,14 @@  #include "x86.h"  static void bootothers(void); -static void mpmain(void) __attribute__((noreturn)); +static void mpmain(void); +void jkstack(void) __attribute__((noreturn));  // Bootstrap processor starts running C code here.  int  main(void)  { -  mpinit(); // collect info about this machine +  mpinit();        // collect info about this machine    lapicinit(mpbcpu());    ksegment();    picinit();       // interrupt controller @@ -28,18 +29,17 @@ mainc(void)  {    cprintf("cpus %p cpu %p\n", cpus, cpu);    cprintf("\ncpu%d: starting xv6\n\n", cpu->id); -  vminit();        // virtual memory +  kvmalloc();      // allocate the kernel page table    pinit();         // process table    tvinit();        // trap vectors    binit();         // buffer cache    fileinit();      // file table    iinit();         // inode cache    ideinit();       // disk -  cprintf("ismp: %d\n", ismp);    if(!ismp)      timerinit();   // uniprocessor timer    userinit();      // first user process -  // bootothers();    // start other processors  XXX fix where to boot from +  bootothers();    // start other processors    // Finish setting up this processor in mpmain.    mpmain(); @@ -53,13 +53,12 @@ mpmain(void)    if(cpunum() != mpbcpu()) {      ksegment();      cprintf("other cpu\n"); -    vminit();      lapicinit(cpunum());    } +  vminit();        // Run with paging on each processor    cprintf("cpu%d: mpmain\n", cpu->id);    idtinit();    xchg(&cpu->booted, 1); -    cprintf("cpu%d: scheduling\n", cpu->id);    scheduler();  } @@ -72,10 +71,10 @@ bootothers(void)    struct cpu *c;    char *stack; -  // Write bootstrap code to unused memory at 0x7000. -  code = (uchar*)0x7000; +  // Write bootstrap code to unused memory at 0x7000.  The linker has +  // placed the start of bootother.S there. +  code = (uchar *) 0x7000;    memmove(code, _binary_bootother_start, (uint)_binary_bootother_size); -    for(c = cpus; c < cpus+ncpu; c++){      if(c == cpus+cpunum())  // We've started already.        continue; @@ -84,15 +83,11 @@ bootothers(void)      stack = kalloc(KSTACKSIZE);      *(void**)(code-4) = stack + KSTACKSIZE;      *(void**)(code-8) = mpmain; -    cprintf("lapicstartap\n");      lapicstartap(c->id, (uint)code); -    cprintf("lapicstartap done\n");      // Wait for cpu to get through bootstrap.      while(c->booted == 0)        ; - -    cprintf("lapicstartap booted\n");    }  } @@ -242,6 +242,7 @@ sched(void)      panic("sched running");    if(readeflags()&FL_IF)      panic("sched interruptible"); +  loadkvm();    // Switch to the kernel page table    intena = cpu->intena;    swtch(&proc->context, cpu->scheduler);    cpu->intena = intena; @@ -73,6 +73,10 @@ trap(struct trapframe *tf)              cpu->id, tf->cs, tf->eip);      lapiceoi();      break; +  case T_TLBFLUSH: +    lapiceoi(); +    lcr3(rcr3()); +    break;    //PAGEBREAK: 13    default: @@ -24,7 +24,8 @@  // These are arbitrarily chosen, but with care not to overlap  // processor defined exceptions or interrupt vectors. -#define T_SYSCALL       64     // system call +#define T_SYSCALL       64      // system call +#define T_TLBFLUSH      65      // flush TLB  #define T_DEFAULT      500      // catchall  #define T_IRQ0          32      // IRQ 0 corresponds to int T_IRQ @@ -176,6 +176,11 @@ static inline uint resp(void)    return val;  } +static inline void nop_pause(void) +{ +  asm volatile("pause" : :); +} +  //PAGEBREAK: 36  // Layout of the trap frame built on the stack by the  // hardware and by trapasm.S, and passed to trap(). | 
