1 // Support for enabling/disabling BIOS ram shadowing.
3 // Copyright (C) 2008-2010 Kevin O'Connor <kevin@koconnor.net>
4 // Copyright (C) 2006 Fabrice Bellard
6 // This file may be distributed under the terms of the GNU LGPLv3 license.
8 #include "util.h" // memcpy
9 #include "pci.h" // pci_config_writeb
10 #include "config.h" // CONFIG_*
11 #include "pci_ids.h" // PCI_VENDOR_ID_INTEL
12 #include "xen.h" // usingXen
14 // On the emulators, the bios at 0xf0000 is also at 0xffff0000
15 #define BIOS_SRC_OFFSET 0xfff00000
17 #define I440FX_PAM0 0x59
19 // Enable shadowing and copy bios.
21 __make_bios_writable_intel(u16 bdf, u32 pam0)
23 // Make ram from 0xc0000-0xf0000 writable
27 u32 pam = pam0 + 1 + i;
28 int reg = pci_config_readb(bdf, pam);
29 if (CONFIG_OPTIONROMS_DEPLOYED && (reg & 0x11) != 0x11) {
30 // Need to copy optionroms to work around qemu implementation
31 void *mem = (void*)(BUILD_ROM_START + i * 32*1024);
32 memcpy((void*)BUILD_BIOS_TMP_ADDR, mem, 32*1024);
33 pci_config_writeb(bdf, pam, 0x33);
34 memcpy(mem, (void*)BUILD_BIOS_TMP_ADDR, 32*1024);
37 pci_config_writeb(bdf, pam, 0x33);
41 memset((void*)BUILD_BIOS_TMP_ADDR, 0, 32*1024);
43 // Make ram from 0xf0000-0x100000 writable
44 int reg = pci_config_readb(bdf, pam0);
45 pci_config_writeb(bdf, pam0, 0x30);
47 // Ram already present.
51 extern u8 code32flat_start[], code32flat_end[];
52 memcpy(code32flat_start, code32flat_start + BIOS_SRC_OFFSET
53 , code32flat_end - code32flat_start);
57 make_bios_writable_intel(u16 bdf, u32 pam0)
59 int reg = pci_config_readb(bdf, pam0);
61 // QEMU doesn't fully implement the piix shadow capabilities -
62 // if ram isn't backing the bios segment when shadowing is
63 // disabled, the code itself wont be in memory. So, run the
64 // code from the high-memory flash location.
65 u32 pos = (u32)__make_bios_writable_intel + BIOS_SRC_OFFSET;
66 void (*func)(u16 bdf, u32 pam0) = (void*)pos;
70 // Ram already present - just enable writes
71 __make_bios_writable_intel(bdf, pam0);
75 make_bios_readonly_intel(u16 bdf, u32 pam0)
77 // Flush any pending writes before locking memory.
80 // Write protect roms from 0xc0000-0xf0000
83 u32 mem = BUILD_ROM_START + i * 32*1024;
84 u32 pam = pam0 + 1 + i;
85 if (RomEnd <= mem + 16*1024) {
87 pci_config_writeb(bdf, pam, 0x31);
90 pci_config_writeb(bdf, pam, 0x11);
93 // Write protect 0xf0000-0x100000
94 pci_config_writeb(bdf, pam0, 0x10);
97 static void i440fx_bios_make_writable(u16 bdf, void *arg)
99 make_bios_writable_intel(bdf, I440FX_PAM0);
102 static void i440fx_bios_make_readonly(u16 bdf, void *arg)
104 make_bios_readonly_intel(bdf, I440FX_PAM0);
107 static const struct pci_device_id dram_controller_make_writable_tbl[] = {
108 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441,
109 i440fx_bios_make_writable),
113 static const struct pci_device_id dram_controller_make_readonly_tbl[] = {
114 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441,
115 i440fx_bios_make_readonly),
119 // Make the 0xc0000-0x100000 area read/writable.
121 make_bios_writable(void)
123 if (CONFIG_COREBOOT || usingXen())
126 dprintf(3, "enabling shadow ram\n");
128 // at this point, statically allocated variables can't be written.
129 // so stack should be used.
131 // Locate chip controlling ram shadowing.
132 int bdf = pci_find_init_device(dram_controller_make_writable_tbl, NULL);
134 dprintf(1, "Unable to unlock ram - bridge not found\n");
138 // Make the BIOS code segment area (0xf0000) read-only.
140 make_bios_readonly(void)
142 if (CONFIG_COREBOOT || usingXen())
145 dprintf(3, "locking shadow ram\n");
146 int bdf = pci_find_init_device(dram_controller_make_readonly_tbl, NULL);
148 dprintf(1, "Unable to lock ram - bridge not found\n");
153 qemu_prep_reset(void)
157 // QEMU doesn't map 0xc0000-0xfffff back to the original rom on a
158 // reset, so do that manually before invoking a hard reset.
159 make_bios_writable();
160 extern u8 code32flat_start[], code32flat_end[];
161 memcpy(code32flat_start, code32flat_start + BIOS_SRC_OFFSET
162 , code32flat_end - code32flat_start);