[PATCH 08/10] Handle Virtutech Simics x86-440bx shadowing with the VIRTUTECH_PC_SHADOW option.

Magnus Christensson mch at virtutech.com
Tue Nov 3 13:43:13 CET 2009


---
 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"



More information about the coreboot mailing list