]> Devi Nivas Git - cs3210-lab1.git/commitdiff
boot more than two CPUs, each on own initial stack
authorrtm <rtm>
Sat, 24 Jun 2006 22:47:06 +0000 (22:47 +0000)
committerrtm <rtm>
Sat, 24 Jun 2006 22:47:06 +0000 (22:47 +0000)
bootother.S
memlayout.h
mp.c
proc.c

index cba4a5fb326e31eaf5ed1d4801c69c565199e66d..eee5ebeddb91a254c3b2021251a4492015743d93 100644 (file)
@@ -9,6 +9,10 @@
  *   CS base set to startup memory address;
  *   CS limit set to 64KB;
  *   CPL and IP set to 0.
+ *
+ * mp.c causes each non-boot CPU in turn to jump to start.
+ * mp.c puts the correct %esp in start-4, and the place to jump
+ * to in start-8.
  *     
  * Credit: Cliff Frey
  */
@@ -28,8 +32,8 @@ start:                .code16                         # This runs in real mode
                movw    %ax,%es                 # -> Extra Segment
                movw    %ax,%ss                 # -> Stack Segment
 
-               # Set up the stack pointer, growing downward from 0x7000.
-               movw    $start,%sp              # Stack Pointer
+               # Set up the stack pointer, growing downward from 0x7000-8.
+               movw    $start-8,%sp            # Stack Pointer
        
 #### Switch from real to protected mode        
 ####     The descriptors in our GDT allow all physical memory to be accessed.
@@ -61,10 +65,9 @@ protcseg:
                movw    %ax, %gs                # -> GS
                movw    %ax, %ss                # -> SS: Stack Segment
 
-       # XXX hack
-               movl    0x10018, %eax           # elfhdr->entry (left over in scratch space)
-               # subl  $KERNBASE, %eax
-               jmp     *%eax                   # this jumps to _start in kern/entry.S
+                movl    start-8, %eax
+                movl    start-4, %esp
+               jmp     *%eax                   
        
 .p2align 2                                     # force 4 byte alignment
 gdt:
index a33f3478af7ed1361780f2b8efd79b8ad290c920..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,3 +0,0 @@
-#define EXTPHYSMEM 0x100000
-
-#define KADDR(a) ((void *) a)
diff --git a/mp.c b/mp.c
index e797f812ddedba1e06f1d10515ac24b29aa27ec8..d4284dc2c93e6b47b0e773f0336c460cdefa3f4d 100644 (file)
--- a/mp.c
+++ b/mp.c
@@ -101,6 +101,10 @@ static struct cpu {
 static int ncpu;
 static struct cpu *bcpu;
 
+// per-cpu start-up stack, only used to get into main()
+#define MPSTACK 512
+char mpstacks[NCPU * MPSTACK];
+
 static int
 lapic_read(int r)
 {
@@ -230,17 +234,17 @@ mp_search(void)
    * 2) in the last KB of system base memory;
    * 3) in the BIOS ROM between 0xE0000 and 0xFFFFF.
    */
-  bda = KADDR(0x400);
+  bda = (uint8_t*) 0x400;
   if((p = (bda[0x0F]<<8)|bda[0x0E])){
-    if((mp = mp_scan(KADDR(p), 1024)))
+    if((mp = mp_scan((uint8_t*) p, 1024)))
       return mp;
   }
   else{
     p = ((bda[0x14]<<8)|bda[0x13])*1024;
-    if((mp = mp_scan(KADDR(p-1024), 1024)))
+    if((mp = mp_scan((uint8_t*)p-1024, 1024)))
       return mp;
   }
-  return mp_scan(KADDR(0xF0000), 0x10000);
+  return mp_scan((uint8_t*)0xF0000, 0x10000);
 }
 
 static int 
@@ -260,7 +264,7 @@ mp_detect(void)
   if((mp = mp_search()) == 0 || mp->physaddr == 0)
     return 1;
 
-  pcmp = KADDR(mp->physaddr);
+  pcmp = (struct MPCTB *) mp->physaddr;
   if(memcmp(pcmp, "PCMP", 4))
     return 2;
 
@@ -290,7 +294,8 @@ mp_init()
   uint8_t *p, *e;
   struct MPCTB *mpctb;
   struct MPPE *proc;
-  struct cpu *c;
+  int c;
+  extern int main();
 
   ncpu = 0;
   if ((r = mp_detect()) != 0) return;
@@ -302,8 +307,8 @@ mp_init()
    * application processors and initialising any I/O APICs. The table
    * is guaranteed to be in order such that only one pass is necessary.
    */
-  mpctb = KADDR(mp->physaddr);
-  lapicaddr = KADDR(mpctb->lapicaddr);
+  mpctb = (struct MPCTB *) mp->physaddr;
+  lapicaddr = (uint32_t *) mpctb->lapicaddr;
   cprintf("apicaddr: %x\n", lapicaddr);
   p = ((uint8_t*)mpctb)+sizeof(struct MPCTB);
   e = ((uint8_t*)mpctb)+mpctb->length;
@@ -348,16 +353,18 @@ mp_init()
   lapic_online();
 
   extern uint8_t _binary_bootother_start[], _binary_bootother_size[];
-  memmove(KADDR(APBOOTCODE),_binary_bootother_start, 
+  memmove((void *) APBOOTCODE,_binary_bootother_start, 
          (uint32_t) _binary_bootother_size);
 
   acquire_spinlock(&kernel_lock);
-  for (c = cpus; c < &cpus[ncpu]; c++) {
-    if (c == bcpu) continue;
-    cprintf ("starting processor %d\n", c - cpus);
-    release_grant_spinlock(&kernel_lock, c - cpus);
-    lapic_startap(c, (uint32_t) KADDR(APBOOTCODE));
+  for(c = 0; c < ncpu; c++){
+    if (cpus+c == bcpu) continue;
+    cprintf ("starting processor %d\n", c);
+    release_grant_spinlock(&kernel_lock, c);
+    *(unsigned *)(APBOOTCODE-4) = (unsigned) mpstacks + (c + 1) * 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);
     acquire_spinlock(&kernel_lock);
-    cprintf ("done starting processor %d\n", c - cpus);
+    cprintf ("done starting processor %d\n", c);
   }
 }
diff --git a/proc.c b/proc.c
index e771c4d0d00f095142f66aa0de13ad8aab13481d..45696a2e905ee07d00c1a8895c9951a34ffee560 100644 (file)
--- a/proc.c
+++ b/proc.c
@@ -112,6 +112,10 @@ swtch()
     acquire_spinlock(&kernel_lock);
   }
   
+  // XXX this may be too late, should probably save on the way
+  // in, in case some other CPU decided to run curproc
+  // before we got here. in fact setting state=WAITING and
+  // setting these variables had better be atomic w.r.t. other CPUs.
   op->ebp = read_ebp();
   op->esp = read_esp();