]> Devi Nivas Git - cs3210-lab1.git/commitdiff
extract lapic code from mp.c
authorkaashoek <kaashoek>
Wed, 12 Jul 2006 17:00:54 +0000 (17:00 +0000)
committerkaashoek <kaashoek>
Wed, 12 Jul 2006 17:00:54 +0000 (17:00 +0000)
Makefile
defs.h
main.c
mp.c

index 1b2b827be9f47becfad816cd034407ae548f98ff..0a5e297f1cb9336c9c6ac057c0d774a9a479486f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -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-
diff --git a/defs.h b/defs.h
index 4561ff63bf0bc12acfe72baaea2f648ed7b7d822..acb0e042a8c292ed397023a3b88b5fd3fd5b194d 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -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;
diff --git a/main.c b/main.c
index 9015ff7276bb9a8d45f43cd1d8b2de13dea40e98..fe850544b5b0d5ce85f2c33794170c6e0e22c74d 100644 (file)
--- a/main.c
+++ b/main.c
@@ -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
diff --git a/mp.c b/mp.c
index 068d0362eaa8309a58411a665ae73f7c147ff610..19e18d103a097d2d16a753994906f39016f1eecc 100644 (file)
--- a/mp.c
+++ b/mp.c
@@ -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);
   }
 }