|
|
1.1 root 1: // Support for enabling/disabling BIOS ram shadowing.
2: //
3: // Copyright (C) 2008,2009 Kevin O'Connor <[email protected]>
4: // Copyright (C) 2006 Fabrice Bellard
5: //
6: // This file may be distributed under the terms of the GNU LGPLv3 license.
7:
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:
13: // Test if 'addr' is in the range from 'start'..'start+size'
14: #define IN_RANGE(addr, start, size) ({ \
15: u32 __addr = (addr); \
16: u32 __start = (start); \
17: u32 __size = (size); \
18: (__addr - __start < __size); \
19: })
20:
21: // On the emulators, the bios at 0xf0000 is also at 0xffff0000
22: #define BIOS_SRC_ADDR 0xffff0000
23:
24: // Enable shadowing and copy bios.
25: static void
26: __make_bios_writable(u16 bdf)
27: {
28: // Make ram from 0xc0000-0xf0000 writable
29: int clear = 0;
30: int i;
31: for (i=0; i<6; i++) {
32: int reg = pci_config_readb(bdf, 0x5a + i);
33: if ((reg & 0x11) != 0x11) {
34: // Need to copy optionroms to work around qemu implementation
35: void *mem = (void*)(BUILD_ROM_START + i * 32*1024);
36: memcpy((void*)BUILD_BIOS_TMP_ADDR, mem, 32*1024);
37: pci_config_writeb(bdf, 0x5a + i, 0x33);
38: memcpy(mem, (void*)BUILD_BIOS_TMP_ADDR, 32*1024);
39: clear = 1;
40: } else {
41: pci_config_writeb(bdf, 0x5a + i, 0x33);
42: }
43: }
44: if (clear)
45: memset((void*)BUILD_BIOS_TMP_ADDR, 0, 32*1024);
46:
47: // Make ram from 0xf0000-0x100000 writable
48: int reg = pci_config_readb(bdf, 0x59);
49: pci_config_writeb(bdf, 0x59, 0x30);
50: if (reg & 0x10)
51: // Ram already present.
52: return;
53:
54: // Copy bios.
55: memcpy((void*)BUILD_BIOS_ADDR, (void*)BIOS_SRC_ADDR, BUILD_BIOS_SIZE);
56: }
57:
58: // Make the 0xc0000-0x100000 area read/writable.
59: void
1.1.1.2 ! root 60: make_bios_writable(void)
1.1 root 61: {
62: if (CONFIG_COREBOOT)
63: return;
64:
65: dprintf(3, "enabling shadow ram\n");
66:
67: // Locate chip controlling ram shadowing.
68: int bdf = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441);
69: if (bdf < 0) {
70: dprintf(1, "Unable to unlock ram - bridge not found\n");
71: return;
72: }
73:
74: int reg = pci_config_readb(bdf, 0x59);
75: if (!(reg & 0x10)) {
76: // QEMU doesn't fully implement the piix shadow capabilities -
77: // if ram isn't backing the bios segment when shadowing is
78: // disabled, the code itself wont be in memory. So, run the
79: // code from the high-memory flash location.
80: u32 pos = (u32)__make_bios_writable - BUILD_BIOS_ADDR + BIOS_SRC_ADDR;
81: void (*func)(u16 bdf) = (void*)pos;
82: func(bdf);
83: return;
84: }
85: // Ram already present - just enable writes
86: __make_bios_writable(bdf);
87: }
88:
89: // Make the BIOS code segment area (0xf0000) read-only.
90: void
1.1.1.2 ! root 91: make_bios_readonly(void)
1.1 root 92: {
93: if (CONFIG_COREBOOT)
94: return;
95:
96: dprintf(3, "locking shadow ram\n");
97:
98: int bdf = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441);
99: if (bdf < 0) {
100: dprintf(1, "Unable to lock ram - bridge not found\n");
101: return;
102: }
103:
104: // Flush any pending writes before locking memory.
105: wbinvd();
106:
107: // Write protect roms from 0xc0000-0xf0000
108: int i;
109: for (i=0; i<6; i++) {
110: u32 mem = BUILD_ROM_START + i * 32*1024;
111: if (RomEnd <= mem + 16*1024) {
112: if (RomEnd > mem)
113: pci_config_writeb(bdf, 0x5a + i, 0x31);
114: break;
115: }
116: pci_config_writeb(bdf, 0x5a + i, 0x11);
117: }
118:
119: // Write protect 0xf0000-0x100000
120: pci_config_writeb(bdf, 0x59, 0x10);
121: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.