// On the emulators, the bios at 0xf0000 is also at 0xffff0000
#define BIOS_SRC_OFFSET 0xfff00000
+union pamdata_u {
+ u8 data8[8];
+ u32 data32[2];
+};
+
// Enable shadowing and copy bios.
static void
__make_bios_writable_intel(u16 bdf, u32 pam0)
{
+ // Read in current PAM settings from pci config space
+ union pamdata_u pamdata;
+ pamdata.data32[0] = pci_config_readl(bdf, ALIGN_DOWN(pam0, 4));
+ pamdata.data32[1] = pci_config_readl(bdf, ALIGN_DOWN(pam0, 4) + 4);
+ u8 *pam = &pamdata.data8[pam0 & 0x03];
+
// Make ram from 0xc0000-0xf0000 writable
int i;
- for (i=0; i<6; i++) {
- u32 pam = pam0 + 1 + i;
- pci_config_writeb(bdf, pam, 0x33);
- }
+ for (i=0; i<6; i++)
+ pam[i + 1] = 0x33;
// Make ram from 0xf0000-0x100000 writable
- int reg = pci_config_readb(bdf, pam0);
- pci_config_writeb(bdf, pam0, 0x30);
- if (reg & 0x10)
- // Ram already present.
- return;
-
- // Copy bios.
- memcpy(VSYMBOL(code32flat_start), VSYMBOL(code32flat_start) + BIOS_SRC_OFFSET
- , SYMBOL(code32flat_end) - SYMBOL(code32flat_start));
+ int ram_present = pam[0] & 0x10;
+ pam[0] = 0x30;
+
+ // Write PAM settings back to pci config space
+ pci_config_writel(bdf, ALIGN_DOWN(pam0, 4), pamdata.data32[0]);
+ pci_config_writel(bdf, ALIGN_DOWN(pam0, 4) + 4, pamdata.data32[1]);
+
+ if (!ram_present)
+ // Copy bios.
+ memcpy(VSYMBOL(code32flat_start)
+ , VSYMBOL(code32flat_start) + BIOS_SRC_OFFSET
+ , SYMBOL(code32flat_end) - SYMBOL(code32flat_start));
}
static void
// Flush any pending writes before locking memory.
wbinvd();
+ // Read in current PAM settings from pci config space
+ union pamdata_u pamdata;
+ pamdata.data32[0] = pci_config_readl(bdf, ALIGN_DOWN(pam0, 4));
+ pamdata.data32[1] = pci_config_readl(bdf, ALIGN_DOWN(pam0, 4) + 4);
+ u8 *pam = &pamdata.data8[pam0 & 0x03];
+
// Write protect roms from 0xc0000-0xf0000
u32 romlast = BUILD_BIOS_ADDR, rommax = BUILD_BIOS_ADDR;
if (CONFIG_WRITABLE_UPPERMEMORY)
int i;
for (i=0; i<6; i++) {
u32 mem = BUILD_ROM_START + i * 32*1024;
- u32 pam = pam0 + 1 + i;
if (romlast < mem + 16*1024 || rommax < mem + 32*1024) {
if (romlast >= mem && rommax >= mem + 16*1024)
- pci_config_writeb(bdf, pam, 0x31);
+ pam[i + 1] = 0x31;
break;
}
- pci_config_writeb(bdf, pam, 0x11);
+ pam[i + 1] = 0x11;
}
// Write protect 0xf0000-0x100000
- pci_config_writeb(bdf, pam0, 0x10);
+ pam[0] = 0x10;
+
+ // Write PAM settings back to pci config space
+ pci_config_writel(bdf, ALIGN_DOWN(pam0, 4), pamdata.data32[0]);
+ pci_config_writel(bdf, ALIGN_DOWN(pam0, 4) + 4, pamdata.data32[1]);
}
static int ShadowBDF = -1;