remove trailing whitespace
[coreboot.git] / src / cpu / amd / model_fxx / model_fxx_init.c
index 8b680980192cf1f036fd54762736a65cfe1ea3f4..ae5429d05d7493005da77730f771ad734fb82e5a 100644 (file)
@@ -5,8 +5,9 @@
  * 2005.02 yhlu add e0 memory hole support
 
  * Copyright 2005 AMD
- * 2005.08 yhlu add microcode support 
-*/
+ * 2005.08 yhlu add microcode support
+ */
+
 #include <console/console.h>
 #include <cpu/x86/msr.h>
 #include <cpu/amd/mtrr.h>
 #include <cpu/x86/pae.h>
 #include <pc80/mc146818rtc.h>
 #include <cpu/x86/lapic.h>
-
-#include "../../../northbridge/amd/amdk8/amdk8.h"
-
+#include "northbridge/amd/amdk8/amdk8.h"
 #include <cpu/amd/model_fxx_rev.h>
+#include <cpu/amd/microcode.h>
 #include <cpu/cpu.h>
 #include <cpu/x86/cache.h>
 #include <cpu/x86/mtrr.h>
-#include <cpu/x86/mem.h>
-
-#include <cpu/amd/dualcore.h>
-
+#include <cpu/x86/smm.h>
+#include <cpu/amd/multicore.h>
 #include <cpu/amd/model_fxx_msr.h>
 
+#if CONFIG_WAIT_BEFORE_CPUS_INIT
 void cpus_ready_for_init(void)
 {
 #if CONFIG_MEM_TRAIN_SEQ == 1
@@ -38,77 +37,78 @@ void cpus_ready_for_init(void)
         wait_all_core0_mem_trained(sysinfox);
 #endif
 }
-
+#endif
 
 #if CONFIG_K8_REV_F_SUPPORT == 0
 int is_e0_later_in_bsp(int nodeid)
 {
-        uint32_t val;
-        uint32_t val_old;
-        int e0_later;
-        if(nodeid==0) { // we don't need to do that for node 0 in core0/node0
-                return !is_cpu_pre_e0();
-        }
-        // d0 will be treated as e0 with this methods, but the d0 nb_cfg_54 always 0
-        device_t dev;
-        dev = dev_find_slot(0, PCI_DEVFN(0x18+nodeid,2));
-        if(!dev) return 0;
-        val_old = pci_read_config32(dev, 0x80);
-        val = val_old;
-        val |= (1<<3);
-        pci_write_config32(dev, 0x80, val);
-        val = pci_read_config32(dev, 0x80);
-        e0_later = !!(val & (1<<3));
-        if(e0_later) { // pre_e0 bit 3 always be 0 and can not be changed
-                pci_write_config32(dev, 0x80, val_old); // restore it
-        }
-
-        return e0_later;
+       uint32_t val;
+       uint32_t val_old;
+       int e0_later;
+       if (nodeid == 0) {      // we don't need to do that for node 0 in core0/node0
+               return !is_cpu_pre_e0();
+       }
+       // d0 will be treated as e0 with this methods, but the d0 nb_cfg_54 always 0
+       device_t dev;
+       dev = dev_find_slot(0, PCI_DEVFN(0x18 + nodeid, 2));
+       if (!dev)
+               return 0;
+       val_old = pci_read_config32(dev, 0x80);
+       val = val_old;
+       val |= (1 << 3);
+       pci_write_config32(dev, 0x80, val);
+       val = pci_read_config32(dev, 0x80);
+       e0_later = !!(val & (1 << 3));
+       if (e0_later) {         // pre_e0 bit 3 always be 0 and can not be changed
+               pci_write_config32(dev, 0x80, val_old); // restore it
+       }
+
+       return e0_later;
 }
 #endif
 
 #if CONFIG_K8_REV_F_SUPPORT == 1
 int is_cpu_f0_in_bsp(int nodeid)
 {
-        uint32_t dword;
-        device_t dev;
-        dev = dev_find_slot(0, PCI_DEVFN(0x18+nodeid, 3));
-        dword = pci_read_config32(dev, 0xfc);
-        return (dword & 0xfff00) == 0x40f00;
+       uint32_t dword;
+       device_t dev;
+       dev = dev_find_slot(0, PCI_DEVFN(0x18 + nodeid, 3));
+       dword = pci_read_config32(dev, 0xfc);
+       return (dword & 0xfff00) == 0x40f00;
 }
 #endif
 
 #define MCI_STATUS 0x401
 
-static inline msr_t rdmsr_amd(unsigned index)
+static inline msr_t rdmsr_amd(u32 index)
 {
-        msr_t result;
-        __asm__ __volatile__ (
-                "rdmsr"
-                : "=a" (result.lo), "=d" (result.hi)
-                : "c" (index), "D" (0x9c5a203a)
-                );
-        return result;
+       msr_t result;
+       __asm__ __volatile__(
+               "rdmsr"
+               :"=a"(result.lo), "=d"(result.hi)
+               :"c"(index), "D"(0x9c5a203a)
+       );
+       return result;
 }
 
-static inline void wrmsr_amd(unsigned index, msr_t msr)
+static inline void wrmsr_amd(u32 index, msr_t msr)
 {
-        __asm__ __volatile__ (
-                "wrmsr"
-                : /* No outputs */
-                : "c" (index), "a" (msr.lo), "d" (msr.hi), "D" (0x9c5a203a)
-                );
+       __asm__ __volatile__(
+               "wrmsr"
+               :       /* No outputs */
+               :"c"(index), "a"(msr.lo), "d"(msr.hi), "D"(0x9c5a203a)
+       );
 }
 
-
 #define MTRR_COUNT 8
-#define ZERO_CHUNK_KB 0x800UL /* 2M */
+#define ZERO_CHUNK_KB 0x800UL  /* 2M */
 #define TOLM_KB 0x400000UL
 
 struct mtrr {
        msr_t base;
        msr_t mask;
 };
+
 struct mtrr_state {
        struct mtrr mtrrs[MTRR_COUNT];
        msr_t top_mem, top_mem2;
@@ -118,11 +118,11 @@ struct mtrr_state {
 static void save_mtrr_state(struct mtrr_state *state)
 {
        int i;
-       for(i = 0; i < MTRR_COUNT; i++) {
+       for (i = 0; i < MTRR_COUNT; i++) {
                state->mtrrs[i].base = rdmsr(MTRRphysBase_MSR(i));
                state->mtrrs[i].mask = rdmsr(MTRRphysMask_MSR(i));
        }
-       state->top_mem  = rdmsr(TOP_MEM);
+       state->top_mem = rdmsr(TOP_MEM);
        state->top_mem2 = rdmsr(TOP_MEM2);
        state->def_type = rdmsr(MTRRdefType_MSR);
 }
@@ -132,34 +132,33 @@ static void restore_mtrr_state(struct mtrr_state *state)
        int i;
        disable_cache();
 
-       for(i = 0; i < MTRR_COUNT; i++) {
+       for (i = 0; i < MTRR_COUNT; i++) {
                wrmsr(MTRRphysBase_MSR(i), state->mtrrs[i].base);
                wrmsr(MTRRphysMask_MSR(i), state->mtrrs[i].mask);
        }
-       wrmsr(TOP_MEM,         state->top_mem);
-       wrmsr(TOP_MEM2,        state->top_mem2);
+       wrmsr(TOP_MEM, state->top_mem);
+       wrmsr(TOP_MEM2, state->top_mem2);
        wrmsr(MTRRdefType_MSR, state->def_type);
 
        enable_cache();
 }
 
-
 #if 0
 static void print_mtrr_state(struct mtrr_state *state)
 {
        int i;
-       for(i = 0; i < MTRR_COUNT; i++) {
-               printk_debug("var mtrr %d: %08x%08x mask: %08x%08x\n",
-                       i,
-                       state->mtrrs[i].base.hi, state->mtrrs[i].base.lo,
-                       state->mtrrs[i].mask.hi, state->mtrrs[i].mask.lo);
+       for (i = 0; i < MTRR_COUNT; i++) {
+               printk(BIOS_DEBUG, "var mtrr %d: %08x%08x mask: %08x%08x\n",
+                      i,
+                      state->mtrrs[i].base.hi, state->mtrrs[i].base.lo,
+                      state->mtrrs[i].mask.hi, state->mtrrs[i].mask.lo);
        }
-       printk_debug("top_mem:  %08x%08x\n",
-               state->top_mem.hi, state->top_mem.lo);
-       printk_debug("top_mem2: %08x%08x\n",
-               state->top_mem2.hi, state->top_mem2.lo);
-       printk_debug("def_type: %08x%08x\n",
-               state->def_type.hi, state->def_type.lo);
+       printk(BIOS_DEBUG, "top_mem:  %08x%08x\n",
+              state->top_mem.hi, state->top_mem.lo);
+       printk(BIOS_DEBUG, "top_mem2: %08x%08x\n",
+              state->top_mem2.hi, state->top_mem2.lo);
+       printk(BIOS_DEBUG, "def_type: %08x%08x\n",
+              state->def_type.hi, state->def_type.lo);
 }
 #endif
 
@@ -170,7 +169,7 @@ static void set_init_ecc_mtrrs(void)
        disable_cache();
 
        /* First clear all of the msrs to be safe */
-       for(i = 0; i < MTRR_COUNT; i++) {
+       for (i = 0; i < MTRR_COUNT; i++) {
                msr_t zero;
                zero.lo = zero.hi = 0;
                wrmsr(MTRRphysBase_MSR(i), zero);
@@ -198,52 +197,52 @@ static void set_init_ecc_mtrrs(void)
        enable_cache();
 }
 
-static inline void clear_2M_ram(unsigned long basek, struct mtrr_state *mtrr_state) 
+static inline void clear_2M_ram(unsigned long basek,
+                               struct mtrr_state *mtrr_state)
 {
-                unsigned long limitk;
-                unsigned long size;
-                void *addr;
+       unsigned long limitk;
+       unsigned long size;
+       void *addr;
 
-                /* Report every 64M */
-                if ((basek % (64*1024)) == 0) {
+       /* Report every 64M */
+       if ((basek % (64 * 1024)) == 0) {
 
-                        /* Restore the normal state */
-                        map_2M_page(0);
-                        restore_mtrr_state(mtrr_state);
-                        enable_lapic();
+               /* Restore the normal state */
+               map_2M_page(0);
+               restore_mtrr_state(mtrr_state);
+               enable_lapic();
 
-                        /* Print a status message */
-                        printk_debug("%c", (basek >= TOLM_KB)?'+':'-');
+               /* Print a status message */
+               printk(BIOS_DEBUG, "%c", (basek >= TOLM_KB) ? '+' : '-');
 
-                        /* Return to the initialization state */
-                        set_init_ecc_mtrrs();
-                        disable_lapic();
+               /* Return to the initialization state */
+               set_init_ecc_mtrrs();
+               disable_lapic();
 
-                }
+       }
 
-                limitk = (basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1);
+       limitk = (basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1);
 #if 0
-               /* couldn't happen, memory must on 2M boundary */
-               if(limitk>endk) {
-                       limitk = enk; 
-               }
+       /* couldn't happen, memory must on 2M boundary */
+       if (limitk > endk) {
+               limitk = enk;
+       }
 #endif
-                size = (limitk - basek) << 10;
-                addr = map_2M_page(basek >> 11);
-                if (addr == MAPPING_ERROR) {
-                        printk_err("Cannot map page: %lx\n", basek >> 11);
-                        return;
-                }
-
-                /* clear memory 2M (limitk - basek) */
-                addr = (void *)(((uint32_t)addr) | ((basek & 0x7ff) << 10));
-                clear_memory(addr, size);
+       size = (limitk - basek) << 10;
+       addr = map_2M_page(basek >> 11);
+       if (addr == MAPPING_ERROR) {
+               printk(BIOS_ERR, "Cannot map page: %lx\n", basek >> 11);
+               return;
+       }
+
+       /* clear memory 2M (limitk - basek) */
+       addr = (void *)(((uint32_t) addr) | ((basek & 0x7ff) << 10));
+       memset(addr, 0, size);
 }
 
 static void init_ecc_memory(unsigned node_id)
 {
        unsigned long startk, begink, endk;
-       unsigned long hole_startk = 0;
        unsigned long basek;
        struct mtrr_state mtrr_state;
 
@@ -266,53 +265,60 @@ static void init_ecc_memory(unsigned node_id)
 
        /* See if we scrubbing should be enabled */
        enable_scrubbing = 1;
-       get_option(&enable_scrubbing, "hw_scrubber");
+       if( get_option(&enable_scrubbing, "hw_scrubber") < 0 )
+       {
+               enable_scrubbing = CONFIG_HW_SCRUBBER;
+       }
 
        /* Enable cache scrubbing at the lowest possible rate */
        if (enable_scrubbing) {
                pci_write_config32(f3_dev, SCRUB_CONTROL,
-                       (SCRUB_84ms << 16) | (SCRUB_84ms << 8) | (SCRUB_NONE << 0));
+                                  (SCRUB_84ms << 16) | (SCRUB_84ms << 8) |
+                                  (SCRUB_NONE << 0));
        } else {
                pci_write_config32(f3_dev, SCRUB_CONTROL,
-                       (SCRUB_NONE << 16) | (SCRUB_NONE << 8) | (SCRUB_NONE << 0));
-               printk_debug("Scrubbing Disabled\n");
+                                  (SCRUB_NONE << 16) | (SCRUB_NONE << 8) |
+                                  (SCRUB_NONE << 0));
+               printk(BIOS_DEBUG, "Scrubbing Disabled\n");
        }
-       
 
        /* If ecc support is not enabled don't touch memory */
        dcl = pci_read_config32(f2_dev, DRAM_CONFIG_LOW);
        if (!(dcl & DCL_DimmEccEn)) {
-               printk_debug("ECC Disabled\n");
+               printk(BIOS_DEBUG, "ECC Disabled\n");
                return;
        }
 
-       startk = (pci_read_config32(f1_dev, 0x40 + (node_id*8)) & 0xffff0000) >> 2;
-       endk   = ((pci_read_config32(f1_dev, 0x44 + (node_id*8)) & 0xffff0000) >> 2) + 0x4000;
+       startk =
+           (pci_read_config32(f1_dev, 0x40 + (node_id * 8)) & 0xffff0000) >> 2;
+       endk =
+           ((pci_read_config32(f1_dev, 0x44 + (node_id * 8)) & 0xffff0000) >>
+            2) + 0x4000;
 
 #if CONFIG_HW_MEM_HOLE_SIZEK != 0
-       #if CONFIG_K8_REV_F_SUPPORT == 0
-        if (!is_cpu_pre_e0()) 
-       {
-       #endif
-
-                uint32_t val;
-                val = pci_read_config32(f1_dev, 0xf0);
-                if(val & 1) {
-                       hole_startk = ((val & (0xff<<24)) >> 10);
-                }
-       #if CONFIG_K8_REV_F_SUPPORT == 0
-        }
-       #endif
+       unsigned long hole_startk = 0;
+
+#if CONFIG_K8_REV_F_SUPPORT == 0
+       if (!is_cpu_pre_e0()) {
+#endif
+
+               uint32_t val;
+               val = pci_read_config32(f1_dev, 0xf0);
+               if (val & 1) {
+                       hole_startk = ((val & (0xff << 24)) >> 10);
+               }
+#if CONFIG_K8_REV_F_SUPPORT == 0
+       }
+#endif
 #endif
-       
 
        /* Don't start too early */
        begink = startk;
        if (begink < (CONFIG_RAMTOP >> 10)) {
-               begink = (CONFIG_RAMTOP >>10);
+               begink = (CONFIG_RAMTOP >> 10);
        }
 
-       printk_debug("Clearing memory %luK - %luK: ", begink, endk);
+       printk(BIOS_DEBUG, "Clearing memory %luK - %luK: ", begink, endk);
 
        /* Save the normal state */
        save_mtrr_state(&mtrr_state);
@@ -324,26 +330,22 @@ static void init_ecc_memory(unsigned node_id)
        /* Walk through 2M chunks and zero them */
 #if CONFIG_HW_MEM_HOLE_SIZEK != 0
        /* here hole_startk can not be equal to begink, never. Also hole_startk is in 2M boundary, 64M? */
-        if ( (hole_startk != 0) && ((begink < hole_startk) && (endk>(4*1024*1024)))) {
-                       for(basek = begink; basek < hole_startk;
-                               basek = ((basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1)))
-                       {
-                               clear_2M_ram(basek, &mtrr_state);
-                       }
-                       for(basek = 4*1024*1024; basek < endk;
-                                basek = ((basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1)))
-                        {
-                                clear_2M_ram(basek, &mtrr_state);
-                        }
-        }
-       else 
+       if ((hole_startk != 0)
+           && ((begink < hole_startk) && (endk > (4 * 1024 * 1024)))) {
+               for (basek = begink; basek < hole_startk;
+                    basek = ((basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1))) {
+                       clear_2M_ram(basek, &mtrr_state);
+               }
+               for (basek = 4 * 1024 * 1024; basek < endk;
+                    basek = ((basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1))) {
+                       clear_2M_ram(basek, &mtrr_state);
+               }
+       } else
 #endif
-        for(basek = begink; basek < endk;
-                basek = ((basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1))) 
-       {
-               clear_2M_ram(basek, &mtrr_state);
-       }
-
+               for (basek = begink; basek < endk;
+                    basek = ((basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1))) {
+                       clear_2M_ram(basek, &mtrr_state);
+               }
 
        /* Restore the normal state */
        map_2M_page(0);
@@ -351,20 +353,20 @@ static void init_ecc_memory(unsigned node_id)
        enable_lapic();
 
        /* Set the scrub base address registers */
-       pci_write_config32(f3_dev, SCRUB_ADDR_LOW,  startk << 10);
+       pci_write_config32(f3_dev, SCRUB_ADDR_LOW, startk << 10);
        pci_write_config32(f3_dev, SCRUB_ADDR_HIGH, startk >> 22);
 
        /* Enable the scrubber? */
        if (enable_scrubbing) {
                /* Enable scrubbing at the lowest possible rate */
                pci_write_config32(f3_dev, SCRUB_CONTROL,
-                       (SCRUB_84ms << 16) | (SCRUB_84ms << 8) | (SCRUB_84ms << 0));
+                                  (SCRUB_84ms << 16) | (SCRUB_84ms << 8) |
+                                  (SCRUB_84ms << 0));
        }
 
-       printk_debug(" done\n");
+       printk(BIOS_DEBUG, " done\n");
 }
 
-
 static inline void k8_errata(void)
 {
        msr_t msr;
@@ -382,35 +384,18 @@ static inline void k8_errata(void)
 
                /* Erratum 81... */
                msr = rdmsr_amd(DC_CFG_MSR);
-               msr.lo |=  (1 << 10);
+               msr.lo |= (1 << 10);
                wrmsr_amd(DC_CFG_MSR, msr);
-                       
-       }
-       /* I can't touch this msr on early buggy cpus */
-       if (!is_cpu_pre_b3()) {
 
-               /* Erratum 89 ... */
-               msr = rdmsr(NB_CFG_MSR);
-               msr.lo |= 1 << 3;
-               
-               if (!is_cpu_pre_c0() && is_cpu_pre_d0()) {
-                       /* D0 later don't need it */
-                       /* Erratum 86 Disable data masking on C0 and 
-                        * later processor revs.
-                        * FIXME this is only needed if ECC is enabled.
-                        */
-                       msr.hi |= 1 << (36 - 32);
-               }
-               wrmsr(NB_CFG_MSR, msr);
        }
-       
+
        /* Erratum 97 ... */
        if (!is_cpu_pre_c0() && is_cpu_pre_d0()) {
                msr = rdmsr_amd(DC_CFG_MSR);
                msr.lo |= 1 << 3;
                wrmsr_amd(DC_CFG_MSR, msr);
-       }       
-       
+       }
+
        /* Erratum 94 ... */
        if (is_cpu_pre_d0()) {
                msr = rdmsr_amd(IC_CFG_MSR);
@@ -430,62 +415,79 @@ static inline void k8_errata(void)
        msr.hi |= 1 << (43 - 32);
        wrmsr_amd(BU_CFG_MSR, msr);
 
-       if(is_cpu_d0()) {
-               /* Erratum 110 ...*/
+       /* Erratum 110 */
+       /* This erratum applies to D0 thru E6 revisions
+        * Revision F and later are unaffected. There are two fixes
+        * depending on processor revision.
+        */
+       if (is_cpu_d0()) {
+               /* Erratum 110 ... */
                msr = rdmsr_amd(CPU_ID_HYPER_EXT_FEATURES);
-               msr.hi |=1;
+               msr.hi |= 1;
                wrmsr_amd(CPU_ID_HYPER_EXT_FEATURES, msr);
-       }
+       }
+
+       if (!is_cpu_pre_e0())
+       {
+               /* Erratum 110 ... */
+               msr = rdmsr_amd(CPU_ID_EXT_FEATURES_MSR);
+               msr.hi |= 1;
+               wrmsr_amd(CPU_ID_EXT_FEATURES_MSR, msr);
+       }
 #endif
 
+
 #if CONFIG_K8_REV_F_SUPPORT == 0
-       if (!is_cpu_pre_e0()) 
+       /* I can't touch this msr on early buggy cpus */
+       if (!is_cpu_pre_b3())
 #endif
        {
-               /* Erratum 110 ... */
-                msr = rdmsr_amd(CPU_ID_EXT_FEATURES_MSR);
-                msr.hi |=1;
-                wrmsr_amd(CPU_ID_EXT_FEATURES_MSR, msr);
-       }
+               msr = rdmsr(NB_CFG_MSR);
 
+#if CONFIG_K8_REV_F_SUPPORT == 0
+               if (!is_cpu_pre_c0() && is_cpu_pre_d0()) {
+                       /* D0 later don't need it */
+                       /* Erratum 86 Disable data masking on C0 and
+                        * later processor revs.
+                        * FIXME this is only needed if ECC is enabled.
+                        */
+                       msr.hi |= 1 << (36 - 32);
+               }
+#endif
+               /* Erratum 89 ... */
+               /* Erratum 89 is mistakenly labeled as 88 in AMD pub #25759
+                * It is correctly labeled as 89 on page 49 of the document
+                * and in AMD pub#33610
+                */
+               msr.lo |= 1 << 3;
+               /* Erratum 169 */
+               /* This supersedes erratum 131; 131 should not be applied with 169
+                * We also need to set some bits in the northbridge, handled in src/northbridge/amdk8/
+                */
+               msr.hi |= 1;
+
+               wrmsr(NB_CFG_MSR, msr);
+       }
        /* Erratum 122 */
        msr = rdmsr(HWCR_MSR);
        msr.lo |= 1 << 6;
        wrmsr(HWCR_MSR, msr);
 
-#if CONFIG_K8_REV_F_SUPPORT == 1
-        /* Erratum 131... */
-        msr = rdmsr(NB_CFG_MSR);
-        msr.lo |= 1 << 20;
-        wrmsr(NB_CFG_MSR, msr);
-#endif
 
 }
 
-extern void model_fxx_update_microcode(unsigned cpu_deviceid);
-int init_processor_name(void);
-
-#if CONFIG_USBDEBUG_DIRECT
+#if CONFIG_USBDEBUG
 static unsigned ehci_debug_addr;
 #endif
 
-void model_fxx_init(device_t dev)
+static void model_fxx_init(device_t dev)
 {
        unsigned long i;
        msr_t msr;
        struct node_core_id id;
-#if CONFIG_LOGICAL_CPUS == 1
-       unsigned siblings;
-#endif
 
-#if CONFIG_K8_REV_F_SUPPORT == 1
-       struct cpuinfo_x86 c;
-       
-       get_fms(&c, dev->device);
-#endif
-
-#if CONFIG_USBDEBUG_DIRECT
-       if(!ehci_debug_addr) 
+#if CONFIG_USBDEBUG
+       if (!ehci_debug_addr)
                ehci_debug_addr = get_ehci_debug();
        set_ehci_debug(0);
 #endif
@@ -495,68 +497,72 @@ void model_fxx_init(device_t dev)
        amd_setup_mtrrs();
        x86_mtrr_check();
 
-#if CONFIG_USBDEBUG_DIRECT
+#if CONFIG_USBDEBUG
        set_ehci_debug(ehci_debug_addr);
 #endif
 
-        /* Update the microcode */
+       /* Update the microcode */
        model_fxx_update_microcode(dev->device);
 
        disable_cache();
-       
+
        /* zero the machine check error status registers */
        msr.lo = 0;
        msr.hi = 0;
-       for(i=0; i<5; i++) {
-               wrmsr(MCI_STATUS + (i*4),msr);
+       for (i = 0; i < 5; i++) {
+               wrmsr(MCI_STATUS + (i * 4), msr);
        }
 
        k8_errata();
-       
-       /* Set SMMLOCK to avoid exploits messing with SMM */
-       msr = rdmsr(HWCR_MSR);
-       msr.lo |= (1 << 0);
-       wrmsr(HWCR_MSR, msr);
-       
+
+       enable_cache();
+
        /* Set the processor name string */
        init_processor_name();
-       
-       enable_cache();
 
        /* Enable the local cpu apics */
        setup_lapic();
 
 #if CONFIG_LOGICAL_CPUS == 1
-        siblings = cpuid_ecx(0x80000008) & 0xff;
-
-               if(siblings>0) {
-                msr = rdmsr_amd(CPU_ID_FEATURES_MSR);
-                msr.lo |= 1 << 28; 
-                wrmsr_amd(CPU_ID_FEATURES_MSR, msr);
+       u32 siblings = cpuid_ecx(0x80000008) & 0xff;
 
-                       msr = rdmsr_amd(LOGICAL_CPUS_NUM_MSR);
-                msr.lo = (siblings+1)<<16; 
-                       wrmsr_amd(LOGICAL_CPUS_NUM_MSR, msr);
+       if (siblings > 0) {
+               msr = rdmsr_amd(CPU_ID_FEATURES_MSR);
+               msr.lo |= 1 << 28;
+               wrmsr_amd(CPU_ID_FEATURES_MSR, msr);
 
-                msr = rdmsr_amd(CPU_ID_EXT_FEATURES_MSR);
-                       msr.hi |= 1<<(33-32); 
-                       wrmsr_amd(CPU_ID_EXT_FEATURES_MSR, msr);
-       } 
+               msr = rdmsr_amd(LOGICAL_CPUS_NUM_MSR);
+               msr.lo = (siblings + 1) << 16;
+               wrmsr_amd(LOGICAL_CPUS_NUM_MSR, msr);
 
+               msr = rdmsr_amd(CPU_ID_EXT_FEATURES_MSR);
+               msr.hi |= 1 << (33 - 32);
+               wrmsr_amd(CPU_ID_EXT_FEATURES_MSR, msr);
+       }
 #endif
 
-       id = get_node_core_id(read_nb_cfg_54()); // pre e0 nb_cfg_54 can not be set
+       id = get_node_core_id(read_nb_cfg_54());        // pre e0 nb_cfg_54 can not be set
 
        /* Is this a bad location?  In particular can another node prefecth
         * data from this node before we have initialized it?
         */
-       if (id.coreid == 0) init_ecc_memory(id.nodeid); // only do it for core 0
+       if (id.coreid == 0)
+               init_ecc_memory(id.nodeid);     // only do it for core 0
 
-#if CONFIG_LOGICAL_CPUS==1
-        /* Start up my cpu siblings */
-//     if(id.coreid==0)  amd_sibling_init(dev); // Don't need core1 is already be put in the CPU BUS in bus_cpu_scan
-#endif
+       /* Set SMM base address for this CPU */
+       msr = rdmsr(SMM_BASE_MSR);
+       msr.lo = SMM_BASE - (lapicid() * 0x400);
+       wrmsr(SMM_BASE_MSR, msr);
+
+       /* Enable the SMM memory window */
+       msr = rdmsr(SMM_MASK_MSR);
+       msr.lo |= (1 << 0); /* Enable ASEG SMRAM Range */
+       wrmsr(SMM_MASK_MSR, msr);
 
+       /* Set SMMLOCK to avoid exploits messing with SMM */
+       msr = rdmsr(HWCR_MSR);
+       msr.lo |= (1 << 0);
+       wrmsr(HWCR_MSR, msr);
 }
 
 static struct device_operations cpu_dev_ops = {
@@ -631,6 +637,7 @@ static struct cpu_device_id cpu_table[] = {
        { X86_VENDOR_AMD, 0x40fc2 }, /* DH-F2 (socket S1g1) */
        { X86_VENDOR_AMD, 0x40f13 }, /* JH-F3 (socket F/1207) */
        { X86_VENDOR_AMD, 0x40f33 }, /* JH-F3 (socket AM2) */
+       { X86_VENDOR_AMD, 0x50fd3 }, /* JH-F3 (socket F/1207) */
        { X86_VENDOR_AMD, 0xc0f13 }, /* JH-F3 (socket F/1207) */
        { X86_VENDOR_AMD, 0x50ff3 }, /* DH-F3 (socket AM2) */
        { X86_VENDOR_AMD, 0x60fb1 }, /* BH-G1 (socket AM2) */
@@ -639,6 +646,7 @@ static struct cpu_device_id cpu_table[] = {
        { X86_VENDOR_AMD, 0x60f82 }, /* BH-G2 (socket S1g1) */
        { X86_VENDOR_AMD, 0x70ff1 }, /* DH-G1 (socket AM2) */
        { X86_VENDOR_AMD, 0x60ff2 }, /* DH-G2 (socket AM2) */
+       { X86_VENDOR_AMD, 0x70ff2 }, /* DH-G2 (socket AM2) */
        { X86_VENDOR_AMD, 0x60fc2 }, /* DH-G2 (socket S1g1) */
        { X86_VENDOR_AMD, 0x70fc2 }, /* DH-G2 (socket S1g1) */
 #endif