1 /* 2004.12 yhlu add dual core support */
3 #include "cpu/amd/dualcore/dualcore_id.c"
5 static void do_k8_init_and_stop_secondaries(void)
7 struct node_core_id id;
10 unsigned max_siblings;
13 /* Skip this if there was a built in self test failure */
15 if (is_cpu_pre_e0()) {
16 id.nodeid = lapicid() & 0x7;
19 /* Which cpu are we on? */
20 id = get_node_core_id_x();
23 * Linux expect the core to be in the least signficant bits.
25 msr = rdmsr(NB_CFG_MSR);
26 msr.hi |= (1<<(54-32)); // InitApicIdCpuIdLo
27 wrmsr(NB_CFG_MSR, msr);
30 /* For now assume all cpus have the same number of siblings */
31 max_siblings = (cpuid_ecx(0x80000008) & 0xff) + 1;
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);
40 lapic_write(LAPIC_ID,(0x10 + id.coreid*0x10 + id.nodeid) << 24);
42 /* Remember the cpuid */
44 dev = PCI_DEV(0, 0x18 + id.nodeid, 2);
45 pci_write_config32(dev, 0x9c, cpuid_eax(1));
48 /* Maybe call distinguish_cpu_resets only on the last core? */
49 distinguish_cpu_resets(id.nodeid);
55 static void k8_init_and_stop_secondaries(void)
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.
64 init_detected = early_mtrr_init_detected();
65 amd_early_mtrr_init();
70 asm volatile ("jmp __cpu_reset");
73 do_k8_init_and_stop_secondaries();