|
|
1.1 root 1: // initialization function which are specific to i440fx chipset
2: //
3: // Copyright (C) 2008 Kevin O'Connor <[email protected]>
4: // Copyright (C) 2006 Fabrice Bellard
5: //
6: // Copyright (C) 2010 Isaku Yamahata <yamahata at valinux co jp>
7: // Split out from pciinit.c
8: //
9: // This file may be distributed under the terms of the GNU LGPLv3 license.
10: //
11:
12: #include "config.h" // CONFIG_DEBUG_LEVEL
13: #include "util.h" // dprintf
14: #include "ioport.h" // outb
15: #include "pci.h" // pci_config_writeb
1.1.1.2 ! root 16: #include "pci_ids.h"
1.1 root 17: #include "pci_regs.h" // PCI_INTERRUPT_LINE
1.1.1.2 ! root 18: #include "acpi.h"
1.1 root 19: #include "dev-i440fx.h"
20:
1.1.1.2 ! root 21: #define I440FX_PAM0 0x59
! 22:
! 23: void i440fx_bios_make_writable(u16 bdf, void *arg)
! 24: {
! 25: make_bios_writable_intel(bdf, I440FX_PAM0);
! 26: }
! 27:
! 28: void i440fx_bios_make_readonly(u16 bdf, void *arg)
! 29: {
! 30: make_bios_readonly_intel(bdf, I440FX_PAM0);
! 31: }
! 32:
1.1 root 33: /* PIIX3/PIIX4 PCI to ISA bridge */
34: void piix_isa_bridge_init(u16 bdf, void *arg)
35: {
36: int i, irq;
37: u8 elcr[2];
38:
39: elcr[0] = 0x00;
40: elcr[1] = 0x00;
41: for (i = 0; i < 4; i++) {
42: irq = pci_irqs[i];
43: /* set to trigger level */
44: elcr[irq >> 3] |= (1 << (irq & 7));
45: /* activate irq remapping in PIIX */
46: pci_config_writeb(bdf, 0x60 + i, irq);
47: }
48: outb(elcr[0], 0x4d0);
49: outb(elcr[1], 0x4d1);
50: dprintf(1, "PIIX3/PIIX4 init: elcr=%02x %02x\n", elcr[0], elcr[1]);
51: }
52:
53: /* PIIX3/PIIX4 IDE */
54: void piix_ide_init(u16 bdf, void *arg)
55: {
56: pci_config_writew(bdf, 0x40, 0x8000); // enable IDE0
57: pci_config_writew(bdf, 0x42, 0x8000); // enable IDE1
58: pci_bios_allocate_regions(bdf, NULL);
59: }
60:
61: /* PIIX4 Power Management device (for ACPI) */
62: void piix4_pm_init(u16 bdf, void *arg)
63: {
64: // acpi sci is hardwired to 9
65: pci_config_writeb(bdf, PCI_INTERRUPT_LINE, 9);
66:
67: pci_config_writel(bdf, 0x40, PORT_ACPI_PM_BASE | 1);
68: pci_config_writeb(bdf, 0x80, 0x01); /* enable PM io space */
69: pci_config_writel(bdf, 0x90, PORT_SMB_BASE | 1);
70: pci_config_writeb(bdf, 0xd2, 0x09); /* enable SMBus io space */
71: }
1.1.1.2 ! root 72:
! 73: #define PIIX4_ACPI_ENABLE 0xf1
! 74: #define PIIX4_ACPI_DISABLE 0xf0
! 75: #define PIIX4_GPE0_BLK 0xafe0
! 76: #define PIIX4_GPE0_BLK_LEN 4
! 77:
! 78: void piix4_fadt_init(u16 bdf, void *arg)
! 79: {
! 80: struct fadt_descriptor_rev1 *fadt = arg;
! 81: fadt->acpi_enable = PIIX4_ACPI_ENABLE;
! 82: fadt->acpi_disable = PIIX4_ACPI_DISABLE;
! 83: fadt->gpe0_blk = cpu_to_le32(PIIX4_GPE0_BLK);
! 84: fadt->gpe0_blk_len = PIIX4_GPE0_BLK_LEN;
! 85: }
! 86:
! 87: #define I440FX_SMRAM 0x72
! 88: #define PIIX_DEVACTB 0x58
! 89: #define PIIX_APMC_EN (1 << 25)
! 90:
! 91: // This code is hardcoded for PIIX4 Power Management device.
! 92: void piix4_apmc_smm_init(u16 bdf, void *arg)
! 93: {
! 94: int i440_bdf = pci_find_device(PCI_VENDOR_ID_INTEL
! 95: , PCI_DEVICE_ID_INTEL_82441);
! 96: if (i440_bdf < 0)
! 97: return;
! 98:
! 99: /* check if SMM init is already done */
! 100: u32 value = pci_config_readl(bdf, PIIX_DEVACTB);
! 101: if (value & PIIX_APMC_EN)
! 102: return;
! 103:
! 104: /* enable the SMM memory window */
! 105: pci_config_writeb(i440_bdf, I440FX_SMRAM, 0x02 | 0x48);
! 106:
! 107: smm_save_and_copy();
! 108:
! 109: /* enable SMI generation when writing to the APMC register */
! 110: pci_config_writel(bdf, PIIX_DEVACTB, value | PIIX_APMC_EN);
! 111:
! 112: smm_relocate_and_restore();
! 113:
! 114: /* close the SMM memory window and enable normal SMM */
! 115: pci_config_writeb(i440_bdf, I440FX_SMRAM, 0x02 | 0x08);
! 116: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.