[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