coreboot-v2/src/northbridge/amd/amdk8/northbridge.c
<<
>>
Prefs
   1/* This should be done by Eric
   2        2004.12 yhlu add dual core support
   3        2005.01 yhlu add support move apic before pci_domain in MB Config.lb
   4        2005.02 yhlu add e0 memory hole support
   5        2005.11 yhlu add put sb ht chain on bus 0
   6*/
   7
   8#include <console/console.h>
   9#include <arch/io.h>
  10#include <stdint.h>
  11#include <device/device.h>
  12#include <device/pci.h>
  13#include <device/pci_ids.h>
  14#include <device/hypertransport.h>
  15#include <stdlib.h>
  16#include <string.h>
  17#include <bitops.h>
  18#include <cpu/cpu.h>
  19
  20#include <cpu/x86/lapic.h>
  21
  22#include <cpu/amd/dualcore.h>
  23#if CONFIG_LOGICAL_CPUS==1
  24#include <pc80/mc146818rtc.h>
  25#endif
  26
  27#include "chip.h"
  28#include "root_complex/chip.h"
  29#include "northbridge.h"
  30
  31#include "amdk8.h"
  32
  33#include <cpu/amd/model_fxx_rev.h>
  34
  35#include <cpu/amd/amdk8_sysconf.h>
  36
  37struct amdk8_sysconf_t sysconf;
  38
  39#define MAX_FX_DEVS 8
  40static device_t __f0_dev[MAX_FX_DEVS];
  41static device_t __f1_dev[MAX_FX_DEVS];
  42static unsigned fx_devs=0;
  43
  44static void get_fx_devs(void)
  45{
  46        int i;
  47        for(i = 0; i < MAX_FX_DEVS; i++) {
  48                __f0_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 0));
  49                __f1_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 1));
  50                if (__f0_dev[i] != NULL && __f1_dev[i] != NULL)
  51                        fx_devs = i+1;
  52        }
  53        if (__f1_dev[0] == NULL || __f0_dev[0] == NULL || fx_devs == 0) {
  54                die("Cannot find 0:0x18.[0|1]\n");
  55        }
  56}
  57
  58static uint32_t f1_read_config32(unsigned reg)
  59{
  60        if ( fx_devs == 0)
  61                get_fx_devs();
  62        return pci_read_config32(__f1_dev[0], reg);
  63}
  64
  65static void f1_write_config32(unsigned reg, uint32_t value)
  66{
  67        int i;
  68        if ( fx_devs == 0)
  69                get_fx_devs();
  70        for(i = 0; i < fx_devs; i++) {
  71                device_t dev;
  72                dev = __f1_dev[i];
  73                if (dev && dev->enabled) {
  74                        pci_write_config32(dev, reg, value);
  75                }
  76        }
  77}
  78
  79static unsigned int amdk8_nodeid(device_t dev)
  80{
  81        return (dev->path.pci.devfn >> 3) - 0x18;
  82}
  83
  84static unsigned int amdk8_scan_chain(device_t dev, unsigned nodeid, unsigned link, unsigned sblink, unsigned int max, unsigned offset_unitid)
  85{
  86
  87                uint32_t link_type;
  88                int i;
  89                uint32_t busses, config_busses;
  90                unsigned free_reg, config_reg;
  91                unsigned ht_unitid_base[4]; // here assume only 4 HT device on chain
  92                unsigned max_bus;
  93                unsigned min_bus;
  94                unsigned max_devfn;
  95
  96                dev->link[link].cap = 0x80 + (link *0x20);
  97                do {
  98                        link_type = pci_read_config32(dev, dev->link[link].cap + 0x18);
  99                } while(link_type & ConnectionPending);
 100                if (!(link_type & LinkConnected)) {
 101                        return max;
 102                }
 103                do {
 104                        link_type = pci_read_config32(dev, dev->link[link].cap + 0x18);
 105                } while(!(link_type & InitComplete));
 106                if (!(link_type & NonCoherent)) {
 107                        return max;
 108                }
 109                /* See if there is an available configuration space mapping
 110                 * register in function 1.
 111                 */
 112                free_reg = 0;
 113                for(config_reg = 0xe0; config_reg <= 0xec; config_reg += 4) {
 114                        uint32_t config;
 115                        config = f1_read_config32(config_reg);
 116                        if (!free_reg && ((config & 3) == 0)) {
 117                                free_reg = config_reg;
 118                                continue;
 119                        }
 120                        if (((config & 3) == 3) &&
 121                                (((config >> 4) & 7) == nodeid) &&
 122                                (((config >> 8) & 3) == link)) {
 123                                break;
 124                        }
 125                }
 126                if (free_reg && (config_reg > 0xec)) {
 127                        config_reg = free_reg;
 128                }
 129                /* If we can't find an available configuration space mapping
 130                 * register skip this bus
 131                 */
 132                if (config_reg > 0xec) {
 133                        return max;
 134                }
 135
 136                /* Set up the primary, secondary and subordinate bus numbers.
 137                 * We have no idea how many busses are behind this bridge yet,
 138                 * so we set the subordinate bus number to 0xff for the moment.
 139                 */
 140#if CONFIG_SB_HT_CHAIN_ON_BUS0 > 0
 141                // first chain will on bus 0
 142                if((nodeid == 0) && (sblink==link)) { // actually max is 0 here
 143                        min_bus = max;
 144                }
 145        #if CONFIG_SB_HT_CHAIN_ON_BUS0 > 1
 146                // second chain will be on 0x40, third 0x80, forth 0xc0
 147                else {
 148                        min_bus = ((max>>6) + 1) * 0x40;
 149                }
 150                max = min_bus;
 151        #else
 152                //other ...
 153                else  {
 154                        min_bus = ++max;
 155                }
 156        #endif
 157#else
 158                min_bus = ++max;
 159#endif
 160                max_bus = 0xff;
 161
 162                dev->link[link].secondary = min_bus;
 163                dev->link[link].subordinate = max_bus;
 164
 165                /* Read the existing primary/secondary/subordinate bus
 166                 * number configuration.
 167                 */
 168                busses = pci_read_config32(dev, dev->link[link].cap + 0x14);
 169                config_busses = f1_read_config32(config_reg);
 170
 171                /* Configure the bus numbers for this bridge: the configuration
 172                 * transactions will not be propagates by the bridge if it is
 173                 * not correctly configured
 174                 */
 175                busses &= 0xff000000;
 176                busses |= (((unsigned int)(dev->bus->secondary) << 0) |
 177                        ((unsigned int)(dev->link[link].secondary) << 8) |
 178                        ((unsigned int)(dev->link[link].subordinate) << 16));
 179                pci_write_config32(dev, dev->link[link].cap + 0x14, busses);
 180
 181                config_busses &= 0x000fc88;
 182                config_busses |=
 183                        (3 << 0) |  /* rw enable, no device compare */
 184                        (( nodeid & 7) << 4) |
 185                        (( link & 3 ) << 8) |
 186                        ((dev->link[link].secondary) << 16) |
 187                        ((dev->link[link].subordinate) << 24);
 188                f1_write_config32(config_reg, config_busses);
 189
 190                /* Now we can scan all of the subordinate busses i.e. the
 191                 * chain on the hypertranport link
 192                 */
 193                for(i=0;i<4;i++) {
 194                        ht_unitid_base[i] = 0x20;
 195                }
 196
 197                if (min_bus == 0)
 198                        max_devfn = (0x17<<3) | 7;
 199                else
 200                        max_devfn = (0x1f<<3) | 7;
 201
 202                max = hypertransport_scan_chain(&dev->link[link], 0, max_devfn, max, ht_unitid_base, offset_unitid);
 203
 204                /* We know the number of busses behind this bridge.  Set the
 205                 * subordinate bus number to it's real value
 206                 */
 207                dev->link[link].subordinate = max;
 208                busses = (busses & 0xff00ffff) |
 209                        ((unsigned int) (dev->link[link].subordinate) << 16);
 210                pci_write_config32(dev, dev->link[link].cap + 0x14, busses);
 211
 212                config_busses = (config_busses & 0x00ffffff) |
 213                        (dev->link[link].subordinate << 24);
 214                f1_write_config32(config_reg, config_busses);
 215
 216                {
 217                        // config config_reg, and ht_unitid_base to update hcdn_reg;
 218                        int index;
 219                        unsigned temp = 0;
 220                        index = (config_reg-0xe0) >> 2;
 221                        for(i=0;i<4;i++) {
 222                                temp |= (ht_unitid_base[i] & 0xff) << (i*8);
 223                        }
 224
 225                        sysconf.hcdn_reg[index] = temp;
 226
 227                }
 228
 229        return max;
 230}
 231
 232static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
 233{
 234        unsigned nodeid;
 235        unsigned link;
 236        unsigned sblink = 0;
 237        unsigned offset_unitid = 0;
 238        nodeid = amdk8_nodeid(dev);
 239
 240        if(nodeid==0) {
 241                sblink = (pci_read_config32(dev, 0x64)>>8) & 3;
 242#if CONFIG_SB_HT_CHAIN_ON_BUS0 > 0
 243        #if ((CONFIG_HT_CHAIN_UNITID_BASE != 1) || (CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20))
 244                offset_unitid = 1;
 245        #endif
 246                max = amdk8_scan_chain(dev, nodeid, sblink, sblink, max, offset_unitid ); // do sb ht chain at first, in case s2885 put sb chain (8131/8111) on link2, but put 8151 on link0
 247#endif
 248        }
 249
 250        for(link = 0; link < dev->links; link++) {
 251#if CONFIG_SB_HT_CHAIN_ON_BUS0 > 0
 252                if( (nodeid == 0) && (sblink == link) ) continue; //already done
 253#endif
 254                offset_unitid = 0;
 255                #if ((CONFIG_HT_CHAIN_UNITID_BASE != 1) || (CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20))
 256                        #if CONFIG_SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
 257                        if((nodeid == 0) && (sblink == link))
 258                        #endif
 259                                offset_unitid = 1;
 260                #endif
 261
 262                max = amdk8_scan_chain(dev, nodeid, link, sblink, max, offset_unitid);
 263        }
 264
 265        return max;
 266}
 267
 268
 269static int reg_useable(unsigned reg,
 270        device_t goal_dev, unsigned goal_nodeid, unsigned goal_link)
 271{
 272        struct resource *res;
 273        unsigned nodeid, link=0;
 274        int result;
 275        res = 0;
 276        for(nodeid = 0; !res && (nodeid < fx_devs); nodeid++) {
 277                device_t dev;
 278                dev = __f0_dev[nodeid];
 279                if (!dev)
 280                        continue;
 281                for(link = 0; !res && (link < 3); link++) {
 282                        res = probe_resource(dev, IOINDEX(0x100 + reg, link));
 283                }
 284        }
 285        result = 2;
 286        if (res) {
 287                result = 0;
 288                if (    (goal_link == (link - 1)) &&
 289                        (goal_nodeid == (nodeid - 1)) &&
 290                        (res->flags <= 1)) {
 291                        result = 1;
 292                }
 293        }
 294
 295        return result;
 296}
 297
 298static unsigned amdk8_find_reg(device_t dev, unsigned nodeid, unsigned link,
 299                               unsigned min, unsigned max)
 300{
 301        unsigned resource;
 302        unsigned free_reg, reg;
 303        resource = 0;
 304        free_reg = 0;
 305        for(reg = min; reg <= max; reg += 0x8) {
 306                int result;
 307                result = reg_useable(reg, dev, nodeid, link);
 308                if (result == 1) {
 309                        /* I have been allocated this one */
 310                        break;
 311                }
 312                else if (result > 1) {
 313                        /* I have a free register pair */
 314                        free_reg = reg;
 315                }
 316        }
 317        if (reg > max) {
 318                reg = free_reg;
 319        }
 320        if (reg > 0) {
 321                resource = IOINDEX(0x100 + reg, link);
 322        }
 323        return resource;
 324}
 325
 326static unsigned amdk8_find_iopair(device_t dev, unsigned nodeid, unsigned link)
 327{
 328        return amdk8_find_reg(dev, nodeid, link, 0xc0, 0xd8);
 329}
 330
 331static unsigned amdk8_find_mempair(device_t dev, unsigned nodeid, unsigned link)
 332{
 333        return amdk8_find_reg(dev, nodeid, link, 0x80, 0xb8);
 334}
 335
 336static void amdk8_link_read_bases(device_t dev, unsigned nodeid, unsigned link)
 337{
 338        struct resource *resource;
 339
 340        /* Initialize the io space constraints on the current bus */
 341        resource = new_resource(dev, IOINDEX(0, link));
 342        if (resource) {
 343                resource->base  = 0;
 344                resource->size  = 0;
 345                resource->align = log2(HT_IO_HOST_ALIGN);
 346                resource->gran  = log2(HT_IO_HOST_ALIGN);
 347                resource->limit = 0xffffUL;
 348                resource->flags = IORESOURCE_IO | IORESOURCE_BRIDGE;
 349        }
 350
 351        /* Initialize the prefetchable memory constraints on the current bus */
 352        resource = new_resource(dev, IOINDEX(2, link));
 353        if (resource) {
 354                resource->base  = 0;
 355                resource->size  = 0;
 356                resource->align = log2(HT_MEM_HOST_ALIGN);
 357                resource->gran  = log2(HT_MEM_HOST_ALIGN);
 358                resource->limit = 0xffffffffffULL;
 359                resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
 360                resource->flags |= IORESOURCE_BRIDGE;
 361        }
 362
 363        /* Initialize the memory constraints on the current bus */
 364        resource = new_resource(dev, IOINDEX(1, link));
 365        if (resource) {
 366                resource->base  = 0;
 367                resource->size  = 0;
 368                resource->align = log2(HT_MEM_HOST_ALIGN);
 369                resource->gran  = log2(HT_MEM_HOST_ALIGN);
 370                resource->limit = 0xffffffffULL;
 371                resource->flags = IORESOURCE_MEM | IORESOURCE_BRIDGE;
 372        }
 373}
 374
 375static void amdk8_create_vga_resource(device_t dev, unsigned nodeid);
 376
 377static void amdk8_read_resources(device_t dev)
 378{
 379        unsigned nodeid, link;
 380        nodeid = amdk8_nodeid(dev);
 381        for(link = 0; link < dev->links; link++) {
 382                if (dev->link[link].children) {
 383                        amdk8_link_read_bases(dev, nodeid, link);
 384                }
 385        }
 386
 387        amdk8_create_vga_resource(dev, nodeid);
 388}
 389
 390static void amdk8_set_resource(device_t dev, struct resource *resource, unsigned nodeid)
 391{
 392        resource_t rbase, rend;
 393        unsigned reg, link;
 394        char buf[50];
 395
 396        /* Make certain the resource has actually been set */
 397        if (!(resource->flags & IORESOURCE_ASSIGNED)) {
 398                printk_err("%s: can't set unassigned resource @%lx %lx\n",
 399                           __func__, resource->index, resource->flags);
 400                return;
 401        }
 402
 403        /* If I have already stored this resource don't worry about it */
 404        if (resource->flags & IORESOURCE_STORED) {
 405                printk_err("%s: can't set stored resource @%lx %lx\n", __func__,
 406                           resource->index, resource->flags);
 407                return;
 408        }
 409
 410        /* Only handle PCI memory and IO resources */
 411        if (!(resource->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
 412                return;
 413
 414        /* Ensure I am actually looking at a resource of function 1 */
 415        if (resource->index < 0x100) {
 416                return;
 417        }
 418
 419        if (resource->size == 0)
 420                return;
 421
 422        /* Get the base address */
 423        rbase = resource->base;
 424
 425        /* Get the limit (rounded up) */
 426        rend  = resource_end(resource);
 427
 428        /* Get the register and link */
 429        reg  = resource->index & 0xfc;
 430        link = IOINDEX_LINK(resource->index);
 431
 432        if (resource->flags & IORESOURCE_IO) {
 433                uint32_t base, limit;
 434                base  = f1_read_config32(reg);
 435                limit = f1_read_config32(reg + 0x4);
 436                base  &= 0xfe000fcc;
 437                base  |= rbase  & 0x01fff000;
 438                base  |= 3;
 439                limit &= 0xfe000fc8;
 440                limit |= rend & 0x01fff000;
 441                limit |= (link & 3) << 4;
 442                limit |= (nodeid & 7);
 443
 444                if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
 445                        printk_spew("%s, enabling legacy VGA IO forwarding for %s link 0x%x\n",
 446                                    __func__, dev_path(dev), link);
 447                        base |= PCI_IO_BASE_VGA_EN;
 448                }
 449                if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_NO_ISA) {
 450                        base |= PCI_IO_BASE_NO_ISA;
 451                }
 452
 453                f1_write_config32(reg + 0x4, limit);
 454                f1_write_config32(reg, base);
 455        }
 456        else if (resource->flags & IORESOURCE_MEM) {
 457                uint32_t base, limit;
 458                base  = f1_read_config32(reg);
 459                limit = f1_read_config32(reg + 0x4);
 460                base  &= 0x000000f0;
 461                base  |= (rbase >> 8) & 0xffffff00;
 462                base  |= 3;
 463                limit &= 0x00000048;
 464                limit |= (rend >> 8) & 0xffffff00;
 465                limit |= (link & 3) << 4;
 466                limit |= (nodeid & 7);
 467                f1_write_config32(reg + 0x4, limit);
 468                f1_write_config32(reg, base);
 469        }
 470        resource->flags |= IORESOURCE_STORED;
 471        sprintf(buf, " <node %d link %d>",
 472                nodeid, link);
 473        report_resource_stored(dev, resource, buf);
 474}
 475
 476#if CONFIG_CONSOLE_VGA_MULTI == 1
 477extern device_t vga_pri;        // the primary vga device, defined in device.c
 478#endif
 479
 480static void amdk8_create_vga_resource(device_t dev, unsigned nodeid)
 481{
 482        struct resource *resource;
 483        unsigned link;
 484
 485        /* find out which link the VGA card is connected,
 486         * we only deal with the 'first' vga card */
 487        for (link = 0; link < dev->links; link++) {
 488                if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
 489#if CONFIG_CONSOLE_VGA_MULTI == 1
 490                        printk_debug("VGA: vga_pri bus num = %d dev->link[link] bus range [%d,%d]\n", vga_pri->bus->secondary,
 491                                dev->link[link].secondary,dev->link[link].subordinate);
 492                        /* We need to make sure the vga_pri is under the link */
 493                        if((vga_pri->bus->secondary >= dev->link[link].secondary ) &&
 494                                (vga_pri->bus->secondary <= dev->link[link].subordinate )
 495                        )
 496#endif
 497                        break;
 498                }
 499        }
 500
 501        /* no VGA card installed */
 502        if (link == dev->links)
 503                return;
 504
 505        printk_debug("VGA: %s (aka node %d) link %d has VGA device\n", dev_path(dev), nodeid, link);
 506
 507        /* allocate a temp resource for the legacy VGA buffer */
 508        resource = new_resource(dev, IOINDEX(4, link));
 509        if(!resource){
 510                printk_debug("VGA: %s out of resources.\n", dev_path(dev));
 511                return;
 512        }
 513        resource->base = 0xa0000;
 514        resource->size = 0x20000;
 515        resource->limit = 0xffffffff;
 516        resource->flags = IORESOURCE_FIXED | IORESOURCE_MEM |
 517                          IORESOURCE_ASSIGNED;
 518}
 519
 520static void amdk8_set_resources(device_t dev)
 521{
 522        unsigned nodeid, link;
 523        int i;
 524
 525        /* Find the nodeid */
 526        nodeid = amdk8_nodeid(dev);
 527
 528        /* Set each resource we have found */
 529        for(i = 0; i < dev->resources; i++) {
 530                struct resource *res = &dev->resource[i];
 531                struct resource *old = NULL;
 532                unsigned index;
 533
 534                if (res->size == 0) /* No need to allocate registers. */
 535                        continue;
 536
 537                if (res->flags & IORESOURCE_IO)
 538                        index = amdk8_find_iopair(dev, nodeid,
 539                                                  IOINDEX_LINK(res->index));
 540                else
 541                        index = amdk8_find_mempair(dev, nodeid,
 542                                                   IOINDEX_LINK(res->index));
 543
 544                old = probe_resource(dev, index);
 545                if (old) {
 546                        res->index = old->index;
 547                        old->index = 0;
 548                        old->flags = 0;
 549                }
 550                else
 551                        res->index = index;
 552
 553                amdk8_set_resource(dev, res, nodeid);
 554        }
 555
 556        compact_resources(dev);
 557
 558        for(link = 0; link < dev->links; link++) {
 559                struct bus *bus;
 560                bus = &dev->link[link];
 561                if (bus->children) {
 562                        assign_resources(bus);
 563                }
 564        }
 565}
 566
 567static void amdk8_enable_resources(device_t dev)
 568{
 569        pci_dev_enable_resources(dev);
 570        enable_childrens_resources(dev);
 571}
 572
 573static void mcf0_control_init(struct device *dev)
 574{
 575#if 0
 576        printk_debug("NB: Function 0 Misc Control.. ");
 577#endif
 578#if 0
 579        printk_debug("done.\n");
 580#endif
 581}
 582
 583static struct device_operations northbridge_operations = {
 584        .read_resources   = amdk8_read_resources,
 585        .set_resources    = amdk8_set_resources,
 586        .enable_resources = amdk8_enable_resources,
 587        .init             = mcf0_control_init,
 588        .scan_bus         = amdk8_scan_chains,
 589        .enable           = 0,
 590        .ops_pci          = 0,
 591};
 592
 593
 594static const struct pci_driver mcf0_driver __pci_driver = {
 595        .ops    = &northbridge_operations,
 596        .vendor = PCI_VENDOR_ID_AMD,
 597        .device = 0x1100,
 598};
 599
 600struct chip_operations northbridge_amd_amdk8_ops = {
 601        CHIP_NAME("AMD K8 Northbridge")
 602        .enable_dev = 0,
 603};
 604
 605static void amdk8_domain_read_resources(device_t dev)
 606{
 607        unsigned reg;
 608
 609        /* Find the already assigned resource pairs */
 610        get_fx_devs();
 611        for(reg = 0x80; reg <= 0xd8; reg+= 0x08) {
 612                uint32_t base, limit;
 613                base  = f1_read_config32(reg);
 614                limit = f1_read_config32(reg + 0x04);
 615                /* Is this register allocated? */
 616                if ((base & 3) != 0) {
 617                        unsigned nodeid, link;
 618                        device_t reg_dev;
 619                        nodeid = limit & 7;
 620                        link   = (limit >> 4) & 3;
 621                        reg_dev = __f0_dev[nodeid];
 622                        if (reg_dev) {
 623                                /* Reserve the resource  */
 624                                struct resource *res;
 625                                res = new_resource(reg_dev, IOINDEX(0x100 + reg, link));
 626                                if (res) {
 627                                        res->base = base;
 628                                        res->limit = limit;
 629                                        res->flags = 1;
 630                                }
 631                        }
 632                }
 633        }
 634
 635        pci_domain_read_resources(dev);
 636
 637#if CONFIG_PCI_64BIT_PREF_MEM == 1
 638        /* Initialize the system wide prefetchable memory resources constraints */
 639        resource = new_resource(dev, 2);
 640        resource->limit = 0xfcffffffffULL;
 641        resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
 642#endif
 643}
 644
 645static void ram_resource(device_t dev, unsigned long index,
 646        unsigned long basek, unsigned long sizek)
 647{
 648        struct resource *resource;
 649
 650        if (!sizek) {
 651                return;
 652        }
 653        resource = new_resource(dev, index);
 654        resource->base  = ((resource_t)basek) << 10;
 655        resource->size  = ((resource_t)sizek) << 10;
 656        resource->flags =  IORESOURCE_MEM | IORESOURCE_CACHEABLE | \
 657                IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
 658}
 659
 660static void tolm_test(void *gp, struct device *dev, struct resource *new)
 661{
 662        struct resource **best_p = gp;
 663        struct resource *best;
 664        best = *best_p;
 665        /* Skip VGA. */
 666        if (!best || (best->base > new->base && new->base > 0xa0000)) {
 667                best = new;
 668        }
 669        *best_p = best;
 670}
 671
 672static uint32_t find_pci_tolm(struct bus *bus)
 673{
 674        struct resource *min;
 675        uint32_t tolm;
 676        min = 0;
 677        search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM, tolm_test, &min);
 678        tolm = 0xffffffffUL;
 679        if (min && tolm > min->base) {
 680                tolm = min->base;
 681        }
 682        return tolm;
 683}
 684
 685#if CONFIG_HW_MEM_HOLE_SIZEK != 0
 686
 687struct hw_mem_hole_info {
 688        unsigned hole_startk;
 689        int node_id;
 690};
 691
 692static struct hw_mem_hole_info get_hw_mem_hole_info(void)
 693{
 694                struct hw_mem_hole_info mem_hole;
 695                int i;
 696
 697                mem_hole.hole_startk = CONFIG_HW_MEM_HOLE_SIZEK;
 698                mem_hole.node_id = -1;
 699
 700                for (i = 0; i < fx_devs; i++) {
 701                        uint32_t base;
 702                        uint32_t hole;
 703                        base  = f1_read_config32(0x40 + (i << 3));
 704                        if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
 705                                continue;
 706                        }
 707
 708                        hole = pci_read_config32(__f1_dev[i], 0xf0);
 709                        if(hole & 1) { // we find the hole
 710                                mem_hole.hole_startk = (hole & (0xff<<24)) >> 10;
 711                                mem_hole.node_id = i; // record the node No with hole
 712                                break; // only one hole
 713                        }
 714                }
 715
 716                //We need to double check if there is speical set on base reg and limit reg are not continous instead of hole, it will find out it's hole_startk
 717                if(mem_hole.node_id==-1) {
 718                        uint32_t limitk_pri = 0;
 719                        for(i=0; i<8; i++) {
 720                                uint32_t base, limit;
 721                                unsigned base_k, limit_k;
 722                                base  = f1_read_config32(0x40 + (i << 3));
 723                                if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
 724                                        continue;
 725                                }
 726
 727                                base_k = (base & 0xffff0000) >> 2;
 728                                if(limitk_pri != base_k) { // we find the hole
 729                                        mem_hole.hole_startk = limitk_pri;
 730                                        mem_hole.node_id = i;
 731                                        break; //only one hole
 732                                }
 733
 734                                limit = f1_read_config32(0x44 + (i << 3));
 735                                limit_k = ((limit + 0x00010000) & 0xffff0000) >> 2;
 736                                limitk_pri = limit_k;
 737                        }
 738                }
 739
 740                return mem_hole;
 741
 742}
 743
 744static void disable_hoist_memory(unsigned long hole_startk, int node_id)
 745{
 746        int i;
 747        device_t dev;
 748        uint32_t base, limit;
 749        uint32_t hoist;
 750        uint32_t hole_sizek;
 751
 752
 753        //1. find which node has hole
 754        //2. change limit in that node.
 755        //3. change base and limit in later node
 756        //4. clear that node f0
 757
 758        //if there is not mem hole enabled, we need to change it's base instead
 759
 760        hole_sizek = (4*1024*1024) - hole_startk;
 761
 762        for(i=7;i>node_id;i--) {
 763
 764                base  = f1_read_config32(0x40 + (i << 3));
 765                if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
 766                        continue;
 767                }
 768                limit = f1_read_config32(0x44 + (i << 3));
 769                f1_write_config32(0x44 + (i << 3),limit - (hole_sizek << 2));
 770                f1_write_config32(0x40 + (i << 3),base - (hole_sizek << 2));
 771        }
 772        limit = f1_read_config32(0x44 + (node_id << 3));
 773        f1_write_config32(0x44 + (node_id << 3),limit - (hole_sizek << 2));
 774        dev = __f1_dev[node_id];
 775        if (dev == NULL) {
 776                printk_err("%s: node %x is NULL!\n", __func__, node_id);
 777                return;
 778        }
 779        hoist = pci_read_config32(dev, 0xf0);
 780        if(hoist & 1)
 781                pci_write_config32(dev, 0xf0, 0);
 782        else {
 783                base = pci_read_config32(dev, 0x40 + (node_id << 3));
 784                f1_write_config32(0x40 + (node_id << 3),base - (hole_sizek << 2));
 785        }
 786}
 787
 788static uint32_t hoist_memory(unsigned long hole_startk, int node_id)
 789{
 790        int i;
 791        uint32_t carry_over;
 792        device_t dev;
 793        uint32_t base, limit;
 794        uint32_t basek;
 795        uint32_t hoist;
 796
 797        carry_over = (4*1024*1024) - hole_startk;
 798
 799        for(i=7;i>node_id;i--) {
 800
 801                base  = f1_read_config32(0x40 + (i << 3));
 802                if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
 803                        continue;
 804                }
 805                limit = f1_read_config32(0x44 + (i << 3));
 806                f1_write_config32(0x44 + (i << 3),limit + (carry_over << 2));
 807                f1_write_config32(0x40 + (i << 3),base + (carry_over << 2));
 808        }
 809        limit = f1_read_config32(0x44 + (node_id << 3));
 810        f1_write_config32(0x44 + (node_id << 3),limit + (carry_over << 2));
 811        dev = __f1_dev[node_id];
 812        base  = pci_read_config32(dev, 0x40 + (node_id << 3));
 813        basek  = (base & 0xffff0000) >> 2;
 814        if(basek == hole_startk) {
 815                //don't need set memhole here, because hole off set will be 0, overflow
 816                //so need to change base reg instead, new basek will be 4*1024*1024
 817                base &= 0x0000ffff;
 818                base |= (4*1024*1024)<<2;
 819                f1_write_config32(0x40 + (node_id<<3), base);
 820        }
 821        else if (dev)
 822        {
 823                hoist = /* hole start address */
 824                        ((hole_startk << 10) & 0xff000000) +
 825                        /* hole address to memory controller address */
 826                        (((basek + carry_over) >> 6) & 0x0000ff00) +
 827                        /* enable */
 828                        1;
 829
 830                pci_write_config32(dev, 0xf0, hoist);
 831        }
 832
 833        return carry_over;
 834}
 835#endif
 836
 837#if CONFIG_WRITE_HIGH_TABLES==1
 838#define HIGH_TABLES_SIZE 64     // maximum size of high tables in KB
 839extern uint64_t high_tables_base, high_tables_size;
 840#if CONFIG_GFXUMA == 1
 841extern uint64_t uma_memory_base, uma_memory_size;
 842#endif
 843#endif
 844
 845static void amdk8_domain_set_resources(device_t dev)
 846{
 847#if CONFIG_PCI_64BIT_PREF_MEM == 1
 848        struct resource *io, *mem1, *mem2;
 849        struct resource *resource, *last;
 850#endif
 851        unsigned long mmio_basek;
 852        uint32_t pci_tolm;
 853        int i, idx;
 854#if CONFIG_HW_MEM_HOLE_SIZEK != 0
 855        struct hw_mem_hole_info mem_hole;
 856        unsigned reset_memhole = 1;
 857#endif
 858
 859#if 0
 860        /* Place the IO devices somewhere safe */
 861        io = find_resource(dev, 0);
 862        io->base = DEVICE_IO_START;
 863#endif
 864#if CONFIG_PCI_64BIT_PREF_MEM == 1
 865        /* Now reallocate the pci resources memory with the
 866         * highest addresses I can manage.
 867         */
 868        mem1 = find_resource(dev, 1);
 869        mem2 = find_resource(dev, 2);
 870
 871#if 1
 872        printk_debug("base1: 0x%08Lx limit1: 0x%08Lx size: 0x%08Lx align: %d\n",
 873                mem1->base, mem1->limit, mem1->size, mem1->align);
 874        printk_debug("base2: 0x%08Lx limit2: 0x%08Lx size: 0x%08Lx align: %d\n",
 875                mem2->base, mem2->limit, mem2->size, mem2->align);
 876#endif
 877
 878        /* See if both resources have roughly the same limits */
 879        if (((mem1->limit <= 0xffffffff) && (mem2->limit <= 0xffffffff)) ||
 880                ((mem1->limit > 0xffffffff) && (mem2->limit > 0xffffffff)))
 881        {
 882                /* If so place the one with the most stringent alignment first
 883                 */
 884                if (mem2->align > mem1->align) {
 885                        struct resource *tmp;
 886                        tmp = mem1;
 887                        mem1 = mem2;
 888                        mem2 = tmp;
 889                }
 890                /* Now place the memory as high up as it will go */
 891                mem2->base = resource_max(mem2);
 892                mem1->limit = mem2->base - 1;
 893                mem1->base = resource_max(mem1);
 894        }
 895        else {
 896                /* Place the resources as high up as they will go */
 897                mem2->base = resource_max(mem2);
 898                mem1->base = resource_max(mem1);
 899        }
 900
 901#if 1
 902        printk_debug("base1: 0x%08Lx limit1: 0x%08Lx size: 0x%08Lx align: %d\n",
 903                mem1->base, mem1->limit, mem1->size, mem1->align);
 904        printk_debug("base2: 0x%08Lx limit2: 0x%08Lx size: 0x%08Lx align: %d\n",
 905                mem2->base, mem2->limit, mem2->size, mem2->align);
 906#endif
 907
 908        last = &dev->resource[dev->resources];
 909        for(resource = &dev->resource[0]; resource < last; resource++)
 910        {
 911                resource->flags |= IORESOURCE_ASSIGNED;
 912                resource->flags |= IORESOURCE_STORED;
 913                report_resource_stored(dev, resource, "");
 914
 915        }
 916#endif
 917
 918
 919        pci_tolm = find_pci_tolm(&dev->link[0]);
 920
 921#warning "FIXME handle interleaved nodes"
 922        mmio_basek = pci_tolm >> 10;
 923        /* Round mmio_basek to something the processor can support */
 924        mmio_basek &= ~((1 << 6) -1);
 925
 926#if 1
 927#warning "FIXME improve mtrr.c so we don't use up all of the mtrrs with a 64M MMIO hole"
 928        /* Round the mmio hold to 64M */
 929        mmio_basek &= ~((64*1024) - 1);
 930#endif
 931
 932#if CONFIG_HW_MEM_HOLE_SIZEK != 0
 933        /* if the hw mem hole is already set in raminit stage, here we will compare mmio_basek and hole_basek
 934         * if mmio_basek is bigger that hole_basek and will use hole_basek as mmio_basek and we don't need to reset hole.
 935         * otherwise We reset the hole to the mmio_basek
 936         */
 937        #if CONFIG_K8_REV_F_SUPPORT == 0
 938                if (!is_cpu_pre_e0()) {
 939        #endif
 940
 941                mem_hole = get_hw_mem_hole_info();
 942
 943                if ((mem_hole.node_id !=  -1) && (mmio_basek > mem_hole.hole_startk)) { //We will use hole_basek as mmio_basek, and we don't need to reset hole anymore
 944                        mmio_basek = mem_hole.hole_startk;
 945                        reset_memhole = 0;
 946                }
 947
 948                //mmio_basek = 3*1024*1024; // for debug to meet boundary
 949
 950                if(reset_memhole) {
 951                        if(mem_hole.node_id!=-1) { // We need to select CONFIG_HW_MEM_HOLE_SIZEK for raminit, it can not make hole_startk to some basek too....!
 952                               // We need to reset our Mem Hole, because We want more big HOLE than we already set
 953                               //Before that We need to disable mem hole at first, becase memhole could already be set on i+1 instead
 954                                disable_hoist_memory(mem_hole.hole_startk, mem_hole.node_id);
 955                        }
 956
 957                #if CONFIG_HW_MEM_HOLE_SIZE_AUTO_INC == 1
 958                        //We need to double check if the mmio_basek is valid for hole setting, if it is equal to basek, we need to decrease it some
 959                        uint32_t basek_pri;
 960                        for (i = 0; i < fx_devs; i++) {
 961                                uint32_t base;
 962                                uint32_t basek;
 963                                base  = f1_read_config32(0x40 + (i << 3));
 964                                if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
 965                                        continue;
 966                                }
 967
 968                                basek = (base & 0xffff0000) >> 2;
 969                                if(mmio_basek == basek) {
 970                                        mmio_basek -= (basek - basek_pri)>>1; // increase mem hole size to make sure it is on middle of pri node
 971                                        break;
 972                                }
 973                                basek_pri = basek;
 974                        }
 975                #endif
 976                }
 977
 978#if CONFIG_K8_REV_F_SUPPORT == 0
 979        } // is_cpu_pre_e0
 980#endif
 981
 982#endif
 983
 984        idx = 0x10;
 985        for(i = 0; i < fx_devs; i++) {
 986                uint32_t base, limit;
 987                unsigned basek, limitk, sizek;
 988                base  = f1_read_config32(0x40 + (i << 3));
 989                limit = f1_read_config32(0x44 + (i << 3));
 990                if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
 991                        continue;
 992                }
 993                basek = (base & 0xffff0000) >> 2;
 994                limitk = ((limit + 0x00010000) & 0xffff0000) >> 2;
 995                sizek = limitk - basek;
 996
 997                /* see if we need a hole from 0xa0000 to 0xbffff */
 998                if ((basek < ((8*64)+(8*16))) && (sizek > ((8*64)+(16*16)))) {
 999                        ram_resource(dev, (idx | i), basek, ((8*64)+(8*16)) - basek);
1000                        idx += 0x10;
1001                        basek = (8*64)+(16*16);
1002                        sizek = limitk - ((8*64)+(16*16));
1003
1004                }
1005
1006
1007#if CONFIG_GFXUMA == 1
1008                printk_debug("node %d : uma_memory_base/1024=0x%08x, mmio_basek=0x%08x, basek=0x%08x, limitk=0x%08x\n", i, uma_memory_base >> 10, mmio_basek, basek, limitk);
1009                if ((uma_memory_base >> 10) < mmio_basek)
1010                        printk_alert("node %d: UMA memory starts below mmio_basek\n", i);
1011#else
1012//              printk_debug("node %d : mmio_basek=%08x, basek=%08x, limitk=%08x\n", i, mmio_basek, basek, limitk); //yhlu
1013#endif
1014
1015                /* See if I need to split the region to accomodate pci memory space */
1016                if ( (basek < 4*1024*1024 ) && (limitk > mmio_basek) ) {
1017                        if (basek <= mmio_basek) {
1018                                unsigned pre_sizek;
1019                                pre_sizek = mmio_basek - basek;
1020                                if(pre_sizek>0) {
1021                                        ram_resource(dev, (idx | i), basek, pre_sizek);
1022                                        idx += 0x10;
1023                                        sizek -= pre_sizek;
1024#if CONFIG_WRITE_HIGH_TABLES==1
1025                                        if (i==0 && high_tables_base==0) {
1026                                        /* Leave some space for ACPI, PIRQ and MP tables */
1027#if CONFIG_GFXUMA == 1
1028                                                high_tables_base = uma_memory_base - (HIGH_TABLES_SIZE * 1024);
1029#else
1030                                                high_tables_base = (mmio_basek - HIGH_TABLES_SIZE) * 1024;
1031#endif
1032                                                high_tables_size = HIGH_TABLES_SIZE * 1024;
1033                                                printk_debug(" split: %dK table at =%08llx\n", HIGH_TABLES_SIZE,
1034                                                             high_tables_base);
1035                                        }
1036#endif
1037                                }
1038                                #if CONFIG_HW_MEM_HOLE_SIZEK != 0
1039                                if(reset_memhole)
1040                                        #if CONFIG_K8_REV_F_SUPPORT == 0
1041                                        if(!is_cpu_pre_e0() )
1042                                        #endif
1043                                                 sizek += hoist_memory(mmio_basek,i);
1044                                #endif
1045
1046                                basek = mmio_basek;
1047                        }
1048                        if ((basek + sizek) <= 4*1024*1024) {
1049                                sizek = 0;
1050                        }
1051                        else {
1052                                basek = 4*1024*1024;
1053                                sizek -= (4*1024*1024 - mmio_basek);
1054                        }
1055                }
1056                /* If sizek == 0, it was split at mmio_basek without a hole.
1057                 * Don't create an empty ram_resource.
1058                 */
1059                if (sizek)
1060                        ram_resource(dev, (idx | i), basek, sizek);
1061                idx += 0x10;
1062#if CONFIG_WRITE_HIGH_TABLES==1
1063                printk_debug("%d: mmio_basek=%08lx, basek=%08x, limitk=%08x\n",
1064                             i, mmio_basek, basek, limitk);
1065                if (i==0 && high_tables_base==0) {
1066                /* Leave some space for ACPI, PIRQ and MP tables */
1067#if CONFIG_GFXUMA == 1
1068                        high_tables_base = uma_memory_base - (HIGH_TABLES_SIZE * 1024);
1069#else
1070                        high_tables_base = (limitk - HIGH_TABLES_SIZE) * 1024;
1071#endif
1072                        high_tables_size = HIGH_TABLES_SIZE * 1024;
1073                }
1074#endif
1075        }
1076        assign_resources(&dev->link[0]);
1077
1078}
1079
1080static unsigned int amdk8_domain_scan_bus(device_t dev, unsigned int max)
1081{
1082        unsigned reg;
1083        int i;
1084        /* Unmap all of the HT chains */
1085        for(reg = 0xe0; reg <= 0xec; reg += 4) {
1086                f1_write_config32(reg, 0);
1087        }
1088        max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0x18, 0), 0xff, max);
1089
1090        /* Tune the hypertransport transaction for best performance.
1091         * Including enabling relaxed ordering if it is safe.
1092         */
1093        get_fx_devs();
1094        for(i = 0; i < fx_devs; i++) {
1095                device_t f0_dev;
1096                f0_dev = __f0_dev[i];
1097                if (f0_dev && f0_dev->enabled) {
1098                        uint32_t httc;
1099                        httc = pci_read_config32(f0_dev, HT_TRANSACTION_CONTROL);
1100                        httc &= ~HTTC_RSP_PASS_PW;
1101                        if (!dev->link[0].disable_relaxed_ordering) {
1102                                httc |= HTTC_RSP_PASS_PW;
1103                        }
1104                        printk_spew("%s passpw: %s\n",
1105                                dev_path(dev),
1106                                (!dev->link[0].disable_relaxed_ordering)?
1107                                "enabled":"disabled");
1108                        pci_write_config32(f0_dev, HT_TRANSACTION_CONTROL, httc);
1109                }
1110        }
1111        return max;
1112}
1113
1114static struct device_operations pci_domain_ops = {
1115        .read_resources   = amdk8_domain_read_resources,
1116        .set_resources    = amdk8_domain_set_resources,
1117        .enable_resources = enable_childrens_resources,
1118        .init             = 0,
1119        .scan_bus         = amdk8_domain_scan_bus,
1120        .ops_pci_bus      = &pci_cf8_conf1,
1121};
1122
1123static unsigned int cpu_bus_scan(device_t dev, unsigned int max)
1124{
1125        struct bus *cpu_bus;
1126        device_t dev_mc;
1127        int bsp_apicid;
1128        int i,j;
1129        unsigned nb_cfg_54;
1130        unsigned siblings;
1131        int e0_later_single_core;
1132        int disable_siblings;
1133
1134        nb_cfg_54 = 0;
1135        sysconf.enabled_apic_ext_id = 0;
1136        sysconf.lift_bsp_apicid = 0;
1137        siblings = 0;
1138
1139        /* Find the bootstrap processors apicid */
1140        bsp_apicid = lapicid();
1141        sysconf.apicid_offset = bsp_apicid;
1142
1143        disable_siblings = !CONFIG_LOGICAL_CPUS;
1144#if CONFIG_LOGICAL_CPUS == 1
1145        get_option(&disable_siblings, "dual_core");
1146#endif
1147
1148        // for pre_e0, nb_cfg_54 can not be set, ( even set, when you read it still be 0)
1149        // How can I get the nb_cfg_54 of every node' nb_cfg_54 in bsp??? and differ d0 and e0 single core
1150
1151        nb_cfg_54 = read_nb_cfg_54();
1152
1153        dev_mc = dev_find_slot(0, PCI_DEVFN(0x18, 0));
1154        if (!dev_mc) {
1155                die("0:18.0 not found?");
1156        }
1157
1158        sysconf.nodes = ((pci_read_config32(dev_mc, 0x60)>>4) & 7) + 1;
1159
1160
1161        if (pci_read_config32(dev_mc, 0x68) & (HTTC_APIC_EXT_ID|HTTC_APIC_EXT_BRD_CST))
1162        {
1163                sysconf.enabled_apic_ext_id = 1;
1164                if(bsp_apicid == 0) {
1165                        /* bsp apic id is not changed */
1166                        sysconf.apicid_offset = CONFIG_APIC_ID_OFFSET;
1167                } else
1168                {
1169                        sysconf.lift_bsp_apicid = 1;
1170                }
1171
1172        }
1173
1174        /* Find which cpus are present */
1175        cpu_bus = &dev->link[0];
1176        for(i = 0; i < sysconf.nodes; i++) {
1177                device_t cpu_dev, cpu;
1178                struct device_path cpu_path;
1179
1180                /* Find the cpu's pci device */
1181                cpu_dev = dev_find_slot(0, PCI_DEVFN(0x18 + i, 3));
1182                if (!cpu_dev) {
1183                        /* If I am probing things in a weird order
1184                         * ensure all of the cpu's pci devices are found.
1185                         */
1186                        int local_j;
1187                        device_t dev_f0;
1188                        for(local_j = 0; local_j <= 3; local_j++) {
1189                                cpu_dev = pci_probe_dev(NULL, dev_mc->bus,
1190                                        PCI_DEVFN(0x18 + i, local_j));
1191                        }
1192                        /* Ok, We need to set the links for that device.
1193                         * otherwise the device under it will not be scanned
1194                         */
1195                        dev_f0 = dev_find_slot(0, PCI_DEVFN(0x18+i,0));
1196                        if(dev_f0) {
1197                                dev_f0->links = 3;
1198                                for(local_j=0;local_j<3;local_j++) {
1199                                        dev_f0->link[local_j].link = local_j;
1200                                        dev_f0->link[local_j].dev = dev_f0;
1201                                }
1202                        }
1203
1204                }
1205
1206                e0_later_single_core = 0;
1207                if (cpu_dev && cpu_dev->enabled) {
1208                        j = pci_read_config32(cpu_dev, 0xe8);
1209                        j = (j >> 12) & 3; // dev is func 3
1210                        printk_debug("  %s siblings=%d\n", dev_path(cpu_dev), j);
1211
1212                        if(nb_cfg_54) {
1213                                // For e0 single core if nb_cfg_54 is set, apicid will be 0, 2, 4....
1214                                //  ----> you can mixed single core e0 and dual core e0 at any sequence
1215                                // That is the typical case
1216
1217                                if(j == 0 ){
1218                                       #if CONFIG_K8_REV_F_SUPPORT == 0
1219                                        e0_later_single_core = is_e0_later_in_bsp(i);  // single core
1220                                       #else
1221                                        e0_later_single_core = is_cpu_f0_in_bsp(i);  // We can read cpuid(1) from Func3
1222                                       #endif
1223                                } else {
1224                                       e0_later_single_core = 0;
1225                                }
1226                                if(e0_later_single_core) {
1227                                        printk_debug("\tFound Rev E or Rev F later single core\r\n");
1228
1229                                        j=1;
1230                                }
1231
1232                                if(siblings > j ) {
1233                                }
1234                                else {
1235                                        siblings = j;
1236                                }
1237                        } else {
1238                                siblings = j;
1239                        }
1240                }
1241
1242                unsigned jj;
1243                if(e0_later_single_core || disable_siblings) {
1244                        jj = 0;
1245                } else
1246                {
1247                        jj = siblings;
1248                }
1249#if 0
1250                jj = 0; // if create cpu core1 path in amd_siblings by core0
1251#endif
1252
1253                for (j = 0; j <=jj; j++ ) {
1254
1255                        /* Build the cpu device path */
1256                        cpu_path.type = DEVICE_PATH_APIC;
1257                        cpu_path.apic.apic_id = i * (nb_cfg_54?(siblings+1):1) + j * (nb_cfg_54?1:8);
1258
1259                        /* See if I can find the cpu */
1260                        cpu = find_dev_path(cpu_bus, &cpu_path);
1261
1262                        /* Enable the cpu if I have the processor */
1263                        if (cpu_dev && cpu_dev->enabled) {
1264                                if (!cpu) {
1265                                        cpu = alloc_dev(cpu_bus, &cpu_path);
1266                                }
1267                                if (cpu) {
1268                                        cpu->enabled = 1;
1269                                }
1270                        }
1271
1272                        /* Disable the cpu if I don't have the processor */
1273                        if (cpu && (!cpu_dev || !cpu_dev->enabled)) {
1274                                cpu->enabled = 0;
1275                        }
1276
1277                        /* Report what I have done */
1278                        if (cpu) {
1279                                cpu->path.apic.node_id = i;
1280                                cpu->path.apic.core_id = j;
1281                                if(sysconf.enabled_apic_ext_id) {
1282                                        if(sysconf.lift_bsp_apicid) {
1283                                                cpu->path.apic.apic_id += sysconf.apicid_offset;
1284                                        } else
1285                                        {
1286                                               if (cpu->path.apic.apic_id != 0)
1287                                                       cpu->path.apic.apic_id += sysconf.apicid_offset;
1288                                        }
1289                                }
1290                                printk_debug("CPU: %s %s\n",
1291                                        dev_path(cpu), cpu->enabled?"enabled":"disabled");
1292                        }
1293
1294                } //j
1295        }
1296        return max;
1297}
1298
1299static void cpu_bus_init(device_t dev)
1300{
1301        initialize_cpus(&dev->link[0]);
1302}
1303
1304static void cpu_bus_noop(device_t dev)
1305{
1306}
1307
1308static struct device_operations cpu_bus_ops = {
1309        .read_resources   = cpu_bus_noop,
1310        .set_resources    = cpu_bus_noop,
1311        .enable_resources = cpu_bus_noop,
1312        .init             = cpu_bus_init,
1313        .scan_bus         = cpu_bus_scan,
1314};
1315
1316static void root_complex_enable_dev(struct device *dev)
1317{
1318        /* Set the operations if it is a special bus type */
1319        if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
1320                dev->ops = &pci_domain_ops;
1321        }
1322        else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
1323                dev->ops = &cpu_bus_ops;
1324        }
1325}
1326
1327struct chip_operations northbridge_amd_amdk8_root_complex_ops = {
1328        CHIP_NAME("AMD K8 Root Complex")
1329        .enable_dev = root_complex_enable_dev,
1330};
1331
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.