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