Annotation of qemu/roms/seabios/src/smm.c, revision 1.1.1.3

1.1       root        1: // System Management Mode support (on emulators)
                      2: //
                      3: // Copyright (C) 2008  Kevin O'Connor <[email protected]>
                      4: // Copyright (C) 2006 Fabrice Bellard
                      5: //
                      6: // This file may be distributed under the terms of the GNU LGPLv3 license.
                      7: 
                      8: #include "pci.h" // pci_config_writel
                      9: #include "util.h" // wbinvd
                     10: #include "config.h" // CONFIG_*
                     11: #include "ioport.h" // outb
                     12: #include "pci_ids.h" // PCI_VENDOR_ID_INTEL
1.1.1.3 ! root       13: #include "dev-i440fx.h"
1.1       root       14: 
1.1.1.2   root       15: ASM32FLAT(
1.1       root       16:     ".global smm_relocation_start\n"
                     17:     ".global smm_relocation_end\n"
                     18:     ".global smm_code_start\n"
                     19:     ".global smm_code_end\n"
                     20:     "  .code16\n"
                     21: 
                     22:     /* code to relocate SMBASE to 0xa0000 */
                     23:     "smm_relocation_start:\n"
                     24:     "  mov $" __stringify(BUILD_SMM_INIT_ADDR) " + 0x7efc, %ebx\n"
                     25:     "  addr32 mov (%ebx), %al\n"  /* revision ID to see if x86_64 or x86 */
                     26:     "  cmp $0x64, %al\n"
                     27:     "  je 1f\n"
                     28:     "  mov $" __stringify(BUILD_SMM_INIT_ADDR) " + 0x7ef8, %ebx\n"
                     29:     "  jmp 2f\n"
                     30:     "1:\n"
                     31:     "  mov $" __stringify(BUILD_SMM_INIT_ADDR) " + 0x7f00, %ebx\n"
                     32:     "2:\n"
                     33:     "  movl $" __stringify(BUILD_SMM_ADDR) " - 0x8000, %eax\n"
                     34:     "  addr32 movl %eax, (%ebx)\n"
                     35:     /* indicate to the BIOS that the SMM code was executed */
                     36:     "  mov $0x00, %al\n"
                     37:     "  movw $" __stringify(PORT_SMI_STATUS) ", %dx\n"
                     38:     "  outb %al, %dx\n"
                     39:     "  rsm\n"
                     40:     "smm_relocation_end:\n"
                     41: 
                     42:     /* minimal SMM code to enable or disable ACPI */
                     43:     "smm_code_start:\n"
                     44:     "  movw $" __stringify(PORT_SMI_CMD) ", %dx\n"
                     45:     "  inb %dx, %al\n"
                     46:     "  cmp $0xf0, %al\n"
                     47:     "  jne 1f\n"
                     48: 
                     49:     /* ACPI disable */
                     50:     "  mov $" __stringify(PORT_ACPI_PM_BASE) " + 0x04, %dx\n" /* PMCNTRL */
                     51:     "  inw %dx, %ax\n"
                     52:     "  andw $~1, %ax\n"
                     53:     "  outw %ax, %dx\n"
                     54: 
                     55:     "  jmp 2f\n"
                     56: 
                     57:     "1:\n"
                     58:     "  cmp $0xf1, %al\n"
                     59:     "  jne 2f\n"
                     60: 
                     61:     /* ACPI enable */
                     62:     "  mov $" __stringify(PORT_ACPI_PM_BASE) " + 0x04, %dx\n" /* PMCNTRL */
                     63:     "  inw %dx, %ax\n"
                     64:     "  orw $1, %ax\n"
                     65:     "  outw %ax, %dx\n"
                     66: 
                     67:     "2:\n"
                     68:     "  rsm\n"
                     69:     "smm_code_end:\n"
                     70:     "  .code32\n"
                     71:     );
                     72: 
                     73: extern u8 smm_relocation_start, smm_relocation_end;
                     74: extern u8 smm_code_start, smm_code_end;
                     75: 
                     76: void
1.1.1.3 ! root       77: smm_save_and_copy(void)
1.1       root       78: {
                     79:     /* save original memory content */
                     80:     memcpy((void *)BUILD_SMM_ADDR, (void *)BUILD_SMM_INIT_ADDR, BUILD_SMM_SIZE);
                     81: 
                     82:     /* copy the SMM relocation code */
                     83:     memcpy((void *)BUILD_SMM_INIT_ADDR, &smm_relocation_start,
                     84:            &smm_relocation_end - &smm_relocation_start);
1.1.1.3 ! root       85: }
1.1       root       86: 
1.1.1.3 ! root       87: void
        !            88: smm_relocate_and_restore(void)
        !            89: {
1.1       root       90:     /* init APM status port */
                     91:     outb(0x01, PORT_SMI_STATUS);
                     92: 
                     93:     /* raise an SMI interrupt */
                     94:     outb(0x00, PORT_SMI_CMD);
                     95: 
                     96:     /* wait until SMM code executed */
                     97:     while (inb(PORT_SMI_STATUS) != 0x00)
                     98:         ;
                     99: 
                    100:     /* restore original memory content */
                    101:     memcpy((void *)BUILD_SMM_INIT_ADDR, (void *)BUILD_SMM_ADDR, BUILD_SMM_SIZE);
                    102: 
                    103:     /* copy the SMM code */
                    104:     memcpy((void *)BUILD_SMM_ADDR, &smm_code_start
                    105:            , &smm_code_end - &smm_code_start);
                    106:     wbinvd();
1.1.1.3 ! root      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;
1.1       root      124: 
1.1.1.3 ! root      125:     dprintf(3, "init smm\n");
        !           126:     pci_find_init_device(smm_init_tbl, NULL);
1.1       root      127: }

unix.superglobalmegacorp.com

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