mirror of https://github.com/bochs-emu/Bochs
I changed the TLB entry from 3 dwords to 4, and (when you compile
with GCC) align them with the GCC special alignment attribute. Since there was then one available field, I split the protection attributes and native host pointers into their own fields. Before, with 3 dwords per TLB entry, some entries (about 3/8) were spanning two processor cache lines (assuming a 32-byte cache line). Now, they all fit within one cache line. Knocked about 1.4% off Win95 boot time, probably more off normal software runs.
This commit is contained in:
parent
59d00a46a3
commit
425ad824c0
|
@ -1,5 +1,5 @@
|
|||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: access.cc,v 1.22 2002-09-06 21:54:55 kevinlawton Exp $
|
||||
// $Id: access.cc,v 1.23 2002-09-10 00:01:00 kevinlawton Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
|
@ -282,17 +282,17 @@ accessOK:
|
|||
lpf = laddr & 0xfffff000;
|
||||
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == BX_TLB_LPF_VALUE(lpf)) {
|
||||
Bit32u accessBits;
|
||||
Bit32u hostPageAddr;
|
||||
Bit8u *hostAddr;
|
||||
|
||||
// See if the TLB entry privilege level allows us write access
|
||||
// from this CPL.
|
||||
hostPageAddr = BX_CPU_THIS_PTR TLB.entry[tlbIndex].hostPageAddr;
|
||||
hostAddr = (Bit8u*) (hostPageAddr | pageOffset);
|
||||
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;
|
||||
}
|
||||
|
@ -335,17 +335,17 @@ accessOK:
|
|||
lpf = laddr & 0xfffff000;
|
||||
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == BX_TLB_LPF_VALUE(lpf)) {
|
||||
Bit32u accessBits;
|
||||
Bit32u hostPageAddr;
|
||||
Bit16u *hostAddr;
|
||||
|
||||
// See if the TLB entry privilege level allows us write access
|
||||
// from this CPL.
|
||||
hostPageAddr = BX_CPU_THIS_PTR TLB.entry[tlbIndex].hostPageAddr;
|
||||
hostAddr = (Bit16u*) (hostPageAddr | pageOffset);
|
||||
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);
|
||||
WriteHostWordToLittleEndian(hostAddr, *data);
|
||||
return;
|
||||
}
|
||||
|
@ -389,17 +389,17 @@ accessOK:
|
|||
lpf = laddr & 0xfffff000;
|
||||
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == BX_TLB_LPF_VALUE(lpf)) {
|
||||
Bit32u accessBits;
|
||||
Bit32u hostPageAddr;
|
||||
Bit32u *hostAddr;
|
||||
|
||||
// See if the TLB entry privilege level allows us write access
|
||||
// from this CPL.
|
||||
hostPageAddr = BX_CPU_THIS_PTR TLB.entry[tlbIndex].hostPageAddr;
|
||||
hostAddr = (Bit32u*) (hostPageAddr | pageOffset);
|
||||
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);
|
||||
WriteHostDWordToLittleEndian(hostAddr, *data);
|
||||
return;
|
||||
}
|
||||
|
@ -444,14 +444,14 @@ accessOK:
|
|||
// See if the TLB entry privilege level allows us read access
|
||||
// from this CPL.
|
||||
Bit32u accessBits;
|
||||
Bit32u hostPageAddr;
|
||||
Bit8u *hostAddr;
|
||||
|
||||
hostPageAddr = BX_CPU_THIS_PTR TLB.entry[tlbIndex].hostPageAddr;
|
||||
hostAddr = (Bit8u*) (hostPageAddr | 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;
|
||||
}
|
||||
|
@ -498,14 +498,14 @@ accessOK:
|
|||
// See if the TLB entry privilege level allows us read access
|
||||
// from this CPL.
|
||||
Bit32u accessBits;
|
||||
Bit32u hostPageAddr;
|
||||
Bit16u *hostAddr;
|
||||
|
||||
hostPageAddr = BX_CPU_THIS_PTR TLB.entry[tlbIndex].hostPageAddr;
|
||||
hostAddr = (Bit16u*) (hostPageAddr | pageOffset);
|
||||
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);
|
||||
ReadHostWordFromLittleEndian(hostAddr, *data);
|
||||
return;
|
||||
}
|
||||
|
@ -553,14 +553,14 @@ accessOK:
|
|||
// See if the TLB entry privilege level allows us read access
|
||||
// from this CPL.
|
||||
Bit32u accessBits;
|
||||
Bit32u hostPageAddr;
|
||||
Bit32u *hostAddr;
|
||||
|
||||
hostPageAddr = BX_CPU_THIS_PTR TLB.entry[tlbIndex].hostPageAddr;
|
||||
hostAddr = (Bit32u*) (hostPageAddr | pageOffset);
|
||||
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);
|
||||
ReadHostDWordFromLittleEndian(hostAddr, *data);
|
||||
return;
|
||||
}
|
||||
|
@ -608,17 +608,17 @@ accessOK:
|
|||
lpf = laddr & 0xfffff000;
|
||||
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == BX_TLB_LPF_VALUE(lpf)) {
|
||||
Bit32u accessBits;
|
||||
Bit32u hostPageAddr;
|
||||
Bit8u *hostAddr;
|
||||
|
||||
// See if the TLB entry privilege level allows us write access
|
||||
// from this CPL.
|
||||
hostPageAddr = BX_CPU_THIS_PTR TLB.entry[tlbIndex].hostPageAddr;
|
||||
hostAddr = (Bit8u*) (hostPageAddr | pageOffset);
|
||||
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.pages = (Bit32u) hostAddr;
|
||||
return;
|
||||
|
@ -664,17 +664,17 @@ accessOK:
|
|||
lpf = laddr & 0xfffff000;
|
||||
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == BX_TLB_LPF_VALUE(lpf)) {
|
||||
Bit32u accessBits;
|
||||
Bit32u hostPageAddr;
|
||||
Bit16u *hostAddr;
|
||||
|
||||
// See if the TLB entry privilege level allows us write access
|
||||
// from this CPL.
|
||||
hostPageAddr = BX_CPU_THIS_PTR TLB.entry[tlbIndex].hostPageAddr;
|
||||
hostAddr = (Bit16u*) (hostPageAddr | pageOffset);
|
||||
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);
|
||||
ReadHostWordFromLittleEndian(hostAddr, *data);
|
||||
BX_CPU_THIS_PTR address_xlation.pages = (Bit32u) hostAddr;
|
||||
return;
|
||||
|
@ -718,17 +718,17 @@ accessOK:
|
|||
lpf = laddr & 0xfffff000;
|
||||
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == BX_TLB_LPF_VALUE(lpf)) {
|
||||
Bit32u accessBits;
|
||||
Bit32u hostPageAddr;
|
||||
Bit32u *hostAddr;
|
||||
|
||||
// See if the TLB entry privilege level allows us write access
|
||||
// from this CPL.
|
||||
hostPageAddr = BX_CPU_THIS_PTR TLB.entry[tlbIndex].hostPageAddr;
|
||||
hostAddr = (Bit32u*) (hostPageAddr | pageOffset);
|
||||
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);
|
||||
ReadHostDWordFromLittleEndian(hostAddr, *data);
|
||||
BX_CPU_THIS_PTR address_xlation.pages = (Bit32u) hostAddr;
|
||||
return;
|
||||
|
@ -856,17 +856,17 @@ accessOK:
|
|||
lpf = laddr & 0xfffff000;
|
||||
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf == BX_TLB_LPF_VALUE(lpf)) {
|
||||
Bit32u accessBits;
|
||||
Bit32u hostPageAddr;
|
||||
Bit64u *hostAddr;
|
||||
|
||||
// See if the TLB entry privilege level allows us write access
|
||||
// from this CPL.
|
||||
hostPageAddr = BX_CPU_THIS_PTR TLB.entry[tlbIndex].hostPageAddr;
|
||||
hostAddr = (Bit64u*) (hostPageAddr | pageOffset);
|
||||
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);
|
||||
WriteHostQWordToLittleEndian(hostAddr, *data);
|
||||
return;
|
||||
}
|
||||
|
@ -913,14 +913,14 @@ accessOK:
|
|||
// See if the TLB entry privilege level allows us read access
|
||||
// from this CPL.
|
||||
Bit32u accessBits;
|
||||
Bit32u hostPageAddr;
|
||||
Bit64u *hostAddr;
|
||||
|
||||
hostPageAddr = BX_CPU_THIS_PTR TLB.entry[tlbIndex].hostPageAddr;
|
||||
hostAddr = (Bit64u*) (hostPageAddr | pageOffset);
|
||||
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);
|
||||
ReadHostQWordFromLittleEndian(hostAddr, *data);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.h,v 1.38 2002-09-09 16:11:23 bdenney Exp $
|
||||
// $Id: cpu.h,v 1.39 2002-09-10 00:01:01 kevinlawton Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
|
@ -543,6 +543,7 @@ typedef struct {
|
|||
Bit32u lpf; // linear page frame
|
||||
Bit32u ppf; // physical page frame
|
||||
Bit32u accessBits;
|
||||
Bit32u hostPageAddr;
|
||||
} bx_TLB_entry;
|
||||
#endif // #if BX_USE_TLB
|
||||
|
||||
|
@ -898,7 +899,15 @@ public: // for now...
|
|||
// for paging
|
||||
#if BX_USE_TLB
|
||||
struct {
|
||||
bx_TLB_entry entry[BX_TLB_SIZE];
|
||||
bx_TLB_entry entry[BX_TLB_SIZE]
|
||||
#ifdef __GNUC__
|
||||
// Preferably, entries are aligned so that an access to
|
||||
// one never crosses a cache line. Since they are currently
|
||||
// 16-bytes in size, align to 16 if the compiler knows how. I only
|
||||
// know how to do this in GCC. (KPL)
|
||||
__attribute__ ((aligned (16)))
|
||||
#endif
|
||||
;
|
||||
#if BX_USE_QUICK_TLB_INVALIDATE
|
||||
# define BX_TLB_LPF_VALUE(lpf) (lpf | BX_CPU_THIS_PTR TLB.tlb_invalidate)
|
||||
Bit32u tlb_invalidate;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: paging.cc,v 1.19 2002-09-07 05:21:28 kevinlawton Exp $
|
||||
// $Id: paging.cc,v 1.20 2002-09-10 00:01:01 kevinlawton Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
|
@ -684,7 +684,7 @@ pageTableWalk:
|
|||
// 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 |=
|
||||
BX_CPU_THIS_PTR TLB.entry[TLB_index].hostPageAddr =
|
||||
(Bit32u) BX_CPU_THIS_PTR mem->getHostMemAddr(A20ADDR(ppf), rw);
|
||||
#endif
|
||||
|
||||
|
@ -858,7 +858,7 @@ pageTableWalk:
|
|||
BX_CPU_THIS_PTR TLB.entry[TLB_index].accessBits = accessBits;
|
||||
|
||||
#if BX_SupportGuest2HostTLB
|
||||
BX_CPU_THIS_PTR TLB.entry[TLB_index].accessBits |=
|
||||
BX_CPU_THIS_PTR TLB.entry[TLB_index].hostPageAddr =
|
||||
(Bit32u) BX_CPU_THIS_PTR mem->getHostMemAddr(A20ADDR(ppf), BX_READ);
|
||||
#endif
|
||||
|
||||
|
@ -1089,21 +1089,23 @@ BX_CPU_C::access_linear(Bit32u laddr, unsigned length, unsigned pl,
|
|||
BX_CPU_THIS_PTR TLB.entry[tlbIndex].lpf = BX_TLB_LPF_VALUE(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 TLB.entry[tlbIndex].hostPageAddr = (Bit32u)
|
||||
BX_CPU_THIS_PTR mem->getHostMemAddr(A20ADDR(lpf), BX_WRITE);
|
||||
if (!BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits) {
|
||||
if (!BX_CPU_THIS_PTR TLB.entry[tlbIndex].hostPageAddr) {
|
||||
// Direct write vetoed. Try requesting only direct reads.
|
||||
BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits = (Bit32u)
|
||||
BX_CPU_THIS_PTR TLB.entry[tlbIndex].hostPageAddr = (Bit32u)
|
||||
BX_CPU_THIS_PTR mem->getHostMemAddr(A20ADDR(lpf), BX_READ);
|
||||
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits) {
|
||||
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].hostPageAddr) {
|
||||
// Got direct read pointer OK.
|
||||
BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits |=
|
||||
BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits =
|
||||
(ReadSysOK | ReadUserOK);
|
||||
}
|
||||
else
|
||||
BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits = 0;
|
||||
}
|
||||
else {
|
||||
// Got direct write pointer OK. Mark for any operation to succeed.
|
||||
BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits |=
|
||||
BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits =
|
||||
(ReadSysOK | ReadUserOK | WriteSysOK | WriteUserOK);
|
||||
}
|
||||
#endif // BX_SupportGuest2HostTLB
|
||||
|
@ -1128,13 +1130,15 @@ BX_CPU_C::access_linear(Bit32u laddr, unsigned length, unsigned pl,
|
|||
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 TLB.entry[tlbIndex].hostPageAddr = (Bit32u)
|
||||
BX_CPU_THIS_PTR mem->getHostMemAddr(A20ADDR(lpf), BX_WRITE);
|
||||
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits) {
|
||||
if (BX_CPU_THIS_PTR TLB.entry[tlbIndex].hostPageAddr) {
|
||||
// Got direct write pointer OK. Mark for any operation to succeed.
|
||||
BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits |=
|
||||
BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits =
|
||||
(ReadSysOK | ReadUserOK | WriteSysOK | WriteUserOK);
|
||||
}
|
||||
else
|
||||
BX_CPU_THIS_PTR TLB.entry[tlbIndex].accessBits = 0;
|
||||
#endif // BX_SupportGuest2HostTLB
|
||||
|
||||
BX_CPU_THIS_PTR mem->writePhysicalPage(this, laddr, length, data);
|
||||
|
|
Loading…
Reference in New Issue