Annotation of qemu/roms/seabios/src/shadow.c, revision 1.1.1.3

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
1.1.1.3 ! root       12: #include "dev-i440fx.h"
1.1       root       13: 
                     14: // Test if 'addr' is in the range from 'start'..'start+size'
                     15: #define IN_RANGE(addr, start, size) ({   \
                     16:             u32 __addr = (addr);         \
                     17:             u32 __start = (start);       \
                     18:             u32 __size = (size);         \
                     19:             (__addr - __start < __size); \
                     20:         })
                     21: 
                     22: // On the emulators, the bios at 0xf0000 is also at 0xffff0000
                     23: #define BIOS_SRC_ADDR 0xffff0000
                     24: 
                     25: // Enable shadowing and copy bios.
                     26: static void
1.1.1.3 ! root       27: __make_bios_writable_intel(u16 bdf, u32 pam0)
1.1       root       28: {
                     29:     // Make ram from 0xc0000-0xf0000 writable
                     30:     int clear = 0;
                     31:     int i;
                     32:     for (i=0; i<6; i++) {
1.1.1.3 ! root       33:       u32 pam = pam0 + 1 + i;
        !            34:       int reg = pci_config_readb(bdf, pam);
1.1       root       35:         if ((reg & 0x11) != 0x11) {
                     36:             // Need to copy optionroms to work around qemu implementation
                     37:             void *mem = (void*)(BUILD_ROM_START + i * 32*1024);
                     38:             memcpy((void*)BUILD_BIOS_TMP_ADDR, mem, 32*1024);
1.1.1.3 ! root       39:             pci_config_writeb(bdf, pam, 0x33);
1.1       root       40:             memcpy(mem, (void*)BUILD_BIOS_TMP_ADDR, 32*1024);
                     41:             clear = 1;
                     42:         } else {
1.1.1.3 ! root       43:             pci_config_writeb(bdf, pam, 0x33);
1.1       root       44:         }
                     45:     }
                     46:     if (clear)
                     47:         memset((void*)BUILD_BIOS_TMP_ADDR, 0, 32*1024);
                     48: 
                     49:     // Make ram from 0xf0000-0x100000 writable
1.1.1.3 ! root       50:     int reg = pci_config_readb(bdf, pam0);
        !            51:     pci_config_writeb(bdf, pam0, 0x30);
1.1       root       52:     if (reg & 0x10)
                     53:         // Ram already present.
                     54:         return;
                     55: 
                     56:     // Copy bios.
                     57:     memcpy((void*)BUILD_BIOS_ADDR, (void*)BIOS_SRC_ADDR, BUILD_BIOS_SIZE);
                     58: }
                     59: 
                     60: void
1.1.1.3 ! root       61: make_bios_writable_intel(u16 bdf, u32 pam0)
1.1       root       62: {
1.1.1.3 ! root       63:     int reg = pci_config_readb(bdf, pam0);
1.1       root       64:     if (!(reg & 0x10)) {
                     65:         // QEMU doesn't fully implement the piix shadow capabilities -
                     66:         // if ram isn't backing the bios segment when shadowing is
                     67:         // disabled, the code itself wont be in memory.  So, run the
                     68:         // code from the high-memory flash location.
1.1.1.3 ! root       69:         u32 pos = (u32)__make_bios_writable_intel - BUILD_BIOS_ADDR +
        !            70:             BIOS_SRC_ADDR;
        !            71:         void (*func)(u16 bdf, u32 pam0) = (void*)pos;
        !            72:         func(bdf, pam0);
1.1       root       73:         return;
                     74:     }
                     75:     // Ram already present - just enable writes
1.1.1.3 ! root       76:     __make_bios_writable_intel(bdf, pam0);
1.1       root       77: }
                     78: 
                     79: void
1.1.1.3 ! root       80: make_bios_readonly_intel(u16 bdf, u32 pam0)
1.1       root       81: {
                     82:     // Flush any pending writes before locking memory.
                     83:     wbinvd();
                     84: 
                     85:     // Write protect roms from 0xc0000-0xf0000
                     86:     int i;
                     87:     for (i=0; i<6; i++) {
                     88:         u32 mem = BUILD_ROM_START + i * 32*1024;
1.1.1.3 ! root       89:         u32 pam = pam0 + 1 + i;
1.1       root       90:         if (RomEnd <= mem + 16*1024) {
                     91:             if (RomEnd > mem)
1.1.1.3 ! root       92:                 pci_config_writeb(bdf, pam, 0x31);
1.1       root       93:             break;
                     94:         }
1.1.1.3 ! root       95:         pci_config_writeb(bdf, pam, 0x11);
1.1       root       96:     }
                     97: 
                     98:     // Write protect 0xf0000-0x100000
1.1.1.3 ! root       99:     pci_config_writeb(bdf, pam0, 0x10);
        !           100: }
        !           101: 
        !           102: static const struct pci_device_id dram_controller_make_writable_tbl[] = {
        !           103:     PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441,
        !           104:                i440fx_bios_make_writable),
        !           105:     PCI_DEVICE_END
        !           106: };
        !           107: 
        !           108: // Make the 0xc0000-0x100000 area read/writable.
        !           109: void
        !           110: make_bios_writable(void)
        !           111: {
        !           112:     if (CONFIG_COREBOOT)
        !           113:         return;
        !           114: 
        !           115:     dprintf(3, "enabling shadow ram\n");
        !           116: 
        !           117:     // at this point, staticlly alloacted variable can't written.
        !           118:     // so stack should be used.
        !           119: 
        !           120:     // Locate chip controlling ram shadowing.
        !           121:     int bdf = pci_find_init_device(dram_controller_make_writable_tbl, NULL);
        !           122:     if (bdf < 0) {
        !           123:         dprintf(1, "Unable to unlock ram - bridge not found\n");
        !           124:     }
        !           125: }
        !           126: 
        !           127: static const struct pci_device_id dram_controller_make_readonly_tbl[] = {
        !           128:     PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441,
        !           129:                i440fx_bios_make_readonly),
        !           130:     PCI_DEVICE_END
        !           131: };
        !           132: 
        !           133: // Make the BIOS code segment area (0xf0000) read-only.
        !           134: void
        !           135: make_bios_readonly(void)
        !           136: {
        !           137:     if (CONFIG_COREBOOT)
        !           138:         return;
        !           139: 
        !           140:     dprintf(3, "locking shadow ram\n");
        !           141:     int bdf = pci_find_init_device(dram_controller_make_readonly_tbl, NULL);
        !           142:     if (bdf < 0) {
        !           143:         dprintf(1, "Unable to lock ram - bridge not found\n");
        !           144:     }
1.1       root      145: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.