~ubuntu-branches/ubuntu/saucy/seabios/saucy-proposed

« back to all changes in this revision

Viewing changes to src/smm.c

  • Committer: Bazaar Package Importer
  • Author(s): Vagrant Cascadian
  • Date: 2010-11-26 17:54:44 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20101126175444-rpdeja25wf6fjycx
Tags: 0.6.1.2-1
* New upstream version from git tag. 
  - Fixes virtio-blk failure after reboot (Closes: #604735).
* Update debian/watch file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
#include "config.h" // CONFIG_*
11
11
#include "ioport.h" // outb
12
12
#include "pci_ids.h" // PCI_VENDOR_ID_INTEL
 
13
#include "dev-i440fx.h"
13
14
 
14
15
ASM32FLAT(
15
16
    ".global smm_relocation_start\n"
73
74
extern u8 smm_code_start, smm_code_end;
74
75
 
75
76
void
76
 
smm_init(void)
 
77
smm_save_and_copy(void)
77
78
{
78
 
    if (CONFIG_COREBOOT)
79
 
        // SMM only supported on emulators.
80
 
        return;
81
 
    if (!CONFIG_USE_SMM)
82
 
        return;
83
 
 
84
 
    dprintf(3, "init smm\n");
85
 
 
86
 
    // This code is hardcoded for PIIX4 Power Management device.
87
 
    int bdf = pci_find_device(PCI_VENDOR_ID_INTEL
88
 
                              , PCI_DEVICE_ID_INTEL_82371AB_3);
89
 
    if (bdf < 0)
90
 
        // Device not found
91
 
        return;
92
 
    int i440_bdf = pci_find_device(PCI_VENDOR_ID_INTEL
93
 
                                   , PCI_DEVICE_ID_INTEL_82441);
94
 
    if (i440_bdf < 0)
95
 
        return;
96
 
 
97
 
    /* check if SMM init is already done */
98
 
    u32 value = pci_config_readl(bdf, 0x58);
99
 
    if (value & (1 << 25))
100
 
        return;
101
 
 
102
 
    /* enable the SMM memory window */
103
 
    pci_config_writeb(i440_bdf, 0x72, 0x02 | 0x48);
104
 
 
105
79
    /* save original memory content */
106
80
    memcpy((void *)BUILD_SMM_ADDR, (void *)BUILD_SMM_INIT_ADDR, BUILD_SMM_SIZE);
107
81
 
108
82
    /* copy the SMM relocation code */
109
83
    memcpy((void *)BUILD_SMM_INIT_ADDR, &smm_relocation_start,
110
84
           &smm_relocation_end - &smm_relocation_start);
111
 
 
112
 
    /* enable SMI generation when writing to the APMC register */
113
 
    pci_config_writel(bdf, 0x58, value | (1 << 25));
114
 
 
 
85
}
 
86
 
 
87
void
 
88
smm_relocate_and_restore(void)
 
89
{
115
90
    /* init APM status port */
116
91
    outb(0x01, PORT_SMI_STATUS);
117
92
 
129
104
    memcpy((void *)BUILD_SMM_ADDR, &smm_code_start
130
105
           , &smm_code_end - &smm_code_start);
131
106
    wbinvd();
132
 
 
133
 
    /* close the SMM memory window and enable normal SMM */
134
 
    pci_config_writeb(i440_bdf, 0x72, 0x02 | 0x08);
 
107
}
 
108
 
 
109
static const struct pci_device_id smm_init_tbl[] = {
 
110
    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3,
 
111
               piix4_apmc_smm_init),
 
112
 
 
113
    PCI_DEVICE_END,
 
114
};
 
115
 
 
116
void
 
117
smm_init(void)
 
118
{
 
119
    if (CONFIG_COREBOOT)
 
120
        // SMM only supported on emulators.
 
121
        return;
 
122
    if (!CONFIG_USE_SMM)
 
123
        return;
 
124
 
 
125
    dprintf(3, "init smm\n");
 
126
    pci_find_init_device(smm_init_tbl, NULL);
135
127
}