<div>again about cpu_bus creation for all core1.</div>
<div>I prefer to create enry to that in scan_cpu_bus in northbridge.c</div>
<div>1. you don't to reorder that in write_smp_processors</div>
<div>2. for 8 way or four way system, We need to set CPU_INIT_SERIAL=0, to init ecc for ap the same time, then with amd_sibling_init create entry for core1 in node nodex, could conflit access with cpu_initli....in node0/core0. esp for the last core1 could be missed to init, because before nodex/core0 add the core1 to the cpu bus, node0/core0 already finish the start cpu bus.
</div>
<div> </div>
<div>YH<br><br> </div>
<div><span class="gmail_quote">On 9/2/05, <b class="gmail_sendername">jason schildt</b> <<a href="mailto:jschildt@lnxi.com">jschildt@lnxi.com</a>> wrote:</span>
<blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">DESCRIPTION:<br>--------------------------------------------<br>## lnxi-patch-4 Big Dual Core Changes ## - (8)files
<br><br>src/include/cpu/amd/dualcore.h<br>       Code Cleanup.<br><br>src/cpu/amd/model_fxx/model_fxx_init.c<br>       Code cleanup:<br>               config guards in header.<br>               dynamic memory hoisting instead of hard coding.
<br>               cpu ranges instead of exact cpu matching.<br>               naming change (dev -> cpu)<br><br><br>src/cpu/amd/dualcore/dualcore.c<br>       Remove chunk with these function calls #if'd out:<br>               get_core_num_in_bsp()  # Not used.
<br>               set_apicid_cpuid_lo()   # Used in Tyan Opteron boards.<br>               real_start_other_core() # Not used.<br>               start_other_core()      # Not used.<br>               get_nodes()             # Not used.
<br>               start_other_cores()     # Used in Tyan Opteron Boards.<br><br>src/cpu/amd/dualcore/amd_sibling.c<br>       Make amd_sibling_init work and generalize get_node_core_id.<br><br>src/cpu/amd/dualcore/dualcore_id.c
<br>       Optimized struct node_core_id so that it fits in 1 register with romcc.<br><br>src/northbridge/amd/amdk8/coherent_ht.c<br>       Dualcore cleanup work:<br>               Added startup_othercores()<br>               only look at low nibble to see link freq.
<br><br>src/northbridge/amd/amdk8/amdk8.h<br>       Added e0 register<br><br>src/northbridge/amd/amdk8/northbridge.c<br>       Added dynamic memory hoisting - hoist_memory()<br>       included 2.6.11/12 kernel bug fix<br>
       Cleaned up cpu_bus_scan()<br><br>src/northbridge/amd/amdk8/raminit.c<br>       factored out set_dimm_map() from set_dimm_size()<br>       added e_step_cpu()<br>               This function holds the logic only needed for e-step.
<br>       removed hardcoded memory hole - set_e0_mem_hole()<br><br>DIFFSTAT:<br>--------------------------------------------<br><br>cpu/amd/dualcore/amd_sibling.c      |  180 +++++++++++-------------------<br>cpu/amd/dualcore/dualcore.c         |  127 ++++++++-------------
<br>cpu/amd/dualcore/dualcore_id.c      |    4<br>cpu/amd/model_fxx/model_fxx_init.c  |   98 +++++-----------<br>include/cpu/amd/dualcore.h          |    9 -<br>northbridge/amd/amdk8/amdk8.h       |    1<br>northbridge/amd/amdk8/coherent_ht.c |   89 +++++++-------
<br>northbridge/amd/amdk8/northbridge.c |  215<br>++++++++++++------------------------<br>northbridge/amd/amdk8/raminit.c     |  154 ++++++++++++-------------<br>9 files changed, 346 insertions(+), 531 deletions(-)<br><br>
PATCH:<br>--------------------------------------------<br><br><br>Index: src/include/cpu/amd/dualcore.h<br>===================================================================<br>--- src/include/cpu/amd/dualcore.h      (revision 1105)
<br>+++ src/include/cpu/amd/dualcore.h      (working copy)<br>@@ -2,18 +2,13 @@<br>#define CPU_AMD_DUALCORE_H<br><br>struct device;<br>-void amd_sibling_init(struct device *cpu);<br><br>-int is_e0_later_in_bsp(int nodeid);
<br>-unsigned int read_nb_cfg_54(void);<br>-<br>struct node_core_id {<br>         unsigned nodeid;<br>         unsigned coreid;<br>};<br><br>-// it can be used to get unitid and coreid it running only<br>-struct node_core_id get_node_core_id(unsigned int nb_cfg_54);
<br>-unsigned get_apicid_base(unsigned ioapic_num);<br>+void amd_sibling_init(struct device *cpu, struct node_core_id id);<br>+struct node_core_id get_node_core_id(void);<br><br>#endif /* CPU_AMD_DUALCORE_H */<br>Index: src/cpu/amd/model_fxx/model_fxx_init.c
<br>===================================================================<br>--- src/cpu/amd/model_fxx/model_fxx_init.c      (revision 1105)<br>+++ src/cpu/amd/model_fxx/model_fxx_init.c      (working copy)<br>@@ -21,10 +21,7 @@
<br>#include <cpu/x86/cache.h><br>#include <cpu/x86/mtrr.h><br>#include <cpu/x86/mem.h><br>-<br>-#if CONFIG_LOGICAL_CPUS==1<br>#include <cpu/amd/dualcore.h><br>-#endif<br><br>#include "model_fxx_msr.h"
<br><br>@@ -152,9 +149,6 @@<br>static void init_ecc_memory(unsigned node_id)<br>{<br>       unsigned long startk, begink, endk;<br>-#if K8_E0_MEM_HOLE_SIZEK != 0<br>-       unsigned long hole_startk = 0, hole_endk = 0;<br>
-#endif<br>       unsigned long basek;<br>       struct mtrr_state mtrr_state;<br>       device_t f1_dev, f2_dev, f3_dev;<br>@@ -199,25 +193,13 @@<br>       startk = (pci_read_config32(f1_dev, 0x40 + (node_id*8)) & 0xffff0000) >>
<br>2;<br>       endk   = ((pci_read_config32(f1_dev, 0x44 + (node_id*8)) & 0xffff0000)<br>>> 2) + 0x4000;<br><br>-#if K8_E0_MEM_HOLE_SIZEK != 0<br>-        if (!is_cpu_pre_e0()) {<br>-                uint32_t val;
<br>-                val = pci_read_config32(f1_dev, 0xf0);<br>-                if((val & 1)==1) {<br>-                       hole_startk = ((val & (0xff<<24)) >> 10);<br>-                       hole_endk = ((val & (0xff<<8))<<(16-10)) - startk;
<br>-                       hole_endk += hole_startk;<br>-                }<br>-        }<br>-#endif<br>-<br><br>       /* Don't start too early */<br>       begink = startk;<br>       if (begink < CONFIG_LB_MEM_TOPK) {
<br>               begink = CONFIG_LB_MEM_TOPK;<br>       }<br>-       printk_debug("Clearing memory %uK - %uK: ", startk, endk);<br>+       printk_debug("Clearing memory %uK - %uK: ", begink, endk);<br>
<br>       /* Save the normal state */<br>       save_mtrr_state(&mtrr_state);<br>@@ -234,9 +216,6 @@<br>               unsigned long size;<br>               void *addr;<br><br>-#if K8_E0_MEM_HOLE_SIZEK != 0<br>-               if ((basek >= hole_startk) && (basek < hole_endk)) continue;
<br>-#endif<br>               /* Report every 64M */<br>               if ((basek % (64*1024)) == 0) {<br>                       /* Restore the normal state */<br>@@ -340,6 +319,7 @@<br><br>       /* Erratum 91 prefetch miss is handled in the kernel */
<br><br>+<br>       /* Erratum 106 ... */<br>       msr = rdmsr_amd(LS_CFG_MSR);<br>       msr.lo |= 1 << 25;<br>@@ -350,7 +330,7 @@<br>       msr.hi |= 1 << (43 - 32);<br>       wrmsr_amd(BU_CFG_MSR, msr);<br>
<br>-       if(is_cpu_d0()) {<br>+       if (is_cpu_pre_e0() && !is_cpu_pre_d0()) {<br>               /* Erratum 110 ...*/<br>               msr = rdmsr_amd(CPU_ID_HYPER_EXT_FEATURES);<br>               msr.hi |=1;
<br>@@ -362,26 +342,34 @@<br>                 msr = rdmsr_amd(CPU_ID_EXT_FEATURES_MSR);<br>                 msr.hi |=1;<br>                 wrmsr_amd(CPU_ID_EXT_FEATURES_MSR, msr);<br>+<br>+               /* Erratum 113 ... */
<br>+               msr = rdmsr_amd(BU_CFG_MSR);<br>+               msr.hi |= (1 << 16);<br>+               wrmsr_amd(BU_CFG_MSR, msr);<br>       }<br><br>       /* Erratum 122 */<br>-       msr = rdmsr(HWCR_MSR);<br>
-       msr.lo |= 1 << 6;<br>-       wrmsr(HWCR_MSR, msr);<br>+       if (!is_cpu_pre_c0()) {<br>+               msr = rdmsr(HWCR_MSR);<br>+               msr.lo |= 1 << 6;<br>+               wrmsr(HWCR_MSR, msr);
<br>+       }<br>+<br>+       /* Erratum 123? dual core deadlock? */<br><br>+       /* Erratum 131 */<br>+       msr = rdmsr(NB_CFG_MSR);<br>+       msr.lo |= 1 << 20;<br>+       wrmsr(NB_CFG_MSR, msr);<br>+<br>}<br>
<br>-void model_fxx_init(device_t dev)<br>+void model_fxx_init(device_t cpu)<br>{<br>       unsigned long i;<br>       msr_t msr;<br>-#if CONFIG_LOGICAL_CPUS<br>       struct node_core_id id;<br>-       unsigned siblings;
<br>-       id.coreid=0;<br>-#else<br>-       unsigned nodeid;<br>-#endif<br><br>       /* Turn on caching if we haven't already */<br>       x86_enable_cache();<br>@@ -404,43 +392,18 @@<br>       /* Enable the local cpu apics */
<br>       setup_lapic();<br><br>-#if CONFIG_LOGICAL_CPUS == 1<br>-        siblings = cpuid_ecx(0x80000008) & 0xff;<br>+       /* Find our node and core */<br>+       id = get_node_core_id();<br><br>-       id = get_node_core_id(read_nb_cfg_54()); // pre e0 nb_cfg_54 can not be
<br>set<br>-<br>-               if(siblings>0) {<br>-                msr = rdmsr_amd(CPU_ID_FEATURES_MSR);<br>-                msr.lo |= 1 << 28;<br>-                wrmsr_amd(CPU_ID_FEATURES_MSR, msr);<br>-<br>-                       msr = rdmsr_amd(LOGICAL_CPUS_NUM_MSR);
<br>-                msr.lo = (siblings+1)<<16;<br>-                       wrmsr_amd(LOGICAL_CPUS_NUM_MSR, msr);<br>-<br>-                msr = rdmsr_amd(CPU_ID_EXT_FEATURES_MSR);<br>-                       msr.hi |= 1<<(33-32);
<br>-                       wrmsr_amd(CPU_ID_EXT_FEATURES_MSR, msr);<br>-       }<br>-<br>-<br>-       /* Is this a bad location?  In particular can another node prefecth<br>+       /* Is this a bad location?  In particular can another node prefetch
<br>        * data from this node before we have initialized it?<br>        */<br>-       if (id.coreid == 0) init_ecc_memory(id.nodeid); // only do it for core 0<br>-#else<br>-       /* Is this a bad location?  In particular can another node prefecth
<br>-        * data from this node before we have initialized it?<br>-        */<br>-       nodeid = lapicid() & 0xf;<br>-       init_ecc_memory(nodeid);<br>-#endif<br>+       if (id.coreid == 0) {<br>+               init_ecc_memory(
id.nodeid); // only do it for core 0<br>+       }<br><br>-#if CONFIG_LOGICAL_CPUS==1<br>-        /* Start up my cpu siblings */<br>-//     if(id.coreid==0)  amd_sibling_init(dev); // Don't need core1 is<br>already be put in the CPU BUS in bus_cpu_scan
<br>-#endif<br>-<br>+       /* Deal with sibling cpus */<br>+       amd_sibling_init(cpu, id);<br>}<br><br>static struct device_operations cpu_dev_ops = {<br>@@ -451,7 +414,7 @@<br>       { X86_VENDOR_AMD, 0xf51 }, /* SH7-B3 */
<br>       { X86_VENDOR_AMD, 0xf58 }, /* SH7-C0 */<br>       { X86_VENDOR_AMD, 0xf48 },<br>-#if 1<br>+<br>       { X86_VENDOR_AMD, 0xf5A }, /* SH7-CG */<br>       { X86_VENDOR_AMD, 0xf4A },<br>       { X86_VENDOR_AMD, 0xf7A },
<br>@@ -483,7 +446,6 @@<br>         { X86_VENDOR_AMD, 0x20fc2 },<br>         { X86_VENDOR_AMD, 0x20f12 }, /* JH-E6 */<br>         { X86_VENDOR_AMD, 0x20f32 },<br>-#endif<br><br>       { 0, 0 },<br>};<br>Index: src/cpu/amd/dualcore/dualcore.c
<br>===================================================================<br>--- src/cpu/amd/dualcore/dualcore.c     (revision 1105)<br>+++ src/cpu/amd/dualcore/dualcore.c     (working copy)<br>@@ -1,99 +1,68 @@<br>/* 2004.12
 yhlu add dual core support */<br><br>-<br>-#ifndef SET_NB_CFG_54<br>-#define SET_NB_CFG_54 1<br>-#endif<br>-<br>#include "cpu/amd/dualcore/dualcore_id.c"<br><br>-static inline unsigned get_core_num_in_bsp(unsigned nodeid)
<br>+static void do_k8_init_and_stop_secondaries(void)<br>{<br>-        return ((pci_read_config32(PCI_DEV(0, 0x18+nodeid, 3), 0xe8)>>12)<br>& 3);<br>-}<br>-<br>-static inline<br>-#if SET_NB_CFG_54 == 1<br>-               uint8_t
<br>-#else<br>-               void<br>-#endif<br>-                       set_apicid_cpuid_lo(void) {<br>-#if SET_NB_CFG_54<br>-       //for pre_e0, even we set nb_cfg_54, but it will still be 0<br>-       //for e0 later you should use get_node_id(read_nb_cfg_54()) even for
<br>single core cpu<br>-       //get siblings via cpuid(0x80000008) ecx[7:0]<br>-       #if CONFIG_MAX_PHYSICAL_CPUS != 8<br>-       if( get_core_num_in_bsp(0) == 0) {<br>-                /*first node only has one core, pre_e0
<br>-                  all e0 single core installed don't need enable lo too,<br>-                  So if mixing e0 single core and dual core,<br>-                  don't put single core in first socket */<br>-               return 0;
<br>-        }<br>-       #endif<br>+       struct node_core_id id;<br>+       device_t dev;<br>+       unsigned apicid;<br>+       unsigned max_siblings;<br>+       msr_t msr;<br><br>-       if(read_option(CMOS_VSTART_dual_core, CMOS_VLEN_dual_core, 0) != 0)
<br>{ // disable dual_core<br>-               return 0;<br>-       }<br>+       /* Skip this if there was a built in self test failure */<br><br>-               // set the NB_CFG[54]=1; why the OS will be happy with that ???
<br>-        msr_t msr;<br>-        msr = rdmsr(NB_CFG_MSR);<br>-        msr.hi |= (1<<(54-32)); // InitApicIdCpuIdLo<br>-        wrmsr(NB_CFG_MSR, msr);<br>+       if (is_cpu_pre_e0()) {<br>+               id.nodeid
 = lapicid() & 0x7;<br>+               id.coreid = 0;<br>+       } else {<br>+               /* Which cpu are we on? */<br>+               id = get_node_core_id_x();<br><br>-       return 1;<br>+               /* Set NB_CFG_MSR
<br>+                * Linux expect the core to be in the least signficant bits.<br>+                */<br>+               msr = rdmsr(NB_CFG_MSR);<br>+               msr.hi |= (1<<(54-32)); // InitApicIdCpuIdLo<br>
+               wrmsr(NB_CFG_MSR, msr);<br>+       }<br><br>-#endif<br>+       /* For now assume all cpus have the same number of siblings */<br>+       max_siblings = (cpuid_ecx(0x80000008) & 0xff) + 1;<br><br>-}<br>
+       /* Set the lapicid */<br>+       lapic_write(LAPIC_ID,((id.nodeid*max_siblings) + id.coreid) << 24);<br><br>-static inline void real_start_other_core(unsigned nodeid)<br>-{<br>-       uint32_t dword;<br>-       // set PCI_DEV(0, 0x18+nodeid, 3), 0x44 bit 27 to redirect all MC4
<br>accesses and error logging to core0<br>-       dword = pci_read_config32(PCI_DEV(0, 0x18+nodeid, 3), 0x44);<br>-       dword |= 1<<27; // NbMcaToMstCpuEn bit<br>-       pci_write_config32(PCI_DEV(0, 0x18+nodeid, 3), 0x44, dword);
<br>-       // set PCI_DEV(0, 0x18+nodeid, 0), 0x68 bit 5 to start core1<br>-       dword = pci_read_config32(PCI_DEV(0, 0x18+nodeid, 0), 0x68);<br>-       dword |= 1<<5;<br>-       pci_write_config32(PCI_DEV(0, 0x18+nodeid, 0), 0x68, dword);
<br>+       /* Remember the cpuid */<br>+       if (id.coreid == 0) {<br>+               dev = PCI_DEV(0, 0x18 + id.nodeid, 2);<br>+               pci_write_config32(dev, 0x9c, cpuid_eax(1));<br>+       }<br>+<br>+       /* Maybe call distinguish_cpu_resets only on the last core? */
<br>+       distinguish_cpu_resets(id.nodeid);<br>+       if (!boot_cpu()) {<br>+               stop_this_cpu();<br>+       }<br>}<br><br>-//it is running on core0 of every node<br>-static inline void start_other_core(unsigned nodeid) {
<br>-<br>-        if(read_option(CMOS_VSTART_dual_core, CMOS_VLEN_dual_core, 0) !=<br>0)  { // disable dual_core<br>-                return;<br>-        }<br>-<br>-       if( get_core_num() >0) { // defined in dualcore_id.c
<br>-               real_start_other_core(nodeid);<br>-        }<br>-}<br>-<br>-static inline unsigned get_nodes(void)<br>+static void k8_init_and_stop_secondaries(void)<br>{<br>-       return ((pci_read_config32(PCI_DEV(0, 0x18, 0), 0x60)>>4) & 7) + 1;
<br>-}<br>+       /* This doesn't work with Cache As Ram because it messes with<br>+          the MTRR state, which breaks the init detection.<br>+          do_k8_init_and_stop_secondaries should be usable by CAR code.<br>
+       */<br><br>-//it is running on core0 of node0<br>-static inline void start_other_cores(void) {<br>-       unsigned nodes;<br>-       unsigned nodeid;<br>+       int init_detected;<br><br>-        if(read_option(CMOS_VSTART_dual_core, CMOS_VLEN_dual_core, 0) !=
<br>0)  { // disable dual_core<br>-                return;<br>-        }<br>+       init_detected = early_mtrr_init_detected();<br>+       amd_early_mtrr_init();<br><br>-        nodes = get_nodes();<br>-<br>-        for(nodeid=0; nodeid<nodes; nodeid++) {
<br>-               if( get_core_num_in_bsp(nodeid) > 0) {<br>-                       real_start_other_core(nodeid);<br>-               }<br>+       enable_lapic();<br>+       init_timer();<br>+       if (init_detected) {
<br>+               asm volatile ("jmp __cpu_reset");<br>       }<br><br>+       do_k8_init_and_stop_secondaries();<br>}<br>Index: src/cpu/amd/dualcore/amd_sibling.c<br>===================================================================
<br>--- src/cpu/amd/dualcore/amd_sibling.c  (revision 1105)<br>+++ src/cpu/amd/dualcore/amd_sibling.c  (working copy)<br>@@ -1,4 +1,5 @@<br>/* 2004.12 yhlu add dual core support */<br>+/* 24 June 2005 Cleaned up dual core support Eric Biederman */
<br><br>#include <console/console.h><br>#include <cpu/cpu.h><br>@@ -14,59 +15,87 @@<br><br>static int first_time = 1;<br>static int disable_siblings = !CONFIG_LOGICAL_CPUS;<br>+void amd_sibling_init(device_t cpu, struct node_core_id id)
<br>+{<br>+       unsigned long i;<br>+       unsigned siblings, max_siblings;<br><br>+       /* On the bootstrap processor see if I want sibling cpus enabled */<br>+       if (first_time) {<br>+               first_time = 0;
<br>+               get_option(&disable_siblings, "dual_core");<br>+       }<br><br>-int is_e0_later_in_bsp(int nodeid)<br>-{<br>-       uint32_t val;<br>-       uint32_t val_old;<br>-       int e0_later;<br>
-       if(nodeid==0) { // we don't need to do that for node 0 in core0/node0<br>-               return !is_cpu_pre_e0();<br>+        siblings = cpuid_ecx(0x80000008) & 0xff;<br>+       printk_debug("%d Sibling Cores found\n", siblings);
<br>+<br>+       /* For now assume all cpus have the same number of siblings */<br>+       max_siblings = siblings + 1;<br>+<br>+       /* Wishlist? make dual cores look like hyperthreading */<br>+<br>+       /* See if I am a sibling cpu */
<br>+       if (disable_siblings && (id.coreid != 0)) {<br>+               cpu->enabled = 0;<br>       }<br>-       // d0 will be treated as e0 with this methods, but the d0 nb_cfg_54<br>always 0<br>-       device_t dev;
<br>-       dev = dev_find_slot(0, PCI_DEVFN(0x18+nodeid,2));<br>-       if(!dev) return 0;<br>-       val_old = pci_read_config32(dev, 0x80);<br>-       val = val_old;<br>-       val |= (1<<3);<br>-       pci_write_config32(dev, 0x80, val);
<br>-       val = pci_read_config32(dev, 0x80);<br>-       e0_later = !!(val & (1<<3));<br>-       if(e0_later) { // pre_e0 bit 3 always be 0 and can not be changed<br>-               pci_write_config32(dev, 0x80, val_old); // restore it
<br>+<br>+       if (id.coreid == 0) {<br>+               /* On the primary cpu find the siblings */<br>+               for (i = 1; i <= siblings; i++) {<br>+                       struct device_path cpu_path;<br>+                       device_t new;
<br>+                       /* Build the cpu device path */<br>+                       cpu_path.type = DEVICE_PATH_APIC;<br>+                       cpu_path.u.apic.apic_id =<br>+                               (id.nodeid*max_siblings
) + i;<br>+                       new = alloc_dev(cpu->bus, &cpu_path);<br>+                       if (!new) {<br>+                               continue;<br>+                       }<br>+                       /* Report what I have done */
<br>+                       printk_debug("CPU: %s %s\n",<br>+                               dev_path(new), new->enabled?"enabled":"disabled");<br>+               }<br>       }<br>-<br>-       return e0_later;
<br>}<br><br>-unsigned int read_nb_cfg_54(void)<br>+struct node_core_id get_node_core_id(void)<br>{<br>-        msr_t msr;<br>-        msr = rdmsr(NB_CFG_MSR);<br>-        return ( ( msr.hi >> (54-32)) & 1);<br>
-}<br>-<br>-struct node_core_id get_node_core_id(unsigned int nb_cfg_54) {<br>         struct node_core_id id;<br>-        //    get the apicid via cpuid(1) ebx[27:24]<br>-       if(nb_cfg_54) {<br>-                // when NB_CFG[54] is set, nodid = ebx[27:25], coreid =
<br>ebx[24]<br>-                        id.coreid = (cpuid_ebx(1) >> 24) & 0xf;<br>-                        id.nodeid = (id.coreid>>1);<br>-                        id.coreid &= 1;<br>-       } else { // single core should be here too
<br>+       unsigned siblings;<br>+       /* Get the apicid at reset */<br>+       id.nodeid = (cpuid_ebx(1) >> 24) & 0xff;<br>+       id.coreid = 0;<br>+       /* Find out how many siblings we have */<br>+       siblings = cpuid_ecx(0x80000008) & 0xff;
<br>+       if (siblings) {<br>+               unsigned bits;<br>+               msr_t msr;<br>+               bits = 0;<br>+               while ((1 << bits) <= siblings)<br>+                       bits++;<br>+<br>
+               msr = rdmsr(NB_CFG_MSR);<br>+               if ((msr.hi >> (54-32)) & 1) {<br>+               // when NB_CFG[54] is set, nodeid = ebx[27:25], coreid = ebx[24]<br>+                       id.coreid
 = id.nodeid & ((1 << bits) - 1);<br>+                       id.nodeid >>= bits;<br>+               } else {<br>                 // when NB_CFG[54] is clear, nodeid = ebx[26:24], coreid<br>= ebx[27]<br>-                        
id.nodeid = (cpuid_ebx(1) >> 24) & 0xf;<br>-                        id.coreid = (id.nodeid>>3);<br>-                        id.nodeid &= 7;<br>+                       id.coreid = id.nodeid >> 3;<br>
+                       id.nodeid &= 7;<br>+               }<br>+       } else {<br>+               if (!is_cpu_pre_e0()) {<br>+                       id.nodeid >>= 1;<br>+               }<br>       }<br>-        return id;
<br>+       return id;<br>+}<br><br><br>-}<br><br>+#if 0<br>static int get_max_siblings(int nodes)<br>{<br>       device_t dev;<br>@@ -169,76 +198,5 @@<br><br>       return apicid_base;<br>}<br>-#if 0<br>-void amd_sibling_init(device_t cpu)
<br>-{<br>-       unsigned i, siblings;<br>-       struct cpuid_result result;<br>-       unsigned nb_cfg_54;<br>-       struct node_core_id id;<br><br>-       /* On the bootstrap processor see if I want sibling cpus enabled */
<br>-       if (first_time) {<br>-               first_time = 0;<br>-               get_option(&disable_siblings, "dual_core");<br>-       }<br>-       result = cpuid(0x80000008);<br>-       /* See how many sibling cpus we have */
<br>-       /* Is dualcore supported */<br>-       siblings = (result.ecx & 0xff);<br>-       if ( siblings < 1) {<br>-               return;<br>-       }<br>-<br>-#if 1<br>-       printk_debug("CPU: %u %d siblings\n",
<br>-               cpu->path.u.apic.apic_id,<br>-               siblings);<br>#endif<br>-<br>-       nb_cfg_54 = read_nb_cfg_54();<br>-#if 1<br>-       id = get_node_core_id(nb_cfg_54); // pre e0 nb_cfg_54 can not be set
<br>-<br>-       /* See if I am a sibling cpu */<br>-       //if ((cpu->path.u.apic.apic_id>>(nb_cfg_54?0:3)) & siblings ) { //<br>siblings = 1, 3, 7, 15,....<br>-       //if ( ( (cpu->path.u.apic.apic_id>>(nb_cfg_54?0:3)) % (siblings+1) ) !=
<br>0 ) {<br>-       if(id.coreid != 0) {<br>-               if (disable_siblings) {<br>-                        cpu->enabled = 0;<br>-                }<br>-                return;<br>-       }<br>-#endif<br>-<br>-       /* I am the primary cpu start up my siblings */
<br>-<br>-       for(i = 1; i <= siblings; i++) {<br>-               struct device_path cpu_path;<br>-               device_t new;<br>-               /* Build the cpu device path */<br>-               cpu_path.type = DEVICE_PATH_APIC;
<br>-               cpu_path.u.apic.apic_id = cpu->path.u.apic.apic_id + i *<br>(nb_cfg_54?1:8);<br>-<br>-                /* See if I can find the cpu */<br>-                new = find_dev_path(cpu->bus, &cpu_path);
<br>-               /* Allocate the new cpu device structure */<br>-               if(!new) {<br>-                       new = alloc_dev(cpu->bus, &cpu_path);<br>-                       new->enabled = 1;<br>-                       new->initialized = 0;
<br>-               }<br>-<br>-#if 1<br>-               printk_debug("CPU: %u has sibling %u\n",<br>-                       cpu->path.u.apic.apic_id,<br>-                       new->path.u.apic.apic_id);<br>
-#endif<br>-               /* Start the new cpu */<br>-               if(new->enabled && !new->initialized)<br>-                       start_cpu(new);<br>-       }<br>-<br>-}<br>-#endif<br>-<br>Index: src/cpu/amd/dualcore/dualcore_id.c
<br>===================================================================<br>--- src/cpu/amd/dualcore/dualcore_id.c  (revision 1105)<br>+++ src/cpu/amd/dualcore/dualcore_id.c  (working copy)<br>@@ -11,8 +11,8 @@<br>}<br><br>
struct node_core_id {<br>-       unsigned nodeid;<br>-       unsigned coreid;<br>+       unsigned nodeid:8;<br>+       unsigned coreid:8;<br>};<br><br>static inline struct node_core_id get_node_core_id(unsigned nb_cfg_54) {
<br>Index: src/northbridge/amd/amdk8/coherent_ht.c<br>===================================================================<br>--- src/northbridge/amd/amdk8/coherent_ht.c     (revision 1105)<br>+++ src/northbridge/amd/amdk8/coherent_ht.c     (working copy)
<br>@@ -155,23 +155,6 @@<br><br>}<br><br>-#ifndef ENABLE_APIC_EXT_ID<br>-#define ENABLE_APIC_EXT_ID 0<br>-#endif<br>-<br>-static void enable_apic_ext_id(u8 node)<br>-{<br>-#if ENABLE_APIC_EXT_ID==1<br>-#warning "FIXME Is the right place to enable apic ext id here?"
<br>-<br>-      u32 val;<br>-<br>-        val = pci_read_config32(NODE_HT(node), 0x68);<br>-        val |= (HTTC_APIC_EXT_SPUR | HTTC_APIC_EXT_ID |<br>HTTC_APIC_EXT_BRD_CST);<br>-        pci_write_config32(NODE_HT(node), 0x68, val);
<br>-#endif<br>-}<br>-<br>static void enable_routing(u8 node)<br>{<br>       u32 val;<br>@@ -292,20 +275,18 @@<br>       return 1;<br>}<br><br>-static uint16_t read_freq_cap(device_t dev, uint8_t pos)<br>+static unsigned read_freq_cap(device_t dev, unsigned pos)
<br>{<br>       /* Handle bugs in valid hypertransport frequency reporting */<br>-       uint16_t freq_cap;<br>+       unsigned freq_cap;<br>       uint32_t id;<br><br>       freq_cap = pci_read_config16(dev, pos);<br>       freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies */
<br><br>-#if K8_HT_FREQ_1G_SUPPORT == 1<br>       if (!is_cpu_pre_e0()) {<br>               return freq_cap;<br>       }<br>-#endif<br><br>       id = pci_read_config32(dev, 0);<br><br>@@ -339,8 +320,10 @@<br><br>       /* See if I am changing the link freqency */
<br>       old_freq = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_FREQ);<br>+       old_freq &= 0x0f;<br>       needs_reset |= old_freq != freq;<br>       old_freq = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_FREQ);
<br>+       old_freq &= 0x0f;<br>       needs_reset |= old_freq != freq;<br><br>       /* Set the Calulcated link frequency */<br>@@ -382,7 +365,6 @@<br><br>       /* Set node2's widths */<br>       pci_write_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1, width);
<br>-<br>       return needs_reset;<br>}<br><br>@@ -1625,9 +1607,9 @@<br>}<br>#endif /* CONFIG_MAX_PHYSICAL_CPUS > 1 */<br><br>+static unsigned count_cpus(unsigned nodes)<br>+{<br>#if CONFIG_LOGICAL_CPUS==1<br>-static unsigned verify_dualcore(unsigned nodes)
<br>-{<br>       unsigned node, totalcpus, tmp;<br><br>       totalcpus = 0;<br>@@ -1637,25 +1619,21 @@<br>       }<br><br>       return totalcpus;<br>+#else<br>+       return nodes;<br>+#endif<br><br>}<br>-#endif<br><br>
static void coherent_ht_finalize(unsigned nodes)<br>{<br>+       unsigned total_cpus;<br>+       unsigned cpu_node_count;<br>       unsigned node;<br>       int rev_a0;<br>-#if CONFIG_LOGICAL_CPUS==1<br>-       unsigned total_cpus;
<br>+       total_cpus = count_cpus(nodes);<br>+       cpu_node_count = ((total_cpus -1)<<16)|((nodes - 1) << 4);<br><br>-       if(read_option(CMOS_VSTART_dual_core, CMOS_VLEN_dual_core, 0) == 0) { /*<br>dual_core */
<br>-               total_cpus = verify_dualcore(nodes);<br>-       }<br>-       else {<br>-               total_cpus = nodes;<br>-       }<br>-#endif<br>-<br>       /* set up cpu count and node count and enable Limit<br>
        * Config Space Range for all available CPUs.<br>        * Also clear non coherent hypertransport bus range<br>@@ -1672,11 +1650,7 @@<br>               /* Set the Total CPU and Node count in the system */<br>               val = pci_read_config32(dev, 0x60);
<br>               val &= (~0x000F0070);<br>-#if CONFIG_LOGICAL_CPUS==1<br>-               val |= ((total_cpus-1)<<16)|((nodes-1)<<4);<br>-#else<br>-               val |= ((nodes-1)<<16)|((nodes-1)<<4);
<br>-#endif<br>+               val |= cpu_node_count;<br>               pci_write_config32(dev, 0x60, val);<br><br>               /* Only respond to real cpu pci configuration cycles<br>@@ -1786,6 +1760,33 @@<br>       return needs_reset;
<br>}<br><br>+static void startup_other_cores(unsigned nodes)<br>+{<br>+       unsigned node;<br>+       for(node = 0; node < nodes; node++) {<br>+               device_t dev;<br>+               unsigned siblings;<br>+               dev = NODE_MC(node);
<br>+               siblings = (pci_read_config32(dev, 0xe8) >> 12) & 0x3;<br>+<br>+               if (siblings) {<br>+                       device_t dev_f0;<br>+                       unsigned val;<br>+                       /* Redirect all MC4 accesses and error logging to core0 */
<br>+                       val = pci_read_config32(dev, 0x44);<br>+                       val |= (1 << 27); //NbMcaToMstCpuEn bit<br>+                       pci_write_config32(dev, 0x44, val);<br>+<br>+                       dev_f0 = NODE_HT(node);
<br>+                       /* Enable extended apic id's and second core */<br>+                       val = pci_read_config32(dev_f0, 0x68);<br>+                       val |= (1 << 18) | (1 << 17) | ( 1 << 5);
<br>+                       pci_write_config32(dev_f0, 0x68, val);<br>+               }<br>+       }<br>+}<br>+<br>+<br>static int setup_coherent_ht_domain(void)<br>{<br>       struct setup_smp_result result;<br>@@ -1799,15 +1800,15 @@
<br>       enable_bsp_routing();<br><br>#if CONFIG_MAX_PHYSICAL_CPUS > 1<br>-        result = setup_smp();<br>-        result.nodes = verify_mp_capabilities(result.nodes);<br>-        clear_dead_routes(result.nodes);<br>
+       result = setup_smp();<br>#endif<br>-<br>+       result.nodes = verify_mp_capabilities(result.nodes);<br>+       clear_dead_routes(result.nodes);<br>       if (result.nodes == 1) {<br>               setup_uniprocessor();
<br>       }<br>       coherent_ht_finalize(result.nodes);<br>+       startup_other_cores(result.nodes);<br>       result.needs_reset = apply_cpu_errata_fixes(result.nodes,<br>result.needs_reset);<br>       result.needs_reset
 = optimize_link_read_pointers(result.nodes,<br>result.needs_reset);<br>       return result.needs_reset;<br>Index: src/northbridge/amd/amdk8/amdk8.h<br>===================================================================<br>
--- src/northbridge/amd/amdk8/amdk8.h   (revision 1105)<br>+++ src/northbridge/amd/amdk8/amdk8.h   (working copy)<br>@@ -136,6 +136,7 @@<br>#define        DCL_DisInRcvrs    (1<<24)<br>#define        DCL_BypMax_SHIFT  25
<br>#define        DCL_En2T          (1<<28)<br>+#define         DCL_UpperCSMap    (1<<29)<br>#define DRAM_CONFIG_HIGH   0x94<br>#define        DCH_ASYNC_LAT_SHIFT  0<br>#define        DCH_ASYNC_LAT_MASK   0xf
<br>Index: src/northbridge/amd/amdk8/northbridge.c<br>===================================================================<br>--- src/northbridge/amd/amdk8/northbridge.c     (revision 1105)<br>+++ src/northbridge/amd/amdk8/northbridge.c     (working copy)
<br>@@ -17,9 +17,9 @@<br>#include <cpu/cpu.h><br><br>#include <cpu/x86/lapic.h><br>+#include <cpu/amd/dualcore.h><br><br>#if CONFIG_LOGICAL_CPUS==1<br>-#include <cpu/amd/dualcore.h><br>#include <pc80/mc146818rtc.h>
<br>#endif<br><br>@@ -27,11 +27,8 @@<br>#include "root_complex/chip.h"<br>#include "northbridge.h"<br>#include "amdk8.h"<br>+#include "cpu_rev.c"<br><br>-#if K8_E0_MEM_HOLE_SIZEK != 0
<br>-#include "./cpu_rev.c"<br>-#endif<br>-<br>#define FX_DEVS 8<br>static device_t __f0_dev[FX_DEVS];<br>static device_t __f1_dev[FX_DEVS];<br>@@ -640,6 +637,41 @@<br>       return tolm;<br>}<br><br>+static uint32_t hoist_memory(unsigned long mmio_basek, int i)
<br>+{<br>+       int ii;<br>+       uint32_t carry_over;<br>+       device_t dev;<br>+       uint32_t base, limit;<br>+       uint32_t basek;<br>+       uint32_t hoist;<br>+<br>+       carry_over = (4*1024*1024) - mmio_basek;
<br>+       for(ii=7;ii>i;ii--) {<br>+<br>+               base  = f1_read_config32(0x40 + (ii << 3));<br>+               limit = f1_read_config32(0x44 + (ii << 3));<br>+               if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
<br>+                       continue;<br>+               }<br>+               f1_write_config32(0x44 + (ii << 3),limit + (carry_over << 2));<br>+               f1_write_config32(0x40 + (ii << 3),base + (carry_over << 2));
<br>+       }<br>+       limit = f1_read_config32(0x44 + (i << 3));<br>+       f1_write_config32(0x44 + (i << 3),limit + (carry_over << 2));<br>+       dev = __f1_dev[i];<br>+       base  = pci_read_config32(dev, 0x40 + (i << 3));
<br>+       basek  = (pci_read_config32(dev, 0x40 + (i << 3)) & 0xffff0000) >> 2;<br>+       hoist = /* hole start address */<br>+               ((mmio_basek << 10) & 0xff000000) +<br>+               /* hole address to memory controller address */
<br>+               (((basek + carry_over) >> 6) & 0x0000ff00) +<br>+               /* enable */<br>+               1;<br>+       pci_write_config32(dev, 0xf0, hoist);<br>+       return carry_over;<br>+}<br>+<br>
static void pci_domain_set_resources(device_t dev)<br>{<br>       unsigned long mmio_basek;<br>@@ -648,41 +680,23 @@<br><br>       pci_tolm = find_pci_tolm(&dev->link[0]);<br><br>+       /* Work around for NUMA bug in all kernels before 
2.6.13.<br>+          If pci memory hole is too small, the kernel memory to NUMA<br>+          node mapping will fail to initialize and system will run in<br>+          non-NUMA mode.<br>+       */<br>+       if(pci_tolm > 0xf8000000) pci_tolm = 0xf8000000;
<br>+<br>#warning "FIXME handle interleaved nodes"<br>       mmio_basek = pci_tolm >> 10;<br>       /* Round mmio_basek to something the processor can support */<br>       mmio_basek &= ~((1 << 6) -1);
<br><br>-#if 1<br>-#warning "FIXME improve mtrr.c so we don't use up all of the mtrrs with a<br>64M MMIO hole"<br>-       /* Round the mmio hold to 64M */<br>-       mmio_basek &= ~((64*1024) - 1);<br>-#endif
<br>-<br>-#if K8_E0_MEM_HOLE_SIZEK != 0<br>-       if (!is_cpu_pre_e0())<br>-        for (i = 0; i < 8; i++) {<br>-                uint32_t base;<br>-                base  = f1_read_config32(0x40 + (i << 3));<br>
-                if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {<br>-                        continue;<br>-                }<br>-<br>-               base = pci_read_config32(__f1_dev[i], 0xf0);
<br>-               if((base & 1)==0) continue;<br>-               base &= 0xff<<24;<br>-               base >>= 10;<br>-               if (mmio_basek > base) {<br>-                       mmio_basek = base;
<br>-               }<br>-               break; // only one hole<br>-       }<br>-#endif<br>-<br>       idx = 10;<br>       for(i = 0; i < 8; i++) {<br>               uint32_t base, limit;<br>               unsigned basek, limitk, sizek;
<br>+<br>               base  = f1_read_config32(0x40 + (i << 3));<br>               limit = f1_read_config32(0x44 + (i << 3));<br>               if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
<br>@@ -708,6 +722,9 @@<br>                               pre_sizek = mmio_basek - basek;<br>                               ram_resource(dev, idx++, basek, pre_sizek);<br>                               sizek -= pre_sizek;
<br>+                               if(! is_cpu_pre_e0() ) {<br>+                                       sizek += hoist_memory(mmio_basek,i);<br>+                                }<br>                               basek = mmio_basek;
<br>                       }<br>                       if ((basek + sizek) <= 4*1024*1024) {<br>@@ -767,55 +784,21 @@<br>       .ops_pci_bus      = &pci_cf8_conf1,<br>};<br><br>-#define APIC_ID_OFFSET 0x10<br>-<br>
static unsigned int cpu_bus_scan(device_t dev, unsigned int max)<br>{<br>       struct bus *cpu_bus;<br>       device_t dev_mc;<br>-       int bsp_apic_id;<br>-       int apic_id_offset;<br>+       unsigned max_siblings;<br>
       int i,j;<br>-       unsigned nb_cfg_54;<br>-       int enable_apic_ext_id;<br>-       unsigned siblings;<br>-#if CONFIG_LOGICAL_CPUS == 1<br>-       int e0_later_single_core;<br>-       int disable_siblings;<br>-#endif
<br><br>-       nb_cfg_54 = 0;<br>-       enable_apic_ext_id = 0;<br>-       siblings = 0;<br>-<br>-       /* Find the bootstrap processors apicid */<br>-       bsp_apic_id = lapicid();<br>-<br>-       /* See if I will enable extended ids' */
<br>-       apic_id_offset = bsp_apic_id;<br>-<br>-#if CONFIG_LOGICAL_CPUS == 1<br>-       disable_siblings = !CONFIG_LOGICAL_CPUS;<br>-       get_option(&disable_siblings, "dual_core");<br>-<br>-       // for pre_e0, nb_cfg_54 can not be set, ( even set, when you read it
<br>still be 0)<br>-       // How can I get the nb_cfg_54 of every node' nb_cfg_54 in bsp??? and<br>differ d0 and e0 single core<br>-<br>-       nb_cfg_54 = read_nb_cfg_54();<br>-#endif<br>       dev_mc = dev_find_slot(0, PCI_DEVFN(0x18, 0));
<br>       if (!dev_mc) {<br>               die("0:18.0 not found?");<br>       }<br>-       if (pci_read_config32(dev_mc, 0x68) &<br>(HTTC_APIC_EXT_ID|HTTC_APIC_EXT_BRD_CST))<br>-       {<br>-               enable_apic_ext_id = 1;
<br>-               if (apic_id_offset == 0) {<br>-                       /* bsp apic id is not changed */<br>-                       apic_id_offset = APIC_ID_OFFSET;<br>-               }<br>-       }<br><br>+       /* For now assume all cpus have the same number of siblings */
<br>+       max_siblings = (cpuid_ecx(0x80000008) & 0xff) + 1;<br>+<br>       /* Find which cpus are present */<br>       cpu_bus = &dev->link[0];<br>       for(i = 0; i < 8; i++) {<br>@@ -834,82 +817,36 @@<br>
                                       PCI_DEVFN(0x18 + i, j));<br>                       }<br>               }<br>+<br>+               /* Build the cpu device path */<br>+               cpu_path.type = DEVICE_PATH_APIC;<br>
+               cpu_path.u.apic.apic_id = i*max_siblings;<br><br>-#if CONFIG_LOGICAL_CPUS == 1<br>-               e0_later_single_core = 0;<br>-               if ((!disable_siblings) && dev && dev->enabled) {
<br>-                       j = (pci_read_config32(dev, 0xe8) >> 12) & 3; // dev is func 3<br>-                       printk_debug("  %s siblings=%d\r\n", dev_path(dev), j);<br>+               /* See if I can find the cpu */
<br>+               cpu = find_dev_path(cpu_bus, &cpu_path);<br><br>-                       if(nb_cfg_54) {<br>-                               // For e0 single core if nb_cfg_54 is set, apicid will be 0, 2, 4....<br>-                               //  ----> you can mixed single core e0 and dual core e0 at any
<br>sequence<br>-                               // That is the typical case<br>-<br>-                               if(j == 0 ){<br>-                                      e0_later_single_core = is_e0_later_in_bsp(i);<br>// single core
<br>-                               } else {<br>-                                      e0_later_single_core = 0;<br>-                                       }<br>-                               if(e0_later_single_core) {<br>
-                                       printk_debug("\tFound e0 single core\r\n");<br>-                                       j=1;<br>-                               }<br>-<br>-                               if(siblings > j ) {
<br>-                                       //actually we can't be here, because d0 nb_cfg_54 can not be set<br>-                                       //even worse is_e0_later_in_bsp() can not find out if it is d0 or e0<br>
-<br>-                                       die("When NB_CFG_54 is set, if you want to mix e0 (single core and<br>dual core) and single core(pre e0) CPUs, you need to put all the single<br>core (pre e0) CPUs before all the (e0 single or dual core) CPUs\r\n");
<br>-                               }<br>-                               else {<br>-                                       siblings = j;<br>-                               }<br>-                       } else {<br>-                               siblings = j;
<br>-                       }<br>-               }<br>-#endif<br>-#if CONFIG_LOGICAL_CPUS==1<br>-                for (j = 0; j <= (e0_later_single_core?0:siblings); j++ )<br>{<br>-#else<br>-               for (j = 0; j <= siblings; j++ ) {
<br>-#endif<br>-                       /* Build the cpu device path */<br>-                       cpu_path.type = DEVICE_PATH_APIC;<br>-                       cpu_path.u.apic.apic_id = i * (nb_cfg_54?(siblings+1):1) + j *
<br>(nb_cfg_54?1:8);<br>-<br>-                       /* See if I can find the cpu */<br>-                       cpu = find_dev_path(cpu_bus, &cpu_path);<br>-<br>-                       /* Enable the cpu if I have the processor */
<br>-                       if (dev && dev->enabled) {<br>-                               if (!cpu) {<br>-                                       cpu = alloc_dev(cpu_bus, &cpu_path);<br>-                               }
<br>-                               if (cpu) {<br>-                                       cpu->enabled = 1;<br>-                               }<br>+               /* Enable the cpu if I have the processor */<br>+               if (dev && dev->enabled) {
<br>+                       if (!cpu) {<br>+                               cpu = alloc_dev(cpu_bus, &cpu_path);<br>                       }<br>-<br>-                       /* Disable the cpu if I don't have the processor */
<br>-                       if (cpu && (!dev || !dev->enabled)) {<br>-                               cpu->enabled = 0;<br>-                       }<br>-<br>-                       /* Report what I have done */
<br>                       if (cpu) {<br>-                                if(enable_apic_ext_id) {<br>-<br>if(cpu->path.u.apic.apic_id<apic_id_offset) { //all add offset except bsp<br>core0<br>-<br>if( (cpu->path.u.apic.apic_id
 > siblings) || (bsp_apic_id!=0) )<br>-<br>cpu->path.u.apic.apic_id += apic_id_offset;<br>-                                       }<br>-                               }<br>-                               printk_debug("CPU: %s %s\n",
<br>-                                       dev_path(cpu), cpu->enabled?"enabled":"disabled");<br>+                               cpu->enabled = 1;<br>                       }<br>-               } //j
<br>+               }<br>+<br>+               /* Disable the cpu if I don't have the processor */<br>+               if (cpu && (!dev || !dev->enabled)) {<br>+                       cpu->enabled = 0;<br>+               }
<br>+<br>+               /* Report what I have done */<br>+               if (cpu) {<br>+                       printk_debug("CPU: %s %s\n",<br>+                       dev_path(cpu), cpu->enabled?"enabled":"disabled");
<br>+               }<br>       }<br>+<br>       return max;<br>}<br><br>Index: src/northbridge/amd/amdk8/raminit.c<br>===================================================================<br>--- src/northbridge/amd/amdk8/raminit.c (revision 1105)
<br>+++ src/northbridge/amd/amdk8/raminit.c (working copy)<br>@@ -585,6 +585,16 @@<br><br>}<br><br>+static void e_step_cpu(const struct mem_controller *ctrl)<br>+{<br>+       uint32_t dcl,data32;<br>+<br>+       /* set bit 29 (upper cs map) of function 2 offset 0x90 */
<br>+       dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);<br>+       dcl |= DCL_UpperCSMap;<br>+       pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);<br>+}<br>+<br>static int is_dual_channel(const struct mem_controller *ctrl)
<br>{<br>       uint32_t dcl;<br>@@ -714,28 +724,14 @@<br>       return sz;<br>}<br><br>-static const unsigned cs_map_aa[15] = {<br>-       /* (row=12, col=8)(14, 12) ---> (0, 0) (2, 4) */<br>-       0, 1, 3, 6, 0,<br>
-       0, 2, 4, 7, 9,<br>-       0, 0, 5, 8,10,<br>-};<br>-<br>static void set_dimm_size(const struct mem_controller *ctrl, struct<br>dimm_size sz, unsigned index)<br>{<br>-       uint32_t base0, base1, map;<br>+       uint32_t base0, base1;
<br>       uint32_t dch;<br><br>       if (sz.side1 != sz.side2) {<br>               sz.side2 = 0;<br>       }<br>-       map = pci_read_config32(ctrl->f2, DRAM_BANK_ADDR_MAP);<br>-       map &= ~(0xf << (index * 4));
<br>-#if K8_4RANK_DIMM_SUPPORT == 1<br>-        if(sz.rank == 4) {<br>-                map &= ~(0xf << ( (index + 2) * 4));<br>-        }<br>-#endif<br><br>       /* For each base register.<br>        * Place the dimm size in 32 MB quantities in the bits 31 - 21.
<br>@@ -747,22 +743,6 @@<br><br>       /* Make certain side1 of the dimm is at least 32MB */<br>       if (sz.side1 >= (25 +3)) {<br>-               if(is_cpu_pre_d0()) {<br>-                       map |= (sz.side1 - (25 + 3)) << (index *4);
<br>-#if K8_4RANK_DIMM_SUPPORT == 1<br>-                       if(sz.rank == 4) {<br>-                             map |= (sz.side1 - (25 + 3)) << ( (index + 2) *<br>4);<br>-                               }<br>-#endif
<br>-               }<br>-               else {<br>-                       map |= cs_map_aa[(sz.rows - 12) * 5 + (sz.col - 8) ] << (index*4);<br>-#if K8_4RANK_DIMM_SUPPORT == 1<br>-                       if(sz.rank == 4) {
<br>-                              map |=  cs_map_aa[(sz.rows - 12) * 5 + (sz.col -<br>8) ] << ( (index + 2) * 4);<br>-                               }<br>-#endif<br>-               }<br>               base0 = (1 << ((
sz.side1 - (25 + 3)) + 21)) | 1;<br>       }<br><br>@@ -791,8 +771,6 @@<br>       }<br>#endif<br><br>-       pci_write_config32(ctrl->f2, DRAM_BANK_ADDR_MAP, map);<br>-<br>       /* Enable the memory clocks for this DIMM */
<br>       if (base0) {<br>               dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);<br>@@ -806,6 +784,52 @@<br>       }<br>}<br><br>+<br>+static void set_dimm_map(const struct mem_controller *ctrl,<br>+       struct dimm_size sz, unsigned index)
<br>+{<br>+       static const unsigned cs_map_aa[15] = {<br>+               /* (row=12, col=8)(14, 12) ---> (0, 0) (2, 4) */<br>+               0, 1, 3, 6, 0,<br>+               0, 2, 4, 7, 9,<br>+               0, 0, 5, 8,10,
<br>+       };<br>+       uint32_t map;<br>+       int row,col;<br>+<br>+       map = pci_read_config32(ctrl->f2, DRAM_BANK_ADDR_MAP);<br>+       map &= ~(0xf << (index * 4));<br>+<br>+#if K8_4RANK_DIMM_SUPPORT == 1
<br>+        if(sz.rank == 4) {<br>+                map &= ~(0xf << ( (index + 2) * 4));<br>+        }<br>+#endif<br>+<br>+       if (is_cpu_pre_d0()) {<br>+               map |= (sz.side1 - (25 + 3)) << (index *4);
<br>+#if K8_4RANK_DIMM_SUPPORT == 1<br>+                       if(sz.rank == 4) {<br>+                             map |= (sz.side1 - (25 + 3)) << ( (index + 2) *<br>4);<br>+                               }<br>+#endif
<br>+       } else {<br>+               unsigned val;<br>+               val = cs_map_aa[(sz.rows - 12) * 5 + (sz.col - 8) ];<br>+               if(val == 0) {<br>+                       print_err("Invalid Column or Row count\r\n");
<br>+                       val = 7;<br>+               }<br>+               map |= val << (index*4);<br>+#if K8_4RANK_DIMM_SUPPORT == 1<br>+               if(sz.rank == 4) {<br>+                       map |= val << ( (index + 2) * 4);
<br>+               }<br>+#endif<br>+       }<br>+       pci_write_config32(ctrl->f2, DRAM_BANK_ADDR_MAP, map);<br>+}<br>+<br>static long spd_set_ram_size(const struct mem_controller *ctrl, long<br>dimm_mask)<br>{<br>       int i;
<br>@@ -820,6 +844,7 @@<br>                       return -1; /* Report SPD error */<br>               }<br>               set_dimm_size(ctrl, sz, i);<br>+               set_dimm_map(ctrl, sz, i);<br>       }<br>       return dimm_mask;
<br>}<br>@@ -865,6 +890,13 @@<br>       print_spew_hex32(tom_k);<br>       print_spew(" KB\r\n");<br><br>+#if 0<br>+       /* Report the amount of memory. */<br>+       print_debug("RAM: 0x");<br>+       print_debug_hex32(tom_k);
<br>+       print_debug(" KB\r\n");<br>+#endif<br>+<br>       /* Now set top of memory */<br>       msr_t msr;<br>       msr.lo = (tom_k & 0x003fffff) << 10;<br>@@ -971,7 +1003,7 @@<br>               if(is_dual_channel(ctrl)) {
<br>                 /* Also we run out of address mask bits if we try and<br>interleave 8 4GB dimms */<br>                       if ((bits == 3) && (common_size == (1 << (32 - 3)))) {<br>-//                                     print_debug("8 4GB chip selects cannot be
<br>interleaved\r\n");<br>+                               print_spew("8 4GB chip selects cannot be<br>interleaved\r\n");<br>                               return 0;<br>                       }<br>                       csbase_inc <<=1;
<br>@@ -981,7 +1013,7 @@<br>               csbase_inc = csbase_low_d0[common_cs_mode];<br>               if(is_dual_channel(ctrl)) {<br>                       if( (bits==3) && (common_cs_mode > 8)) {<br>-//                             print_debug("8 cs_mode>8 chip selects cannot
<br>be interleaved\r\n");<br>+                               print_spew("8 cs_mode>8 chip selects cannot be<br>interleaved\r\n");<br>                               return 0;<br>                       }<br>
                       csbase_inc <<=1;<br>@@ -1100,25 +1132,6 @@<br>       return end_k;<br>}<br><br>-#if K8_E0_MEM_HOLE_SIZEK != 0<br>-#define K8_E0_MEM_HOLE_LIMITK 4*1024*1024<br>-#define K8_E0_MEM_HOLE_BASEK (K8_E0_MEM_HOLE_LIMITK -
<br>K8_E0_MEM_HOLE_SIZEK )<br>-<br>-static void set_e0_mem_hole(const struct mem_controller *ctrl, unsigned<br>base_k)<br>-{<br>-        /* Route the addresses to the controller node */<br>-        unsigned val;<br>-<br>-       val = pci_read_config32(ctrl->f1,0xf0);
<br>-<br>-       val &= 0x00ff00fe;<br>-        val = (K8_E0_MEM_HOLE_BASEK << 10) |<br>((K8_E0_MEM_HOLE_SIZEK+base_k)>>(16-10)) | 1;<br>-<br>-       pci_write_config32(ctrl->f1, 0xf0, val);<br>-}<br>-<br>
-#endif<br>-<br>static void order_dimms(const struct mem_controller *ctrl)<br>{<br>       unsigned long tom_k, base_k;<br>@@ -1135,14 +1148,6 @@<br>       /* Compute the memory base address */<br>       base_k = memory_end_k(ctrl, ctrl->node_id);
<br>       tom_k += base_k;<br>-#if K8_E0_MEM_HOLE_SIZEK != 0<br>-       if(!is_cpu_pre_e0()) {<br>-                /* See if I need to check the range cover hole */<br>-                if ((base_k <= K8_E0_MEM_HOLE_BASEK) && (tom_k >
<br>K8_E0_MEM_HOLE_BASEK)) {<br>-                       tom_k += K8_E0_MEM_HOLE_SIZEK;<br>-                }<br>-       }<br>-#endif<br>       route_dram_accesses(ctrl, base_k, tom_k);<br>       set_top_mem(tom_k);<br>}<br>
@@ -2145,12 +2150,11 @@<br>       struct spd_set_memclk_result result;<br>       const struct mem_param *param;<br>       long dimm_mask;<br>-#if 1<br>+<br>       if (!controller_present(ctrl)) {<br>-//             print_debug("No memory controller present\r\n");
<br>+               print_debug("No memory controller present\r\n");<br>               return;<br>       }<br>-#endif<br>       hw_enable_ecc(ctrl);<br>       activate_spd_rom(ctrl);<br>       dimm_mask = spd_detect_dimms(ctrl);
<br>@@ -2176,6 +2180,10 @@<br>       if (dimm_mask < 0)<br>               goto hw_spd_err;<br>       order_dimms(ctrl);<br>+       if( !is_cpu_pre_e0() ) {<br>+               print_debug("E step CPU\r\n");<br>
+               e_step_cpu(ctrl);<br>+       }<br>       return;<br>  hw_spd_err:<br>       /* Unrecoverable error reading SPD data */<br>@@ -2280,22 +2288,6 @@<br>                       } while(((dcl & DCL_MemClrStatus) == 0) || ((dcl & DCL_DramEnable) ==
<br>0) );<br>               }<br><br>-                       // init e0 mem hole here<br>-#if K8_E0_MEM_HOLE_SIZEK != 0<br>-               if (!is_cpu_pre_e0()) {<br>-                        uint32_t base, limit;<br>-                        unsigned base_k, limit_k;
<br>-                        base  = pci_read_config32(ctrl->f1, 0x40 + (i <<<br>3));<br>-                        limit = pci_read_config32(ctrl->f1, 0x44 + (i <<<br>3));<br>-                        base_k = (base & 0xffff0000) >> 2;
<br>-                        limit_k = ((limit + 0x00010000) & 0xffff0000) >><br>2;<br>-                        if ((base_k <= K8_E0_MEM_HOLE_BASEK) && (limit_k<br>> K8_E0_MEM_HOLE_BASEK)) {<br>-                                set_e0_mem_hole(ctrl+i, base_k);
<br>-                        }<br>-                }<br>-<br>-#endif<br>-<br>               print_debug(" done\r\n");<br>       }<br><br><br><br><br>--<br>Using Opera's revolutionary e-mail client: <a href="http://www.opera.com/mail/">
http://www.opera.com/mail/</a><br><br>--<br>LinuxBIOS mailing list<br><a href="mailto:LinuxBIOS@openbios.org">LinuxBIOS@openbios.org</a><br><a href="http://www.openbios.org/mailman/listinfo/linuxbios">http://www.openbios.org/mailman/listinfo/linuxbios
</a><br></blockquote></div><br>