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

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

unix.superglobalmegacorp.com

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