---
src/config.h | 1 +
src/shadow.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+), 0 deletions(-)
diff --git a/src/config.h b/src/config.h
index 71903bb..754559b 100644
--- a/src/config.h
+++ b/src/config.h
@@ -191,5 +191,6 @@
/* Options for running on the Virtutech Simics x86-440bx machine model */
#define VIRTUTECH_IRQ0_OVERRIDE 1
+#define VIRTUTECH_PC_SHADOW 1
#endif // config.h
diff --git a/src/shadow.c b/src/shadow.c
index f0f97c5..4b7f15c 100644
--- a/src/shadow.c
+++ b/src/shadow.c
@@ -9,6 +9,7 @@
#include "pci.h" // pci_config_writeb
#include "config.h" // CONFIG_*
#include "pci_ids.h" // PCI_VENDOR_ID_INTEL
+#include "ioport.h" // outb
// Test if 'addr' is in the range from 'start'..'start+size'
#define IN_RANGE(addr, start, size) ({ \
@@ -21,6 +22,40 @@
// On the emulators, the bios at 0xf0000 is also at 0xffff0000
#define BIOS_SRC_ADDR 0xffff0000
+#if VIRTUTECH_PC_SHADOW
+
+#define Read_Only 1
+#define Write_Only 2
+#define Read_Write 3
+
+static void modify_shadow(unsigned long start, unsigned long len, int mode)
+{
+ int start_loc = ((int)(start >> 10) - 640) >> 1;
+ int len_remaining = len >> 11;
+ int i;
+ for (i = 0; i < len_remaining; i++) {
+ outb(start_loc + i, 0xfff4);
+ if (mode == Read_Only) {
+ outb(1, 0xfff5);
+ } else if (mode == Read_Write) {
+ outb(3, 0xfff5);
+ } else if (mode == Write_Only) {
+ outb(2, 0xfff5);
+ } else {
+ outb(0, 0xfff5);
+ }
+ }
+}
+
+static void
+__copy_bios(void)
+{
+ // Copy bios.
+ memcpy((void*)BUILD_BIOS_ADDR, (void*)BIOS_SRC_ADDR, BUILD_BIOS_SIZE);
+}
+
+#else
+
// Enable shadowing and copy bios.
static void
__make_bios_writable(u16 bdf)
@@ -59,6 +94,8 @@ __make_bios_writable(u16 bdf)
memcpy((void*)BUILD_BIOS_ADDR, (void*)BIOS_SRC_ADDR, BUILD_BIOS_SIZE);
}
+#endif // VIRTUTECH_PC_SHADOW
+
// Make the 0xc0000-0x100000 area read/writable.
void
make_bios_writable()
@@ -68,6 +105,19 @@ make_bios_writable()
dprintf(3, "enabling shadow ram\n");
+#if VIRTUTECH_PC_SHADOW
+ /* Read (and execute) from PCI, write to RAM */
+ modify_shadow(0xf0000, 0x10000, Write_Only);
+
+ /* Run the copy from the high address to avoid simulator flushes after each
+ write (the flushes ruin performance) */
+ u32 pos = (u32)__copy_bios - BUILD_BIOS_ADDR + BIOS_SRC_ADDR;
+ void (*func)(void) = (void*)pos;
+ func();
+
+ /* Keep BIOS read/write */
+ modify_shadow(0xf0000, 0x10000, Read_Write);
+#else
// Locate chip controlling ram shadowing.
int bdf = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441);
if (bdf < 0) {
@@ -88,6 +138,7 @@ make_bios_writable()
}
// Ram already present - just enable writes
__make_bios_writable(bdf);
+#endif
}
// Make the BIOS code segment area (0xf0000) read-only.
@@ -99,6 +150,9 @@ make_bios_readonly()
dprintf(3, "locking shadow ram\n");
+#if VIRTUTECH_PC_SHADOW
+ modify_shadow(0xf0000, 0x10000, Read_Only);
+#else
int bdf = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441);
if (bdf < 0) {
dprintf(1, "Unable to lock ram - bridge not found\n");
@@ -122,4 +176,5 @@ make_bios_readonly()
// Write protect 0xf0000-0x100000
pci_config_writeb(bdf, 0x59, 0x10);
+#endif
}
--
1.6.2.5
--------------080100040501080908060605
Content-Type: text/x-patch;
name="0009-Properly-mask-value-for-MTRR-mask.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="0009-Properly-mask-value-for-MTRR-mask.patch"