Index: /trunk/include/VBox/pdmdev.h
===================================================================
--- /trunk/include/VBox/pdmdev.h	(revision 4381)
+++ /trunk/include/VBox/pdmdev.h	(revision 4382)
@@ -1791,10 +1791,15 @@
      * @param   pvBinary            Pointer to the binary data backing the ROM image.
      *                              This must be cbRange bytes big.
-     *                              It will be copied and doesn't have to stick around.
+     *                              It will be copied and doesn't have to stick around if fShadow is clear. 
+     * @param   fShadow             Whether to emulate ROM shadowing. This involves leaving
+     *                              the ROM writable for a while during the POST and refreshing
+     *                              it at reset. When this flag is set, the memory pointed to by
+     *                              pvBinary has to stick around for the lifespan of the VM.
      * @param   pszDesc             Pointer to description string. This must not be freed.
+     * 
      * @remark  There is no way to remove the rom, automatically on device cleanup or
      *          manually from the device yet. At present I doubt we need such features...
      */
-    DECLR3CALLBACKMEMBER(int, pfnROMRegister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, const void *pvBinary, const char *pszDesc));
+    DECLR3CALLBACKMEMBER(int, pfnROMRegister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, const void *pvBinary, bool fShadow, const char *pszDesc));
 
     /**
@@ -2527,7 +2532,20 @@
     DECLR3CALLBACKMEMBER(void, pfnGetCpuId,(PPDMDEVINS pDevIns, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx));
 
+    /**
+     * Write protects a shadow ROM mapping.
+     * 
+     * This is intented for use by the system BIOS or by the device that 
+     * employs a shadow ROM BIOS, so that the shadow ROM mapping can be
+     * write protected once the POST is over.
+     * 
+     * @param   pDevIns     Device instance.
+     * @param   GCPhysStart Where the shadow ROM mapping starts.
+     * @param   cbRange     The size of the shadow ROM mapping.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnROMProtectShadow,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange));
+
     /** @} */
 
-    /** Just a safety precaution. (The value is 0.) */
+    /** Just a safety precaution. (PDM_DEVHLP_VERSION) */
     uint32_t                        u32TheEnd;
 } PDMDEVHLP;
@@ -2539,5 +2557,5 @@
 
 /** Current PDMDEVHLP version number. */
-#define PDM_DEVHLP_VERSION  0xf2040000
+#define PDM_DEVHLP_VERSION  0xf2050000
 
 
@@ -2998,7 +3016,15 @@
  * @copydoc PDMDEVHLP::pfnROMRegister
  */
-DECLINLINE(int) PDMDevHlpROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, const void *pvBinary, const char *pszDesc)
-{
-    return pDevIns->pDevHlp->pfnROMRegister(pDevIns, GCPhysStart, cbRange, pvBinary, pszDesc);
+DECLINLINE(int) PDMDevHlpROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, const void *pvBinary, bool fShadow, const char *pszDesc)
+{
+    return pDevIns->pDevHlp->pfnROMRegister(pDevIns, GCPhysStart, cbRange, pvBinary, fShadow, pszDesc);
+}
+
+/**
+ * @copydoc PDMDEVHLP::pfnROMProtectShadow
+ */
+DECLINLINE(int) PDMDevHlpROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange)
+{
+    return pDevIns->pDevHlp->pfnROMProtectShadow(pDevIns, GCPhysStart, cbRange);
 }
 
Index: /trunk/src/VBox/Devices/Graphics/DevVGA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 4381)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 4382)
@@ -4735,5 +4735,6 @@
     AssertReleaseMsg(g_cbVgaBiosBinary <= _64K && g_cbVgaBiosBinary >= 32*_1K, ("g_cbVgaBiosBinary=%#x\n", g_cbVgaBiosBinary));
     AssertReleaseMsg(RT_ALIGN_Z(g_cbVgaBiosBinary, PAGE_SIZE) == g_cbVgaBiosBinary, ("g_cbVgaBiosBinary=%#x\n", g_cbVgaBiosBinary));
-    rc = PDMDevHlpROMRegister(pDevIns, 0x000c0000, g_cbVgaBiosBinary, &g_abVgaBiosBinary[0], "VGA BIOS");
+    rc = PDMDevHlpROMRegister(pDevIns, 0x000c0000, g_cbVgaBiosBinary, &g_abVgaBiosBinary[0], 
+                              false /* fShadow */, "VGA BIOS");
     if (VBOX_FAILURE(rc))
         return rc;
Index: /trunk/src/VBox/Devices/PC/DevACPI.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevACPI.cpp	(revision 4381)
+++ /trunk/src/VBox/Devices/PC/DevACPI.cpp	(revision 4382)
@@ -1561,5 +1561,5 @@
         return rc;
 
-    rc = PDMDevHlpROMRegister (pDevIns, rsdp_addr, 0x1000, s->au8RSDPPage, "ACPI RSDP");
+    rc = PDMDevHlpROMRegister (pDevIns, rsdp_addr, 0x1000, s->au8RSDPPage, false /* fShadow */, "ACPI RSDP");
     if (VBOX_FAILURE (rc))
         return rc;
Index: /trunk/src/VBox/Devices/PC/DevPcBios.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevPcBios.cpp	(revision 4381)
+++ /trunk/src/VBox/Devices/PC/DevPcBios.cpp	(revision 4382)
@@ -1146,5 +1146,5 @@
         pcbiosPlantMPStable(pDevIns, pData->au8DMIPage + 0x100);
 
-    rc = PDMDevHlpROMRegister(pDevIns, VBOX_DMI_TABLE_BASE, 0x1000, pData->au8DMIPage, "DMI tables");
+    rc = PDMDevHlpROMRegister(pDevIns, VBOX_DMI_TABLE_BASE, 0x1000, pData->au8DMIPage, false /* fShadow */, "DMI tables");
     if (VBOX_FAILURE(rc))
         return rc;
@@ -1161,10 +1161,10 @@
                      ("g_cbPcBiosBinary=%#x\n", g_cbPcBiosBinary));
     cb = RT_MIN(g_cbPcBiosBinary, 128 * _1K);
-    rc = PDMDevHlpROMRegister(pDevIns, 0x00100000 - cb, cb,
-                              &g_abPcBiosBinary[g_cbPcBiosBinary - cb], "PC BIOS - 0xfffff");
+    rc = PDMDevHlpROMRegister(pDevIns, 0x00100000 - cb, cb, &g_abPcBiosBinary[g_cbPcBiosBinary - cb], 
+                              false /* fShadow */, "PC BIOS - 0xfffff");
     if (VBOX_FAILURE(rc))
         return rc;
-    rc = PDMDevHlpROMRegister(pDevIns, (uint32_t)-g_cbPcBiosBinary, g_cbPcBiosBinary,
-                              &g_abPcBiosBinary[0], "PC BIOS - 0xffffffff");
+    rc = PDMDevHlpROMRegister(pDevIns, (uint32_t)-g_cbPcBiosBinary, g_cbPcBiosBinary, &g_abPcBiosBinary[0], 
+                              false /* fShadow */, "PC BIOS - 0xffffffff");
     if (VBOX_FAILURE(rc))
         return rc;
@@ -1399,5 +1399,6 @@
      */
     if (pu8LanBoot)
-        rc = PDMDevHlpROMRegister(pDevIns, VBOX_LANBOOT_SEG << 4, cbFileLanBoot, pu8LanBoot, "Net Boot ROM");
+        rc = PDMDevHlpROMRegister(pDevIns, VBOX_LANBOOT_SEG << 4, cbFileLanBoot, pu8LanBoot, 
+                                  false /* fShadow */, "Net Boot ROM");
 
     rc = CFGMR3QueryU8(pCfgHandle, "DelayBoot", &pData->uBootDelay);
Index: /trunk/src/VBox/VMM/PDMDevice.cpp
===================================================================
--- /trunk/src/VBox/VMM/PDMDevice.cpp	(revision 4381)
+++ /trunk/src/VBox/VMM/PDMDevice.cpp	(revision 4382)
@@ -96,5 +96,5 @@
                                            const char *pszDesc);
 static DECLCALLBACK(int) pdmR3DevHlp_MMIODeregister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange);
-static DECLCALLBACK(int) pdmR3DevHlp_ROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, const void *pvBinary, const char *pszDesc);
+static DECLCALLBACK(int) pdmR3DevHlp_ROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, const void *pvBinary, bool fShadow, const char *pszDesc);
 static DECLCALLBACK(int) pdmR3DevHlp_SSMRegister(PPDMDEVINS pDevIns, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess,
                                         PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
@@ -163,4 +163,5 @@
 static DECLCALLBACK(void) pdmR3DevHlp_GetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf,
                                                uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx);
+static DECLCALLBACK(int) pdmR3DevHlp_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange);
 
 static DECLCALLBACK(PVM) pdmR3DevHlp_Untrusted_GetVM(PPDMDEVINS pDevIns);
@@ -195,5 +196,5 @@
 static DECLCALLBACK(void) pdmR3DevHlp_Untrusted_QueryCPUId(PPDMDEVINS pDevIns, uint32_t iLeaf,
                                                            uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx);
-
+static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange);
 /** @} */
 
@@ -358,4 +359,5 @@
     pdmR3DevHlp_CMOSRead,
     pdmR3DevHlp_GetCpuId,
+    pdmR3DevHlp_ROMProtectShadow,
     PDM_DEVHLP_VERSION /* the end */
 };
@@ -446,4 +448,5 @@
     pdmR3DevHlp_Untrusted_CMOSRead,
     pdmR3DevHlp_Untrusted_QueryCPUId,
+    pdmR3DevHlp_Untrusted_ROMProtectShadow,
     PDM_DEVHLP_VERSION /* the end */
 };
@@ -1478,11 +1481,12 @@
 
 /** @copydoc PDMDEVHLP::pfnROMRegister */
-static DECLCALLBACK(int) pdmR3DevHlp_ROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, const void *pvBinary, const char *pszDesc)
+static DECLCALLBACK(int) pdmR3DevHlp_ROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, const void *pvBinary, bool fShadow, const char *pszDesc)
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
     VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC);
-    LogFlow(("pdmR3DevHlp_ROMRegister: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvBinary=%p pszDesc=%p:{%s}\n",
-             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvBinary, pszDesc, pszDesc));
-
+    LogFlow(("pdmR3DevHlp_ROMRegister: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x pvBinary=%p fShadow=%RTbool pszDesc=%p:{%s}\n",
+             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange, pvBinary, fShadow, pszDesc, pszDesc));
+
+AssertReturn(!fShadow, VERR_NOT_IMPLEMENTED); /* be patient. */
     int rc = MMR3PhysRomRegister(pDevIns->Internal.s.pVMHC, pDevIns, GCPhysStart, cbRange, pvBinary, pszDesc);
 
@@ -3587,4 +3591,18 @@
 
 
+/** @copydoc PDMDEVHLP::pfnROMProtectShadow */
+static DECLCALLBACK(int) pdmR3DevHlp_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmR3DevHlp_ROMProtectShadow: caller='%s'/%d: GCPhysStart=%VGp cbRange=%#x\n",
+             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, GCPhysStart, cbRange));
+
+AssertFailed(); /* be patient. */
+    int rc = VERR_NOT_IMPLEMENTED;
+
+    LogFlow(("pdmR3DevHlp_ROMProtectShadow: caller='%s'/%d: returns %Vrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
+    return rc;
+}
+
 
 
@@ -3886,4 +3904,13 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
+}
+
+
+/** @copydoc PDMDEVHLP::pfnROMProtectShadow */
+static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_ROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    AssertReleaseMsgFailed(("Untrusted device called trusted helper! '%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
+    return VERR_ACCESS_DENIED;
 }
 
