diff options
Diffstat (limited to 'src/cpu/amd/dualcore/dualcore.c')
-rw-r--r-- | src/cpu/amd/dualcore/dualcore.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/src/cpu/amd/dualcore/dualcore.c b/src/cpu/amd/dualcore/dualcore.c index 1c3b2751a5..12cdaf7589 100644 --- a/src/cpu/amd/dualcore/dualcore.c +++ b/src/cpu/amd/dualcore/dualcore.c @@ -1,12 +1,15 @@ /* 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" +#if 0 static inline unsigned get_core_num_in_bsp(unsigned nodeid) { return ((pci_read_config32(PCI_DEV(0, 0x18+nodeid, 3), 0xe8)>>12) & 3); @@ -97,3 +100,56 @@ static inline void start_other_cores(void) { } } +#endif + +static void k8_init_and_stop_secondaries(void) +{ + struct node_core_id id; + device_t dev; + unsigned apicid; + unsigned max_siblings; + int init_detected; + msr_t msr; + + /* Skip this if there was a built in self test failure */ + init_detected = early_mtrr_init_detected(); + amd_early_mtrr_init(); + enable_lapic(); + init_timer(); + if (init_detected) { + asm volatile ("jmp __cpu_reset"); + } + + if (is_cpu_pre_e0()) { + id.nodeid = lapicid() & 0x7; + id.coreid = 0; + } else { + /* Which cpu are we on? */ + id = get_node_core_id_x(); + + /* Set NB_CFG_MSR + * Linux expect the core to be in the least signficant bits. + */ + msr = rdmsr(NB_CFG_MSR); + msr.hi |= (1<<(54-32)); // InitApicIdCpuIdLo + wrmsr(NB_CFG_MSR, msr); + } + + /* For now assume all cpus have the same number of siblings */ + max_siblings = (cpuid_ecx(0x80000008) & 0xff) + 1; + + /* Set the lapicid */ + lapic_write(LAPIC_ID,((id.nodeid*max_siblings) + id.coreid) << 24); + + /* Remember the cpuid */ + if (id.coreid == 0) { + dev = PCI_DEV(0, 0x18 + id.nodeid, 2); + pci_write_config32(dev, 0x9c, cpuid_eax(1)); + } + + /* Maybe call distinguish_cpu_resets only on the last core? */ + distinguish_cpu_resets(id.nodeid); + if (!boot_cpu()) { + stop_this_cpu(); + } +} |