Now, when you compile with --enable-guest2host-tlb, non-paged

mode uses the notion of the guest-to-host TLB.  This has the
benefit of allowing more uniform and streamlined acceleration
code in access.cc which does not have to check if CR0.PG
is set, eliminating a few instructions per guest access.
Shaved just a little off execution time, as expected.

Also, access_linear now breaks accesses which span two pages,
into two calls the the physical memory routines, when paging
is off, just like it always has for paging on.  Besides
being more uniform, this allows the physical memory access
routines to known the complete data item is contained
within a single physical page, and stop reapplying the
A20ADDR() macro to pointers as it increments them.
Perhaps things can be optimized a little more now there too...
I renamed the routines to {read,write}PhysicalPage() as
a reminder that these routines now operate on data
solely within one page.

I also added a little code so that the paging module is
notified when the A20 line is tweaked, so it can dump
whatever mappings it wants to.
This commit is contained in:
Kevin Lawton 2002-09-05 02:31:24 +00:00
parent f4157cad97
commit f0c9896964
9 changed files with 642 additions and 517 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: bochs.h,v 1.86 2002-09-03 08:34:17 bdenney Exp $
// $Id: bochs.h,v 1.87 2002-09-05 02:31:23 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -150,9 +150,9 @@ extern "C" {
#define BX_HRQ (bx_pc_system.HRQ)
#define BX_RAISE_HLDA() bx_dma.raise_HLDA()
#define BX_MEM_READ_PHYSICAL(phy_addr, len, ptr) \
BX_MEM(0)->read_physical(BX_CPU(0), phy_addr, len, ptr)
BX_MEM(0)->readPhysicalPage(BX_CPU(0), phy_addr, len, ptr)
#define BX_MEM_WRITE_PHYSICAL(addr, len, ptr) \
BX_MEM(0)->write_physical(BX_CPU(0), phy_addr, len, ptr)
BX_MEM(0)->writePhysicalPage(BX_CPU(0), phy_addr, len, ptr)
// macro for PCI handling
#define BX_REGISTER_PCI_HANDLERS(this_ptr, pci_read, pci_write, devfunc, name) \
bx_pci.register_pci_handlers(this_ptr, pci_read, pci_write, devfunc, name)

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: access.cc,v 1.16 2002-09-04 20:23:54 kevinlawton Exp $
// $Id: access.cc,v 1.17 2002-09-05 02:31:24 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -274,31 +274,31 @@ accessOK:
pl = (CPL==3);
#if BX_SupportGuest2HostTLB
if (BX_CPU_THIS_PTR cr0.pg) {
Bit32u lpf, tlbIndex, pageOffset;
{
Bit32u lpf, tlbIndex, pageOffset;
pageOffset = laddr & 0xfff;
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
Bit32u accessBits;
pageOffset = laddr & 0xfff;
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
Bit32u accessBits;
// See if the TLB entry privilege level allows us write access
// from this CPL.
accessBits = BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits;
if ( accessBits & (1 << (2 | pl)) ) {
// Current write access has privilege.
Bit32u hostPageAddr;
Bit8u *hostAddr;
hostPageAddr = accessBits & 0xfffff000;
if (hostPageAddr) {
hostAddr = (Bit8u*) (hostPageAddr | pageOffset);
*hostAddr = *data;
return;
}
// See if the TLB entry privilege level allows us write access
// from this CPL.
accessBits = BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits;
if ( accessBits & (1 << (2 | pl)) ) {
// Current write access has privilege.
Bit32u hostPageAddr;
Bit8u *hostAddr;
hostPageAddr = accessBits & 0xfffff000;
if (hostPageAddr) {
hostAddr = (Bit8u*) (hostPageAddr | pageOffset);
*hostAddr = *data;
return;
}
}
}
}
#endif // BX_SupportGuest2HostTLB
// all checks OK
@ -326,33 +326,33 @@ accessOK:
pl = (CPL==3);
#if BX_SupportGuest2HostTLB
if (BX_CPU_THIS_PTR cr0.pg) {
Bit32u lpf, tlbIndex, pageOffset;
{
Bit32u lpf, tlbIndex, pageOffset;
pageOffset = laddr & 0xfff;
if (pageOffset <= 0xffe) { // Make sure access does not span 2 pages.
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
Bit32u accessBits;
pageOffset = laddr & 0xfff;
if (pageOffset <= 0xffe) { // Make sure access does not span 2 pages.
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
Bit32u accessBits;
// See if the TLB entry privilege level allows us write access
// from this CPL.
accessBits = BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits;
if ( accessBits & (1 << (2 | pl)) ) {
// Current write access has privilege.
Bit32u hostPageAddr;
Bit16u *hostAddr;
hostPageAddr = accessBits & 0xfffff000;
if (hostPageAddr) {
hostAddr = (Bit16u*) (hostPageAddr | pageOffset);
*hostAddr = *data;
return;
}
// See if the TLB entry privilege level allows us write access
// from this CPL.
accessBits = BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits;
if ( accessBits & (1 << (2 | pl)) ) {
// Current write access has privilege.
Bit32u hostPageAddr;
Bit16u *hostAddr;
hostPageAddr = accessBits & 0xfffff000;
if (hostPageAddr) {
hostAddr = (Bit16u*) (hostPageAddr | pageOffset);
*hostAddr = *data;
return;
}
}
}
}
}
#endif // BX_SupportGuest2HostTLB
// all checks OK
@ -380,33 +380,33 @@ accessOK:
pl = (CPL==3);
#if BX_SupportGuest2HostTLB
if (BX_CPU_THIS_PTR cr0.pg) {
Bit32u lpf, tlbIndex, pageOffset;
pageOffset = laddr & 0xfff;
if (pageOffset <= 0xffc) { // Make sure access does not span 2 pages.
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
Bit32u accessBits;
{
Bit32u lpf, tlbIndex, pageOffset;
// See if the TLB entry privilege level allows us write access
// from this CPL.
accessBits = BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits;
if ( accessBits & (1 << (2 | pl)) ) {
// Current write access has privilege.
Bit32u hostPageAddr;
Bit32u *hostAddr;
hostPageAddr = accessBits & 0xfffff000;
if (hostPageAddr) {
hostAddr = (Bit32u*) (hostPageAddr | pageOffset);
*hostAddr = *data;
return;
}
pageOffset = laddr & 0xfff;
if (pageOffset <= 0xffc) { // Make sure access does not span 2 pages.
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
Bit32u accessBits;
// See if the TLB entry privilege level allows us write access
// from this CPL.
accessBits = BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits;
if ( accessBits & (1 << (2 | pl)) ) {
// Current write access has privilege.
Bit32u hostPageAddr;
Bit32u *hostAddr;
hostPageAddr = accessBits & 0xfffff000;
if (hostPageAddr) {
hostAddr = (Bit32u*) (hostPageAddr | pageOffset);
*hostAddr = *data;
return;
}
}
}
}
}
#endif // BX_SupportGuest2HostTLB
// all checks OK
@ -434,30 +434,30 @@ accessOK:
pl = (CPL==3);
#if BX_SupportGuest2HostTLB
if (BX_CPU_THIS_PTR cr0.pg) {
Bit32u lpf, tlbIndex, pageOffset;
pageOffset = laddr & 0xfff;
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
// See if the TLB entry privilege level allows us read access
// from this CPL.
Bit32u accessBits;
{
Bit32u lpf, tlbIndex, pageOffset;
accessBits = BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits;
if ( accessBits & (1<<pl) ) { // Read this pl OK.
Bit32u hostPageAddr;
Bit8u *hostAddr;
hostPageAddr = accessBits & 0xfffff000;
if (hostPageAddr) {
hostAddr = (Bit8u*) (hostPageAddr | pageOffset);
*data = *hostAddr;
return;
}
pageOffset = laddr & 0xfff;
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
// See if the TLB entry privilege level allows us read access
// from this CPL.
Bit32u accessBits;
accessBits = BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits;
if ( accessBits & (1<<pl) ) { // Read this pl OK.
Bit32u hostPageAddr;
Bit8u *hostAddr;
hostPageAddr = accessBits & 0xfffff000;
if (hostPageAddr) {
hostAddr = (Bit8u*) (hostPageAddr | pageOffset);
*data = *hostAddr;
return;
}
}
}
}
#endif // BX_SupportGuest2HostTLB
// all checks OK
@ -486,33 +486,33 @@ accessOK:
pl = (CPL==3);
#if BX_SupportGuest2HostTLB
if (BX_CPU_THIS_PTR cr0.pg) {
Bit32u pageOffset;
{
Bit32u pageOffset;
pageOffset = laddr & 0xfff;
if (pageOffset <= 0xffe) { // Make sure access does not span 2 pages.
Bit32u lpf, tlbIndex;
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
// See if the TLB entry privilege level allows us read access
// from this CPL.
Bit32u accessBits;
pageOffset = laddr & 0xfff;
if (pageOffset <= 0xffe) { // Make sure access does not span 2 pages.
Bit32u lpf, tlbIndex;
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
// See if the TLB entry privilege level allows us read access
// from this CPL.
Bit32u accessBits;
accessBits = BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits;
if ( accessBits & (1<<pl) ) { // Read this pl OK.
Bit32u hostPageAddr;
Bit16u *hostAddr;
hostPageAddr = accessBits & 0xfffff000;
if (hostPageAddr) {
hostAddr = (Bit16u*) (hostPageAddr | pageOffset);
*data = *hostAddr;
return;
}
accessBits = BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits;
if ( accessBits & (1<<pl) ) { // Read this pl OK.
Bit32u hostPageAddr;
Bit16u *hostAddr;
hostPageAddr = accessBits & 0xfffff000;
if (hostPageAddr) {
hostAddr = (Bit16u*) (hostPageAddr | pageOffset);
*data = *hostAddr;
return;
}
}
}
}
}
#endif // BX_SupportGuest2HostTLB
// all checks OK
@ -541,33 +541,33 @@ accessOK:
pl = (CPL==3);
#if BX_SupportGuest2HostTLB
if (BX_CPU_THIS_PTR cr0.pg) {
Bit32u pageOffset;
{
Bit32u pageOffset;
pageOffset = laddr & 0xfff;
if (pageOffset <= 0xffc) { // Make sure access does not span 2 pages.
Bit32u lpf, tlbIndex;
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
// See if the TLB entry privilege level allows us read access
// from this CPL.
Bit32u accessBits;
pageOffset = laddr & 0xfff;
if (pageOffset <= 0xffc) { // Make sure access does not span 2 pages.
Bit32u lpf, tlbIndex;
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
// See if the TLB entry privilege level allows us read access
// from this CPL.
Bit32u accessBits;
accessBits = BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits;
if ( accessBits & (1<<pl) ) { // Read this pl OK.
Bit32u hostPageAddr;
Bit32u *hostAddr;
hostPageAddr = accessBits & 0xfffff000;
if (hostPageAddr) {
hostAddr = (Bit32u*) (hostPageAddr | pageOffset);
*data = *hostAddr;
return;
}
accessBits = BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits;
if ( accessBits & (1<<pl) ) { // Read this pl OK.
Bit32u hostPageAddr;
Bit32u *hostAddr;
hostPageAddr = accessBits & 0xfffff000;
if (hostPageAddr) {
hostAddr = (Bit32u*) (hostPageAddr | pageOffset);
*data = *hostAddr;
return;
}
}
}
}
}
#endif // BX_SupportGuest2HostTLB
// all checks OK
@ -599,46 +599,40 @@ accessOK:
BX_INSTR_MEM_DATA(laddr, 1, BX_READ);
pl = (CPL==3);
if (BX_CPU_THIS_PTR cr0.pg) {
#if BX_SupportGuest2HostTLB
Bit32u lpf, tlbIndex, pageOffset;
{
Bit32u lpf, tlbIndex, pageOffset;
pageOffset = laddr & 0xfff;
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
Bit32u accessBits;
pageOffset = laddr & 0xfff;
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
Bit32u accessBits;
// See if the TLB entry privilege level allows us write access
// from this CPL.
accessBits = BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits;
if ( accessBits & (1 << (2 | pl)) ) {
// Current write access has privilege.
Bit32u hostPageAddr;
Bit8u *hostAddr;
hostPageAddr = accessBits & 0xfffff000;
if (hostPageAddr) {
hostAddr = (Bit8u*) (hostPageAddr | pageOffset);
*data = *hostAddr;
BX_CPU_THIS_PTR address_xlation.paddress1 =
BX_CPU_THIS_PTR TLB.entry[tlbIndex].ppf | pageOffset;
//BX_CPU_THIS_PTR address_xlation.pages = 1;
return;
}
// See if the TLB entry privilege level allows us write access
// from this CPL.
accessBits = BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits;
if ( accessBits & (1 << (2 | pl)) ) {
// Current write access has privilege.
Bit32u hostPageAddr;
Bit8u *hostAddr;
hostPageAddr = accessBits & 0xfffff000;
if (hostPageAddr) {
hostAddr = (Bit8u*) (hostPageAddr | pageOffset);
*data = *hostAddr;
BX_CPU_THIS_PTR address_xlation.paddress1 =
BX_CPU_THIS_PTR TLB.entry[tlbIndex].ppf | pageOffset;
//BX_CPU_THIS_PTR address_xlation.pages = 1;
return;
}
}
}
}
#endif // BX_SupportGuest2HostTLB
// Accelerated attempt falls through to long path. Do it the
// old fashioned way...
access_linear(laddr, 1, pl, BX_RW, (void *) data);
}
else {
BX_CPU_THIS_PTR address_xlation.paddress1 = laddr;
BX_INSTR_LIN_READ(laddr, laddr, 1);
BX_INSTR_LIN_WRITE(laddr, laddr, 1);
BX_CPU_THIS_PTR mem->read_physical(this, laddr, 1, (void *) data);
}
// Accelerated attempt falls through to long path. Do it the
// old fashioned way...
access_linear(laddr, 1, pl, BX_RW, (void *) data);
return;
}
}
@ -662,46 +656,40 @@ accessOK:
BX_INSTR_MEM_DATA(laddr, 2, BX_READ);
pl = (CPL==3);
if (BX_CPU_THIS_PTR cr0.pg) {
#if BX_SupportGuest2HostTLB
Bit32u lpf, tlbIndex, pageOffset;
{
Bit32u lpf, tlbIndex, pageOffset;
pageOffset = laddr & 0xfff;
if (pageOffset <= 0xffe) { // Make sure access does not span 2 pages.
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
Bit32u accessBits;
pageOffset = laddr & 0xfff;
if (pageOffset <= 0xffe) { // Make sure access does not span 2 pages.
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
Bit32u accessBits;
// See if the TLB entry privilege level allows us write access
// from this CPL.
accessBits = BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits;
if ( accessBits & (1 << (2 | pl)) ) {
// Current write access has privilege.
Bit32u hostPageAddr;
Bit16u *hostAddr;
hostPageAddr = accessBits & 0xfffff000;
if (hostPageAddr) {
hostAddr = (Bit16u*) (hostPageAddr | pageOffset);
*data = *hostAddr;
BX_CPU_THIS_PTR address_xlation.paddress1 =
BX_CPU_THIS_PTR TLB.entry[tlbIndex].ppf | pageOffset;
BX_CPU_THIS_PTR address_xlation.pages = 1;
return;
}
// See if the TLB entry privilege level allows us write access
// from this CPL.
accessBits = BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits;
if ( accessBits & (1 << (2 | pl)) ) {
// Current write access has privilege.
Bit32u hostPageAddr;
Bit16u *hostAddr;
hostPageAddr = accessBits & 0xfffff000;
if (hostPageAddr) {
hostAddr = (Bit16u*) (hostPageAddr | pageOffset);
*data = *hostAddr;
BX_CPU_THIS_PTR address_xlation.paddress1 =
BX_CPU_THIS_PTR TLB.entry[tlbIndex].ppf | pageOffset;
BX_CPU_THIS_PTR address_xlation.pages = 1;
return;
}
}
}
}
}
#endif // BX_SupportGuest2HostTLB
access_linear(laddr, 2, pl, BX_RW, (void *) data);
}
else {
BX_CPU_THIS_PTR address_xlation.paddress1 = laddr;
BX_INSTR_LIN_READ(laddr, laddr, 2);
BX_INSTR_LIN_WRITE(laddr, laddr, 2);
BX_CPU_THIS_PTR mem->read_physical(this, laddr, 2, data);
}
access_linear(laddr, 2, pl, BX_RW, (void *) data);
return;
}
}
@ -724,46 +712,40 @@ accessOK:
BX_INSTR_MEM_DATA(laddr, 4, BX_READ);
pl = (CPL==3);
if (BX_CPU_THIS_PTR cr0.pg) {
#if BX_SupportGuest2HostTLB
Bit32u lpf, tlbIndex, pageOffset;
pageOffset = laddr & 0xfff;
if (pageOffset <= 0xffc) { // Make sure access does not span 2 pages.
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
Bit32u accessBits;
{
Bit32u lpf, tlbIndex, pageOffset;
// See if the TLB entry privilege level allows us write access
// from this CPL.
accessBits = BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits;
if ( accessBits & (1 << (2 | pl)) ) {
// Current write access has privilege.
Bit32u hostPageAddr;
Bit32u *hostAddr;
hostPageAddr = accessBits & 0xfffff000;
if (hostPageAddr) {
hostAddr = (Bit32u*) (hostPageAddr | pageOffset);
*data = *hostAddr;
BX_CPU_THIS_PTR address_xlation.paddress1 =
BX_CPU_THIS_PTR TLB.entry[tlbIndex].ppf | pageOffset;
BX_CPU_THIS_PTR address_xlation.pages = 1;
return;
}
pageOffset = laddr & 0xfff;
if (pageOffset <= 0xffc) { // Make sure access does not span 2 pages.
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
Bit32u accessBits;
// See if the TLB entry privilege level allows us write access
// from this CPL.
accessBits = BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits;
if ( accessBits & (1 << (2 | pl)) ) {
// Current write access has privilege.
Bit32u hostPageAddr;
Bit32u *hostAddr;
hostPageAddr = accessBits & 0xfffff000;
if (hostPageAddr) {
hostAddr = (Bit32u*) (hostPageAddr | pageOffset);
*data = *hostAddr;
BX_CPU_THIS_PTR address_xlation.paddress1 =
BX_CPU_THIS_PTR TLB.entry[tlbIndex].ppf | pageOffset;
BX_CPU_THIS_PTR address_xlation.pages = 1;
return;
}
}
}
}
}
#endif // BX_SupportGuest2HostTLB
access_linear(laddr, 4, pl, BX_RW, (void *) data);
}
else {
BX_CPU_THIS_PTR address_xlation.paddress1 = laddr;
BX_INSTR_LIN_READ(laddr, laddr, 4);
BX_INSTR_LIN_WRITE(laddr, laddr, 4);
BX_CPU_THIS_PTR mem->read_physical(this, laddr, 4, data);
}
access_linear(laddr, 4, pl, BX_RW, (void *) data);
return;
}
}
@ -776,16 +758,9 @@ BX_CPU_C::write_RMW_virtual_byte(Bit8u val8)
{
BX_INSTR_MEM_DATA(BX_CPU_THIS_PTR address_xlation.paddress1, 1, BX_WRITE);
#if BX_CPU_LEVEL >= 3
if (BX_CPU_THIS_PTR cr0.pg) {
// BX_CPU_THIS_PTR address_xlation.pages must be 1
BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 1, &val8);
}
else
#endif
{
BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 1, &val8);
}
// address_xlation.pages must be 1
BX_CPU_THIS_PTR mem->writePhysicalPage(this,
BX_CPU_THIS_PTR address_xlation.paddress1, 1, &val8);
}
void
@ -793,29 +768,22 @@ BX_CPU_C::write_RMW_virtual_word(Bit16u val16)
{
BX_INSTR_MEM_DATA(BX_CPU_THIS_PTR address_xlation.paddress1, 2, BX_WRITE);
#if BX_CPU_LEVEL >= 3
if (BX_CPU_THIS_PTR cr0.pg) {
if (BX_CPU_THIS_PTR address_xlation.pages == 1) {
BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 2, &val16);
}
else {
#ifdef BX_LITTLE_ENDIAN
BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 1,
&val16);
BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2, 1,
((Bit8u *) &val16) + 1);
#else
BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 1,
((Bit8u *) &val16) + 1);
BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2, 1,
&val16);
#endif
}
if (BX_CPU_THIS_PTR address_xlation.pages == 1) {
BX_CPU_THIS_PTR mem->writePhysicalPage(this,
BX_CPU_THIS_PTR address_xlation.paddress1, 2, &val16);
}
else
else {
#ifdef BX_LITTLE_ENDIAN
BX_CPU_THIS_PTR mem->writePhysicalPage(this,
BX_CPU_THIS_PTR address_xlation.paddress1, 1, &val16);
BX_CPU_THIS_PTR mem->writePhysicalPage(this,
BX_CPU_THIS_PTR address_xlation.paddress2, 1, ((Bit8u *) &val16) + 1);
#else
BX_CPU_THIS_PTR mem->writePhysicalPage(this,
BX_CPU_THIS_PTR address_xlation.paddress1, 1, ((Bit8u *) &val16) + 1);
BX_CPU_THIS_PTR mem->writePhysicalPage(this,
BX_CPU_THIS_PTR address_xlation.paddress2, 1, &val16);
#endif
{
BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 2, &val16);
}
}
@ -824,33 +792,30 @@ BX_CPU_C::write_RMW_virtual_dword(Bit32u val32)
{
BX_INSTR_MEM_DATA(BX_CPU_THIS_PTR address_xlation.paddress1, 4, BX_WRITE);
#if BX_CPU_LEVEL >= 3
if (BX_CPU_THIS_PTR cr0.pg) {
if (BX_CPU_THIS_PTR address_xlation.pages == 1) {
BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 4, &val32);
}
else {
#ifdef BX_LITTLE_ENDIAN
BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR address_xlation.len1,
&val32);
BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR address_xlation.len2,
((Bit8u *) &val32) + BX_CPU_THIS_PTR address_xlation.len1);
#else
BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR address_xlation.len1,
((Bit8u *) &val32) + (4 - BX_CPU_THIS_PTR address_xlation.len1));
BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR address_xlation.len2,
&val32);
#endif
}
if (BX_CPU_THIS_PTR address_xlation.pages == 1) {
BX_CPU_THIS_PTR mem->writePhysicalPage(this,
BX_CPU_THIS_PTR address_xlation.paddress1, 4, &val32);
}
else
else {
#ifdef BX_LITTLE_ENDIAN
BX_CPU_THIS_PTR mem->writePhysicalPage(this,
BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR address_xlation.len1,
&val32);
BX_CPU_THIS_PTR mem->writePhysicalPage(this,
BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR address_xlation.len2,
((Bit8u *) &val32) + BX_CPU_THIS_PTR address_xlation.len1);
#else
BX_CPU_THIS_PTR mem->writePhysicalPage(this,
BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR address_xlation.len1,
((Bit8u *) &val32) + (4 - BX_CPU_THIS_PTR address_xlation.len1));
BX_CPU_THIS_PTR mem->writePhysicalPage(this,
BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR address_xlation.len2,
&val32);
#endif
{
BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 4, &val32);
}
}
@ -865,47 +830,43 @@ BX_CPU_C::write_virtual_qword(unsigned s, Bit32u offset, Bit64u *data)
if (seg->cache.valid & SegAccessWOK) {
if (offset <= (seg->cache.u.segment.limit_scaled-7)) {
unsigned pl;
Bit32u dwordLow, dwordHigh;
accessOK:
laddr = seg->cache.u.segment.base + offset;
BX_INSTR_MEM_DATA(laddr, 8, BX_WRITE);
pl = (CPL==3);
#if BX_SupportGuest2HostTLB
if (BX_CPU_THIS_PTR cr0.pg) {
Bit32u lpf, tlbIndex, pageOffset;
pageOffset = laddr & 0xfff;
if (pageOffset <= 0xff8) { // Make sure access does not span 2 pages.
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
Bit32u accessBits;
{
Bit32u lpf, tlbIndex, pageOffset;
// See if the TLB entry privilege level allows us write access
// from this CPL.
accessBits = BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits;
if ( accessBits & (1 << (2 | pl)) ) {
// Current write access has privilege.
Bit32u hostPageAddr;
Bit64u *hostAddr;
hostPageAddr = accessBits & 0xfffff000;
if (hostPageAddr) {
hostAddr = (Bit64u*) (hostPageAddr | pageOffset);
*hostAddr = *data;
return;
}
pageOffset = laddr & 0xfff;
if (pageOffset <= 0xff8) { // Make sure access does not span 2 pages.
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
Bit32u accessBits;
// See if the TLB entry privilege level allows us write access
// from this CPL.
accessBits = BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits;
if ( accessBits & (1 << (2 | pl)) ) {
// Current write access has privilege.
Bit32u hostPageAddr;
Bit64u *hostAddr;
hostPageAddr = accessBits & 0xfffff000;
if (hostPageAddr) {
hostAddr = (Bit64u*) (hostPageAddr | pageOffset);
*hostAddr = *data;
return;
}
}
}
}
}
#endif // BX_SupportGuest2HostTLB
// all checks OK
dwordLow = (Bit32u) *data;
dwordHigh = (Bit32u) (*data >> 32);
access_linear(laddr, 4, pl, BX_WRITE, (void *) &dwordLow);
access_linear(laddr+4, 4, pl, BX_WRITE, (void *) &dwordHigh);
access_linear(laddr, 8, pl, BX_WRITE, (void *) data);
return;
}
}
@ -923,46 +884,43 @@ BX_CPU_C::read_virtual_qword(unsigned s, Bit32u offset, Bit64u *data)
if (seg->cache.valid & SegAccessROK) {
if (offset <= (seg->cache.u.segment.limit_scaled-7)) {
unsigned pl;
Bit32u dwordLow, dwordHigh;
accessOK:
laddr = seg->cache.u.segment.base + offset;
BX_INSTR_MEM_DATA(laddr, 8, BX_READ);
pl = (CPL==3);
#if BX_SupportGuest2HostTLB
if (BX_CPU_THIS_PTR cr0.pg) {
Bit32u pageOffset;
{
Bit32u pageOffset;
pageOffset = laddr & 0xfff;
if (pageOffset <= 0xff8) { // Make sure access does not span 2 pages.
Bit32u lpf, tlbIndex;
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
// See if the TLB entry privilege level allows us read access
// from this CPL.
Bit32u accessBits;
pageOffset = laddr & 0xfff;
if (pageOffset <= 0xff8) { // Make sure access does not span 2 pages.
Bit32u lpf, tlbIndex;
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
// See if the TLB entry privilege level allows us read access
// from this CPL.
Bit32u accessBits;
accessBits = BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits;
if ( accessBits & (1<<pl) ) { // Read this pl OK.
Bit32u hostPageAddr;
Bit64u *hostAddr;
hostPageAddr = accessBits & 0xfffff000;
if (hostPageAddr) {
hostAddr = (Bit64u*) (hostPageAddr | pageOffset);
*data = *hostAddr;
return;
}
accessBits = BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits;
if ( accessBits & (1<<pl) ) { // Read this pl OK.
Bit32u hostPageAddr;
Bit64u *hostAddr;
hostPageAddr = accessBits & 0xfffff000;
if (hostPageAddr) {
hostAddr = (Bit64u*) (hostPageAddr | pageOffset);
*data = *hostAddr;
return;
}
}
}
}
}
#endif // BX_SupportGuest2HostTLB
// all checks OK
access_linear(laddr, 4, pl, BX_READ, (void *) &dwordLow);
access_linear(laddr+4, 4, pl, BX_READ, (void *) &dwordHigh);
*data = (((Bit64u)dwordHigh)<<32) | ((Bit64u)dwordLow);
access_linear(laddr, 8, pl, BX_READ, (void *) data);
return;
}
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.28 2002-09-04 20:23:54 kevinlawton Exp $
// $Id: cpu.h,v 1.29 2002-09-05 02:31:24 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -1484,6 +1484,8 @@ public: // for now...
BX_SMF void disable_paging(void);
BX_SMF void CR3_change(Bit32u value32);
BX_SMF void pagingWPChanged(void);
BX_SMF void pagingA20Changed(void);
BX_SMF void reset(unsigned source);
BX_SMF void jump_protected(BxInstruction_t *, Bit16u cs, Bit32u disp32);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: paging.cc,v 1.12 2002-09-04 08:59:13 kevinlawton Exp $
// $Id: paging.cc,v 1.13 2002-09-05 02:31:24 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -312,6 +312,16 @@
// +---------------> Current CR0.wp value
#define ReadSysOK 0x01
#define ReadUserOK 0x02
#define WriteSysOK 0x04
#define WriteUserOK 0x08
#define AccessBitsRVetoed 0x10
#define AccessBitsWVetoed 0x20
#ifndef _MSC_VER
// MSC++ doesn't understand a #warning
#warning "Move priv_check to CPU fields, or init.cc"
@ -361,6 +371,12 @@ BX_CPU_C::pagingWPChanged(void)
#endif
}
void
BX_CPU_C::pagingA20Changed(void)
{
TLB_clear();
}
void
BX_CPU_C::TLB_init(void)
{
@ -473,7 +489,7 @@ BX_CPU_C::INVLPG(BxInstruction_t* i)
// a data access (D)
Bit32u
BX_CPU_C::dtranslate_linear(Bit32u laddress, unsigned pl, unsigned rw)
BX_CPU_C::dtranslate_linear(Bit32u laddr, unsigned pl, unsigned rw)
{
Bit32u lpf, ppf, poffset, TLB_index, error_code, paddress;
Bit32u pde, pde_addr;
@ -481,8 +497,8 @@ BX_CPU_C::dtranslate_linear(Bit32u laddress, unsigned pl, unsigned rw)
Bit32u accessBits, combined_access;
unsigned priv_index;
lpf = laddress & 0xfffff000; // linear page frame
poffset = laddress & 0x00000fff; // physical offset
lpf = laddr & 0xfffff000; // linear page frame
poffset = laddr & 0x00000fff; // physical offset
TLB_index = BX_TLB_INDEX_OF(lpf);
@ -506,8 +522,8 @@ pageTableWalk:
// Get page dir entry
pde_addr = (BX_CPU_THIS_PTR cr3 & 0xfffff000) |
((laddress & 0xffc00000) >> 20);
BX_CPU_THIS_PTR mem->read_physical(this, pde_addr, 4, &pde);
((laddr & 0xffc00000) >> 20);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, pde_addr, 4, &pde);
if ( !(pde & 0x01) ) {
// Page Directory Entry NOT present
error_code = 0x00000000; // RSVD=0, P=0
@ -539,13 +555,13 @@ pageTableWalk:
}
// make up the physical frame number
ppf = (pde & 0xFFC00000) | (laddress & 0x003FF000);
ppf = (pde & 0xFFC00000) | (laddr & 0x003FF000);
// Update PDE if A/D bits if needed.
if ( ((pde & 0x20)==0) ||
(isWrite && ((pde&0x40)==0)) ) {
pde |= (0x20 | (isWrite<<6)); // Update A and possibly D bits
BX_CPU_THIS_PTR mem->write_physical(this, pde_addr, 4, &pde);
BX_CPU_THIS_PTR mem->writePhysicalPage(this, pde_addr, 4, &pde);
}
}
@ -559,14 +575,14 @@ pageTableWalk:
// update PDE if A bit was not set before
if ( !(pde & 0x20) ) {
pde |= 0x20;
BX_CPU_THIS_PTR mem->write_physical(this, pde_addr, 4, &pde);
BX_CPU_THIS_PTR mem->writePhysicalPage(this, pde_addr, 4, &pde);
}
#endif
// Get page table entry
pte_addr = (pde & 0xfffff000) |
((laddress & 0x003ff000) >> 10);
BX_CPU_THIS_PTR mem->read_physical(this, pte_addr, 4, &pte);
((laddr & 0x003ff000) >> 10);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, pte_addr, 4, &pte);
if ( !(pte & 0x01) ) {
// Page Table Entry NOT present
@ -602,7 +618,7 @@ pageTableWalk:
// update PDE if A bit was not set before
if ( !(pde & 0x20) ) {
pde |= 0x20;
BX_CPU_THIS_PTR mem->write_physical(this, pde_addr, 4, &pde);
BX_CPU_THIS_PTR mem->writePhysicalPage(this, pde_addr, 4, &pde);
}
#endif
@ -610,7 +626,7 @@ pageTableWalk:
if ( ((pte & 0x20)==0) ||
(isWrite && ((pte&0x40)==0)) ) {
pte |= (0x20 | (isWrite<<6)); // Update A and possibly D bits
BX_CPU_THIS_PTR mem->write_physical(this, pte_addr, 4, &pte);
BX_CPU_THIS_PTR mem->writePhysicalPage(this, pte_addr, 4, &pte);
}
}
@ -641,17 +657,11 @@ pageTableWalk:
BX_CPU_THIS_PTR TLB.entry[TLB_index].accessBits = accessBits;
#if BX_SupportGuest2HostTLB
{
Bit32u hostPageAddr;
hostPageAddr = (Bit32u) BX_CPU_THIS_PTR mem->getHostMemAddr(A20ADDR(ppf), rw);
if (hostPageAddr) {
// No veto; a host address was returned.
// Host addresses are now always 4k page aligned.
BX_CPU_THIS_PTR TLB.entry[TLB_index].accessBits |= hostPageAddr;
}
// Else leave the host address component zero (NULL) to signal no
// valid host address; use long path.
}
// Attempt to get a host pointer to this physical page. Put that
// pointer in the TLB cache. Note if the request is vetoed, NULL
// will be returned, and it's OK to OR zero in anyways.
BX_CPU_THIS_PTR TLB.entry[TLB_index].accessBits |=
(Bit32u) BX_CPU_THIS_PTR mem->getHostMemAddr(A20ADDR(ppf), rw);
#endif // BX_SupportGuest2HostTLB
return(paddress);
@ -661,7 +671,7 @@ page_fault_access:
page_fault_not_present:
error_code |= (pl << 2) | (isWrite << 1);
BX_CPU_THIS_PTR cr2 = laddress;
BX_CPU_THIS_PTR cr2 = laddr;
// Invalidate TLB entry.
BX_CPU_THIS_PTR TLB.entry[TLB_index].lpf = BX_INVALID_TLB_ENTRY;
exception(BX_PF_EXCEPTION, error_code, 0);
@ -673,15 +683,15 @@ page_fault_not_present:
// an instruction fetch access (I)
Bit32u
BX_CPU_C::itranslate_linear(Bit32u laddress, unsigned pl)
BX_CPU_C::itranslate_linear(Bit32u laddr, unsigned pl)
{
Bit32u lpf, ppf, poffset, TLB_index, error_code, paddress;
Bit32u pde, pde_addr;
Bit32u accessBits, combined_access;
unsigned priv_index;
lpf = laddress & 0xfffff000; // linear page frame
poffset = laddress & 0x00000fff; // physical offset
lpf = laddr & 0xfffff000; // linear page frame
poffset = laddr & 0x00000fff; // physical offset
TLB_index = BX_TLB_INDEX_OF(lpf);
@ -703,8 +713,8 @@ pageTableWalk:
// Get page dir entry
pde_addr = (BX_CPU_THIS_PTR cr3 & 0xfffff000) |
((laddress & 0xffc00000) >> 20);
BX_CPU_THIS_PTR mem->read_physical(this, pde_addr, 4, &pde);
((laddr & 0xffc00000) >> 20);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, pde_addr, 4, &pde);
if ( !(pde & 0x01) ) {
// Page Directory Entry NOT present
error_code = 0x00000000; // RSVD=0, P=0
@ -731,12 +741,12 @@ pageTableWalk:
}
// make up the physical frame number
ppf = (pde & 0xFFC00000) | (laddress & 0x003FF000);
ppf = (pde & 0xFFC00000) | (laddr & 0x003FF000);
// Update PDE if A/D bits if needed.
if ( (pde & 0x20)==0 ) {
pde |= 0x20; // Update A and possibly D bits
BX_CPU_THIS_PTR mem->write_physical(this, pde_addr, 4, &pde);
BX_CPU_THIS_PTR mem->writePhysicalPage(this, pde_addr, 4, &pde);
}
}
@ -750,14 +760,14 @@ pageTableWalk:
// update PDE if A bit was not set before
if ( !(pde & 0x20) ) {
pde |= 0x20;
BX_CPU_THIS_PTR mem->write_physical(this, pde_addr, 4, &pde);
BX_CPU_THIS_PTR mem->writePhysicalPage(this, pde_addr, 4, &pde);
}
#endif
// Get page table entry
pte_addr = (pde & 0xfffff000) |
((laddress & 0x003ff000) >> 10);
BX_CPU_THIS_PTR mem->read_physical(this, pte_addr, 4, &pte);
((laddr & 0x003ff000) >> 10);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, pte_addr, 4, &pte);
if ( !(pte & 0x01) ) {
// Page Table Entry NOT present
@ -793,14 +803,14 @@ pageTableWalk:
// update PDE if A bit was not set before
if ( !(pde & 0x20) ) {
pde |= 0x20;
BX_CPU_THIS_PTR mem->write_physical(this, pde_addr, 4, &pde);
BX_CPU_THIS_PTR mem->writePhysicalPage(this, pde_addr, 4, &pde);
}
#endif
// Update PTE if A/D bits if needed.
if ( (pte & 0x20)==0 ) {
pte |= 0x20; // Update A and possibly D bits
BX_CPU_THIS_PTR mem->write_physical(this, pte_addr, 4, &pte);
BX_CPU_THIS_PTR mem->writePhysicalPage(this, pte_addr, 4, &pte);
}
}
@ -824,16 +834,8 @@ pageTableWalk:
BX_CPU_THIS_PTR TLB.entry[TLB_index].accessBits = accessBits;
#if BX_SupportGuest2HostTLB
{
Bit32u hostPageAddr;
hostPageAddr = (Bit32u)
BX_CPU_THIS_PTR mem->getHostMemAddr(A20ADDR(ppf), BX_READ);
if (hostPageAddr) {
// No veto; a host address was returned.
// Host addresses are now always 4k page aligned.
BX_CPU_THIS_PTR TLB.entry[TLB_index].accessBits |= hostPageAddr;
}
}
BX_CPU_THIS_PTR TLB.entry[TLB_index].accessBits |=
(Bit32u) BX_CPU_THIS_PTR mem->getHostMemAddr(A20ADDR(ppf), BX_READ);
#endif // BX_SupportGuest2HostTLB
return(paddress);
@ -843,7 +845,7 @@ page_fault_access:
page_fault_not_present:
error_code |= (pl << 2);
BX_CPU_THIS_PTR cr2 = laddress;
BX_CPU_THIS_PTR cr2 = laddr;
// Invalidate TLB entry.
BX_CPU_THIS_PTR TLB.entry[TLB_index].lpf = BX_INVALID_TLB_ENTRY;
exception(BX_PF_EXCEPTION, error_code, 0);
@ -854,20 +856,20 @@ page_fault_not_present:
#if BX_DEBUGGER || BX_DISASM || BX_INSTRUMENTATION
void
BX_CPU_C::dbg_xlate_linear2phy(Bit32u laddress, Bit32u *phy, Boolean *valid)
BX_CPU_C::dbg_xlate_linear2phy(Bit32u laddr, Bit32u *phy, Boolean *valid)
{
Bit32u lpf, ppf, poffset, TLB_index, paddress;
Bit32u pde, pde_addr;
Bit32u pte, pte_addr;
if (BX_CPU_THIS_PTR cr0.pg == 0) {
*phy = laddress;
*phy = laddr;
*valid = 1;
return;
}
lpf = laddress & 0xfffff000; // linear page frame
poffset = laddress & 0x00000fff; // physical offset
lpf = laddr & 0xfffff000; // linear page frame
poffset = laddr & 0x00000fff; // physical offset
TLB_index = BX_TLB_INDEX_OF(lpf);
// see if page is in the TLB first
@ -880,8 +882,8 @@ BX_CPU_C::dbg_xlate_linear2phy(Bit32u laddress, Bit32u *phy, Boolean *valid)
// Get page dir entry
pde_addr = (BX_CPU_THIS_PTR cr3 & 0xfffff000) |
((laddress & 0xffc00000) >> 20);
BX_CPU_THIS_PTR mem->read_physical(this, pde_addr, 4, &pde);
((laddr & 0xffc00000) >> 20);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, pde_addr, 4, &pde);
if ( !(pde & 0x01) ) {
// Page Directory Entry NOT present
goto page_fault;
@ -889,8 +891,8 @@ BX_CPU_C::dbg_xlate_linear2phy(Bit32u laddress, Bit32u *phy, Boolean *valid)
// Get page table entry
pte_addr = (pde & 0xfffff000) |
((laddress & 0x003ff000) >> 10);
BX_CPU_THIS_PTR mem->read_physical(this, pte_addr, 4, &pte);
((laddr & 0x003ff000) >> 10);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, pte_addr, 4, &pte);
if ( !(pte & 0x01) ) {
// Page Table Entry NOT present
goto page_fault;
@ -913,10 +915,10 @@ page_fault:
void
BX_CPU_C::access_linear(Bit32u laddress, unsigned length, unsigned pl,
BX_CPU_C::access_linear(Bit32u laddr, unsigned length, unsigned pl,
unsigned rw, void *data)
{
Bit32u mod4096;
Bit32u pageOffset;
unsigned xlate_rw;
@ -930,7 +932,7 @@ BX_CPU_C::access_linear(Bit32u laddress, unsigned length, unsigned pl,
opb = opa;
else // BX_WRITE or BX_RW; also compare vs 01b
opb = BX_HWDebugMemW;
dr6_bits = hwdebug_compare(laddress, length, opa, opb);
dr6_bits = hwdebug_compare(laddr, length, opa, opb);
if (dr6_bits) {
BX_CPU_THIS_PTR debug_trap |= dr6_bits;
BX_CPU_THIS_PTR async_event = 1;
@ -946,92 +948,93 @@ BX_CPU_C::access_linear(Bit32u laddress, unsigned length, unsigned pl,
xlate_rw = rw;
}
// perhaps put this check before all code which calls this function,
// so we don't have to here
pageOffset = laddr & 0x00000fff;
if (BX_CPU_THIS_PTR cr0.pg) {
/* check for reference across multiple pages */
mod4096 = laddress & 0x00000fff;
if ( (mod4096 + length) <= 4096 ) {
// Bit32u paddress1;
/* access within single page */
BX_CPU_THIS_PTR address_xlation.paddress1 = dtranslate_linear(laddress, pl, xlate_rw);
if ( (pageOffset + length) <= 4096 ) {
// Access within single page.
BX_CPU_THIS_PTR address_xlation.paddress1 =
dtranslate_linear(laddr, pl, xlate_rw);
BX_CPU_THIS_PTR address_xlation.pages = 1;
if (rw == BX_READ) {
BX_INSTR_LIN_READ(laddress, BX_CPU_THIS_PTR address_xlation.paddress1, length);
BX_CPU_THIS_PTR mem->read_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, length, data);
BX_INSTR_LIN_READ(laddr, BX_CPU_THIS_PTR address_xlation.paddress1, length);
BX_CPU_THIS_PTR mem->readPhysicalPage(this,
BX_CPU_THIS_PTR address_xlation.paddress1, length, data);
}
else {
BX_INSTR_LIN_WRITE(laddress, BX_CPU_THIS_PTR address_xlation.paddress1, length);
BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, length, data);
BX_INSTR_LIN_WRITE(laddr, BX_CPU_THIS_PTR address_xlation.paddress1, length);
BX_CPU_THIS_PTR mem->writePhysicalPage(this,
BX_CPU_THIS_PTR address_xlation.paddress1, length, data);
}
return;
}
else {
// access across 2 pages
BX_CPU_THIS_PTR address_xlation.paddress1 = dtranslate_linear(laddress, pl, xlate_rw);
BX_CPU_THIS_PTR address_xlation.len1 = 4096 - mod4096;
BX_CPU_THIS_PTR address_xlation.len2 = length - BX_CPU_THIS_PTR address_xlation.len1;
BX_CPU_THIS_PTR address_xlation.paddress1 =
dtranslate_linear(laddr, pl, xlate_rw);
BX_CPU_THIS_PTR address_xlation.len1 = 4096 - pageOffset;
BX_CPU_THIS_PTR address_xlation.len2 = length -
BX_CPU_THIS_PTR address_xlation.len1;
BX_CPU_THIS_PTR address_xlation.pages = 2;
BX_CPU_THIS_PTR address_xlation.paddress2 = dtranslate_linear(laddress + BX_CPU_THIS_PTR address_xlation.len1, pl, xlate_rw);
BX_CPU_THIS_PTR address_xlation.paddress2 =
dtranslate_linear(laddr + BX_CPU_THIS_PTR address_xlation.len1,
pl, xlate_rw);
#ifdef BX_LITTLE_ENDIAN
if (rw == BX_READ) {
BX_INSTR_LIN_READ(laddress,
BX_INSTR_LIN_READ(laddr,
BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR address_xlation.len1);
BX_CPU_THIS_PTR mem->read_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR mem->readPhysicalPage(this, BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR address_xlation.len1, data);
BX_INSTR_LIN_READ(laddress + BX_CPU_THIS_PTR address_xlation.len1,
BX_INSTR_LIN_READ(laddr + BX_CPU_THIS_PTR address_xlation.len1,
BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR address_xlation.len2);
BX_CPU_THIS_PTR mem->read_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR mem->readPhysicalPage(this, BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR address_xlation.len2,
((Bit8u*)data) + BX_CPU_THIS_PTR address_xlation.len1);
}
else {
BX_INSTR_LIN_WRITE(laddress,
BX_INSTR_LIN_WRITE(laddr,
BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR address_xlation.len1);
BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR mem->writePhysicalPage(this, BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR address_xlation.len1, data);
BX_INSTR_LIN_WRITE(laddress + BX_CPU_THIS_PTR address_xlation.len1,
BX_INSTR_LIN_WRITE(laddr + BX_CPU_THIS_PTR address_xlation.len1,
BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR address_xlation.len2);
BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR mem->writePhysicalPage(this, BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR address_xlation.len2,
((Bit8u*)data) + BX_CPU_THIS_PTR address_xlation.len1);
}
#else // BX_BIG_ENDIAN
if (rw == BX_READ) {
BX_INSTR_LIN_READ(laddress,
BX_INSTR_LIN_READ(laddr,
BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR address_xlation.len1);
BX_CPU_THIS_PTR mem->read_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR mem->readPhysicalPage(this, BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR address_xlation.len1,
((Bit8u*)data) + (length - BX_CPU_THIS_PTR address_xlation.len1));
BX_INSTR_LIN_READ(laddress + BX_CPU_THIS_PTR address_xlation.len1,
BX_INSTR_LIN_READ(laddr + BX_CPU_THIS_PTR address_xlation.len1,
BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR address_xlation.len2);
BX_CPU_THIS_PTR mem->read_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR mem->readPhysicalPage(this, BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR address_xlation.len2, data);
}
else {
BX_INSTR_LIN_WRITE(laddress,
BX_INSTR_LIN_WRITE(laddr,
BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR address_xlation.len1);
BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR mem->writePhysicalPage(this, BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR address_xlation.len1,
((Bit8u*)data) + (length - BX_CPU_THIS_PTR address_xlation.len1));
BX_INSTR_LIN_WRITE(laddress + BX_CPU_THIS_PTR address_xlation.len1,
BX_INSTR_LIN_WRITE(laddr + BX_CPU_THIS_PTR address_xlation.len1,
BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR address_xlation.len2);
BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR mem->writePhysicalPage(this, BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR address_xlation.len2, data);
}
#endif
@ -1039,15 +1042,165 @@ BX_CPU_C::access_linear(Bit32u laddress, unsigned length, unsigned pl,
return;
}
}
else {
// paging off, pass linear address thru to physical
if (rw == BX_READ) {
BX_INSTR_LIN_READ(laddress, laddress, length);
BX_CPU_THIS_PTR mem->read_physical(this, laddress, length, data);
// Paging off.
if ( (pageOffset + length) <= 4096 ) {
// Access within single page.
BX_CPU_THIS_PTR address_xlation.paddress1 = laddr;
BX_CPU_THIS_PTR address_xlation.pages = 1;
if (rw == BX_READ) {
Bit32u lpf, tlbIndex;
BX_INSTR_LIN_READ(laddr, laddr, length);
#if BX_SupportGuest2HostTLB
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
BX_CPU_THIS_PTR mem->readPhysicalPage(this, laddr, length, data);
return;
}
// We haven't seen this page, or it's been bumped before.
BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf = lpf;
BX_CPU_THIS_PTR TLB.entry[tlbIndex].ppf = lpf;
// Request a direct write pointer so we can do either R or W.
BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits = (Bit32u)
BX_CPU_THIS_PTR mem->getHostMemAddr(A20ADDR(lpf), BX_WRITE);
if (!BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits) {
// Direct write vetoed. Try requesting only direct reads.
BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits = (Bit32u)
BX_CPU_THIS_PTR mem->getHostMemAddr(A20ADDR(lpf), BX_READ);
if (!BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits) {
// No permissions, both R & W direct accesses vetoed. Accesses
// will fall through to this function always.
BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits =
(AccessBitsWVetoed | AccessBitsRVetoed);
}
else {
// Got direct read pointer OK.
BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits |=
(ReadSysOK | ReadUserOK);
}
}
else {
// Got direct write pointer OK. Mark for any operation to succeed.
BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits |=
(ReadSysOK | ReadUserOK | WriteSysOK | WriteUserOK);
}
#endif // BX_SupportGuest2HostTLB
// Let access fall through to the following for this iteration.
BX_CPU_THIS_PTR mem->readPhysicalPage(this, laddr, length, data);
}
else { // Write
Bit32u lpf, tlbIndex;
BX_INSTR_LIN_WRITE(laddr, laddr, length);
#if BX_SupportGuest2HostTLB
tlbIndex = BX_TLB_INDEX_OF(laddr);
lpf = laddr & 0xfffff000;
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == lpf) {
BX_CPU_THIS_PTR mem->writePhysicalPage(this, laddr, length, data);
return;
}
// We haven't seen this page, or it's been bumped before.
BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf = lpf;
BX_CPU_THIS_PTR TLB.entry[tlbIndex].ppf = lpf;
// TLB.entry[tlbIndex].ppf field not used for PG==0.
// Request a direct write pointer so we can do either R or W.
BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits = (Bit32u)
BX_CPU_THIS_PTR mem->getHostMemAddr(A20ADDR(lpf), BX_WRITE);
if (!BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits) {
// Direct write vetoed. Try requesting only direct reads.
BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits =
(AccessBitsWVetoed | AccessBitsRVetoed);
}
else {
// Got direct write pointer OK. Mark for any operation to succeed.
BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits |=
(ReadSysOK | ReadUserOK | WriteSysOK | WriteUserOK);
}
#endif // BX_SupportGuest2HostTLB
BX_CPU_THIS_PTR mem->writePhysicalPage(this, laddr, length, data);
}
}
else {
BX_INSTR_LIN_WRITE(laddress, laddress, length);
BX_CPU_THIS_PTR mem->write_physical(this, laddress, length, data);
// Access spans two pages.
BX_CPU_THIS_PTR address_xlation.paddress1 = laddr;
BX_CPU_THIS_PTR address_xlation.len1 = 4096 - pageOffset;
BX_CPU_THIS_PTR address_xlation.len2 = length -
BX_CPU_THIS_PTR address_xlation.len1;
BX_CPU_THIS_PTR address_xlation.pages = 2;
BX_CPU_THIS_PTR address_xlation.paddress2 = laddr +
BX_CPU_THIS_PTR address_xlation.len1;
#ifdef BX_LITTLE_ENDIAN
if (rw == BX_READ) {
BX_INSTR_LIN_READ(laddr,
BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR address_xlation.len1);
BX_CPU_THIS_PTR mem->readPhysicalPage(this,
BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR address_xlation.len1, data);
BX_INSTR_LIN_READ(laddr + BX_CPU_THIS_PTR address_xlation.len1,
BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR address_xlation.len2);
BX_CPU_THIS_PTR mem->readPhysicalPage(this,
BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR address_xlation.len2,
((Bit8u*)data) + BX_CPU_THIS_PTR address_xlation.len1);
}
else {
BX_INSTR_LIN_WRITE(laddr,
BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR address_xlation.len1);
BX_CPU_THIS_PTR mem->writePhysicalPage(this,
BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR address_xlation.len1, data);
BX_INSTR_LIN_WRITE(laddr + BX_CPU_THIS_PTR address_xlation.len1,
BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR address_xlation.len2);
BX_CPU_THIS_PTR mem->writePhysicalPage(this,
BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR address_xlation.len2,
((Bit8u*)data) + BX_CPU_THIS_PTR address_xlation.len1);
}
#else // BX_BIG_ENDIAN
if (rw == BX_READ) {
BX_INSTR_LIN_READ(laddr,
BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR address_xlation.len1);
BX_CPU_THIS_PTR mem->readPhysicalPage(this,
BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR address_xlation.len1,
((Bit8u*)data) + (length - BX_CPU_THIS_PTR address_xlation.len1));
BX_INSTR_LIN_READ(laddr + BX_CPU_THIS_PTR address_xlation.len1,
BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR address_xlation.len2);
BX_CPU_THIS_PTR mem->readPhysicalPage(this,
BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR address_xlation.len2, data);
}
else {
BX_INSTR_LIN_WRITE(laddr,
BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR address_xlation.len1);
BX_CPU_THIS_PTR mem->writePhysicalPage(this,
BX_CPU_THIS_PTR address_xlation.paddress1,
BX_CPU_THIS_PTR address_xlation.len1,
((Bit8u*)data) + (length - BX_CPU_THIS_PTR address_xlation.len1));
BX_INSTR_LIN_WRITE(laddr + BX_CPU_THIS_PTR address_xlation.len1,
BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR address_xlation.len2);
BX_CPU_THIS_PTR mem->writePhysicalPage(this,
BX_CPU_THIS_PTR address_xlation.paddress2,
BX_CPU_THIS_PTR address_xlation.len2, data);
}
#endif
}
return;
}
@ -1084,7 +1237,7 @@ BX_CPU_C::CR3_change(Bit32u value32)
void
BX_CPU_C::access_linear(Bit32u laddress, unsigned length, unsigned pl,
BX_CPU_C::access_linear(Bit32u laddr, unsigned length, unsigned pl,
unsigned rw, void *data)
{
/* perhaps put this check before all code which calls this function,
@ -1092,9 +1245,9 @@ BX_CPU_C::access_linear(Bit32u laddress, unsigned length, unsigned pl,
*/
if (BX_CPU_THIS_PTR cr0.pg == 0) {
if (rw == BX_READ)
BX_CPU_THIS_PTR mem->read_physical(this, laddress, length, data);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, laddr, length, data);
else
BX_CPU_THIS_PTR mem->write_physical(this, laddress, length, data);
BX_CPU_THIS_PTR mem->writePhysicalPage(this, laddr, length, data);
return;
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: proc_ctrl.cc,v 1.28 2002-09-04 08:59:13 kevinlawton Exp $
// $Id: proc_ctrl.cc,v 1.29 2002-09-05 02:31:24 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -653,7 +653,7 @@ BX_CPU_C::LOADALL(BxInstruction_t *i)
BX_PANIC(("LOADALL: handle CR0.val32"));
/* MSW */
BX_CPU_THIS_PTR mem->read_physical(this, 0x806, 2, &msw);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x806, 2, &msw);
BX_CPU_THIS_PTR cr0.pe = (msw & 0x01); msw >>= 1;
BX_CPU_THIS_PTR cr0.mp = (msw & 0x01); msw >>= 1;
BX_CPU_THIS_PTR cr0.em = (msw & 0x01); msw >>= 1;
@ -667,15 +667,15 @@ BX_PANIC(("LOADALL: handle CR0.val32"));
BX_PANIC(("LOADALL set PE, MP, EM or TS bits in MSW!"));
/* TR */
BX_CPU_THIS_PTR mem->read_physical(this, 0x816, 2, &tr);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x816, 2, &tr);
BX_CPU_THIS_PTR tr.selector.value = tr;
BX_CPU_THIS_PTR tr.selector.rpl = (tr & 0x03); tr >>= 2;
BX_CPU_THIS_PTR tr.selector.ti = (tr & 0x01); tr >>= 1;
BX_CPU_THIS_PTR tr.selector.index = tr;
BX_CPU_THIS_PTR mem->read_physical(this, 0x860, 2, &base_15_0);
BX_CPU_THIS_PTR mem->read_physical(this, 0x862, 1, &base_23_16);
BX_CPU_THIS_PTR mem->read_physical(this, 0x863, 1, &access);
BX_CPU_THIS_PTR mem->read_physical(this, 0x864, 2, &limit);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x860, 2, &base_15_0);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x862, 1, &base_23_16);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x863, 1, &access);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x864, 2, &limit);
BX_CPU_THIS_PTR tr.cache.valid =
@ -713,15 +713,15 @@ BX_PANIC(("LOADALL: handle CR0.val32"));
/* FLAGS */
BX_CPU_THIS_PTR mem->read_physical(this, 0x818, 2, &flags);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x818, 2, &flags);
write_flags(flags, 1, 1);
/* IP */
BX_CPU_THIS_PTR mem->read_physical(this, 0x81a, 2, &ip);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x81a, 2, &ip);
IP = ip;
/* LDTR */
BX_CPU_THIS_PTR mem->read_physical(this, 0x81c, 2, &ldtr);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x81c, 2, &ldtr);
BX_CPU_THIS_PTR ldtr.selector.value = ldtr;
BX_CPU_THIS_PTR ldtr.selector.rpl = (ldtr & 0x03); ldtr >>= 2;
BX_CPU_THIS_PTR ldtr.selector.ti = (ldtr & 0x01); ldtr >>= 1;
@ -738,10 +738,10 @@ BX_PANIC(("LOADALL: handle CR0.val32"));
BX_CPU_THIS_PTR ldtr.selector.ti = 0;
}
else {
BX_CPU_THIS_PTR mem->read_physical(this, 0x854, 2, &base_15_0);
BX_CPU_THIS_PTR mem->read_physical(this, 0x856, 1, &base_23_16);
BX_CPU_THIS_PTR mem->read_physical(this, 0x857, 1, &access);
BX_CPU_THIS_PTR mem->read_physical(this, 0x858, 2, &limit);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x854, 2, &base_15_0);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x856, 1, &base_23_16);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x857, 1, &access);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x858, 2, &limit);
BX_CPU_THIS_PTR ldtr.cache.valid =
BX_CPU_THIS_PTR ldtr.cache.p = access >> 7;
BX_CPU_THIS_PTR ldtr.cache.dpl = (access >> 5) & 0x03;
@ -766,15 +766,15 @@ BX_PANIC(("LOADALL: handle CR0.val32"));
}
/* DS */
BX_CPU_THIS_PTR mem->read_physical(this, 0x81e, 2, &ds_raw);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x81e, 2, &ds_raw);
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value = ds_raw;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.rpl = (ds_raw & 0x03); ds_raw >>= 2;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.ti = (ds_raw & 0x01); ds_raw >>= 1;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.index = ds_raw;
BX_CPU_THIS_PTR mem->read_physical(this, 0x848, 2, &base_15_0);
BX_CPU_THIS_PTR mem->read_physical(this, 0x84a, 1, &base_23_16);
BX_CPU_THIS_PTR mem->read_physical(this, 0x84b, 1, &access);
BX_CPU_THIS_PTR mem->read_physical(this, 0x84c, 2, &limit);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x848, 2, &base_15_0);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x84a, 1, &base_23_16);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x84b, 1, &access);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x84c, 2, &limit);
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base = (base_23_16 << 16) | base_15_0;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit = limit;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.a = (access & 0x01); access >>= 1;
@ -795,15 +795,15 @@ BX_PANIC(("LOADALL: handle CR0.val32"));
}
/* SS */
BX_CPU_THIS_PTR mem->read_physical(this, 0x820, 2, &ss_raw);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x820, 2, &ss_raw);
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = ss_raw;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl = (ss_raw & 0x03); ss_raw >>= 2;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.ti = (ss_raw & 0x01); ss_raw >>= 1;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.index = ss_raw;
BX_CPU_THIS_PTR mem->read_physical(this, 0x842, 2, &base_15_0);
BX_CPU_THIS_PTR mem->read_physical(this, 0x844, 1, &base_23_16);
BX_CPU_THIS_PTR mem->read_physical(this, 0x845, 1, &access);
BX_CPU_THIS_PTR mem->read_physical(this, 0x846, 2, &limit);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x842, 2, &base_15_0);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x844, 1, &base_23_16);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x845, 1, &access);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x846, 2, &limit);
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base = (base_23_16 << 16) | base_15_0;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit = limit;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.a = (access & 0x01); access >>= 1;
@ -824,7 +824,7 @@ BX_PANIC(("LOADALL: handle CR0.val32"));
/* CS */
BX_CPU_THIS_PTR mem->read_physical(this, 0x822, 2, &cs_raw);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x822, 2, &cs_raw);
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = cs_raw;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = (cs_raw & 0x03); cs_raw >>= 2;
@ -833,10 +833,10 @@ BX_PANIC(("LOADALL: handle CR0.val32"));
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti = (cs_raw & 0x01); cs_raw >>= 1;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index = cs_raw;
BX_CPU_THIS_PTR mem->read_physical(this, 0x83c, 2, &base_15_0);
BX_CPU_THIS_PTR mem->read_physical(this, 0x83e, 1, &base_23_16);
BX_CPU_THIS_PTR mem->read_physical(this, 0x83f, 1, &access);
BX_CPU_THIS_PTR mem->read_physical(this, 0x840, 2, &limit);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x83c, 2, &base_15_0);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x83e, 1, &base_23_16);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x83f, 1, &access);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x840, 2, &limit);
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base = (base_23_16 << 16) | base_15_0;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit = limit;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.a = (access & 0x01); access >>= 1;
@ -856,15 +856,15 @@ BX_PANIC(("LOADALL: handle CR0.val32"));
}
/* ES */
BX_CPU_THIS_PTR mem->read_physical(this, 0x824, 2, &es_raw);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x824, 2, &es_raw);
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value = es_raw;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.rpl = (es_raw & 0x03); es_raw >>= 2;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.ti = (es_raw & 0x01); es_raw >>= 1;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.index = es_raw;
BX_CPU_THIS_PTR mem->read_physical(this, 0x836, 2, &base_15_0);
BX_CPU_THIS_PTR mem->read_physical(this, 0x838, 1, &base_23_16);
BX_CPU_THIS_PTR mem->read_physical(this, 0x839, 1, &access);
BX_CPU_THIS_PTR mem->read_physical(this, 0x83a, 2, &limit);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x836, 2, &base_15_0);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x838, 1, &base_23_16);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x839, 1, &access);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x83a, 2, &limit);
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base = (base_23_16 << 16) | base_15_0;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit = limit;
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.a = (access & 0x01); access >>= 1;
@ -899,42 +899,42 @@ BX_PANIC(("LOADALL: handle CR0.val32"));
}
/* DI */
BX_CPU_THIS_PTR mem->read_physical(this, 0x826, 2, &di);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x826, 2, &di);
DI = di;
/* SI */
BX_CPU_THIS_PTR mem->read_physical(this, 0x828, 2, &si);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x828, 2, &si);
SI = si;
/* BP */
BX_CPU_THIS_PTR mem->read_physical(this, 0x82a, 2, &bp);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x82a, 2, &bp);
BP = bp;
/* SP */
BX_CPU_THIS_PTR mem->read_physical(this, 0x82c, 2, &sp);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x82c, 2, &sp);
SP = sp;
/* BX */
BX_CPU_THIS_PTR mem->read_physical(this, 0x82e, 2, &bx);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x82e, 2, &bx);
BX = bx;
/* DX */
BX_CPU_THIS_PTR mem->read_physical(this, 0x830, 2, &dx);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x830, 2, &dx);
DX = dx;
/* CX */
BX_CPU_THIS_PTR mem->read_physical(this, 0x832, 2, &cx);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x832, 2, &cx);
CX = cx;
/* AX */
BX_CPU_THIS_PTR mem->read_physical(this, 0x834, 2, &ax);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x834, 2, &ax);
AX = ax;
/* GDTR */
BX_CPU_THIS_PTR mem->read_physical(this, 0x84e, 2, &base_15_0);
BX_CPU_THIS_PTR mem->read_physical(this, 0x850, 1, &base_23_16);
BX_CPU_THIS_PTR mem->read_physical(this, 0x851, 1, &access);
BX_CPU_THIS_PTR mem->read_physical(this, 0x852, 2, &limit);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x84e, 2, &base_15_0);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x850, 1, &base_23_16);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x851, 1, &access);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x852, 2, &limit);
BX_CPU_THIS_PTR gdtr.base = (base_23_16 << 16) | base_15_0;
BX_CPU_THIS_PTR gdtr.limit = limit;
@ -945,10 +945,10 @@ BX_PANIC(("LOADALL: handle CR0.val32"));
#endif
/* IDTR */
BX_CPU_THIS_PTR mem->read_physical(this, 0x85a, 2, &base_15_0);
BX_CPU_THIS_PTR mem->read_physical(this, 0x85c, 1, &base_23_16);
BX_CPU_THIS_PTR mem->read_physical(this, 0x85d, 1, &access);
BX_CPU_THIS_PTR mem->read_physical(this, 0x85e, 2, &limit);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x85a, 2, &base_15_0);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x85c, 1, &base_23_16);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x85d, 1, &access);
BX_CPU_THIS_PTR mem->readPhysicalPage(this, 0x85e, 2, &limit);
BX_CPU_THIS_PTR idtr.base = (base_23_16 << 16) | base_15_0;
BX_CPU_THIS_PTR idtr.limit = limit;
#endif

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: dbg_main.cc,v 1.49 2002-08-27 21:32:03 bdenney Exp $
// $Id: dbg_main.cc,v 1.50 2002-09-05 02:31:24 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -4523,7 +4523,7 @@ dbg_lin2phys(BX_CPU_C *cpu, Bit32u laddress, Bit32u *phy, Boolean *valid, Bit32u
// Get page dir entry
pde_addr = (cpu->cr3 & 0xfffff000) |
((laddress & 0xffc00000) >> 20);
BX_MEM(0)->read_physical(cpu, pde_addr, 4, &pde);
BX_MEM(0)->readPhysicalPage(cpu, pde_addr, 4, &pde);
if ( !(pde & 0x01) ) {
// Page Directory Entry NOT present
goto page_fault;
@ -4532,7 +4532,7 @@ dbg_lin2phys(BX_CPU_C *cpu, Bit32u laddress, Bit32u *phy, Boolean *valid, Bit32u
// Get page table entry
pte_addr = (pde & 0xfffff000) |
((laddress & 0x003ff000) >> 10);
BX_MEM(0)->read_physical(cpu, pte_addr, 4, &pte);
BX_MEM(0)->readPhysicalPage(cpu, pte_addr, 4, &pte);
if ( !(pte & 0x01) ) {
// Page Table Entry NOT present
goto page_fault;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: memory.cc,v 1.19 2002-09-01 23:02:36 kevinlawton Exp $
// $Id: memory.cc,v 1.20 2002-09-05 02:31:24 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -37,7 +37,7 @@
#if BX_PROVIDE_CPU_MEMORY
void
BX_MEM_C::write_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
BX_MEM_C::writePhysicalPage(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
{
Bit8u *data_ptr;
Bit32u a20addr;
@ -86,11 +86,11 @@ BX_MEM_C::write_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
* ((Bit8u *) (&vector[a20addr])) = data32; data32 >>= 8;
BX_DBG_DIRTY_PAGE(a20addr >> 12);
BX_DYN_DIRTY_PAGE(a20addr >> 12);
* ((Bit8u *) (&vector[A20ADDR(addr+1)])) = data32; data32 >>= 8;
* ((Bit8u *) (&vector[A20ADDR(addr+2)])) = data32; data32 >>= 8;
* ((Bit8u *) (&vector[A20ADDR(addr+3)])) = data32;
* ((Bit8u *) (&vector[addr+1])) = data32; data32 >>= 8;
* ((Bit8u *) (&vector[addr+2])) = data32; data32 >>= 8;
* ((Bit8u *) (&vector[addr+3])) = data32;
// worst case, last byte is in different page; possible extra dirty page
BX_DBG_DIRTY_PAGE(A20ADDR(addr+3) >> 12);
BX_DBG_DIRTY_PAGE((addr+3) >> 12);
BX_DYN_DIRTY_PAGE(a20addr >> 12);
return;
}
@ -116,8 +116,8 @@ BX_MEM_C::write_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
* ((Bit8u *) (&vector[a20addr])) = (Bit8u) data16;
BX_DBG_DIRTY_PAGE(a20addr >> 12);
BX_DYN_DIRTY_PAGE(a20addr >> 12);
* ((Bit8u *) (&vector[A20ADDR(a20addr+1)])) = (data16 >> 8);
BX_DBG_DIRTY_PAGE(A20ADDR(a20addr+1) >> 12);
* ((Bit8u *) (&vector[a20addr+1])) = (data16 >> 8);
BX_DBG_DIRTY_PAGE((a20addr+1) >> 12);
BX_DYN_DIRTY_PAGE(a20addr >> 12);
return;
}
@ -150,7 +150,7 @@ inc_one:
if (len == 1) return;
len--;
addr++;
a20addr = A20ADDR(addr);
a20addr = (addr);
#ifdef BX_LITTLE_ENDIAN
data_ptr++;
#else // BX_BIG_ENDIAN
@ -206,7 +206,7 @@ inc_one:
BX_DEBUG(("Write to ROM ignored: address %08x, data %02x", (unsigned) a20addr, *data_ptr));
goto inc_one;
default:
BX_PANIC(("write_physical: default case"));
BX_PANIC(("writePhysicalPage: default case"));
goto inc_one;
}
}
@ -242,7 +242,7 @@ inc_one:
// otherwise ignore byte, since it overruns memory
addr++;
a20addr = A20ADDR(addr);
a20addr = (addr);
#ifdef BX_LITTLE_ENDIAN
data_ptr++;
#else // BX_BIG_ENDIAN
@ -275,7 +275,7 @@ inc_one:
}
// otherwise ignore byte, since it overruns memory
addr++;
a20addr = A20ADDR(addr);
a20addr = (addr);
#ifdef BX_LITTLE_ENDIAN
data_ptr++;
#else // BX_BIG_ENDIAN
@ -288,7 +288,7 @@ inc_one:
void
BX_MEM_C::read_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
BX_MEM_C::readPhysicalPage(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
{
Bit8u *data_ptr;
Bit32u a20addr;
@ -331,9 +331,9 @@ BX_MEM_C::read_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
else {
Bit32u data32;
data32 = * ((Bit8u *) (&vector[A20ADDR(addr+3)])); data32 <<= 8;
data32 |= * ((Bit8u *) (&vector[A20ADDR(addr+2)])); data32 <<= 8;
data32 |= * ((Bit8u *) (&vector[A20ADDR(addr+1)])); data32 <<= 8;
data32 = * ((Bit8u *) (&vector[addr+3])); data32 <<= 8;
data32 |= * ((Bit8u *) (&vector[addr+2])); data32 <<= 8;
data32 |= * ((Bit8u *) (&vector[addr+1])); data32 <<= 8;
data32 |= * ((Bit8u *) (&vector[a20addr]));
* (Bit32u *) data = data32;
@ -356,7 +356,7 @@ BX_MEM_C::read_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
else {
Bit16u data16;
data16 = * ((Bit8u *) (&vector[A20ADDR(addr+1)])); data16 <<= 8;
data16 = * ((Bit8u *) (&vector[addr+1])); data16 <<= 8;
data16 |= * ((Bit8u *) (&vector[a20addr]));
* (Bit16u *) data = data16;
@ -390,7 +390,7 @@ inc_one:
if (len == 1) return;
len--;
addr++;
a20addr = A20ADDR(addr);
a20addr = (addr);
#ifdef BX_LITTLE_ENDIAN
data_ptr++;
#else // BX_BIG_ENDIAN
@ -439,7 +439,7 @@ inc_one:
//BX_INFO(("Reading from ROM %08x, Data %02x ", (unsigned) a20addr, *data_ptr));
goto inc_one;
default:
BX_PANIC(("::read_physical: default case"));
BX_PANIC(("::readPhysicalPage: default case"));
}
}
goto inc_one;
@ -472,7 +472,7 @@ inc_one:
// otherwise ignore byte, since it overruns memory
addr++;
a20addr = A20ADDR(addr);
a20addr = (addr);
#ifdef BX_LITTLE_ENDIAN
data_ptr++;
#else // BX_BIG_ENDIAN
@ -519,7 +519,7 @@ inc_one:
BX_INFO(("Reading from ShadowRAM %08x, Data %02x ", (unsigned) a20addr, *data_ptr));
break;
default:
BX_PANIC(("read_physical: default case"));
BX_PANIC(("readPhysicalPage: default case"));
} // Switch
}
}
@ -532,7 +532,7 @@ inc_one:
*data_ptr = 0xff;
#endif // BX_PCI_SUPPORT == 0
addr++;
a20addr = A20ADDR(addr);
a20addr = (addr);
#ifdef BX_LITTLE_ENDIAN
data_ptr++;
#else // BX_BIG_ENDIAN

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: memory.h,v 1.9 2002-09-04 02:11:33 bdenney Exp $
// $Id: memory.h,v 1.10 2002-09-05 02:31:24 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -62,8 +62,10 @@ public:
~BX_MEM_C(void);
BX_MEM_SMF void alloc_vector_aligned (size_t bytes, size_t alignment);
BX_MEM_SMF void init_memory(int memsize);
BX_MEM_SMF void read_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data);
BX_MEM_SMF void write_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data);
BX_MEM_SMF void readPhysicalPage(BX_CPU_C *cpu, Bit32u addr,
unsigned len, void *data);
BX_MEM_SMF void writePhysicalPage(BX_CPU_C *cpu, Bit32u addr,
unsigned len, void *data);
BX_MEM_SMF void load_ROM(const char *path, Bit32u romaddress);
BX_MEM_SMF Bit32u get_memory_in_k(void);
#if BX_PCI_SUPPORT

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: pc_system.cc,v 1.21 2002-08-27 21:30:48 bdenney Exp $
// $Id: pc_system.cc,v 1.22 2002-09-05 02:31:23 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -135,6 +135,8 @@ bx_pc_system_c::set_enable_a20(Bit8u value)
#else
#if BX_SUPPORT_A20
unsigned old_enable_a20 = enable_a20;
if (value) {
enable_a20 = 1;
#if BX_CPU_LEVEL == 2
@ -151,6 +153,14 @@ bx_pc_system_c::set_enable_a20(Bit8u value)
BX_DBG_A20_REPORT(value);
BX_DEBUG(("A20: set() = %u", (unsigned) enable_a20));
// If there has been a transition, we need to notify the CPUs so
// they can potentially invalidate certain cache info based on
// A20-line-applied physical addresses.
if (old_enable_a20 != enable_a20) {
for (unsigned i=0; i<BX_SMP_PROCESSORS; i++)
BX_CPU(i)->pagingA20Changed();
}
#else
BX_DEBUG(("set_enable_a20: ignoring: SUPPORT_A20 = 0"));
#endif // #if BX_SUPPORT_A20