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 "dev-i440fx.h"
13 #include "xen.h" // usingXen
15 // On the emulators, the bios at 0xf0000 is also at 0xffff0000
16 #define BIOS_SRC_OFFSET 0xfff00000
18 // Enable shadowing and copy bios.
20 __make_bios_writable_intel(u16 bdf, u32 pam0)
22 // Make ram from 0xc0000-0xf0000 writable
26 u32 pam = pam0 + 1 + i;
27 int reg = pci_config_readb(bdf, pam);
28 if (CONFIG_OPTIONROMS_DEPLOYED && (reg & 0x11) != 0x11) {
29 // Need to copy optionroms to work around qemu implementation
30 void *mem = (void*)(BUILD_ROM_START + i * 32*1024);
31 memcpy((void*)BUILD_BIOS_TMP_ADDR, mem, 32*1024);
32 pci_config_writeb(bdf, pam, 0x33);
33 memcpy(mem, (void*)BUILD_BIOS_TMP_ADDR, 32*1024);
36 pci_config_writeb(bdf, pam, 0x33);
40 memset((void*)BUILD_BIOS_TMP_ADDR, 0, 32*1024);
42 // Make ram from 0xf0000-0x100000 writable
43 int reg = pci_config_readb(bdf, pam0);
44 pci_config_writeb(bdf, pam0, 0x30);
46 // Ram already present.
50 extern u8 code32flat_start[], code32flat_end[];
51 memcpy(code32flat_start, code32flat_start + BIOS_SRC_OFFSET
52 , code32flat_end - code32flat_start);
56 make_bios_writable_intel(u16 bdf, u32 pam0)
58 int reg = pci_config_readb(bdf, pam0);
60 // QEMU doesn't fully implement the piix shadow capabilities -
61 // if ram isn't backing the bios segment when shadowing is
62 // disabled, the code itself wont be in memory. So, run the
63 // code from the high-memory flash location.
64 u32 pos = (u32)__make_bios_writable_intel + BIOS_SRC_OFFSET;
65 void (*func)(u16 bdf, u32 pam0) = (void*)pos;
69 // Ram already present - just enable writes
70 __make_bios_writable_intel(bdf, pam0);
74 make_bios_readonly_intel(u16 bdf, u32 pam0)
76 // Flush any pending writes before locking memory.
79 // Write protect roms from 0xc0000-0xf0000
82 u32 mem = BUILD_ROM_START + i * 32*1024;
83 u32 pam = pam0 + 1 + i;
84 if (RomEnd <= mem + 16*1024) {
86 pci_config_writeb(bdf, pam, 0x31);
89 pci_config_writeb(bdf, pam, 0x11);
92 // Write protect 0xf0000-0x100000
93 pci_config_writeb(bdf, pam0, 0x10);
96 static const struct pci_device_id dram_controller_make_writable_tbl[] = {
97 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441,
98 i440fx_bios_make_writable),
102 // Make the 0xc0000-0x100000 area read/writable.
104 make_bios_writable(void)
106 if (CONFIG_COREBOOT || usingXen())
109 dprintf(3, "enabling shadow ram\n");
111 // at this point, statically allocated variables can't be written.
112 // so stack should be used.
114 // Locate chip controlling ram shadowing.
115 int bdf = pci_find_init_device(dram_controller_make_writable_tbl, NULL);
117 dprintf(1, "Unable to unlock ram - bridge not found\n");
121 static const struct pci_device_id dram_controller_make_readonly_tbl[] = {
122 PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441,
123 i440fx_bios_make_readonly),
127 // Make the BIOS code segment area (0xf0000) read-only.
129 make_bios_readonly(void)
131 if (CONFIG_COREBOOT || usingXen())
134 dprintf(3, "locking shadow ram\n");
135 int bdf = pci_find_init_device(dram_controller_make_readonly_tbl, NULL);
137 dprintf(1, "Unable to lock ram - bridge not found\n");
142 qemu_prep_reset(void)
146 // QEMU doesn't map 0xc0000-0xfffff back to the original rom on a
147 // reset, so do that manually before invoking a hard reset.
148 make_bios_writable();
149 extern u8 code32flat_start[], code32flat_end[];
150 memcpy(code32flat_start, code32flat_start + BIOS_SRC_OFFSET
151 , code32flat_end - code32flat_start);