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

1.1       root        1: // Support for enabling/disabling BIOS ram shadowing.
                      2: //
1.1.1.4   root        3: // Copyright (C) 2008-2010  Kevin O'Connor <[email protected]>
1.1       root        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.5 ! root       12: #include "pci_regs.h" // PCI_VENDOR_ID
        !            13: #include "xen.h" // usingXen
1.1       root       14: 
                     15: // On the emulators, the bios at 0xf0000 is also at 0xffff0000
1.1.1.4   root       16: #define BIOS_SRC_OFFSET 0xfff00000
1.1       root       17: 
1.1.1.5 ! root       18: #define I440FX_PAM0     0x59
        !            19: 
1.1       root       20: // Enable shadowing and copy bios.
                     21: static void
1.1.1.3   root       22: __make_bios_writable_intel(u16 bdf, u32 pam0)
1.1       root       23: {
                     24:     // Make ram from 0xc0000-0xf0000 writable
                     25:     int clear = 0;
                     26:     int i;
                     27:     for (i=0; i<6; i++) {
1.1.1.4   root       28:         u32 pam = pam0 + 1 + i;
                     29:         int reg = pci_config_readb(bdf, pam);
                     30:         if (CONFIG_OPTIONROMS_DEPLOYED && (reg & 0x11) != 0x11) {
1.1       root       31:             // Need to copy optionroms to work around qemu implementation
                     32:             void *mem = (void*)(BUILD_ROM_START + i * 32*1024);
                     33:             memcpy((void*)BUILD_BIOS_TMP_ADDR, mem, 32*1024);
1.1.1.3   root       34:             pci_config_writeb(bdf, pam, 0x33);
1.1       root       35:             memcpy(mem, (void*)BUILD_BIOS_TMP_ADDR, 32*1024);
                     36:             clear = 1;
                     37:         } else {
1.1.1.3   root       38:             pci_config_writeb(bdf, pam, 0x33);
1.1       root       39:         }
                     40:     }
                     41:     if (clear)
                     42:         memset((void*)BUILD_BIOS_TMP_ADDR, 0, 32*1024);
                     43: 
                     44:     // Make ram from 0xf0000-0x100000 writable
1.1.1.3   root       45:     int reg = pci_config_readb(bdf, pam0);
                     46:     pci_config_writeb(bdf, pam0, 0x30);
1.1       root       47:     if (reg & 0x10)
                     48:         // Ram already present.
                     49:         return;
                     50: 
                     51:     // Copy bios.
1.1.1.4   root       52:     extern u8 code32flat_start[], code32flat_end[];
                     53:     memcpy(code32flat_start, code32flat_start + BIOS_SRC_OFFSET
                     54:            , code32flat_end - code32flat_start);
1.1       root       55: }
                     56: 
1.1.1.5 ! root       57: static void
1.1.1.3   root       58: make_bios_writable_intel(u16 bdf, u32 pam0)
1.1       root       59: {
1.1.1.3   root       60:     int reg = pci_config_readb(bdf, pam0);
1.1       root       61:     if (!(reg & 0x10)) {
                     62:         // QEMU doesn't fully implement the piix shadow capabilities -
                     63:         // if ram isn't backing the bios segment when shadowing is
                     64:         // disabled, the code itself wont be in memory.  So, run the
                     65:         // code from the high-memory flash location.
1.1.1.4   root       66:         u32 pos = (u32)__make_bios_writable_intel + BIOS_SRC_OFFSET;
1.1.1.3   root       67:         void (*func)(u16 bdf, u32 pam0) = (void*)pos;
                     68:         func(bdf, pam0);
1.1       root       69:         return;
                     70:     }
                     71:     // Ram already present - just enable writes
1.1.1.3   root       72:     __make_bios_writable_intel(bdf, pam0);
1.1       root       73: }
                     74: 
1.1.1.5 ! root       75: static void
1.1.1.3   root       76: make_bios_readonly_intel(u16 bdf, u32 pam0)
1.1       root       77: {
                     78:     // Flush any pending writes before locking memory.
                     79:     wbinvd();
                     80: 
                     81:     // Write protect roms from 0xc0000-0xf0000
                     82:     int i;
                     83:     for (i=0; i<6; i++) {
                     84:         u32 mem = BUILD_ROM_START + i * 32*1024;
1.1.1.3   root       85:         u32 pam = pam0 + 1 + i;
1.1       root       86:         if (RomEnd <= mem + 16*1024) {
                     87:             if (RomEnd > mem)
1.1.1.3   root       88:                 pci_config_writeb(bdf, pam, 0x31);
1.1       root       89:             break;
                     90:         }
1.1.1.3   root       91:         pci_config_writeb(bdf, pam, 0x11);
1.1       root       92:     }
                     93: 
                     94:     // Write protect 0xf0000-0x100000
1.1.1.3   root       95:     pci_config_writeb(bdf, pam0, 0x10);
                     96: }
                     97: 
1.1.1.5 ! root       98: static void i440fx_bios_make_readonly(struct pci_device *pci, void *arg)
        !            99: {
        !           100:     make_bios_readonly_intel(pci->bdf, I440FX_PAM0);
        !           101: }
        !           102: 
        !           103: static const struct pci_device_id dram_controller_make_readonly_tbl[] = {
1.1.1.3   root      104:     PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441,
1.1.1.5 ! root      105:                i440fx_bios_make_readonly),
1.1.1.3   root      106:     PCI_DEVICE_END
                    107: };
                    108: 
                    109: // Make the 0xc0000-0x100000 area read/writable.
                    110: void
                    111: make_bios_writable(void)
                    112: {
1.1.1.5 ! root      113:     if (CONFIG_COREBOOT || usingXen())
1.1.1.3   root      114:         return;
                    115: 
                    116:     dprintf(3, "enabling shadow ram\n");
                    117: 
1.1.1.5 ! root      118:     // At this point, statically allocated variables can't be written,
        !           119:     // so do this search manually.
        !           120:     int bdf;
        !           121:     foreachbdf(bdf, 0) {
        !           122:         u32 vendev = pci_config_readl(bdf, PCI_VENDOR_ID);
        !           123:         u16 vendor = vendev & 0xffff, device = vendev >> 16;
        !           124:         if (vendor == PCI_VENDOR_ID_INTEL
        !           125:             && device == PCI_DEVICE_ID_INTEL_82441) {
        !           126:             make_bios_writable_intel(bdf, I440FX_PAM0);
        !           127:             return;
        !           128:         }
1.1.1.3   root      129:     }
1.1.1.5 ! root      130:     dprintf(1, "Unable to unlock ram - bridge not found\n");
1.1.1.3   root      131: }
                    132: 
                    133: // Make the BIOS code segment area (0xf0000) read-only.
                    134: void
                    135: make_bios_readonly(void)
                    136: {
1.1.1.5 ! root      137:     if (CONFIG_COREBOOT || usingXen())
1.1.1.3   root      138:         return;
                    139: 
                    140:     dprintf(3, "locking shadow ram\n");
1.1.1.5 ! root      141:     struct pci_device *pci = pci_find_init_device(
        !           142:         dram_controller_make_readonly_tbl, NULL);
        !           143:     if (!pci)
1.1.1.3   root      144:         dprintf(1, "Unable to lock ram - bridge not found\n");
1.1       root      145: }
1.1.1.4   root      146: 
                    147: void
                    148: qemu_prep_reset(void)
                    149: {
                    150:     if (CONFIG_COREBOOT)
                    151:         return;
                    152:     // QEMU doesn't map 0xc0000-0xfffff back to the original rom on a
                    153:     // reset, so do that manually before invoking a hard reset.
                    154:     make_bios_writable();
                    155:     extern u8 code32flat_start[], code32flat_end[];
                    156:     memcpy(code32flat_start, code32flat_start + BIOS_SRC_OFFSET
                    157:            , code32flat_end - code32flat_start);
                    158: }

unix.superglobalmegacorp.com

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