SMM for AMD K8 Part 1/2
[coreboot.git] / src / cpu / x86 / smm / smihandler.c
index bb58140c67efe1fb2a302acfdf11432f58b4ee49..bdaedf8dbcf9ad504c0955c82a21a06b7803cd5e 100644 (file)
 #include <cpu/x86/cache.h>
 #include <cpu/x86/smm.h>
 
-void southbridge_smi_set_eos(void);
-
-/* To enable SMI define DEBUG_SMI in smiutil.c */
-
 typedef enum { SMI_LOCKED, SMI_UNLOCKED } smi_semaphore;
 
 /* SMI multiprocessing semaphore */
@@ -72,7 +68,7 @@ void io_trap_handler(int smif)
        /* If a handler function handled a given IO trap, it
         * shall return a non-zero value
         */
-        printk_debug("SMI function trap 0x%x: ", smif);
+        printk(BIOS_DEBUG, "SMI function trap 0x%x: ", smif);
 
        if (southbridge_io_trap_handler(smif))
                return;
@@ -80,7 +76,7 @@ void io_trap_handler(int smif)
        if (mainboard_io_trap_handler(smif))
                return;
 
-       printk_debug("Unknown function\n");
+       printk(BIOS_DEBUG, "Unknown function\n");
 }
 
 /**
@@ -91,6 +87,24 @@ static void smi_set_eos(void)
        southbridge_smi_set_eos();
 }
 
+static u32 pci_orig;
+
+/**
+ * @brief Backup PCI address to make sure we do not mess up the OS
+ */
+static void smi_backup_pci_address(void)
+{
+       pci_orig = inl(0xcf8);
+}
+
+/**
+ * @brief Restore PCI address previously backed up
+ */
+static void smi_restore_pci_address(void)
+{
+       outl(pci_orig, 0xcf8);
+}
+
 /**
  * @brief Interrupt handler for SMI#
  *
@@ -111,11 +125,13 @@ void smi_handler(u32 smm_revision)
                return;
        }
 
+       smi_backup_pci_address();
+
        node=nodeid();
 
        console_init();
 
-       printk_spew("\nSMI# #%d\n", node);
+       printk(BIOS_SPEW, "\nSMI# #%d\n", node);
 
        switch (smm_revision) {
        case 0x00030002:
@@ -135,17 +151,15 @@ void smi_handler(u32 smm_revision)
                        (0xa8000 + 0x7e00 - (node * 0x400));
                break;
        default:
-               printk_debug("smm_revision: 0x%08x\n", smm_revision);
-               printk_debug("SMI# not supported on your CPU\n");
+               printk(BIOS_DEBUG, "smm_revision: 0x%08x\n", smm_revision);
+               printk(BIOS_DEBUG, "SMI# not supported on your CPU\n");
                /* Don't release lock, so no further SMI will happen,
                 * if we don't handle it anyways.
                 */
                return;
        }
 
-       /* Call chipset specific SMI handlers. This would be the place to
-        * add a CPU or northbridge specific SMI handler, too
-        */
+       /* Call chipset specific SMI handlers. */
        if (cpu_smi_handler)
                cpu_smi_handler(node, &state_save);
        if (northbridge_smi_handler)
@@ -153,6 +167,8 @@ void smi_handler(u32 smm_revision)
        if (southbridge_smi_handler)
                southbridge_smi_handler(node, &state_save);
 
+       smi_restore_pci_address();
+
        smi_release_lock();
 
        /* De-assert SMI# signal to allow another SMI */