9c292b823c6dd4b2340dfa5989354d5f359a2713
[coreboot.git] / src / cpu / amd / dualcore / dualcore.c
1 /* 2004.12 yhlu add dual core support */
2
3 #include "cpu/amd/dualcore/dualcore_id.c"
4
5 static void do_k8_init_and_stop_secondaries(void)
6 {
7         struct node_core_id id;
8         device_t dev;
9         unsigned apicid;
10         unsigned max_siblings;
11         msr_t msr;
12         
13         /* Skip this if there was a built in self test failure */
14
15         if (is_cpu_pre_e0()) {
16                 id.nodeid = lapicid() & 0x7;
17                 id.coreid = 0;
18         } else {
19                 /* Which cpu are we on? */
20                 id = get_node_core_id_x();
21
22                 /* Set NB_CFG_MSR
23                  * Linux expect the core to be in the least signficant bits.
24                  */
25                 msr = rdmsr(NB_CFG_MSR);
26                 msr.hi |= (1<<(54-32)); // InitApicIdCpuIdLo
27                 wrmsr(NB_CFG_MSR, msr);
28         }
29
30         /* For now assume all cpus have the same number of siblings */
31         max_siblings = (cpuid_ecx(0x80000008) & 0xff) + 1;
32
33         /* Enable extended apic ids */
34         device_t dev_f0 = PCI_DEV(0, 0x18+id.nodeid, 0);
35         unsigned val = pci_read_config32(dev_f0, 0x68);
36         val |= (1 << 18) | (1 << 17);
37         pci_write_config32(dev_f0, 0x68, val);
38
39         /* Set the lapicid */
40         lapic_write(LAPIC_ID,(0x10 + id.coreid*0x10 + id.nodeid) << 24);
41
42         /* Remember the cpuid */
43         if (id.coreid == 0) {
44                 dev = PCI_DEV(0, 0x18 + id.nodeid, 2);
45                 pci_write_config32(dev, 0x9c, cpuid_eax(1));    
46         }
47         
48         /* Maybe call distinguish_cpu_resets only on the last core? */
49         distinguish_cpu_resets(id.nodeid);
50         if (!boot_cpu()) {
51                 stop_this_cpu();
52         }
53 }
54
55 static void k8_init_and_stop_secondaries(void)
56 {
57         /* This doesn't work with Cache As Ram because it messes with 
58            the MTRR state, which breaks the init detection.
59            do_k8_init_and_stop_secondaries should be usable by CAR code.
60         */
61
62         int init_detected;
63
64         init_detected = early_mtrr_init_detected();
65         amd_early_mtrr_init();
66
67         enable_lapic();
68         init_timer();
69         if (init_detected) {
70                 asm volatile ("jmp __cpu_reset");
71         }
72
73         do_k8_init_and_stop_secondaries();
74 }