summaryrefslogtreecommitdiff
path: root/src/cpu/amd/dualcore
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/amd/dualcore')
-rw-r--r--src/cpu/amd/dualcore/Config.lb6
-rw-r--r--src/cpu/amd/dualcore/dualcore.c78
-rw-r--r--src/cpu/amd/dualcore/dualcore_id.c20
3 files changed, 81 insertions, 23 deletions
diff --git a/src/cpu/amd/dualcore/Config.lb b/src/cpu/amd/dualcore/Config.lb
index dd8dd09963..acc5d2e2f8 100644
--- a/src/cpu/amd/dualcore/Config.lb
+++ b/src/cpu/amd/dualcore/Config.lb
@@ -1,5 +1 @@
-uses CONFIG_LOGICAL_CPUS
-
-if CONFIG_LOGICAL_CPUS
- object amd_sibling.o
-end
+object amd_sibling.o
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) {
diff --git a/src/cpu/amd/dualcore/dualcore_id.c b/src/cpu/amd/dualcore/dualcore_id.c
index a1a898a4fa..389969795b 100644
--- a/src/cpu/amd/dualcore/dualcore_id.c
+++ b/src/cpu/amd/dualcore/dualcore_id.c
@@ -1,26 +1,27 @@
/* 2004.12 yhlu add dual core support */
#include <arch/cpu.h>
+#include <cpu/amd/dualcore.h>
+#ifdef __ROMCC__
#include <cpu/amd/model_fxx_msr.h>
+#endif
-static inline unsigned int read_nb_cfg_54(void)
+//called by bus_cpu_scan too
+unsigned int read_nb_cfg_54(void)
{
msr_t msr;
msr = rdmsr(NB_CFG_MSR);
return ( ( msr.hi >> (54-32)) & 1);
}
-struct node_core_id {
- unsigned nodeid:8;
- unsigned coreid:8;
-};
-
-static inline unsigned get_initial_apicid(void)
+static inline unsigned get_initial_apicid(void)
{
return ((cpuid_ebx(1) >> 24) & 0xf);
}
-static inline struct node_core_id get_node_core_id(unsigned nb_cfg_54) {
+//called by amd_siblings too
+struct node_core_id get_node_core_id(unsigned nb_cfg_54)
+{
struct node_core_id id;
// get the apicid via cpuid(1) ebx[27:24]
if( nb_cfg_54) {
@@ -45,6 +46,7 @@ static inline unsigned get_core_num(void)
}
static inline struct node_core_id get_node_core_id_x(void) {
- return get_node_core_id( read_nb_cfg_54() );
+
+ return get_node_core_id( read_nb_cfg_54() ); // for pre_e0() nb_cfg_54 always be 0
}