diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | defs.h | 8 | ||||
| -rw-r--r-- | main.c | 5 | ||||
| -rw-r--r-- | mp.c | 209 | 
4 files changed, 18 insertions, 206 deletions
@@ -1,5 +1,5 @@  OBJS = main.o console.o string.o kalloc.o proc.o trapasm.o trap.o vectors.o \ -       syscall.o ide.o picirq.o mp.o spinlock.o fd.o pipe.o swtch.o +       syscall.o ide.o picirq.o mp.o lapic.o spinlock.o fd.o pipe.o swtch.o  # Cross-compiling (e.g., on Mac OS X)  TOOLPREFIX = i386-jos-elf- @@ -49,13 +49,17 @@ void pic_init(void);  // mp.c  void mp_init(void);  void mp_startthem(void); -int cpu(void); -int mp_isbcpu(void); +int mp_bcpu(void); + +// lapic +extern uint32_t *lapicaddr;  void lapic_init(int); +void lapic_startap(uint8_t, int);  void lapic_timerinit(void);  void lapic_timerintr(void);  void lapic_enableintr(void);  void lapic_disableintr(void); +int cpu(void);  // spinlock.c  struct spinlock; @@ -38,11 +38,14 @@ main()    // clear BSS    memset(edata, 0, end - edata); -  mp_init(); // just set up apic so cpu() works +  mp_init(); // collect info about this machine +    use_printf_lock = 1;    cpus[cpu()].clis = 1; // cpu starts as if we had called cli() +  lapic_init(mp_bcpu()); +    cprintf("\nxV6\n\n");    pic_init(); // initialize PIC @@ -8,90 +8,6 @@  #include "mmu.h"  #include "proc.h" -/*  - * Credit: Plan 9 sources, Intel MP spec, and Cliff Frey - */ - -enum {					/* Local APIC registers */ -  LAPIC_ID  = 0x0020,	/* ID */ -  LAPIC_VER = 0x0030,	/* Version */ -  LAPIC_TPR = 0x0080,	/* Task Priority */ -  LAPIC_APR = 0x0090,	/* Arbitration Priority */ -  LAPIC_PPR = 0x00A0,	/* Processor Priority */ -  LAPIC_EOI = 0x00B0,	/* EOI */ -  LAPIC_LDR = 0x00D0,	/* Logical Destination */ -  LAPIC_DFR = 0x00E0,	/* Destination Format */ -  LAPIC_SVR = 0x00F0,	/* Spurious Interrupt Vector */ -  LAPIC_ISR = 0x0100,	/* Interrupt Status (8 registers) */ -  LAPIC_TMR = 0x0180,	/* Trigger Mode (8 registers) */ -  LAPIC_IRR = 0x0200,	/* Interrupt Request (8 registers) */ -  LAPIC_ESR = 0x0280,	/* Error Status */ -  LAPIC_ICRLO = 0x0300,	/* Interrupt Command */ -  LAPIC_ICRHI = 0x0310,	/* Interrupt Command [63:32] */ -  LAPIC_TIMER = 0x0320,	/* Local Vector Table 0 (TIMER) */ -  LAPIC_PCINT = 0x0340,	/* Performance Counter LVT */ -  LAPIC_LINT0 = 0x0350,	/* Local Vector Table 1 (LINT0) */ -  LAPIC_LINT1 = 0x0360,	/* Local Vector Table 2 (LINT1) */ -  LAPIC_ERROR = 0x0370,	/* Local Vector Table 3 (ERROR) */ -  LAPIC_TICR = 0x0380,	/* Timer Initial Count */ -  LAPIC_TCCR = 0x0390,	/* Timer Current Count */ -  LAPIC_TDCR = 0x03E0,	/* Timer Divide Configuration */ -}; - -enum {					/* LAPIC_SVR */ -  LAPIC_ENABLE	= 0x00000100,	/* Unit Enable */ -  LAPIC_FOCUS	= 0x00000200,	/* Focus Processor Checking Disable */ -}; - -enum {					/* LAPIC_ICRLO */ -					/* [14] IPI Trigger Mode Level (RW) */ -  LAPIC_DEASSERT = 0x00000000,	/* Deassert level-sensitive interrupt */ -  LAPIC_ASSERT	= 0x00004000,	/* Assert level-sensitive interrupt */ - -  /* [17:16] Remote Read Status */ -  LAPIC_INVALID	= 0x00000000,	/* Invalid */ -  LAPIC_WAIT	= 0x00010000,	/* In-Progress */ -  LAPIC_VALID	= 0x00020000,	/* Valid */ - -  /* [19:18] Destination Shorthand */ -  LAPIC_FIELD	= 0x00000000,	/* No shorthand */ -  LAPIC_SELF	= 0x00040000,	/* Self is single destination */ -  LAPIC_ALLINC	= 0x00080000,	/* All including self */ -  LAPIC_ALLEXC	= 0x000C0000,	/* All Excluding self */ -}; - -enum {					/* LAPIC_ESR */ -  LAPIC_SENDCS	= 0x00000001,	/* Send CS Error */ -  LAPIC_RCVCS	= 0x00000002,	/* Receive CS Error */ -  LAPIC_SENDACCEPT = 0x00000004,	/* Send Accept Error */ -  LAPIC_RCVACCEPT = 0x00000008,	/* Receive Accept Error */ -  LAPIC_SENDVECTOR = 0x00000020,	/* Send Illegal Vector */ -  LAPIC_RCVVECTOR = 0x00000040,	/* Receive Illegal Vector */ -  LAPIC_REGISTER = 0x00000080,	/* Illegal Register Address */ -}; - -enum {					/* LAPIC_TIMER */ -					/* [17] Timer Mode (RW) */ -  LAPIC_ONESHOT	= 0x00000000,	/* One-shot */ -  LAPIC_PERIODIC = 0x00020000,	/* Periodic */ - -  /* [19:18] Timer Base (RW) */ -  LAPIC_CLKIN	= 0x00000000,	/* use CLKIN as input */ -  LAPIC_TMBASE	= 0x00040000,	/* use TMBASE */ -  LAPIC_DIVIDER	= 0x00080000,	/* use output of the divider */ -}; - -enum {					/* LAPIC_TDCR */ -  LAPIC_X2 = 0x00000000,	/* divide by 2 */ -  LAPIC_X4 = 0x00000001,	/* divide by 4 */ -  LAPIC_X8 = 0x00000002,	/* divide by 8 */ -  LAPIC_X16 = 0x00000003,	/* divide by 16 */ -  LAPIC_X32 = 0x00000008,	/* divide by 32 */ -  LAPIC_X64 = 0x00000009,	/* divide by 64 */ -  LAPIC_X128 = 0x0000000A,	/* divide by 128 */ -  LAPIC_X1 = 0x0000000B,	/* divide by 1 */ -}; -  static char* buses[] = {  	"CBUSI ",  	"CBUSII", @@ -117,119 +33,10 @@ static char* buses[] = {  #define APBOOTCODE 0x7000 // XXX hack  static struct MP* mp;  // The MP floating point structure -static uint32_t *lapicaddr;  struct cpu cpus[NCPU];  int ncpu;  static struct cpu *bcpu; -static int -lapic_read(int r) -{ -  return *(lapicaddr+(r/sizeof(*lapicaddr))); -} - -static void -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, 10000000); -  lapic_write(LAPIC_TICR, 10000000); -} - -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); - -  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 - -  // in virtual wire mode, set up the LINT0 and LINT1 as follows: -  lapic_write(LAPIC_LINT0, APIC_IMASK | APIC_EXTINT); -  lapic_write(LAPIC_LINT1, APIC_IMASK | APIC_NMI); - -  lapic_write(LAPIC_EOI, 0); // acknowledge any outstanding interrupts. - -  lvt = (lapic_read(LAPIC_VER)>>16) & 0xFF; -  if(lvt >= 4) -    lapic_write(LAPIC_PCINT, APIC_IMASK); -  lapic_write(LAPIC_ERROR, IRQ_OFFSET+IRQ_ERROR); -  lapic_write(LAPIC_ESR, 0); -  lapic_read(LAPIC_ESR); - -  /* -   * Issue an INIT Level De-Assert to synchronise arbitration ID's. -   */ -  lapic_write(LAPIC_ICRHI, 0); -  lapic_write(LAPIC_ICRLO, LAPIC_ALLINC|APIC_LEVEL|LAPIC_DEASSERT|APIC_INIT); -  while(lapic_read(LAPIC_ICRLO) & APIC_DELIVS) -    ; - -  cprintf("Done init of an apic\n"); -} - -void -lapic_enableintr(void)  -{ -  lapic_write(LAPIC_TPR, 0); -} - -void -lapic_disableintr(void)  -{ -  lapic_write(LAPIC_TPR, 0xFF); -} - -int -cpu(void) -{ -  return (lapic_read(LAPIC_ID)>>24) & 0xFF; -} - -static void -lapic_startap(struct cpu *c, int v) -{ -  int crhi, i; -  volatile int j = 0; - -  crhi = c->apicid<<24; -  lapic_write(LAPIC_ICRHI, crhi); -  lapic_write(LAPIC_ICRLO, LAPIC_FIELD|APIC_LEVEL|LAPIC_ASSERT|APIC_INIT); - -  while (j++ < 10000) {;} -  lapic_write(LAPIC_ICRLO, LAPIC_FIELD|APIC_LEVEL|LAPIC_DEASSERT|APIC_INIT); - -  while (j++ < 1000000) {;} - -  // in p9 code, this was i < 2, which is what the spec says on page B-3 -  for(i = 0; i < 1; i++){ -    lapic_write(LAPIC_ICRHI, crhi); -    lapic_write(LAPIC_ICRLO, LAPIC_FIELD|APIC_EDGE|APIC_STARTUP|(v/PGSIZE)); -    while (j++ < 100000) {;} -  } -} -  static struct MP*  mp_scan(uint8_t *addr, int len)  { @@ -310,13 +117,6 @@ mp_detect(void)    return 0;  } -int -mp_isbcpu() -{ -  if (bcpu == 0) return 1; -  else return 0; -} -  void  mp_init()  {  @@ -382,10 +182,15 @@ mp_init()      }    } -  lapic_init(bcpu-cpus);    cprintf("ncpu: %d boot %d\n", ncpu, bcpu-cpus);  } +int +mp_bcpu(void) +{ +  return bcpu-cpus; +} +  void  mp_startthem()  { @@ -401,6 +206,6 @@ mp_startthem()      cprintf ("starting processor %d\n", c);      *(unsigned *)(APBOOTCODE-4) = (unsigned) (cpus[c].mpstack) + MPSTACK; // tell it what to use for %esp      *(unsigned *)(APBOOTCODE-8) = (unsigned)&main; // tell it where to jump to -    lapic_startap(cpus + c, (uint32_t) APBOOTCODE); +    lapic_startap(cpus[c].apicid, (uint32_t) APBOOTCODE);    }  }  | 
