fix some glitches in cht code: always enable routing on node7, plus do masking right...
[coreboot.git] / src / northbridge / amd / amdk8 / coherent_ht.c
1 #if 0
2 static void setup_coherent_ht_domain(void)
3 {
4         static const unsigned int register_values[] = {
5         /* Routing Table Node i 
6          * F0:0x40 i = 0, 
7          * F0:0x44 i = 1,
8          * F0:0x48 i = 2, 
9          * F0:0x4c i = 3,
10          * F0:0x50 i = 4, 
11          * F0:0x54 i = 5,
12          * F0:0x58 i = 6, 
13          * F0:0x5c i = 7
14          * [ 0: 3] Request Route
15          *     [0] Route to this node
16          *     [1] Route to Link 0
17          *     [2] Route to Link 1
18          *     [3] Route to Link 2
19          * [11: 8] Response Route
20          *     [0] Route to this node
21          *     [1] Route to Link 0
22          *     [2] Route to Link 1
23          *     [3] Route to Link 2
24          * [19:16] Broadcast route
25          *     [0] Route to this node
26          *     [1] Route to Link 0
27          *     [2] Route to Link 1
28          *     [3] Route to Link 2
29          */
30         PCI_ADDR(0, 0x18, 0, 0x40), 0xfff0f0f0, 0x00010101,
31         PCI_ADDR(0, 0x18, 0, 0x44), 0xfff0f0f0, 0x00010101,
32         PCI_ADDR(0, 0x18, 0, 0x48), 0xfff0f0f0, 0x00010101,
33         PCI_ADDR(0, 0x18, 0, 0x4c), 0xfff0f0f0, 0x00010101,
34         PCI_ADDR(0, 0x18, 0, 0x50), 0xfff0f0f0, 0x00010101,
35         PCI_ADDR(0, 0x18, 0, 0x54), 0xfff0f0f0, 0x00010101,
36         PCI_ADDR(0, 0x18, 0, 0x58), 0xfff0f0f0, 0x00010101,
37         PCI_ADDR(0, 0x18, 0, 0x5c), 0xfff0f0f0, 0x00010101,
38
39         /* Hypetransport Transaction Control Register 
40          * F0:0x68
41          * [ 0: 0] Disable read byte probe
42          *         0 = Probes issues
43          *         1 = Probes not issued
44          * [ 1: 1] Disable Read Doubleword probe
45          *         0 = Probes issued
46          *         1 = Probes not issued
47          * [ 2: 2] Disable write byte probes
48          *         0 = Probes issued
49          *         1 = Probes not issued
50          * [ 3: 3] Disable Write Doubleword Probes
51          *         0 = Probes issued
52          *         1 = Probes not issued.
53          * [ 4: 4] Disable Memroy Controller Target Start
54          *         0 = TgtStart packets are generated
55          *         1 = TgtStart packets are not generated.
56          * [ 5: 5] CPU1 Enable
57          *         0 = Second CPU disabled or not present
58          *         1 = Second CPU enabled.
59          * [ 6: 6] CPU Request PassPW
60          *         0 = CPU requests do not pass posted writes
61          *         1 = CPU requests pass posted writes.
62          * [ 7: 7] CPU read Respons PassPW
63          *         0 = CPU Responses do not pass posted writes
64          *         1 = CPU responses pass posted writes.
65          * [ 8: 8] Disable Probe Memory Cancel
66          *         0 = Probes may generate MemCancels
67          *         1 = Probes may not generate MemCancels
68          * [ 9: 9] Disable Remote Probe Memory Cancel.
69          *         0 = Probes hitting dirty blocks generate memory cancel packets
70          *         1 = Only probed caches on the same node as the memory controller
71          *              generate cancel packets.
72          * [10:10] Disable Fill Probe
73          *         0 = Probes issued for cache fills
74          *         1 = Probes not issued for cache fills.
75          * [11:11] Response PassPw
76          *         0 = Downstream response PassPW based on original request
77          *         1 = Downstream response PassPW set to 1
78          * [12:12] Change ISOC to Ordered
79          *         0 = Bit 1 of coherent HT RdSz/WrSz command used for iosynchronous prioritization
80          *         1 = Bit 1 of coherent HT RdSz/WrSz command used for ordering.
81          * [14:13] Buffer Release Priority select 
82          *         00 = 64
83          *         01 = 16
84          *         10 = 8
85          *         11 = 2
86          * [15:15] Limit Coherent HT Configuration Space Range
87          *         0 = No coherent HT configuration space restrictions
88          *         1 = Limit coherent HT configuration space based on node count
89          * [16:16] Local Interrupt Conversion Enable.
90          *         0 = ExtInt/NMI interrups unaffected.
91          *         1 = ExtInt/NMI broadcat interrupts converted to LINT0/1
92          * [17:17] APIC Extended Broadcast Enable.
93          *         0 = APIC broadcast is 0F
94          *         1 = APIC broadcast is FF
95          * [18:18] APIC Extended ID Enable
96          *         0 = APIC ID is 4 bits.
97          *         1 = APIC ID is 8 bits.
98          * [19:19] APIC Extended Spurious Vector Enable
99          *         0 = Lower 4 bits of spurious vector are read-only 1111
100          *         1 = Lower 4 bits of spurious vecotr are writeable.
101          * [20:20] Sequence ID Source Node Enable
102          *         0 = Normal operation
103          *         1 = Keep SeqID on routed packets for debugging.
104          * [22:21] Downstream non-posted request limit
105          *         00 = No limit
106          *         01 = Limited to 1
107          *         10 = Limited to 4
108          *         11 = Limited to 8
109          * [23:23] RESERVED
110          * [25:24] Medium-Priority Bypass Count
111          *         - Maximum # of times a medium priority access can pass a low
112          *           priority access before Medium-Priority mode is disabled for one access.
113          * [27:26] High-Priority Bypass Count
114          *         - Maximum # of times a high prioirty access can pass a medium or low
115          *           priority access before High-prioirty mode is disabled for one access.
116          * [28:28] Enable High Priority CPU Reads
117          *         0 = Cpu reads are medium prioirty
118          *         1 = Cpu reads are high prioirty
119          * [29:29] Disable Low Priority Writes
120          *         0 = Non-isochronous writes are low priority
121          *         1 = Non-isochronous writes are medium prioirty
122          * [30:30] Disable High Priority Isochronous writes
123          *         0 = Isochronous writes are high priority
124          *         1 = Isochronous writes are medium priority
125          * [31:31] Disable Medium Priority Isochronous writes
126          *         0 = Isochronous writes are medium are high
127          *         1 = With bit 30 set makes Isochrouns writes low priority.
128          */
129         PCI_ADDR(0, 0x18, 0, 0x68), 0x00800000, 0x0f00840f,
130         /* HT Initialization Control Register
131          * F0:0x6C ok...
132          * [ 0: 0] Routing Table Disable
133          *         0 = Packets are routed according to routing tables
134          *         1 = Packets are routed according to the default link field
135          * [ 1: 1] Request Disable (BSP should clear this)
136          *         0 = Request packets may be generated
137          *         1 = Request packets may not be generated.
138          * [ 3: 2] Default Link (Read-only)
139          *         00 = LDT0
140          *         01 = LDT1
141          *         10 = LDT2
142          *         11 = CPU on same node
143          * [ 4: 4] Cold Reset
144          *         - Scratch bit cleared by a cold reset
145          * [ 5: 5] BIOS Reset Detect
146          *         - Scratch bit cleared by a cold reset
147          * [ 6: 6] INIT Detect
148          *         - Scratch bit cleared by a warm or cold reset not by an INIT
149          *
150          */
151         PCI_ADDR(0, 0x18, 0, 0x6C), 0xffffff8c, 0x00000000 | (1 << 6) |(1 << 5)| (1 << 4),
152         /* LDTi Capabilities Registers
153          * F0:0x80 i = 0,
154          * F0:0xA0 i = 1,
155          * F0:0xC0 i = 2,
156          */
157         /* LDTi Link Control Registrs
158          * F0:0x84 i = 0,
159          * F0:0xA4 i = 1,
160          * F0:0xC4 i = 2,
161          * [ 1: 1] CRC Flood Enable
162          *         0 = Do not generate sync packets on CRC error
163          *         1 = Generate sync packets on CRC error
164          * [ 2: 2] CRC Start Test (Read-Only)
165          * [ 3: 3] CRC Force Frame Error
166          *         0 = Do not generate bad CRC
167          *         1 = Generate bad CRC
168          * [ 4: 4] Link Failure
169          *         0 = No link failure detected
170          *         1 = Link failure detected
171          * [ 5: 5] Initialization Complete
172          *         0 = Initialization not complete
173          *         1 = Initialization complete
174          * [ 6: 6] Receiver off
175          *         0 = Recevier on
176          *         1 = Receiver off
177          * [ 7: 7] Transmitter Off
178          *         0 = Transmitter on
179          *         1 = Transmitter off
180          * [ 9: 8] CRC_Error
181          *         00 = No error
182          *         [0] = 1 Error on byte lane 0
183          *         [1] = 1 Error on byte lane 1
184          * [12:12] Isochrnous Enable  (Read-Only)
185          * [13:13] HT Stop Tristate Enable
186          *         0 = Driven during an LDTSTOP_L
187          *         1 = Tristated during and LDTSTOP_L
188          * [14:14] Extended CTL Time 
189          *         0 = CTL is asserted for 16 bit times during link initialization
190          *         1 = CTL is asserted for 50us during link initialization
191          * [18:16] Max Link Width In (Read-Only?)
192          *         000 = 8 bit link
193          *         001 = 16bit link
194          * [19:19] Doubleword Flow Control in (Read-Only)
195          *         0 = This link does not support doubleword flow control
196          *         1 = This link supports doubleword flow control
197          * [22:20] Max Link Width Out (Read-Only?)
198          *         000 = 8 bit link
199          *         001 = 16bit link
200          * [23:23] Doubleworld Flow Control out (Read-Only)
201          *         0 = This link does not support doubleword flow control
202          *         1 = This link supports doubleworkd flow control
203          * [26:24] Link Width In
204          *         000 = Use 8 bits
205          *         001 = Use 16 bits
206          *         010 = reserved
207          *         011 = Use 32 bits
208          *         100 = Use 2 bits
209          *         101 = Use 4 bits
210          *         110 = reserved
211          *         111 = Link physically not connected
212          * [27:27] Doubleword Flow Control In Enable
213          *         0 = Doubleword flow control disabled
214          *         1 = Doubleword flow control enabled (Not currently supported)
215          * [30:28] Link Width Out
216          *         000 = Use 8 bits
217          *         001 = Use 16 bits
218          *         010 = reserved
219          *         011 = Use 32 bits
220          *         100 = Use 2 bits
221          *         101 = Use 4 bits
222          *         110 = reserved
223          *         111 = Link physically not connected
224          * [31:31] Doubleworld Flow Control Out Enable
225          *         0 = Doubleworld flow control disabled
226          *         1 = Doubleword flow control enabled (Not currently supported)
227          */
228         PCI_ADDR(0, 0x18, 0, 0x84), 0x00009c05, 0x11110020,
229         /* LDTi Frequency/Revision Registers
230          * F0:0x88 i = 0,
231          * F0:0xA8 i = 1,
232          * F0:0xC8 i = 2,
233          * [ 4: 0] Minor Revision
234          *         Contains the HT Minor revision
235          * [ 7: 5] Major Revision
236          *         Contains the HT Major revision
237          * [11: 8] Link Frequency  (Takes effect the next time the link is reconnected)
238          *         0000 = 200Mhz
239          *         0001 = reserved
240          *         0010 = 400Mhz
241          *         0011 = reserved
242          *         0100 = 600Mhz
243          *         0101 = 800Mhz
244          *         0110 = 1000Mhz
245          *         0111 = reserved
246          *         1000 = reserved
247          *         1001 = reserved
248          *         1010 = reserved
249          *         1011 = reserved
250          *         1100 = reserved
251          *         1101 = reserved
252          *         1110 = reserved
253          *         1111 = 100 Mhz
254          * [15:12] Error (Not currently Implemented)
255          * [31:16] Indicates the frequency capabilities of the link
256          *         [16] = 1 encoding 0000 of freq supported
257          *         [17] = 1 encoding 0001 of freq supported
258          *         [18] = 1 encoding 0010 of freq supported
259          *         [19] = 1 encoding 0011 of freq supported
260          *         [20] = 1 encoding 0100 of freq supported
261          *         [21] = 1 encoding 0101 of freq supported
262          *         [22] = 1 encoding 0110 of freq supported
263          *         [23] = 1 encoding 0111 of freq supported
264          *         [24] = 1 encoding 1000 of freq supported
265          *         [25] = 1 encoding 1001 of freq supported
266          *         [26] = 1 encoding 1010 of freq supported
267          *         [27] = 1 encoding 1011 of freq supported
268          *         [28] = 1 encoding 1100 of freq supported
269          *         [29] = 1 encoding 1101 of freq supported
270          *         [30] = 1 encoding 1110 of freq supported
271          *         [31] = 1 encoding 1111 of freq supported
272          */
273         PCI_ADDR(0, 0x18, 0, 0x88), 0xfffff0ff, 0x00000200,
274         /* LDTi Feature Capability
275          * F0:0x8C i = 0,
276          * F0:0xAC i = 1,
277          * F0:0xCC i = 2,
278          */
279         /* LDTi Buffer Count Registers
280          * F0:0x90 i = 0,
281          * F0:0xB0 i = 1,
282          * F0:0xD0 i = 2,
283          */
284         /* LDTi Bus Number Registers
285          * F0:0x94 i = 0,
286          * F0:0xB4 i = 1,
287          * F0:0xD4 i = 2,
288          * For NonCoherent HT specifies the bus number downstream (behind the host bridge)
289          * [ 0: 7] Primary Bus Number
290          * [15: 8] Secondary Bus Number
291          * [23:15] Subordiante Bus Number
292          * [31:24] reserved
293          */
294         PCI_ADDR(0, 0x18, 0, 0x94), 0xff000000, 0x00ff0000,
295         /* LDTi Type Registers
296          * F0:0x98 i = 0,
297          * F0:0xB8 i = 1,
298          * F0:0xD8 i = 2,
299          */
300         };
301         int i;
302         int max;
303         print_debug("setting up coherent ht domain....\r\n");
304         max = sizeof(register_values)/sizeof(register_values[0]);
305         for(i = 0; i < max; i += 3) {
306                 device_t dev;
307                 unsigned where;
308                 unsigned long reg;
309 #if 0
310                 print_debug_hex32(register_values[i]);
311                 print_debug(" <-");
312                 print_debug_hex32(register_values[i+2]);
313                 print_debug("\r\n");
314 #endif
315                 dev = register_values[i] & ~0xff;
316                 where = register_values[i] & 0xff;
317                 reg = pci_read_config32(dev, where);
318                 reg &= register_values[i+1];
319                 reg |= register_values[i+2];
320                 pci_write_config32(dev, where, reg);
321 #if 0
322                 reg = pci_read_config32(register_values[i]);
323                 reg &= register_values[i+1];
324                 reg |= register_values[i+2] & ~register_values[i+1];
325                 pci_write_config32(register_values[i], reg);
326 #endif
327         }
328         print_debug("done.\r\n");
329 }
330 #else
331 /* coherent hypertransport initialization for AMD64 
332  * written by Stefan Reinauer <stepan@openbios.info>
333  * (c) 2003 by SuSE Linux AG
334  *
335  * This code is licensed under GPL.
336  */
337
338 /*
339  * This algorithm assumes a grid configuration as follows:
340  *
341  * nodes :  1    2    4    6    8
342  * org.  :  1x1  2x1  2x2  2x3  2x4
343  *
344  */
345
346 #if 0
347 #include "compat.h"
348 #endif
349
350 #include <device/pci_def.h>
351 #include "arch/romcc_io.h"
352
353
354 /* when generating a temporary row configuration we
355  * don't want broadcast to be enabled for that node.
356  */
357
358 #define generate_temp_row(x...) ((generate_row(x)&(~0x0f0000))|0x010000)
359 #define clear_temp_row(x)       fill_row(x,7,DEFAULT)
360 #define enable_bsp_routing()    enable_routing(0)
361
362 #define NODE_HT(x) PCI_DEV(0,24+x,0)
363 #define NODE_MP(x) PCI_DEV(0,24+x,1)
364 #define NODE_MC(x) PCI_DEV(0,24+x,3)
365
366 #define DEFAULT 0x00010101      /* default row entry */
367
368 typedef uint8_t u8;
369 typedef uint32_t u32;
370 typedef int8_t bool;
371
372 #define TRUE  (-1)
373 #define FALSE (0)
374
375 static void disable_probes(void)
376 {
377         /* disable read/write/fill probes for uniprocessor setup
378          * they don't make sense if only one cpu is available
379          */
380
381         /* Hypetransport Transaction Control Register 
382          * F0:0x68
383          * [ 0: 0] Disable read byte probe
384          *         0 = Probes issues
385          *         1 = Probes not issued
386          * [ 1: 1] Disable Read Doubleword probe
387          *         0 = Probes issued
388          *         1 = Probes not issued
389          * [ 2: 2] Disable write byte probes
390          *         0 = Probes issued
391          *         1 = Probes not issued
392          * [ 3: 3] Disable Write Doubleword Probes
393          *         0 = Probes issued
394          *         1 = Probes not issued.
395          * [10:10] Disable Fill Probe
396          *         0 = Probes issued for cache fills
397          *         1 = Probes not issued for cache fills.
398          */
399
400         u32 val;
401
402         print_debug("Disabling read/write/fill probes for UP... ");
403
404         val=pci_read_config32(NODE_HT(0), 0x68);
405         val |= 0x0000040f;
406         pci_write_config32(NODE_HT(0), 0x68, val);
407
408         print_debug("done.\r\n");
409
410 }
411
412 static void enable_routing(u8 node)
413 {
414         u32 val;
415
416         /* HT Initialization Control Register
417          * F0:0x6C
418          * [ 0: 0] Routing Table Disable
419          *         0 = Packets are routed according to routing tables
420          *         1 = Packets are routed according to the default link field
421          * [ 1: 1] Request Disable (BSP should clear this)
422          *         0 = Request packets may be generated
423          *         1 = Request packets may not be generated.
424          * [ 3: 2] Default Link (Read-only)
425          *         00 = LDT0
426          *         01 = LDT1
427          *         10 = LDT2
428          *         11 = CPU on same node
429          * [ 4: 4] Cold Reset
430          *         - Scratch bit cleared by a cold reset
431          * [ 5: 5] BIOS Reset Detect
432          *         - Scratch bit cleared by a cold reset
433          * [ 6: 6] INIT Detect
434          *         - Scratch bit cleared by a warm or cold reset not by an INIT
435          *
436          */
437
438         /* Enable routing table for BSP */
439         print_debug("Enabling routing table for node ");
440         print_debug_hex32(node);
441
442         val=pci_read_config32(NODE_HT(node), 0x6c);
443         val |= (1 << 6) | (1 << 5) | (1 << 4);
444 #if 0
445         val &= ~((1<<1)|(1<<0));
446 #else
447         /* Don't enable requests here as the indicated processor starts booting */
448         val &= ~(1<<0);
449 #endif
450         pci_write_config32(NODE_HT(node), 0x6c, val);
451
452         print_debug(" done.\r\n");
453 }
454
455 #if MAX_CPUS > 1
456
457 static void rename_temp_node(u8 node)
458 {
459         u32 val;
460
461         print_debug("Renaming current temp node to ");
462         print_debug_hex32(node);
463
464         val=pci_read_config32(NODE_HT(7), 0x60);
465         val &= (~7);  /* clear low bits. */
466         val |= node;   /* new node        */
467         pci_write_config32(NODE_HT(7), 0x60, val);
468
469         print_debug(" done.\r\n");
470
471
472 }
473
474 static bool check_connection(u8 src, u8 dest, u8 link)
475 {
476         /* this function does 2 things:
477          * 1) detect whether the coherent HT link is connected.
478          *    After this step follows a small idle loop.
479          * 2) verify that the coherent hypertransport link
480          *    is established and actually working by reading the
481          *    remote node's vendor/device id
482          */
483
484 #define UP      0x00
485 #define ACROSS  0x20
486 #define DOWN    0x40
487
488         u32 val;
489         
490         /* 1) */
491         val=pci_read_config32(NODE_HT(src), 0x98+link);
492         if ( (val&0x17) != 0x03)
493                 return 0;
494
495         /* idle loop to make sure the link is established */
496         for (val=0;val<16;val++);
497
498         /* 2) */
499         val=pci_read_config32(NODE_HT(dest),0);
500         if(val != 0x11001022)
501                 return 0;
502
503         return 1;
504 }
505
506 static unsigned int generate_row(u8 node, u8 row, u8 maxnodes)
507 {
508         /* Routing Table Node i 
509          *
510          * F0: 0x40, 0x44, 0x48, 0x4c, 0x50, 0x54, 0x58, 0x5c 
511          *  i:    0,    1,    2,    3,    4,    5,    6,    7
512          *
513          * [ 0: 3] Request Route
514          *     [0] Route to this node
515          *     [1] Route to Link 0
516          *     [2] Route to Link 1
517          *     [3] Route to Link 2
518          * [11: 8] Response Route
519          *     [0] Route to this node
520          *     [1] Route to Link 0
521          *     [2] Route to Link 1
522          *     [3] Route to Link 2
523          * [19:16] Broadcast route
524          *     [0] Route to this node
525          *     [1] Route to Link 0
526          *     [2] Route to Link 1
527          *     [3] Route to Link 2
528          */
529
530         u32 ret=DEFAULT;
531
532         static const unsigned int rows_2p[2][2] = {
533                 { 0x00030101, 0x00010404 },
534                 { 0x00010404, 0x00030101 }
535         };
536
537         static const unsigned int rows_4p[4][4] = {
538                 { 0x00070101, 0x00010404, 0x00050202, 0x00010402 },
539                 { 0x00010808, 0x000b0101, 0x00010802, 0x00090202 },
540                 { 0x00090202, 0x00010802, 0x000b0101, 0x00010808 },
541                 { 0x00010402, 0x00050202, 0x00010404, 0x00070101 }
542         };
543
544         if (!(node>=maxnodes || row>=maxnodes)) {
545                 if (maxnodes==2)
546                         ret=rows_2p[node][row];
547                 if (maxnodes==4)
548                         ret=rows_4p[node][row];
549         }
550
551 #if 0
552         printk_spew("generating entry n=%d, r=%d, max=%d - row=%x\n", 
553                 node,row,maxnodes,ret);
554 #endif
555         
556         return ret;
557 }
558
559 static void fill_row(u8 node, u8 row, u32 value)
560 {
561 #if 0
562         print_debug("fill_row: pci_write_config32(");
563         print_debug_hex32(NODE_HT(node));
564         print_debug_char(',');
565         print_debug_hex32(0x40 + (row << 2));
566         print_debug_char(',');
567         print_debug_hex32(value);
568         print_debug(")\r\n");
569 #endif  
570         pci_write_config32(NODE_HT(node), 0x40+(row<<2), value);
571 }
572
573 static void setup_row(u8 source, u8 dest, u8 cpus)
574 {
575 #if 0
576         printk_spew("setting up link from node %d to %d (%d cpus)\r\n",
577                 source, dest, cpus);
578 #endif
579
580         fill_row(source,dest,generate_row(source,dest,cpus));
581 }
582
583 static void setup_temp_row(u8 source, u8 dest, u8 cpus)
584 {
585 #if 0
586         printk_spew("setting up temp. link from node %d to %d (%d cpus)\r\n",
587                 source, dest, cpus);
588 #endif
589
590         fill_row(source,7,generate_temp_row(source,dest,cpus));
591 }
592
593 static void setup_node(u8 node, u8 cpus)
594 {
595         u8 row;
596         for(row=0; row<cpus; row++)
597                 setup_row(node, row, cpus);
598 }
599
600 static void setup_remote_row(u8 source, u8 dest, u8 cpus)
601 {
602         fill_row(7, dest, generate_row(source, dest, cpus));
603 }
604
605 static void setup_remote_node(u8 node, u8 cpus)
606 {
607         static const uint8_t pci_reg[] = { 
608                 0x44, 0x4c, 0x54, 0x5c, 0x64, 0x6c, 0x74, 0x7c, 
609                 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78,
610                 0x84, 0x8c, 0x94, 0x9c, 0xa4, 0xac, 0xb4, 0xbc,
611                 0x80, 0x88, 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8,
612                 0xc4, 0xcc, 0xd4, 0xdc,
613                 0xc0, 0xc8, 0xd0, 0xd8,
614                 0xe0, 0xe4, 0xe8, 0xec,
615         };
616         uint8_t row;
617         int i;
618 #if 1
619         print_debug("setup_remote_node\r\n");
620 #endif
621         for(row=0; row<cpus; row++)
622                 setup_remote_row(node, row, cpus);
623
624         /* copy the default resource map from node 0 */
625         for(i = 0; i < sizeof(pci_reg)/sizeof(pci_reg[0]); i++) {
626                 uint32_t value;
627                 uint8_t reg;
628                 reg = pci_reg[i];
629                 print_debug("copying reg: ");
630                 print_debug_hex8(reg);
631                 print_debug("\r\n");
632                 value = pci_read_config32(NODE_MP(0), reg);
633                 pci_write_config32(NODE_MP(7), reg, value);
634
635         }
636 #if 1
637         print_debug("setup_remote_done\r\n");
638 #endif
639 }
640
641 #endif
642
643 #if MAX_CPUS > 2
644 static void setup_temp_node(u8 node, u8 cpus)
645 {
646         u8 row;
647         for(row=0; row<cpus; row++)
648                 fill_row(7,row,generate_row(node,row,cpus));
649 }
650 #endif
651
652 static u8 setup_uniprocessor(void)
653 {
654         print_debug("Enabling UP settings\r\n");
655         disable_probes();
656         return 1;
657 }
658
659 #if MAX_CPUS > 1
660 static u8 setup_smp(void)
661 {
662         u8 cpus=2;
663
664         print_debug("Enabling SMP settings\r\n");
665
666         setup_row(0,0,cpus);
667         /* Setup and check a temporary connection to node 1 */
668         setup_temp_row(0,1,cpus);
669         
670         if (!check_connection(0, 7, ACROSS)) {  // Link: ACROSS
671                 print_debug("No connection to Node 1.\r\n");
672                 clear_temp_row(0);      /* delete temp connection */
673                 setup_uniprocessor();   /* and get up working     */
674                 return 1;
675         }
676
677         /* We found 2 nodes so far */
678         setup_node(0, cpus);    /* Node 1 is there. Setup Node 0 correctly */
679         setup_remote_node(1, cpus);  /* Setup the routes on the remote node */
680         enable_routing(7);      /* Enable routing on Node 1 */
681         rename_temp_node(1);    /* Rename Node 7 to Node 1  */
682         
683         clear_temp_row(0);      /* delete temporary connection */
684         
685 #if MAX_CPUS > 2
686         cpus=4;
687         
688         /* Setup and check temporary connection from Node 0 to Node 2 */
689         setup_temp_row(0,2,cpus);
690
691         if (!check_connection(0, 7, UP)) {      // Link: UP
692                 print_debug("No connection to Node 2.\r\n");
693                 clear_temp_row(0);       /* delete temp connection */
694                 return 2;
695         }
696
697         /* We found 3 nodes so far. Now setup a temporary
698          * connection from node 0 to node 3 via node 1
699          */
700
701         setup_temp_row(0,1,cpus); /* temp. link between nodes 0 and 1 */
702         setup_temp_row(1,3,cpus); /* temp. link between nodes 1 and 3 */
703
704         if (!check_connection(1, 7, UP)) {      // Link: UP
705                 print_debug("No connection to Node 3.\r\n");
706                 clear_temp_row(0);       /* delete temp connection */
707                 clear_temp_row(1);       /* delete temp connection */
708                 return 2;
709         }
710
711         /* We found 4 nodes so far. Now setup all nodes for 4p */
712
713         setup_node(0, cpus);  /* The first 2 nodes are configured    */
714         setup_node(1, cpus);  /* already. Just configure them for 4p */
715         
716         setup_temp_row(0,2,cpus);
717         setup_temp_node(2,cpus);
718         enable_routing(7);
719         rename_temp_node(2);
720
721         setup_temp_row(0,1,cpus);
722         setup_temp_row(1,3,cpus);
723         setup_temp_node(3,cpus);
724         enable_routing(7);      /* enable routing on node 3 (temp.) */
725         rename_temp_node(3);
726         
727         clear_temp_row(0);
728         clear_temp_row(1);
729         clear_temp_row(2);
730         clear_temp_row(3);
731
732 #endif
733         print_debug_hex32(cpus);
734         print_debug(" nodes initialized.\r\n");
735         return cpus;
736 }
737 #endif
738
739 #if MAX_CPUS > 1
740 static unsigned detect_mp_capabilities(unsigned cpus)
741 {
742         unsigned node, row, mask;
743         bool mp_cap=TRUE;
744
745 #if 1
746         print_debug("detect_mp_capabilities: ");
747         print_debug_hex32(cpus);
748         print_debug("\r\n");
749 #endif
750         if (cpus>2)
751                 mask=0x06;      /* BigMPCap */
752         else
753                 mask=0x02;      /* MPCap    */
754
755         for (node=0; node<cpus; node++) {
756                 if ((pci_read_config32(NODE_MC(node), 0xe8) & mask)!=mask)
757                         mp_cap=FALSE;
758         }
759
760         if (mp_cap)
761                 return cpus;
762
763         /* one of our cpus is not mp capable */
764
765         print_debug("One of the CPUs is not MP capable. Going back to UP\r\n");
766
767         for (node=cpus; node>0; node--)
768             for (row=cpus; row>0; row--)
769                 fill_row(NODE_HT(node-1), row-1, DEFAULT);
770         
771         return setup_uniprocessor();
772 }
773
774 #endif
775
776 /* this is a shrunken cpuid. */
777
778 static unsigned int cpuid(unsigned int op)
779 {
780         unsigned int ret;
781
782         asm volatile ( "cpuid" : "=a" (ret) : "a" (op));
783
784         return ret;
785 }
786
787 static void coherent_ht_finalize(unsigned cpus)
788 {
789         int node;
790         bool rev_a0;
791         
792         /* set up cpu count and node count and enable Limit
793          * Config Space Range for all available CPUs.
794          * Also clear non coherent hypertransport bus range
795          * registers on Hammer A0 revision.
796          */
797
798 #if 1
799         print_debug("coherent_ht_finalize\r\n");
800 #endif
801         rev_a0=((cpuid(1)&0xffff)==0x0f10);
802
803         for (node=0; node<cpus; node++) {
804                 u32 val;
805                 val=pci_read_config32(NODE_HT(node), 0x60);
806                 val &= (~0x000F0070);
807                 val |= ((cpus-1)<<16)|((cpus-1)<<4);
808                 pci_write_config32(NODE_HT(node),0x60,val);
809
810                 val=pci_read_config32(NODE_HT(node), 0x68);
811                 val |= 0x00008000;
812                 pci_write_config32(NODE_HT(node),0x68,val);
813
814                 if (rev_a0) {
815                         pci_write_config32(NODE_HT(node),0x94,0);
816                         pci_write_config32(NODE_HT(node),0xb4,0);
817                         pci_write_config32(NODE_HT(node),0xd4,0);
818                 }
819         }
820
821 #if 1
822         print_debug("done\n");
823 #endif
824 }
825
826 static void setup_coherent_ht_domain(void)
827 {
828         unsigned cpus;
829
830         enable_bsp_routing();
831
832 #if MAX_CPUS == 1
833         cpus=setup_uniprocessor();
834 #else
835         cpus=setup_smp();
836         cpus=detect_mp_capabilities(cpus);
837 #endif
838         coherent_ht_finalize(cpus);
839 }
840
841 #endif