Пример #1
0
// Enable shadowing and copy bios.
static void
__make_bios_writable_intel(u16 bdf, u32 pam0)
{
    // Make ram from 0xc0000-0xf0000 writable
    int clear = 0;
    int i;
    for (i=0; i<6; i++) {
        u32 pam = pam0 + 1 + i;
        int reg = pci_config_readb(bdf, pam);
        if (CONFIG_OPTIONROMS_DEPLOYED && (reg & 0x11) != 0x11) {
            // Need to copy optionroms to work around qemu implementation
            void *mem = (void*)(BUILD_ROM_START + i * 32*1024);
            memcpy((void*)BUILD_BIOS_TMP_ADDR, mem, 32*1024);
            pci_config_writeb(bdf, pam, 0x33);
            memcpy(mem, (void*)BUILD_BIOS_TMP_ADDR, 32*1024);
            clear = 1;
        } else {
            pci_config_writeb(bdf, pam, 0x33);
        }
    }
    if (clear)
        memset((void*)BUILD_BIOS_TMP_ADDR, 0, 32*1024);

    // Make ram from 0xf0000-0x100000 writable
    int reg = pci_config_readb(bdf, pam0);
    pci_config_writeb(bdf, pam0, 0x30);
    if (reg & 0x10)
        // Ram already present.
        return;

    // Copy bios.
    extern u8 code32flat_start[], code32flat_end[];
    memcpy(code32flat_start, code32flat_start + BIOS_SRC_OFFSET
           , code32flat_end - code32flat_start);
}
Пример #2
0
Файл: smm.c Проект: 3a9LL/panda
// This code is hardcoded for PIIX4 Power Management device.
static void piix4_apmc_smm_init(struct pci_device *pci, void *arg)
{
    struct pci_device *i440_pci = pci_find_device(PCI_VENDOR_ID_INTEL
                                                  , PCI_DEVICE_ID_INTEL_82441);
    if (!i440_pci)
        return;

    /* check if SMM init is already done */
    u32 value = pci_config_readl(pci->bdf, PIIX_DEVACTB);
    if (value & PIIX_APMC_EN)
        return;

    /* enable the SMM memory window */
    pci_config_writeb(i440_pci->bdf, I440FX_SMRAM, 0x02 | 0x48);

    smm_save_and_copy();

    /* enable SMI generation when writing to the APMC register */
    pci_config_writel(pci->bdf, PIIX_DEVACTB, value | PIIX_APMC_EN);

    smm_relocate_and_restore();

    /* close the SMM memory window and enable normal SMM */
    pci_config_writeb(i440_pci->bdf, I440FX_SMRAM, 0x02 | 0x08);
}
Пример #3
0
static void pci_bios_init_bridges(u16 bdf)
{
    u16 vendor_id = pci_config_readw(bdf, PCI_VENDOR_ID);
    u16 device_id = pci_config_readw(bdf, PCI_DEVICE_ID);

    if (vendor_id == PCI_VENDOR_ID_INTEL
        && (device_id == PCI_DEVICE_ID_INTEL_82371SB_0
            || device_id == PCI_DEVICE_ID_INTEL_82371AB_0)) {
        int i, irq;
        u8 elcr[2];

        /* PIIX3/PIIX4 PCI to ISA bridge */

        elcr[0] = 0x00;
        elcr[1] = 0x00;
        for (i = 0; i < 4; i++) {
            irq = pci_irqs[i];
            /* set to trigger level */
            elcr[irq >> 3] |= (1 << (irq & 7));
            /* activate irq remapping in PIIX */
            pci_config_writeb(bdf, 0x60 + i, irq);
        }
        outb(elcr[0], 0x4d0);
        outb(elcr[1], 0x4d1);
        dprintf(1, "PIIX3/PIIX4 init: elcr=%02x %02x\n",
                elcr[0], elcr[1]);
    }
Пример #4
0
void
make_bios_readonly_intel(u16 bdf, u32 pam0)
{
    // Flush any pending writes before locking memory.
    wbinvd();

    // Write protect roms from 0xc0000-0xf0000
    int i;
    for (i=0; i<6; i++) {
        u32 mem = BUILD_ROM_START + i * 32*1024;
        u32 pam = pam0 + 1 + i;
        if (RomEnd <= mem + 16*1024) {
            if (RomEnd > mem)
                pci_config_writeb(bdf, pam, 0x31);
            break;
        }
        pci_config_writeb(bdf, pam, 0x11);
    }

    // Write protect 0xf0000-0x100000
    pci_config_writeb(bdf, pam0, 0x10);
}
Пример #5
0
void
acpi_reboot(void)
{
    // Check it passed the sanity checks in acpi_set_reset_reg() and was set
    if (acpi_reset_reg.register_bit_width != 8)
        return;

    u64 addr = le64_to_cpu(acpi_reset_reg.address);

    dprintf(1, "ACPI hard reset %d:%llx (%x)\n",
            acpi_reset_reg.address_space_id, addr, acpi_reset_val);

    switch (acpi_reset_reg.address_space_id) {
    case 0: // System Memory
        writeb((void *)(u32)addr, acpi_reset_val);
        break;
    case 1: // System I/O
        outb(acpi_reset_val, addr);
        break;
    case 2: // PCI config space
        pci_config_writeb(acpi_ga_to_bdf(addr), addr & 0xffff, acpi_reset_val);
        break;
    }
}
Пример #6
0
void
smm_init()
{
    if (CONFIG_COREBOOT)
        // SMM only supported on emulators.
        return;
    if (!CONFIG_USE_SMM)
        return;

    dprintf(3, "init smm\n");

    // This code is hardcoded for PIIX4 Power Management device.
    int bdf = pci_find_device(PCI_VENDOR_ID_INTEL
                              , PCI_DEVICE_ID_INTEL_82371AB_3);
    if (bdf < 0)
        // Device not found
        return;
    int i440_bdf = pci_find_device(PCI_VENDOR_ID_INTEL
                                   , PCI_DEVICE_ID_INTEL_82441);
    if (i440_bdf < 0)
        return;

    /* check if SMM init is already done */
    u32 value = pci_config_readl(bdf, 0x58);
    if (value & (1 << 25))
        return;

    /* enable the SMM memory window */
    pci_config_writeb(i440_bdf, 0x72, 0x02 | 0x48);

    /* save original memory content */
    memcpy((void *)BUILD_SMM_ADDR, (void *)BUILD_SMM_INIT_ADDR, BUILD_SMM_SIZE);

    /* copy the SMM relocation code */
    memcpy((void *)BUILD_SMM_INIT_ADDR, &smm_relocation_start,
           &smm_relocation_end - &smm_relocation_start);

    /* enable SMI generation when writing to the APMC register */
    pci_config_writel(bdf, 0x58, value | (1 << 25));

    /* init APM status port */
    outb(0x01, PORT_SMI_STATUS);

    /* raise an SMI interrupt */
    outb(0x00, PORT_SMI_CMD);

    /* wait until SMM code executed */
    while (inb(PORT_SMI_STATUS) != 0x00)
        ;

    /* restore original memory content */
    memcpy((void *)BUILD_SMM_INIT_ADDR, (void *)BUILD_SMM_ADDR, BUILD_SMM_SIZE);

    /* copy the SMM code */
    memcpy((void *)BUILD_SMM_ADDR, &smm_code_start
           , &smm_code_end - &smm_code_start);
    wbinvd();

    /* close the SMM memory window and enable normal SMM */
    pci_config_writeb(i440_bdf, 0x72, 0x02 | 0x08);
}