b1894ce1544c0811f3d3819ba4c4ff38f10b0783
[coreboot.git] / src / cpu / amd / dualcore / dualcore.c
1 /* 2004.12 yhlu add dual core support */
2
3
4 #ifndef SET_NB_CFG_54
5         #define SET_NB_CFG_54 1
6 #endif
7
8 #include "cpu/amd/dualcore/dualcore_id.c"
9 #include <pc80/mc146818rtc.h>
10 #if CONFIG_HAVE_OPTION_TABLE
11 #include "option_table.h"
12 #endif
13
14 static inline unsigned get_core_num_in_bsp(unsigned nodeid)
15 {
16         uint32_t dword;
17         dword = pci_read_config32(PCI_DEV(0, 0x18+nodeid, 3), 0xe8);
18         dword >>= 12;
19         dword &= 3;
20         return dword;
21 }
22
23 #if SET_NB_CFG_54 == 1
24 static inline uint8_t set_apicid_cpuid_lo(void)
25 {
26 #if CONFIG_K8_REV_F_SUPPORT == 0
27         if(is_cpu_pre_e0()) return 0; // pre_e0 can not be set
28 #endif
29
30         // set the NB_CFG[54]=1; why the OS will be happy with that ???
31         msr_t msr;
32         msr = rdmsr(NB_CFG_MSR);
33         msr.hi |= (1<<(54-32)); // InitApicIdCpuIdLo
34         wrmsr(NB_CFG_MSR, msr);
35
36         return 1;
37 }
38 #else
39
40 static inline void set_apicid_cpuid_lo(void) { }
41
42 #endif
43
44 static inline void real_start_other_core(unsigned nodeid)
45 {
46         uint32_t dword;
47         // set PCI_DEV(0, 0x18+nodeid, 3), 0x44 bit 27 to redirect all MC4 accesses and error logging to core0
48         dword = pci_read_config32(PCI_DEV(0, 0x18+nodeid, 3), 0x44);
49         dword |= 1<<27; // NbMcaToMstCpuEn bit
50         pci_write_config32(PCI_DEV(0, 0x18+nodeid, 3), 0x44, dword);
51         // set PCI_DEV(0, 0x18+nodeid, 0), 0x68 bit 5 to start core1
52         dword = pci_read_config32(PCI_DEV(0, 0x18+nodeid, 0), 0x68);
53         dword |= 1<<5;
54         pci_write_config32(PCI_DEV(0, 0x18+nodeid, 0), 0x68, dword);
55 }
56
57 //it is running on core0 of node0
58 static inline void start_other_cores(void)
59 {
60         unsigned nodes;
61         unsigned nodeid;
62
63         if (read_option(CMOS_VSTART_multi_core, CMOS_VLEN_multi_core, 0))  {
64                 return; // disable multi_core
65         }
66
67         nodes = get_nodes();
68
69         for(nodeid=0; nodeid<nodes; nodeid++) {
70                 if( get_core_num_in_bsp(nodeid) > 0) {
71                         real_start_other_core(nodeid);
72                 }
73         }
74
75 }
76
77