<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>