summaryrefslogtreecommitdiff
path: root/src/cpu/amd/dualcore/dualcore.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/amd/dualcore/dualcore.c')
-rw-r--r--src/cpu/amd/dualcore/dualcore.c78
1 files changed, 69 insertions, 9 deletions
diff --git a/src/cpu/amd/dualcore/dualcore.c b/src/cpu/amd/dualcore/dualcore.c
index 3923891678..e2158424e6 100644
--- a/src/cpu/amd/dualcore/dualcore.c
+++ b/src/cpu/amd/dualcore/dualcore.c
@@ -1,31 +1,72 @@
/* 2004.12 yhlu add dual core support */
+
+#ifndef SET_NB_CFG_54
+ #define SET_NB_CFG_54 1
+#endif
+
#include "cpu/amd/dualcore/dualcore_id.c"
static inline unsigned get_core_num_in_bsp(unsigned nodeid)
{
- return ((pci_read_config32(PCI_DEV(0, 0x18+nodeid, 3), 0xe8)>>12) & 3);
+ uint32_t dword;
+ dword = pci_read_config32(PCI_DEV(0, 0x18+nodeid, 3), 0xe8);
+ dword >>= 12;
+ dword &= 3;
+ return dword;
}
-static inline uint8_t set_apicid_cpuid_lo(void)
+#if SET_NB_CFG_54 == 1
+static inline uint8_t set_apicid_cpuid_lo(void)
{
if(is_cpu_pre_e0()) return 0; // pre_e0 can not be set
-
- if(read_option(CMOS_VSTART_dual_core, CMOS_VLEN_dual_core, 0) != 0) { // disable dual_core
- return 0;
- }
-
- // set the NB_CFG[54]=1; why the OS will be happy with that ???
+ // set the NB_CFG[54]=1; why the OS will be happy with that ???
msr_t msr;
msr = rdmsr(NB_CFG_MSR);
msr.hi |= (1<<(54-32)); // InitApicIdCpuIdLo
wrmsr(NB_CFG_MSR, msr);
return 1;
+}
+#else
+
+static inline void set_apicid_cpuid_lo(void) { }
+
+#endif
+static inline void real_start_other_core(unsigned nodeid)
+{
+ uint32_t dword;
+ // set PCI_DEV(0, 0x18+nodeid, 3), 0x44 bit 27 to redirect all MC4 accesses and error logging to core0
+ dword = pci_read_config32(PCI_DEV(0, 0x18+nodeid, 3), 0x44);
+ dword |= 1<<27; // NbMcaToMstCpuEn bit
+ pci_write_config32(PCI_DEV(0, 0x18+nodeid, 3), 0x44, dword);
+ // set PCI_DEV(0, 0x18+nodeid, 0), 0x68 bit 5 to start core1
+ dword = pci_read_config32(PCI_DEV(0, 0x18+nodeid, 0), 0x68);
+ dword |= 1<<5;
+ pci_write_config32(PCI_DEV(0, 0x18+nodeid, 0), 0x68, dword);
}
+//it is running on core0 of node0
+static inline void start_other_cores(void)
+{
+ unsigned nodes;
+ unsigned nodeid;
+
+ if(read_option(CMOS_VSTART_dual_core, CMOS_VLEN_dual_core, 0) != 0) { // disable dual_core
+ return;
+ }
+
+ nodes = get_nodes();
+
+ for(nodeid=0; nodeid<nodes; nodeid++) {
+ if( get_core_num_in_bsp(nodeid) > 0) {
+ real_start_other_core(nodeid);
+ }
+ }
+
+}
#if USE_DCACHE_RAM == 0
static void do_k8_init_and_stop_secondaries(void)
{
@@ -62,7 +103,26 @@ static void do_k8_init_and_stop_secondaries(void)
pci_write_config32(dev_f0, 0x68, val);
/* Set the lapicid */
- lapic_write(LAPIC_ID,(0x10 + id.coreid*0x10 + id.nodeid) << 24);
+ #if (ENABLE_APIC_EXT_ID == 1)
+ unsigned initial_apicid = get_initial_apicid();
+ #if LIFT_BSP_APIC_ID == 0
+ if( initial_apicid != 0 ) // other than bsp
+ #endif
+ {
+ /* use initial apic id to lift it */
+ uint32_t dword = lapic_read(LAPIC_ID);
+ dword &= ~(0xff<<24);
+ dword |= (((initial_apicid + APIC_ID_OFFSET) & 0xff)<<24);
+
+ lapic_write(LAPIC_ID, dword);
+ }
+
+ #if LIFT_BSP_APIC_ID == 1
+ bsp_apicid += APIC_ID_OFFSET;
+ #endif
+
+ #endif
+
/* Remember the cpuid */
if (id.coreid == 0) {