[eros-cvs] cvs commit: eros/src/base/sys/console cons_VESA.cxx

shap@eros.cs.jhu.edu shap@eros.cs.jhu.edu
Wed, 22 Aug 2001 13:38:35 -0400


shap        01/08/22 13:38:35

  Modified:    src/base/sys/arch/i486/kernel Machine.cxx
               src/base/sys/console cons_VESA.cxx
  Log:
  I have now created a quasi-successful virtual mapping where V==P. The
  logo *sort of* draws (bits in right places, bad colors). The previous
  map upper/lower bounds were wrong.
  
  This is before the GDT is enabled -- look for the calls to animate()
  in arch/i486/kernel/Machine.cxx.
  
  I then try to draw at the mapped linear address (the one that will be
  used after GDT loads). Haven't tried this yet.
  
  After GDT loads, though, things go south in a hurry still.

Revision  Changes    Path
1.124     +130 -117  eros/src/base/sys/arch/i486/kernel/Machine.cxx

Index: Machine.cxx
===================================================================
RCS file: /cvs/eros/src/base/sys/arch/i486/kernel/Machine.cxx,v
retrieving revision 1.123
retrieving revision 1.124
diff -u -r1.123 -r1.124
--- Machine.cxx	2001/08/22 00:24:10	1.123
+++ Machine.cxx	2001/08/22 17:38:35	1.124
@@ -114,21 +114,44 @@
   (void) Machine::SetMappingTable(KERNPAGEDIR); /* Well known address! */
   (void) Machine::EnableVirtualMapping();
 
-  if (BootInfoPtr->useGraphicsFB)
+  MsgLog::printf("FB updated -- now virtual\n");
+
+  if (BootInfoPtr->useGraphicsFB) {
+    extern void animate();
+    extern void redrawLogos();
+
+    animate();
+    redrawLogos();
+
+    /* Now try it at the linear address, before we load the GDT: */
     Machine::frameBuffer = KVTOL(Machine::mappedFrameBuffer);
 
-  MsgLog::printf("FB updated -- now virtual\n");
+    animate();
+    redrawLogos();
+  }
+
+  MsgLog::printf("About to load GDT\n");
 
   GDT::Init();
   
-  if (BootInfoPtr->useGraphicsFB)
+  if (BootInfoPtr->useGraphicsFB) {
+    extern void animate();
+    extern void redrawLogos();
+
     Machine::frameBuffer = Machine::mappedFrameBuffer;
 
+    animate();
+    redrawLogos();
+  }
+
   if (BootInfoPtr->consInfo)
     MsgLog::printf("FB at 0x%08x\n", (unsigned long) BootInfoPtr->consInfo->frameBuffer);
   else
     MsgLog::printf("No FB console found.");
 
+  if (BootInfoPtr->useGraphicsFB)
+    pause();
+
   /*    MsgLog::printf("main(): loaded GDT\n");
    * Commented out to avoid missing symbol complaints
    */
@@ -295,6 +318,52 @@
 }
 #endif
   
+static void 
+MapPageAt(kva_t va, kpa_t pa, uint32_t mode)
+{
+  PTE *pageDir = (PTE*) PTOV(KERNPAGEDIR); /* kernel page directory */
+  PTE *pageTab;
+
+  uint32_t tabndx = (va >> 12) & 0x3ffu;
+  uint32_t dirndx = (va >> 22);
+
+  if (mode & PTE_PGSZ) {
+    pageDir[dirndx].Invalidate();
+    PTE_SET(pageDir[dirndx], (VTOP(pa) & PTE_FRAMEBITS) );
+    PTE_SET(pageDir[dirndx], mode);
+
+    return;
+  }
+
+  if ( PTE_IS(pageDir[dirndx], PTE_V) ) {
+    pageTab = (PTE *) PTOV(pageDir[dirndx].PageFrame());
+  }
+  else {
+    /* Allocate a new page table. Allocating here also has the
+       * property that all of the pages above those allocated for use
+       * by the kernel will be contiguous in virtual space.
+       */
+    pageTab = KPAtoP(PTE *,PhysMem::Alloc(EROS_PAGE_SIZE, &PhysMem::pages));
+    bzero(pageTab, EROS_PAGE_SIZE);
+
+    assert (((uint32_t)pageTab & EROS_PAGE_MASK) == 0);
+      
+    /* pageTab = ::new PTE[NPTE_PER_PAGE]; */
+
+#if 0
+    MsgLog::printf("Allocated new page table at 0x%x, dirndx 0x%x\n",
+		   pageTab, dirndx);
+#endif
+    
+    PTE_SET(pageDir[dirndx], (VTOP(pageTab) & PTE_FRAMEBITS) );
+    PTE_SET(pageDir[dirndx], PTE_W | PTE_V | mode);
+  }
+
+  pageTab[tabndx].Invalidate();
+  PTE_SET(pageTab[tabndx], (pa & PTE_FRAMEBITS) );
+  PTE_SET(pageTab[tabndx], mode);
+}
+
 /* Build a kernel mapping table.  In the initial construction, we
    create TWO mappings for the kernel.  The first begins at VA=0x0,
    and is used until we get a chance to set up a new global descriptor
@@ -391,67 +460,45 @@
     uint32_t dirndx = (vaddr >> 22);
     uint32_t pdirndx = (paddr >> 22);
       
+    uint32_t mode = globalPage | PTE_V;
+
 #ifndef NO_LARGE_PAGES
     if (supports_large_pages) {
-      assert (tabndx == 0);
-      /* Pentium or higher.  Use large pages: */
-      PTE_SET(pageDir[dirndx], (paddr & PTE_FRAMEBITS) );
-      PTE_SET(pageDir[dirndx], PTE_W|PTE_V|PTE_PGSZ|globalPage);
+      mode |= PTE_W|PTE_PGSZ;
 #ifdef WRITE_THROUGH
-      PTE_SET(pageDir[dirndx], PTE_WT);
+      mode |= PTE_WT;
 #endif
-      pageDir[pdirndx] = pageDir[dirndx];
-      continue;
-    }
-#endif
 
-    if (tabndx == 0) {
-      /* Allocate a new page table. Allocating here also has the
-       * property that all of the pages above those allocated for use
-       * by the kernel will be contiguous in virtual space.
-       */
-      pageTab = KPAtoP(PTE *,PhysMem::Alloc(EROS_PAGE_SIZE, &PhysMem::pages));
-      bzero(pageTab, EROS_PAGE_SIZE);
-
-      assert (((uint32_t)pageTab & EROS_PAGE_MASK) == 0);
-      
-      /* pageTab = ::new PTE[NPTE_PER_PAGE]; */
+      assert (tabndx == 0);
 
-#if 0
-      MsgLog::printf("Allocated new page table at 0x%x, dirndx 0x%x\n",
-		     pageTab, dirndx);
-#endif
-    
-      PTE_SET(pageDir[dirndx], (VTOP(pageTab) & PTE_FRAMEBITS) );
-      PTE_SET(pageDir[dirndx], PTE_W|PTE_V|globalPage);
+      MapPageAt(vaddr, paddr, mode);
       pageDir[pdirndx] = pageDir[dirndx];
+      continue;
     }
+#endif
 
     assert((paddr & EROS_PAGE_MASK) == 0);
-    
-    PTE_SET(pageTab[tabndx], (paddr & PTE_FRAMEBITS) );
-    PTE_SET(pageTab[tabndx], PTE_V|globalPage);
 
-    /* Note that the processor won't honor the writable bit in
-     * supervisor mode, so there really isn't any point to setting it.
-     * We could enable the WP bit in CR0, but then the DMA code would
-     * be forced to check before flushing on inbound I/O.  Better,
-     * IMHO, to trust the kernel from the start.
-     */
-    
     if (paddr < (uint32_t) start ||
 	paddr >= ((uint32_t)etext & PTE_FRAMEBITS)){
-      PTE_SET(pageTab[tabndx], PTE_W);
+      mode |= PTE_W;
 #ifdef WRITE_THROUGH
-      PTE_SET(pageTab[tabndx], PTE_WT);
+      mode |= PTE_WT;
 #endif
-      /* Hand-protect kernel page zero, which holds the kernel page
-       * directory, but is never referenced by virtual addresses once
-       * we load the new mapping table pointer:
-       */
-      if (vaddr == 0) 
-	PTE_CLR(pageTab[tabndx], PTE_W|PTE_V);
     }
+
+    /* Hand-protect kernel page zero, which holds the kernel page
+     * directory, but is never referenced by virtual addresses once
+     * we load the new mapping table pointer:
+     */
+    if (vaddr == 0)
+      mode = 0;
+
+    MapPageAt(vaddr, paddr, mode);
+
+    /* This is a sleazy trick to avoid redundant page table
+       allocation: */
+    pageDir[pdirndx] = pageDir[dirndx];
   }
 
   unsigned heap_first_page = physPages;
@@ -519,31 +566,12 @@
 
     heap_bound += heap_start;
 
-    /* Place the heap right at the end of the physical page map: */
-    for(unsigned va = heap_start; va < heap_bound; va += EROS_PAGE_SIZE) {
-      unsigned vaddr = KVTOL(va);
-      uint32_t tabndx = (vaddr >> 12) & 0x3ffu;
-      uint32_t dirndx = (vaddr >> 22);
-
-      if (tabndx == 0) {
-	/* Allocate a new page table. Allocating here also has the
-	 * property that all of the pages above those allocated for use
-	 * by the kernel will be contiguous in virtual space.
-	 */
-	pageTab = KPAtoP(PTE *,PhysMem::Alloc(EROS_PAGE_SIZE, &PhysMem::pages));
-	bzero(pageTab, EROS_PAGE_SIZE);
+    /* Place the heap right at the end of the physical page map:
 
-	assert (((uint32_t)pageTab & EROS_PAGE_MASK) == 0);
-      
-#if 1
-	MsgLog::printf("Allocated new page table 0x%x va 0x%x, dirndx 0x%x\n",
-		       pageTab, vaddr, dirndx);
-#endif
-    
-	PTE_SET(pageDir[dirndx], (VTOP(pageTab) & PTE_FRAMEBITS) );
-	PTE_SET(pageDir[dirndx], PTE_W|PTE_V|globalPage);
-      }
-    }
+       We build this mapping for the side effect of ensuring that
+       mapping entries for the heap are actually present. */
+    for(unsigned va = heap_start; va < heap_bound; va += EROS_PAGE_SIZE)
+      MapPageAt(KVTOL(va), 0, PTE_W|globalPage);
   }
 
   /* Now set up the console frame buffer, if any. Do this only if the 
@@ -554,48 +582,43 @@
   if (BootInfoPtr->consInfo) {
     ConsoleInfo *ci = BootInfoPtr->consInfo;
  
-    kpa_t paddr = (kpa_t)ci->frameBuffer & ~EROS_PAGE_MASK;
-    kpa_t fb_len = ci->bytesPerScanLine * ci->Ylimit;
+    kpa_t pbase = align_down(ci->frameBuffer, EROS_PAGE_SIZE);
+    kpa_t ptop = ((kpa_t)ci->frameBuffer) + ci->bytesPerScanLine * ci->Ylimit;
+    ptop = align_up(ptop, EROS_PAGE_SIZE);
+
+    kpa_t paddr = pbase;
+
+    kpa_t fb_len = ptop - pbase;
 
+    assert((fb_len % EROS_PAGE_SIZE) == 0);
+
     kva_t fb_start = heap_bound;
-    kva_t fb_bound = align_up(fb_start + fb_len, EROS_PAGE_SIZE);
+    kva_t fb_bound = fb_start + fb_len;
 
     /* Place the frame buffer at the end of the heap: */
     for(unsigned va = fb_start; va < fb_bound; 
 	va += EROS_PAGE_SIZE, paddr += EROS_PAGE_SIZE) {
       unsigned vaddr = KVTOL(va);
-      uint32_t tabndx = (vaddr >> 12) & 0x3ffu;
-      uint32_t dirndx = (vaddr >> 22);
-
-      if (tabndx == 0) {
-	/* Allocate a new page table. Allocating here also has the
-	 * property that all of the pages above those allocated for use
-	 * by the kernel will be contiguous in virtual space.
-	 */
-	pageTab = KPAtoP(PTE *,PhysMem::Alloc(EROS_PAGE_SIZE, &PhysMem::pages));
-	bzero(pageTab, EROS_PAGE_SIZE);
 
-	assert (((uint32_t)pageTab & EROS_PAGE_MASK) == 0);
-      
-#if 1
-	MsgLog::printf("Allocated new page table 0x%x va 0x%x, dirndx 0x%x\n",
-		       pageTab, vaddr, dirndx);
-#endif
-    
-	PTE_SET(pageDir[dirndx], (VTOP(pageTab) & PTE_FRAMEBITS) );
-	PTE_SET(pageDir[dirndx], PTE_W|PTE_V|globalPage);
-      }
-
       assert((paddr & EROS_PAGE_MASK) == 0);
     
-      PTE_SET(pageTab[tabndx], (paddr & PTE_FRAMEBITS) );
-      PTE_SET(pageTab[tabndx], PTE_V|globalPage); /* disable caching */
-    }
+      uint32_t mode = PTE_W|PTE_V /* |PTE_WT */;
+
+      MapPageAt(vaddr, paddr, mode | globalPage);
 
-    Machine::mappedFrameBuffer = fb_start + ((kpa_t)ci->frameBuffer & EROS_PAGE_MASK);
+      /* Make the one at the physically congruent address non-global,
+	 just in case: */
+      MapPageAt(paddr, paddr, mode);
 
-    MsgLog::printf("Framebuffer (ci = 0x%08x pa = 0x%08x) mapped at 0x%08x, len 0x%08x\n",
-		   ci, (unsigned long) ci->frameBuffer, Machine::mappedFrameBuffer, fb_len);
+      Machine::mappedFrameBuffer = fb_start + (pbase & EROS_PAGE_MASK);
+    }
+
+    MsgLog::printf("Framebuffer (ci = 0x%08x pa = 0x%08x) mapped at "
+		   "0x%08x (linear 0x%08x), len 0x%08x\n",
+		   ci, (unsigned long) ci->frameBuffer, 
+		   Machine::mappedFrameBuffer, 
+		   KVTOL(Machine::mappedFrameBuffer), 
+		   fb_len);
   }
 
   /* BELOW THIS POINT we do not use the /globalPage/ bit, as
@@ -651,27 +674,17 @@
 {
   assert((paddr & EROS_PAGE_MASK) == 0);
     
-  PTE *pageDir = (PTE*) PTOV(KERNPAGEDIR); /* kernel page directory */
+  uint32_t mode = PTE_V|PTE_W;
 
-  uint32_t vaddr = KVTOL(va);
-  uint32_t tabndx = (vaddr >> 12) & 0x3ffu;
-  uint32_t dirndx = (vaddr >> 22);
-      
 #ifndef NO_GLOBAL_PAGES
-  uint32_t globalPage = 0;
-
   if (CpuIdHi > 1 && CpuFeatures & CPUFEAT_PGE)
-    globalPage = PTE_GLBL;
+    mode |= PTE_GLBL;
 #endif
-
-  PTE *pageTab = (PTE*) PTOV(pageDir[dirndx].PageFrame());
-
-  PTE_SET(pageTab[tabndx], (paddr & PTE_FRAMEBITS) );
-  PTE_SET(pageTab[tabndx], PTE_V|globalPage);
-  PTE_SET(pageTab[tabndx], PTE_W);
 #ifdef WRITE_THROUGH
-  PTE_SET(pageTab[tabndx], PTE_WT);
+  mode |= PTE_WT;
 #endif
+
+  MapPageAt(KVTOL(va), paddr, mode);
 }
 
 static inline



1.8       +8 -0      eros/src/base/sys/console/cons_VESA.cxx

Index: cons_VESA.cxx
===================================================================
RCS file: /cvs/eros/src/base/sys/console/cons_VESA.cxx,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- cons_VESA.cxx	2001/08/22 00:24:10	1.7
+++ cons_VESA.cxx	2001/08/22 17:38:35	1.8
@@ -288,6 +288,7 @@
 drawHeader()
 {
   animate();
+
   drawLogo(0,0);
   drawLogo2(XRES-width2,0);
 
@@ -295,6 +296,13 @@
   TheConsVESA.baseRow = height/16 + 2;
   TheConsVESA.row += TheConsVESA.baseRow - 1;
   TheConsVESA.row = TheConsVESA.baseRow;
+}
+
+void
+redrawLogos()
+{
+  drawLogo(0,0);
+  drawLogo2(XRES-width2,0);
 }
 
 void