Bochs PAE support
Posted: Thu Apr 14, 2005 1:10 am
Hi,
After much investigation I've found that Bochs PAE support did have a bug in it, but does work.
Bochs uses a variable to "cache" the physlcal address contained in CR3, and this variable wasn't updated when CR4 was changed. This means that if your code loads CR3, then enables PAE and then enables paging Bochs will use "CR3 & 0xFFFFF000" instead of "CR3 & 0xFFFFFFE0", resulting in the wrong address used for the PDPT.
To fix this you can enable PAE before setting CR3, or you can fix Bochs' code.
To fix Bochs' code find the "pagingCR4Changed()" function within the file "cpu/paging.cc" and change it to this:
Note: I have reported this to the Bochs bug list. I'm hoping when Bochs 2.2 is released it will be fixed
.
Cheers,
Brendan
After much investigation I've found that Bochs PAE support did have a bug in it, but does work.
Bochs uses a variable to "cache" the physlcal address contained in CR3, and this variable wasn't updated when CR4 was changed. This means that if your code loads CR3, then enables PAE and then enables paging Bochs will use "CR3 & 0xFFFFF000" instead of "CR3 & 0xFFFFFFE0", resulting in the wrong address used for the PDPT.
To fix this you can enable PAE before setting CR3, or you can fix Bochs' code.
To fix Bochs' code find the "pagingCR4Changed()" function within the file "cpu/paging.cc" and change it to this:
Code: Select all
void BX_CPP_AttrRegparmN(2)
BX_CPU_C::pagingCR4Changed(Bit32u oldCR4, Bit32u newCR4)
{
// Modification of PGE,PAE,PSE flushes TLB cache according to docs.
if ( (oldCR4 & 0x000000b0) != (newCR4 & 0x000000b0) )
TLB_flush(1); // 1 = Flush Global entries also.
if (bx_dbg.paging)
BX_INFO(("pagingCR4Changed(0x%x -> 0x%x):", oldCR4, newCR4));
if ( (oldCR4 & 0x00000020) != (newCR4 & 0x00000020) ) {
#if BX_SupportPAE
if (BX_CPU_THIS_PTR cr4.get_PAE())
BX_CPU_THIS_PTR cr3_masked = BX_CPU_THIS_PTR cr3 & 0xffffffe0;
else
#endif
BX_CPU_THIS_PTR cr3_masked = BX_CPU_THIS_PTR cr3 & 0xfffff000;
}
}

Cheers,
Brendan