amdfam10: add phenom II as known cpu
[coreboot.git] / src / northbridge / amd / amdfam10 / conf.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 #if defined(__PRE_RAM__)
21 typedef struct sys_info sys_info_conf_t;
22 #else
23 typedef struct amdfam10_sysconf_t sys_info_conf_t;
24 #endif
25
26 struct dram_base_mask_t {
27         u32 base; //[47:27] at [28:8]
28         u32 mask; //[47:27] at [28:8] and enable at bit 0
29 };
30
31 static struct dram_base_mask_t get_dram_base_mask(u32 nodeid)
32 {
33         device_t dev;
34         struct dram_base_mask_t d;
35 #if defined(__PRE_RAM__)
36         dev = PCI_DEV(CONFIG_CBB, CONFIG_CDB, 1);
37 #else
38         dev = __f1_dev[0];
39 #endif
40
41 #if CONFIG_EXT_CONF_SUPPORT == 1
42         // I will use ext space only for simple
43         pci_write_config32(dev, 0x110, nodeid | (1<<28)); // [47:27] at [28:8]
44         d.mask = pci_read_config32(dev, 0x114);  // enable is bit 0
45         pci_write_config32(dev, 0x110, nodeid | (0<<28));
46         d.base = pci_read_config32(dev, 0x114) & 0x1fffff00; //[47:27] at [28:8];
47 #else
48         u32 temp;
49         temp = pci_read_config32(dev, 0x44 + (nodeid << 3)); //[39:24] at [31:16]
50         d.mask = ((temp & 0xfff80000)>>(8+3)); // mask out  DramMask [26:24] too
51         temp = pci_read_config32(dev, 0x144 + (nodeid <<3)) & 0xff; //[47:40] at [7:0]
52         d.mask |= temp<<21;
53
54         temp = pci_read_config32(dev, 0x40 + (nodeid << 3)); //[39:24] at [31:16]
55         d.mask |= (temp & 1); // enable bit
56
57         d.base = ((temp & 0xfff80000)>>(8+3)); // mask out DramBase [26:24) too
58         temp = pci_read_config32(dev, 0x140 + (nodeid <<3)) & 0xff; //[47:40] at [7:0]
59         d.base |= temp<<21;
60 #endif
61         return d;
62 }
63
64 #if CONFIG_AMDMCT == 0
65 static void set_dram_base_mask(u32 nodeid, struct dram_base_mask_t d, u32 nodes)
66 {
67         u32 i;
68         device_t dev;
69 #if CONFIG_EXT_CONF_SUPPORT == 1
70         // I will use ext space only for simple
71         u32 d_base_i, d_base_d, d_mask_i, d_mask_d;
72         d_base_i = nodeid | (0<<28);
73         d_base_d = d.base | nodeid; //[47:27] at [28:8];
74         d_mask_i = nodeid | (1<<28); // [47:27] at [28:8]
75         d_mask_d = d.mask;  // enable is bit 0
76
77 #else
78         u32 d_base_lo, d_base_hi, d_mask_lo, d_mask_hi;
79         u32 d_base_lo_reg, d_base_hi_reg, d_mask_lo_reg, d_mask_hi_reg;
80         d_mask_lo =  (((d.mask<<(8+3))|(0x07<<16)) & 0xffff0000)|nodeid; // need to fill DramMask[26:24] with ones
81         d_mask_hi =  (d.mask>>21) & 0xff;
82         d_base_lo = ((d.base<<(8+3)) & 0xffff0000);
83         if(d.mask & 1) d_base_lo |= 3;
84         d_base_hi = (d.base>>21) & 0xff;
85         d_mask_lo_reg = 0x44+(nodeid<<3);
86         d_mask_hi_reg = 0x144+(nodeid<<3);
87         d_base_lo_reg = 0x40+(nodeid<<3);
88         d_base_hi_reg = 0x140+(nodeid<<3);
89 #endif
90
91         for(i=0;i<nodes;i++) {
92 #if defined(__PRE_RAM__)
93                 dev = NODE_PCI(i, 1);
94 #else
95                 dev = __f1_dev[i];
96 #endif
97
98 #if CONFIG_EXT_CONF_SUPPORT == 1
99                 // I will use ext space only for simple
100                 pci_write_config32(dev, 0x110, d_base_i);
101                 pci_write_config32(dev, 0x114, d_base_d); //[47:27] at [28:8];
102                 pci_write_config32(dev, 0x110, d_mask_i); // [47:27] at [28:8]
103                 pci_write_config32(dev, 0x114, d_mask_d);  // enable is bit 0
104 #else
105                 pci_write_config32(dev, d_mask_lo_reg, d_mask_lo); // need to fill DramMask[26:24] with ones
106                 pci_write_config32(dev, d_mask_hi_reg, d_mask_hi);
107                 pci_write_config32(dev, d_base_lo_reg, d_base_lo);
108                 pci_write_config32(dev, d_base_hi_reg, d_base_hi);
109 #endif
110         }
111
112 #if defined(__PRE_RAM__)
113         dev = NODE_PCI(nodeid, 1);
114 #else
115         dev = __f1_dev[nodeid];
116 #endif
117         pci_write_config32(dev, 0x120, d.base>>8);
118         pci_write_config32(dev, 0x124, d.mask>>8);
119
120 }
121 #endif
122
123 #if CONFIG_AMDMCT == 0
124 static void set_DctSelBaseAddr(u32 i, u32 sel_m)
125 {
126         device_t dev;
127 #if defined(__PRE_RAM__)
128         dev = NODE_PCI(i, 2);
129 #else
130                 dev = __f2_dev[i];
131 #endif
132         u32 dcs_lo;
133         dcs_lo = pci_read_config32(dev, DRAM_CTRL_SEL_LOW);
134         dcs_lo &= ~(DCSL_DctSelBaseAddr_47_27_MASK<<DCSL_DctSelBaseAddr_47_27_SHIFT);
135         dcs_lo |= (sel_m<<(20+DCSL_DctSelBaseAddr_47_27_SHIFT-27));
136         pci_write_config32(dev, DRAM_CTRL_SEL_LOW, dcs_lo);
137
138 }
139
140
141 static u32 get_DctSelBaseAddr(u32 i)
142 {
143         device_t dev;
144 #if defined(__PRE_RAM__)
145         dev = NODE_PCI(i, 2);
146 #else
147                 dev = __f2_dev[i];
148 #endif
149         u32 sel_m;
150         u32 dcs_lo;
151         dcs_lo = pci_read_config32(dev, DRAM_CTRL_SEL_LOW);
152         dcs_lo &= DCSL_DctSelBaseAddr_47_27_MASK<<DCSL_DctSelBaseAddr_47_27_SHIFT;
153         sel_m = dcs_lo>>(20+DCSL_DctSelBaseAddr_47_27_SHIFT-27);
154         return sel_m;
155 }
156
157 #ifdef UNUSED_CODE
158 static void set_DctSelHiEn(u32 i, u32 val)
159 {
160         device_t dev;
161 #if defined(__PRE_RAM__)
162         dev = NODE_PCI(i, 2);
163 #else
164                 dev = __f2_dev[i];
165 #endif
166         u32 dcs_lo;
167         dcs_lo = pci_read_config32(dev, DRAM_CTRL_SEL_LOW);
168         dcs_lo &= ~(7);
169         dcs_lo |= (val & 7);
170         pci_write_config32(dev, DRAM_CTRL_SEL_LOW, dcs_lo);
171
172 }
173 #endif
174
175 static u32 get_DctSelHiEn(u32 i)
176 {
177         device_t dev;
178 #if defined(__PRE_RAM__)
179         dev = NODE_PCI(i, 2);
180 #else
181         dev = __f2_dev[i];
182 #endif
183         u32 dcs_lo;
184         dcs_lo = pci_read_config32(dev, DRAM_CTRL_SEL_LOW);
185         dcs_lo &= 7;
186         return dcs_lo;
187
188 }
189
190 static void set_DctSelBaseOffset(u32 i, u32 sel_off_m)
191 {
192         device_t dev;
193 #if defined(__PRE_RAM__)
194         dev = NODE_PCI(i, 2);
195 #else
196         dev = __f2_dev[i];
197 #endif
198         u32 dcs_hi;
199         dcs_hi = pci_read_config32(dev, DRAM_CTRL_SEL_HIGH);
200         dcs_hi &= ~(DCSH_DctSelBaseOffset_47_26_MASK<<DCSH_DctSelBaseOffset_47_26_SHIFT);
201         dcs_hi |= sel_off_m<<(20+DCSH_DctSelBaseOffset_47_26_SHIFT-26);
202         pci_write_config32(dev, DRAM_CTRL_SEL_HIGH, dcs_hi);
203
204 }
205
206 #ifdef UNUSED_CODE
207 static u32 get_DctSelBaseOffset(u32 i)
208 {
209         device_t dev;
210 #if defined(__PRE_RAM__)
211         dev = NODE_PCI(i, 2);
212 #else
213         dev = __f2_dev[i];
214 #endif
215         u32 sel_off_m;
216         u32 dcs_hi;
217         dcs_hi = pci_read_config32(dev, DRAM_CTRL_SEL_HIGH);
218         dcs_hi &= DCSH_DctSelBaseOffset_47_26_MASK<<DCSH_DctSelBaseOffset_47_26_SHIFT;
219         sel_off_m = dcs_hi>>(20+DCSH_DctSelBaseOffset_47_26_SHIFT-26);
220         return sel_off_m;
221 }
222 #endif
223
224 static u32 get_one_DCT(struct mem_info *meminfo)
225 {
226         u32 one_DCT = 1;
227         if(meminfo->is_Width128) {
228                 one_DCT = 1;
229         } else {
230                 u32 dimm_mask = meminfo->dimm_mask;
231                 if((dimm_mask >> DIMM_SOCKETS) && (dimm_mask & ((1<<DIMM_SOCKETS)-1))) {
232                          one_DCT = 0;
233                 }
234         }
235
236         return one_DCT;
237 }
238
239 #if CONFIG_HW_MEM_HOLE_SIZEK != 0
240 // See that other copy in northbridge.c
241 static u32 hoist_memory(u32 hole_startk, u32 i, u32 one_DCT, u32 nodes)
242 {
243         u32 ii;
244         u32 carry_over;
245         device_t dev;
246         struct dram_base_mask_t d;
247         u32 sel_m;
248         u32 sel_hi_en;
249         u32 hoist;
250
251
252         carry_over = (4*1024*1024) - hole_startk;
253
254         for(ii=nodes - 1;ii>i;ii--) {
255                 d = get_dram_base_mask(ii);
256                 if(!(d.mask & 1)) continue;
257                 d.base += (carry_over>>9);
258                 d.mask += (carry_over>>9);
259                 set_dram_base_mask(ii, d, nodes);
260
261                 if(get_DctSelHiEn(ii) & 1) {
262                         sel_m = get_DctSelBaseAddr(ii);
263                         sel_m += carry_over>>10;
264                         set_DctSelBaseAddr(ii, sel_m);
265                 }
266
267         }
268         d = get_dram_base_mask(i);
269         d.mask += (carry_over>>9);
270         set_dram_base_mask(i,d, nodes);
271 #if defined(__PRE_RAM__)
272         dev = NODE_PCI(i, 1);
273 #else
274         dev = __f1_dev[i];
275 #endif
276         sel_hi_en =  get_DctSelHiEn(i);
277         if(sel_hi_en & 1) {
278                 sel_m = get_DctSelBaseAddr(i);
279         }
280         if(d.base == (hole_startk>>9)) {
281                 //don't need set memhole here, because hole off set will be 0, overflow
282                 //so need to change base reg instead, new basek will be 4*1024*1024
283                 d.base = (4*1024*1024)>>9;
284                 set_dram_base_mask(i, d, nodes);
285
286                 if(sel_hi_en & 1) {
287                         sel_m += carry_over>>10;
288                         set_DctSelBaseAddr(i, sel_m);
289                 }
290         } else {
291                 hoist = /* hole start address */
292                         ((hole_startk << 10) & 0xff000000) +
293                         /* enable */
294                         1;
295                 if(one_DCT||(sel_m>=(hole_startk>>10))) { //one DCT or hole in DCT0
296                         hoist +=
297                         /* hole address to memory controller address */
298                         ((((d.base<<9) + carry_over) >> 6) & 0x0000ff00) ;
299
300                         if(sel_hi_en & 1) {
301                                 sel_m += (carry_over>>10);
302                                 set_DctSelBaseAddr(i, sel_m);
303                                 set_DctSelBaseOffset(i, sel_m);
304                         }
305                 } else { // hole in DCT1 range
306                         hoist +=
307                         /* hole address to memory controller address */
308                         ((((sel_m<<10) + carry_over) >> 6) & 0x0000ff00) ;
309                         // don't need to update DctSelBaseAddr
310                         if(sel_hi_en & 1) {
311                                 set_DctSelBaseOffset(i, sel_m);
312                         }
313                 }
314                 pci_write_config32(dev, 0xf0, hoist);
315
316         }
317
318         return carry_over;
319 }
320 #endif
321 #endif // CONFIG_AMDMCT
322
323
324 #if CONFIG_EXT_CONF_SUPPORT
325 static void set_addr_map_reg_4_6_in_one_node(u32 nodeid, u32 cfg_map_dest,
326                                                 u32 busn_min, u32 busn_max,
327                                                 u32 type)
328 {
329         device_t dev;
330         u32 i;
331         u32 tempreg;
332         u32 index_min, index_max;
333         u32 dest_min, dest_max;
334         index_min = busn_min>>2; dest_min = busn_min - (index_min<<2);
335         index_max = busn_max>>2; dest_max = busn_max - (index_max<<2);
336
337         // three case: index_min==index_max, index_min+1=index_max; index_min+1<index_max
338 #if defined(__PRE_RAM__)
339         dev = NODE_PCI(nodeid, 1);
340 #else
341         dev = __f1_dev[nodeid];
342 #endif
343         if(index_min== index_max) {
344                 pci_write_config32(dev, 0x110, index_min | (type<<28));
345                 tempreg = pci_read_config32(dev, 0x114);
346                 for(i=dest_min; i<=dest_max; i++) {
347                         tempreg &= ~(0xff<<(i*8));
348                         tempreg |= (cfg_map_dest<<(i*8));
349                 }
350                 pci_write_config32(dev, 0x110, index_min | (type<<28)); // do i need to write it again
351                 pci_write_config32(dev, 0x114, tempreg);
352         } else if(index_min<index_max) {
353                 pci_write_config32(dev, 0x110, index_min | (type<<28));
354                 tempreg = pci_read_config32(dev, 0x114);
355                 for(i=dest_min; i<=3; i++) {
356                         tempreg &= ~(0xff<<(i*8));
357                         tempreg |= (cfg_map_dest<<(i*8));
358                 }
359                 pci_write_config32(dev, 0x110, index_min | (type<<28)); // do i need to write it again
360                 pci_write_config32(dev, 0x114, tempreg);
361
362                 pci_write_config32(dev, 0x110, index_max | (type<<28));
363                 tempreg = pci_read_config32(dev, 0x114);
364                 for(i=0; i<=dest_max; i++) {
365                         tempreg &= ~(0xff<<(i*8));
366                         tempreg |= (cfg_map_dest<<(i*8));
367                 }
368                 pci_write_config32(dev, 0x110, index_max | (type<<28)); // do i need to write it again
369                 pci_write_config32(dev, 0x114, tempreg);
370                 if((index_max-index_min)>1) {
371                         tempreg = 0;
372                         for(i=0; i<=3; i++) {
373                                 tempreg &= ~(0xff<<(i*8));
374                                 tempreg |= (cfg_map_dest<<(i*8));
375                         }
376                         for(i=index_min+1; i<index_max;i++) {
377                                 pci_write_config32(dev, 0x110, i | (type<<28));
378                                 pci_write_config32(dev, 0x114, tempreg);
379                         }
380                 }
381         }
382 }
383 #endif
384
385 static void set_config_map_reg(u32 nodeid, u32 linkn, u32 ht_c_index,
386                                 u32 busn_min, u32 busn_max, u32 segbit,
387                                 u32 nodes)
388 {
389         u32 tempreg;
390         u32 i;
391         device_t dev;
392
393         busn_min>>=segbit;
394         busn_max>>=segbit;
395
396 #if CONFIG_EXT_CONF_SUPPORT
397         if(ht_c_index < 4) {
398 #endif
399                 tempreg = 3 | ((nodeid&0xf)<<4) | ((nodeid & 0x30)<<(12-4))|(linkn<<8)|((busn_min & 0xff)<<16)|((busn_max&0xff)<<24);
400                 for(i=0; i<nodes; i++) {
401                 #if defined(__PRE_RAM__)
402                         dev = NODE_PCI(i, 1);
403                 #else
404                         dev = __f1_dev[i];
405                 #endif
406                         pci_write_config32(dev, 0xe0 + ht_c_index * 4, tempreg);
407                 }
408 #if CONFIG_EXT_CONF_SUPPORT
409
410                 return;
411         }
412
413         // if ht_c_index > 3, We should use extend space x114_x6
414         u32 cfg_map_dest;
415         u32 j;
416
417         // for nodeid at first
418         cfg_map_dest = (1<<7) | (1<<6) | (linkn<<0);
419
420         set_addr_map_reg_4_6_in_one_node(nodeid, cfg_map_dest, busn_min, busn_max, 6);
421
422         // all other nodes
423         cfg_map_dest = (1<<7) | (0<<6) | (nodeid<<0);
424         for(j = 0; j< nodes; j++) {
425                 if(j== nodeid) continue;
426                 set_addr_map_reg_4_6_in_one_node(j,cfg_map_dest, busn_min, busn_max, 6);
427         }
428 #endif
429 }
430
431 static void clear_config_map_reg(u32 nodeid, u32 linkn, u32 ht_c_index,
432                                         u32 busn_min, u32 busn_max, u32 nodes)
433 {
434         u32 i;
435         device_t dev;
436
437 #if CONFIG_EXT_CONF_SUPPORT
438         if(ht_c_index<4) {
439 #endif
440                 for(i=0; i<nodes; i++) {
441                 #if defined(__PRE_RAM__)
442                         dev = NODE_PCI(i, 1);
443                 #else
444                         dev = __f1_dev[i];
445                 #endif
446                         pci_write_config32(dev, 0xe0 + ht_c_index * 4, 0);
447                 }
448 #if CONFIG_EXT_CONF_SUPPORT
449                 return;
450         }
451
452         // if hc_c_index >3, We should use busn_min and busn_max to clear extend space
453         u32 cfg_map_dest;
454         u32 j;
455
456
457         // all nodes
458         cfg_map_dest = 0;
459         for(j = 0; j< nodes; j++) {
460                 set_addr_map_reg_4_6_in_one_node(j,cfg_map_dest, busn_min, busn_max, 6);
461         }
462 #endif
463
464 }
465
466 #if CONFIG_PCI_BUS_SEGN_BITS
467 static u32 check_segn(device_t dev, u32 segbusn, u32 nodes,
468                         sys_info_conf_t *sysinfo)
469 {
470         //check segbusn here, We need every node have the same segn
471         if((segbusn & 0xff)>(0xe0-1)) {// use next segn
472                 u32 segn = (segbusn >> 8) & 0x0f;
473                 segn++;
474                 segbusn = segn<<8;
475         }
476         if(segbusn>>8) {
477                 u32 val;
478                 val = pci_read_config32(dev, 0x160);
479                 val &= ~(0xf<<25);
480                 val |= (segbusn & 0xf00)<<(25-8);
481                 pci_write_config32(dev, 0x160, val);
482         }
483
484         return segbusn;
485 }
486 #endif
487
488 #if defined(__PRE_RAM__)
489 static void set_ht_c_io_addr_reg(u32 nodeid, u32 linkn, u32 ht_c_index,
490                                         u32 io_min, u32 io_max, u32 nodes)
491 {
492         u32 i;
493         u32 tempreg;
494         device_t dev;
495
496 #if CONFIG_EXT_CONF_SUPPORT
497         if(ht_c_index<4) {
498 #endif
499                 /* io range allocation */
500                 tempreg = (nodeid&0xf) | ((nodeid & 0x30)<<(8-4)) | (linkn<<4) |  ((io_max&0xf0)<<(12-4)); //limit
501                 for(i=0; i<nodes; i++) {
502                 #if defined(__PRE_RAM__)
503                         dev = NODE_PCI(i, 1);
504                 #else
505                         dev = __f1_dev[i];
506                 #endif
507                         pci_write_config32(dev, 0xC4 + ht_c_index * 8, tempreg);
508                 }
509                 tempreg = 3 /*| ( 3<<4)*/ | ((io_min&0xf0)<<(12-4));         //base :ISA and VGA ?
510                 for(i=0; i<nodes; i++){
511                 #if defined(__PRE_RAM__)
512                         dev = NODE_PCI(i, 1);
513                 #else
514                         dev = __f1_dev[i];
515                 #endif
516                         pci_write_config32(dev, 0xC0 + ht_c_index * 8, tempreg);
517                 }
518 #if CONFIG_EXT_CONF_SUPPORT
519                 return;
520         }
521
522         u32 cfg_map_dest;
523         u32 j;
524
525         // if ht_c_index > 3, We should use extend space
526
527         if(io_min>io_max) return;
528
529         // for nodeid at first
530         cfg_map_dest = (1<<7) | (1<<6) | (linkn<<0);
531
532         set_addr_map_reg_4_6_in_one_node(nodeid, cfg_map_dest, io_min, io_max, 4);
533
534         // all other nodes
535         cfg_map_dest = (1<<7) | (0<<6) | (nodeid<<0);
536         for(j = 0; j< nodes; j++) {
537                 if(j== nodeid) continue;
538                 set_addr_map_reg_4_6_in_one_node(j,cfg_map_dest, io_min, io_max, 4);
539         }
540 #endif
541 }
542
543
544 static void clear_ht_c_io_addr_reg(u32 nodeid, u32 linkn, u32 ht_c_index,
545                                         u32 io_min, u32 io_max, u32 nodes)
546 {
547         u32 i;
548         device_t dev;
549 #if CONFIG_EXT_CONF_SUPPORT
550         if(ht_c_index<4) {
551 #endif
552                  /* io range allocation */
553                 for(i=0; i<nodes; i++) {
554                 #if defined(__PRE_RAM__)
555                         dev = NODE_PCI(i, 1);
556                 #else
557                         dev = __f1_dev[i];
558                 #endif
559                         pci_write_config32(dev, 0xC4 + ht_c_index * 8, 0);
560                         pci_write_config32(dev, 0xC0 + ht_c_index * 8, 0);
561                 }
562 #if CONFIG_EXT_CONF_SUPPORT
563                 return;
564         }
565         // : if hc_c_index > 3, We should use io_min, io_max to clear extend space
566         u32 cfg_map_dest;
567         u32 j;
568
569
570         // all nodes
571         cfg_map_dest = 0;
572         for(j = 0; j< nodes; j++) {
573                 set_addr_map_reg_4_6_in_one_node(j,cfg_map_dest, io_min, io_max, 4);
574         }
575 #endif
576 }
577 #endif
578
579 #ifdef UNUSED_CODE
580 static void re_set_all_config_map_reg(u32 nodes, u32 segbit,
581                                         sys_info_conf_t *sysinfo)
582 {
583         u32 ht_c_index;
584         device_t dev;
585
586         set_config_map_reg(0, sysinfo->sblk, 0, 0, sysinfo->ht_c_conf_bus[0]>>20, segbit, nodes);
587
588         /* clean others */
589         for(ht_c_index=1;ht_c_index<4; ht_c_index++) {
590                 u32 i;
591                 for(i=0; i<nodes; i++) {
592                 #if defined(__PRE_RAM__)
593                         dev = NODE_PCI(i, 1);
594                 #else
595                         dev = __f1_dev[i];
596                 #endif
597                         pci_write_config32(dev, 0xe0 + ht_c_index * 4, 0);
598                 }
599         }
600 #if CONFIG_EXT_CONF_SUPPORT
601         u32 j;
602         // clear the extend space
603         for(j = 0; j< nodes; j++) {
604                 set_addr_map_reg_4_6_in_one_node(j,0, 0, 0xff, 6);
605         }
606 #endif
607
608         for(ht_c_index = 1; ht_c_index<sysinfo->ht_c_num; ht_c_index++) {
609                 u32 nodeid, linkn;
610                 u32 busn_max;
611                 u32 busn_min;
612                 nodeid = (sysinfo->ht_c_conf_bus[ht_c_index] >> 2) & 0x3f;
613                 linkn = (sysinfo->ht_c_conf_bus[ht_c_index]>>8) & 0x7;
614                 busn_max = sysinfo->ht_c_conf_bus[ht_c_index]>>20;
615                 busn_min = (sysinfo->ht_c_conf_bus[ht_c_index]>>12) & 0xff;
616                 busn_min |= busn_max & 0xf00;
617                 set_config_map_reg(nodeid, linkn, ht_c_index, busn_min, busn_max, segbit, nodes);
618         }
619
620 }
621 #endif
622
623 static u32 get_ht_c_index(u32 nodeid, u32 linkn, sys_info_conf_t *sysinfo)
624 {
625         u32 tempreg;
626         u32 ht_c_index = 0;
627
628 #if 0
629         tempreg = 3 | ((nodeid & 0xf) <<4) | ((nodeid & 0x30)<<(12-4)) | (linkn<<8);
630
631         for(ht_c_index=0;ht_c_index<4; ht_c_index++) {
632                 reg = pci_read_config32(PCI_DEV(CONFIG_CBB, CONFIG_CDB, 1), 0xe0 + ht_c_index * 4);
633                 if(((reg & 0xffff) == 0x0000)) {  /*found free*/
634                         break;
635                 }
636         }
637 #endif
638         tempreg = 3 | ((nodeid & 0x3f)<<2) | (linkn<<8);
639         for(ht_c_index=0; ht_c_index<32; ht_c_index++) {
640                 if(((sysinfo->ht_c_conf_bus[ht_c_index] & 0xfff) == tempreg)){
641                         return ht_c_index;
642                 }
643         }
644
645         for(ht_c_index=0; ht_c_index<32; ht_c_index++) {
646                 if((sysinfo->ht_c_conf_bus[ht_c_index] == 0)){
647                          return ht_c_index;
648                 }
649         }
650
651         return  -1;
652
653 }
654
655 static void store_ht_c_conf_bus(u32 nodeid, u32 linkn, u32 ht_c_index,
656                                 u32 busn_min, u32 busn_max,
657                                 sys_info_conf_t *sysinfo)
658 {
659         u32 val;
660         val = 3 | ((nodeid & 0x3f)<<2) | (linkn<<8);
661         sysinfo->ht_c_conf_bus[ht_c_index] = val | ((busn_min & 0xff) <<12) | (busn_max<<20);  // same node need segn are same
662
663 }
664
665 #ifdef UNUSED_CODE
666 static  void set_BusSegmentEn(u32 node, u32 segbit)
667 {
668 #if CONFIG_PCI_BUS_SEGN_BITS
669         u32 dword;
670         device_t dev;
671
672 #if defined(__PRE_RAM__)
673         dev = NODE_PCI(node, 0);
674 #else
675         dev = __f0_dev[node];
676 #endif
677
678         dword = pci_read_config32(dev, 0x68);
679         dword &= ~(7<<28);
680         dword |= (segbit<<28); /* bus segment enable */
681         pci_write_config32(dev, 0x68, dword);
682 #endif
683 }
684 #endif
685
686 #if !defined(__PRE_RAM__)
687 static u32 get_io_addr_index(u32 nodeid, u32 linkn)
688 {
689         u32 index;
690
691         for(index=0; index<256; index++) {
692                 if((sysconf.conf_io_addrx[index+4] == 0)){
693                         sysconf.conf_io_addr[index+4] =  (nodeid & 0x3f)  ;
694                         sysconf.conf_io_addrx[index+4] = 1 | ((linkn & 0x7)<<4);
695                         return index;
696                  }
697          }
698
699          return  0;
700
701 }
702
703 static u32 get_mmio_addr_index(u32 nodeid, u32 linkn)
704 {
705         u32 index;
706
707
708         for(index=0; index<64; index++) {
709                 if((sysconf.conf_mmio_addrx[index+8] == 0)){
710                         sysconf.conf_mmio_addr[index+8] = (nodeid & 0x3f) ;
711                         sysconf.conf_mmio_addrx[index+8] = 1 | ((linkn & 0x7)<<4);
712                         return index;
713                 }
714         }
715
716         return   0;
717
718 }
719
720 static void store_conf_io_addr(u32 nodeid, u32 linkn, u32 reg, u32 index,
721                                 u32 io_min, u32 io_max)
722 {
723         u32 val;
724 #if CONFIG_EXT_CONF_SUPPORT
725         if(reg!=0x110) {
726 #endif
727                 /* io range allocation */
728                 index = (reg-0xc0)>>3;
729 #if CONFIG_EXT_CONF_SUPPORT
730         } else {
731                 index+=4;
732         }
733 #endif
734
735         val = (nodeid & 0x3f); // 6 bits used
736         sysconf.conf_io_addr[index] = val | ((io_max<<8) & 0xfffff000); //limit : with nodeid
737         val = 3 | ((linkn & 0x7)<<4) ; // 8 bits used
738         sysconf.conf_io_addrx[index] = val | ((io_min<<8) & 0xfffff000); // base : with enable bit
739
740         if( sysconf.io_addr_num<(index+1))
741                 sysconf.io_addr_num = index+1;
742 }
743
744
745 static void store_conf_mmio_addr(u32 nodeid, u32 linkn, u32 reg, u32 index,
746                                         u32 mmio_min, u32 mmio_max)
747 {
748         u32 val;
749 #if CONFIG_EXT_CONF_SUPPORT
750         if(reg!=0x110) {
751 #endif
752                 /* io range allocation */
753                 index = (reg-0x80)>>3;
754 #if CONFIG_EXT_CONF_SUPPORT
755         } else {
756                 index+=8;
757         }
758 #endif
759
760         val = (nodeid & 0x3f) ; // 6 bits used
761         sysconf.conf_mmio_addr[index] = val | (mmio_max & 0xffffff00); //limit : with nodeid and linkn
762         val = 3 | ((linkn & 0x7)<<4) ; // 8 bits used
763         sysconf.conf_mmio_addrx[index] = val | (mmio_min & 0xffffff00); // base : with enable bit
764
765         if( sysconf.mmio_addr_num<(index+1))
766                 sysconf.mmio_addr_num = index+1;
767 }
768
769
770 static void set_io_addr_reg(device_t dev, u32 nodeid, u32 linkn, u32 reg,
771                                 u32 io_min, u32 io_max)
772 {
773
774         u32 i;
775         u32 tempreg;
776 #if CONFIG_EXT_CONF_SUPPORT
777         if(reg!=0x110) {
778 #endif
779                 /* io range allocation */
780                 tempreg = (nodeid&0xf) | ((nodeid & 0x30)<<(8-4)) | (linkn<<4) |  ((io_max&0xf0)<<(12-4)); //limit
781                 for(i=0; i<sysconf.nodes; i++)
782                         pci_write_config32(__f1_dev[i], reg+4, tempreg);
783
784                 tempreg = 3 /*| ( 3<<4)*/ | ((io_min&0xf0)<<(12-4));          //base :ISA and VGA ?
785 #if 0
786                 // FIXME: can we use VGA reg instead?
787                 if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
788                         printk(BIOS_SPEW, "%s, enabling legacy VGA IO forwarding for %s link %s\n",
789                                 __func__, dev_path(dev), link);
790                         tempreg |= PCI_IO_BASE_VGA_EN;
791                 }
792                 if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_NO_ISA) {
793                         tempreg |= PCI_IO_BASE_NO_ISA;
794                 }
795 #endif
796                 for(i=0; i<sysconf.nodes; i++)
797                         pci_write_config32(__f1_dev[i], reg, tempreg);
798 #if CONFIG_EXT_CONF_SUPPORT
799                 return;
800         }
801
802         u32 cfg_map_dest;
803         u32 j;
804         // if ht_c_index > 3, We should use extend space
805         if(io_min>io_max) return;
806         // for nodeid at first
807         cfg_map_dest = (1<<7) | (1<<6) | (linkn<<0);
808
809         set_addr_map_reg_4_6_in_one_node(nodeid, cfg_map_dest, io_min, io_max, 4);
810
811         // all other nodes
812         cfg_map_dest = (1<<7) | (0<<6) | (nodeid<<0);
813         for(j = 0; j< sysconf.nodes; j++) {
814                 if(j== nodeid) continue;
815                 set_addr_map_reg_4_6_in_one_node(j,cfg_map_dest, io_min, io_max, 4);
816         }
817 #endif
818
819 }
820 static void set_mmio_addr_reg(u32 nodeid, u32 linkn, u32 reg, u32 index, u32 mmio_min, u32 mmio_max, u32 nodes)
821 {
822
823         u32 i;
824         u32 tempreg;
825 #if CONFIG_EXT_CONF_SUPPORT
826         if(reg!=0x110) {
827 #endif
828                 /* io range allocation */
829                 tempreg = (nodeid&0xf) | (linkn<<4) |    (mmio_max&0xffffff00); //limit
830                 for(i=0; i<nodes; i++)
831                         pci_write_config32(__f1_dev[i], reg+4, tempreg);
832                 tempreg = 3 | (nodeid & 0x30) | (mmio_min&0xffffff00);
833                 for(i=0; i<sysconf.nodes; i++)
834                         pci_write_config32(__f1_dev[i], reg, tempreg);
835 #if CONFIG_EXT_CONF_SUPPORT
836                 return;
837         }
838
839         device_t dev;
840         u32 j;
841         // if ht_c_index > 3, We should use extend space
842         // for nodeid at first
843         u32 enable;
844
845         if(mmio_min>mmio_max) {
846                 return;
847         }
848
849         enable = 1;
850
851         dev = __f1_dev[nodeid];
852         tempreg = ((mmio_min>>3) & 0x1fffff00)| (1<<6) | (linkn<<0);
853         pci_write_config32(dev, 0x110, index | (2<<28));
854         pci_write_config32(dev, 0x114, tempreg);
855
856         tempreg = ((mmio_max>>3) & 0x1fffff00) | enable;
857         pci_write_config32(dev, 0x110, index | (3<<28));
858         pci_write_config32(dev, 0x114, tempreg);
859
860
861         // all other nodes
862         tempreg = ((mmio_min>>3) & 0x1fffff00) | (0<<6) | (nodeid<<0);
863         for(j = 0; j< sysconf.nodes; j++) {
864                 if(j== nodeid) continue;
865                 dev = __f1_dev[j];
866                 pci_write_config32(dev, 0x110, index | (2<<28));
867                 pci_write_config32(dev, 0x114, tempreg);
868         }
869
870         tempreg = ((mmio_max>>3) & 0x1fffff00) | enable;
871         for(j = 0; j< sysconf.nodes; j++) {
872                 if(j==nodeid) continue;
873                 dev = __f1_dev[j];
874                 pci_write_config32(dev, 0x110, index | (3<<28));
875                 pci_write_config32(dev, 0x114, tempreg);
876          }
877 #endif
878 }
879
880 #endif