819f9b16663a81db80ba0cde4632c47df3be610d
[coreboot.git] / src / cpu / amd / model_10xxx / init_cpus.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2007 Advanced Micro Devices, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
18  */
19
20
21 //it takes the ENABLE_APIC_EXT_ID and APIC_ID_OFFSET and LIFT_BSP_APIC_ID
22 #ifndef FAM10_SET_FIDVID
23         #define FAM10_SET_FIDVID 1
24 #endif
25
26 #ifndef FAM10_SET_FIDVID_CORE0_ONLY
27         /* MSR FIDVID_CTL and FIDVID_STATUS are shared by cores,
28            Need to do every AP to set common FID/VID*/
29         #define FAM10_SET_FIDVID_CORE0_ONLY 0
30 #endif
31
32
33 static inline void print_initcpu8 (const char *strval, u8 val)
34 {
35         printk_debug("%s%02x\n", strval, val);
36 }
37
38 static inline void print_initcpu8_nocr (const char *strval, u8 val)
39 {
40         printk_debug("%s%02x", strval, val);
41 }
42
43
44 static inline void print_initcpu16 (const char *strval, u16 val)
45 {
46         printk_debug("%s%04x\n", strval, val);
47 }
48
49
50 static inline void print_initcpu(const char *strval, u32 val)
51 {
52         printk_debug("%s%08x\n", strval, val);
53 }
54
55
56 static void prep_fid_change(void);
57 static void init_fidvid_stage2(u32 apicid, u32 nodeid);
58
59 #if PCI_IO_CFG_EXT == 1
60 static inline void set_EnableCf8ExtCfg(void)
61 {
62         // set the NB_CFG[46]=1;
63         msr_t msr;
64         msr = rdmsr(NB_CFG_MSR);
65         // EnableCf8ExtCfg: We need that to access PCI_IO_CFG_EXT 4K range
66         msr.hi |= (1<<(46-32));
67         wrmsr(NB_CFG_MSR, msr);
68 }
69 #else
70 static inline void set_EnableCf8ExtCfg(void) { }
71 #endif
72
73
74 /*[39:8] */
75 #define PCI_MMIO_BASE 0xfe000000
76 /* because we will use gs to store hi, so need to make sure lo can start
77    from 0, So PCI_MMIO_BASE & 0x00ffffff should be equal to 0*/
78
79 static inline void set_pci_mmio_conf_reg(void)
80 {
81 #if MMCONF_SUPPORT
82         msr_t msr;
83         msr = rdmsr(0xc0010058);
84         msr.lo &= ~(0xfff00000 | (0xf << 2));
85         // 256 bus per segment, MMIO reg will be 4G , enable MMIO Config space
86         msr.lo |= ((8+PCI_BUS_SEGN_BITS) << 2) | (1 << 0);
87         msr.hi &= ~(0x0000ffff);
88         msr.hi |= (PCI_MMIO_BASE >> (32-8));
89         wrmsr(0xc0010058, msr); // MMIO Config Base Address Reg
90
91         //mtrr for that range?
92 //      set_var_mtrr_x(7, PCI_MMIO_BASE<<8, PCI_MMIO_BASE>>(32-8), 0x00000000, 0x01, MTRR_TYPE_UNCACHEABLE);
93
94         set_wrap32dis();
95
96         msr.hi = (PCI_MMIO_BASE >> (32-8));
97         msr.lo = 0;
98         wrmsr(0xc0000101, msr); //GS_Base Reg
99
100
101
102 #endif
103 }
104
105
106 typedef void (*process_ap_t)(u32 apicid, void *gp);
107
108 //core_range = 0 : all cores
109 //core range = 1 : core 0 only
110 //core range = 2 : cores other than core0
111
112 static void for_each_ap(u32 bsp_apicid, u32 core_range,
113                                 process_ap_t process_ap, void *gp)
114 {
115         // here assume the OS don't change our apicid
116         u32 ap_apicid;
117
118         u32 nodes;
119         u32 siblings;
120         u32 disable_siblings;
121         u32 cores_found;
122         u32 nb_cfg_54;
123         int i,j;
124         u32 ApicIdCoreIdSize;
125
126         /* get_nodes define in ht_wrapper.c */
127         nodes = get_nodes();
128
129         disable_siblings = !CONFIG_LOGICAL_CPUS;
130
131 #if CONFIG_LOGICAL_CPUS == 1
132         if(read_option(CMOS_VSTART_quad_core, CMOS_VLEN_quad_core, 0) != 0) { // 0 mean quad core
133                 disable_siblings = 1;
134         }
135 #endif
136
137         /* Assume that all node are same stepping, otherwise we can use use
138            nb_cfg_54 from bsp for all nodes */
139         nb_cfg_54 = read_nb_cfg_54();
140
141         ApicIdCoreIdSize = (cpuid_ecx(0x80000008) >> 12 & 0xf);
142         if(ApicIdCoreIdSize) {
143                 siblings = ((1 << ApicIdCoreIdSize) - 1);
144         } else {
145                 siblings = 3; //quad core
146         }
147
148         for (i = 0; i < nodes; i++) {
149                 cores_found = get_core_num_in_bsp(i);
150
151                 u32 jstart, jend;
152
153                 if (core_range == 2) {
154                         jstart = 1;
155                 } else {
156                         jstart = 0;
157                 }
158
159                 if (disable_siblings || (core_range==1)) {
160                         jend = 0;
161                 } else {
162                         jend = cores_found;
163                 }
164
165
166                 for (j = jstart; j <= jend; j++) {
167                         ap_apicid = i * (nb_cfg_54 ? (siblings + 1):1) + j * (nb_cfg_54 ? 1:64);
168
169                 #if (ENABLE_APIC_EXT_ID == 1) && (APIC_ID_OFFSET > 0)
170                         #if LIFT_BSP_APIC_ID == 0
171                         if( (i != 0) || (j != 0)) /* except bsp */
172                         #endif
173                                 ap_apicid += APIC_ID_OFFSET;
174                 #endif
175
176                         if(ap_apicid == bsp_apicid) continue;
177
178                         process_ap(ap_apicid, gp);
179
180                 }
181         }
182 }
183
184 /* FIXME: Duplicate of what is in lapic.h? */
185 static inline int lapic_remote_read(int apicid, int reg, u32 *pvalue)
186 {
187         int timeout;
188         u32 status;
189         int result;
190         lapic_wait_icr_idle();
191         lapic_write(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(apicid));
192         lapic_write(LAPIC_ICR, LAPIC_DM_REMRD | (reg >> 4));
193         timeout = 0;
194
195         do {
196                 status = lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY;
197         } while (status == LAPIC_ICR_BUSY && timeout++ < 1000);
198
199         timeout = 0;
200         do {
201                 status = lapic_read(LAPIC_ICR) & LAPIC_ICR_RR_MASK;
202         } while (status == LAPIC_ICR_RR_INPROG && timeout++ < 1000);
203
204         result = -1;
205
206         if (status == LAPIC_ICR_RR_VALID) {
207                 *pvalue = lapic_read(LAPIC_RRR);
208                 result = 0;
209         }
210         return result;
211 }
212
213
214 /* Use the LAPIC timer count register to hold each cores init status */
215 #define LAPIC_MSG_REG 0x380
216
217
218 #if FAM10_SET_FIDVID == 1
219 static void init_fidvid_ap(u32 bsp_apicid, u32 apicid, u32 nodeid, u32 coreid);
220 #endif
221
222 static inline __attribute__((always_inline)) void print_apicid_nodeid_coreid(u32 apicid, struct node_core_id id, const char *str)
223 {
224                 printk_debug("%s --- {   APICID = %02x NODEID = %02x COREID = %02x} ---\n", str, apicid, id.nodeid, id.coreid);
225 }
226
227
228 static unsigned wait_cpu_state(u32 apicid, u32 state)
229 {
230         u32 readback = 0;
231         u32 timeout = 1;
232         int loop = 4000000;
233         while (--loop > 0) {
234                 if (lapic_remote_read(apicid, LAPIC_MSG_REG, &readback) != 0) continue;
235                 if ((readback & 0x3f) == state) {
236                         timeout = 0;
237                         break; //target cpu is in stage started
238                 }
239         }
240         if (timeout) {
241                 if (readback) {
242                         timeout = readback;
243                 }
244         }
245
246         return timeout;
247 }
248
249
250 static void wait_ap_started(u32 ap_apicid, void *gp )
251 {
252         u32 timeout;
253         timeout = wait_cpu_state(ap_apicid, 0x13); // started
254         if(timeout) {
255                 print_initcpu8_nocr("* AP ", ap_apicid);
256                 print_initcpu(" didn't start timeout:", timeout);
257         }
258         else {
259                 print_initcpu8_nocr("AP started: ", ap_apicid);
260         }
261 }
262
263
264 static void wait_all_aps_started(u32 bsp_apicid)
265 {
266         for_each_ap(bsp_apicid, 0 , wait_ap_started, (void *)0);
267 }
268
269
270 static void wait_all_other_cores_started(u32 bsp_apicid)
271 {
272         // all aps other than core0
273         print_debug("started ap apicid: ");
274         for_each_ap(bsp_apicid, 2 , wait_ap_started, (void *)0);
275         print_debug("\n");
276 }
277
278
279 static void allow_all_aps_stop(u32 bsp_apicid)
280 {
281         /* Called by the BSP to indicate AP can stop */
282
283         /* FIXME Do APs use this?
284            Looks like wait_till_sysinfo_in_ram is used instead. */
285
286         // allow aps to stop use 6 bits for state
287         lapic_write(LAPIC_MSG_REG, (bsp_apicid << 24) | 0x14);
288 }
289
290
291 static void STOP_CAR_AND_CPU()
292 {
293         disable_cache_as_ram(); // inline
294         stop_this_cpu();
295 }
296
297
298 #ifndef MEM_TRAIN_SEQ
299 #define MEM_TRAIN_SEQ 0
300 #endif
301
302 #if RAMINIT_SYSINFO == 1
303 static u32 init_cpus(u32 cpu_init_detectedx ,struct sys_info *sysinfo)
304 #else
305 static u32 init_cpus(u32 cpu_init_detectedx)
306 #endif
307 {
308         u32 bsp_apicid = 0;
309         u32 apicid;
310         struct node_core_id id;
311
312         /*
313          * already set early mtrr in cache_as_ram.inc
314          */
315
316         /* enable access pci conf via mmio*/
317         set_pci_mmio_conf_reg();
318
319         /* that is from initial apicid, we need nodeid and coreid
320            later */
321         id = get_node_core_id_x();
322
323         /* NB_CFG MSR is shared between cores, so we need make sure
324           core0 is done at first --- use wait_all_core0_started  */
325         if(id.coreid == 0) {
326                 set_apicid_cpuid_lo(); /* only set it on core0 */
327                 set_EnableCf8ExtCfg(); /* only set it on core0 */
328                 #if (ENABLE_APIC_EXT_ID == 1)
329                 enable_apic_ext_id(id.nodeid);
330                 #endif
331         }
332
333         enable_lapic();
334
335
336 #if (ENABLE_APIC_EXT_ID == 1) && (APIC_ID_OFFSET > 0)
337         u32 initial_apicid = get_initial_apicid();
338
339         #if LIFT_BSP_APIC_ID == 0
340         if( initial_apicid != 0 ) // other than bsp
341         #endif
342         {
343                 /* use initial apic id to lift it */
344                 u32 dword = lapic_read(LAPIC_ID);
345                 dword &= ~(0xff << 24);
346                 dword |= (((initial_apicid + APIC_ID_OFFSET) & 0xff) << 24);
347
348                 lapic_write(LAPIC_ID, dword);
349         }
350
351         #if LIFT_BSP_APIC_ID == 1
352         bsp_apicid += APIC_ID_OFFSET;
353         #endif
354
355 #endif
356
357         /* get the apicid, it may be lifted already */
358         apicid = lapicid();
359
360         // show our apicid, nodeid, and coreid
361         if( id.coreid==0 ) {
362                 if (id.nodeid!=0) //all core0 except bsp
363                         print_apicid_nodeid_coreid(apicid, id, " core0: ");
364         }
365         else { //all other cores
366                 print_apicid_nodeid_coreid(apicid, id, " corex: ");
367         }
368
369
370         if (cpu_init_detectedx) {
371                 print_apicid_nodeid_coreid(apicid, id, "\n\n\nINIT detected from ");
372                 print_debug("\nIssuing SOFT_RESET...\n");
373                 soft_reset();
374         }
375
376         if(id.coreid == 0) {
377                 if(!(warm_reset_detect(id.nodeid))) //FIXME: INIT is checked above but check for more resets?
378                         distinguish_cpu_resets(id.nodeid); // Also indicates we are started
379         }
380
381         // Mark the core as started.
382         lapic_write(LAPIC_MSG_REG, (apicid << 24) | 0x13);
383
384
385         if(apicid != bsp_apicid) {
386 #if FAM10_SET_FIDVID == 1
387         #if (CONFIG_LOGICAL_CPUS == 1)  && (FAM10_SET_FIDVID_CORE0_ONLY == 1)
388                 // Run on all AP for proper FID/VID setup.
389                 if(id.coreid == 0 ) // only need set fid for core0
390         #endif
391                 {
392                 // check warm(bios) reset to call stage2 otherwise do stage1
393                         if (warm_reset_detect(id.nodeid)) {
394                                 printk_debug("init_fidvid_stage2 apicid: %02x\n", apicid);
395                                 init_fidvid_stage2(apicid, id.nodeid);
396                         } else {
397                                 printk_debug("init_fidvid_ap(stage1) apicid: %02x\n", apicid);
398                                 init_fidvid_ap(bsp_apicid, apicid, id.nodeid, id.coreid);
399                         }
400                 }
401 #endif
402
403                 /* AP is ready, Wait for the BSP to get memory configured */
404                 /* FIXME: many cores spinning on node0 pci register seems to be bad.
405                  * Why do we need to wait? These APs are just going to go sit in a hlt.
406                  */
407                 //wait_till_sysinfo_in_ram();
408
409                 set_init_ram_access();
410
411                 STOP_CAR_AND_CPU();
412                 printk_debug("\nAP %02x should be halted but you are reading this....\n", apicid);
413         }
414
415         return bsp_apicid;
416 }
417
418
419 static u32 is_core0_started(u32 nodeid)
420 {
421         u32 htic;
422         device_t device;
423         device = NODE_PCI(nodeid, 0);
424         htic = pci_read_config32(device, HT_INIT_CONTROL);
425         htic &= HTIC_ColdR_Detect;
426         return htic;
427 }
428
429
430 static void wait_all_core0_started(void)
431 {
432         /* When core0 is started, it will distingush_cpu_resets
433           . So wait for that to finish */
434         u32 i;
435         u32 nodes = get_nodes();
436
437         printk_debug("Wait all core0s started \n");
438         for(i=1;i<nodes;i++) { // skip bsp, because it is running on bsp
439                 while(!is_core0_started(i)) {}
440                 print_initcpu8("  Core0 started on node: ", i);
441         }
442         printk_debug("Wait all core0s started done\n");
443 }
444 #if CONFIG_MAX_PHYSICAL_CPUS > 1
445 /**
446  * void start_node(u32 node)
447  *
448  *  start the core0 in node, so it can generate HT packet to feature code.
449  *
450  * This function starts the AP nodes core0s. wait_all_core0_started() in
451  * cache_as_ram_auto.c waits for all the AP to be finished before continuing
452  * system init.
453  */
454 static void start_node(u8 node)
455 {
456         u32 val;
457
458         /* Enable routing table */
459         printk_debug("Start node %02x", node);
460
461 #if CAR_FAM10 == 1
462         /* For CAR_FAM10 support, we need to set Dram base/limit for the new node */
463         pci_write_config32(NODE_MP(node), 0x44, 0);
464         pci_write_config32(NODE_MP(node), 0x40, 3);
465 #endif
466
467         /* Allow APs to make requests (ROM fetch) */
468         val=pci_read_config32(NODE_HT(node), 0x6c);
469         val &= ~(1 << 1);
470         pci_write_config32(NODE_HT(node), 0x6c, val);
471
472         printk_debug(" done.\n");
473 }
474
475
476 /**
477  * static void setup_remote_node(u32 node)
478  *
479  * Copy the BSP Adress Map to each AP.
480  */
481 static void setup_remote_node(u8 node)
482 {
483         /* There registers can be used with F1x114_x Address Map at the
484            same time, So must set them even 32 node */
485         static const u16 pci_reg[] = {
486                 /* DRAM Base/Limits Registers */
487                 0x44, 0x4c, 0x54, 0x5c, 0x64, 0x6c, 0x74, 0x7c,
488                 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78,
489                 0x144, 0x14c, 0x154, 0x15c, 0x164, 0x16c, 0x174, 0x17c,
490                 0x140, 0x148, 0x150, 0x158, 0x160, 0x168, 0x170, 0x178,
491                 /* MMIO Base/Limits Registers */
492                 0x84, 0x8c, 0x94, 0x9c, 0xa4, 0xac, 0xb4, 0xbc,
493                 0x80, 0x88, 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8,
494                 /* IO Base/Limits Registers */
495                 0xc4, 0xcc, 0xd4, 0xdc,
496                 0xc0, 0xc8, 0xd0, 0xd8,
497                 /* Configuration Map Registers */
498                 0xe0, 0xe4, 0xe8, 0xec,
499         };
500         u16 i;
501
502         printk_debug("setup_remote_node: %02x", node);
503
504         /* copy the default resource map from node 0 */
505         for(i = 0; i < sizeof(pci_reg)/sizeof(pci_reg[0]); i++) {
506                 u32 value;
507                 u16 reg;
508                 reg = pci_reg[i];
509                 value = pci_read_config32(NODE_MP(0), reg);
510                 pci_write_config32(NODE_MP(node), reg, value);
511
512         }
513         printk_debug(" done\n");
514 }
515 #endif
516 /**
517  * finalize_node_setup()
518  *
519  * Do any additional post HT init
520  *
521  * This could really be moved to cache_as_ram_auto.c since it really isn't HT init.
522  */
523 void finalize_node_setup(struct sys_info *sysinfo)
524 {
525         u8 i;
526         u8 nodes = get_nodes();
527         u32 reg;
528
529 #if RAMINIT_SYSINFO == 1
530         /* read Node0 F0_0x64 bit [8:10] to find out SbLink # */
531         reg = pci_read_config32(NODE_HT(0), 0x64);
532         sysinfo->sblk = (reg>>8) & 7;
533         sysinfo->sbbusn = 0;
534         sysinfo->nodes = nodes;
535         sysinfo->sbdn = get_sbdn(sysinfo->sbbusn);
536 #endif
537
538         setup_link_trans_cntrl();
539
540 #if FAM10_SET_FIDVID == 1
541         // Prep each node for FID/VID setup.
542         prep_fid_change();
543 #endif
544
545 #if CONFIG_MAX_PHYSICAL_CPUS > 1
546         /* Skip the BSP, start at node 1 */
547         for(i=1; i<nodes; i++) {
548                 setup_remote_node(i);
549                 start_node(i);
550         }
551 #endif
552 }
553