linux/arch/x86/kernel/aperture_64.c
<<
>>
Prefs
   1/*
   2 * Firmware replacement code.
   3 *
   4 * Work around broken BIOSes that don't set an aperture or only set the
   5 * aperture in the AGP bridge.
   6 * If all fails map the aperture over some low memory.  This is cheaper than
   7 * doing bounce buffering. The memory is lost. This is done at early boot
   8 * because only the bootmem allocator can allocate 32+MB.
   9 *
  10 * Copyright 2002 Andi Kleen, SuSE Labs.
  11 */
  12#include <linux/kernel.h>
  13#include <linux/types.h>
  14#include <linux/init.h>
  15#include <linux/bootmem.h>
  16#include <linux/mmzone.h>
  17#include <linux/pci_ids.h>
  18#include <linux/pci.h>
  19#include <linux/bitops.h>
  20#include <linux/ioport.h>
  21#include <linux/suspend.h>
  22#include <asm/e820.h>
  23#include <asm/io.h>
  24#include <asm/iommu.h>
  25#include <asm/gart.h>
  26#include <asm/pci-direct.h>
  27#include <asm/dma.h>
  28#include <asm/k8.h>
  29
  30int gart_iommu_aperture;
  31int gart_iommu_aperture_disabled __initdata;
  32int gart_iommu_aperture_allowed __initdata;
  33
  34int fallback_aper_order __initdata = 1; /* 64MB */
  35int fallback_aper_force __initdata;
  36
  37int fix_aperture __initdata = 1;
  38
  39struct bus_dev_range {
  40        int bus;
  41        int dev_base;
  42        int dev_limit;
  43};
  44
  45static struct bus_dev_range bus_dev_ranges[] __initdata = {
  46        { 0x00, 0x18, 0x20},
  47        { 0xff, 0x00, 0x20},
  48        { 0xfe, 0x00, 0x20}
  49};
  50
  51static struct resource gart_resource = {
  52        .name   = "GART",
  53        .flags  = IORESOURCE_MEM,
  54};
  55
  56static void __init insert_aperture_resource(u32 aper_base, u32 aper_size)
  57{
  58        gart_resource.start = aper_base;
  59        gart_resource.end = aper_base + aper_size - 1;
  60        insert_resource(&iomem_resource, &gart_resource);
  61}
  62
  63/* This code runs before the PCI subsystem is initialized, so just
  64   access the northbridge directly. */
  65
  66static u32 __init allocate_aperture(void)
  67{
  68        u32 aper_size;
  69        void *p;
  70
  71        /* aper_size should <= 1G */
  72        if (fallback_aper_order > 5)
  73                fallback_aper_order = 5;
  74        aper_size = (32 * 1024 * 1024) << fallback_aper_order;
  75
  76        /*
  77         * Aperture has to be naturally aligned. This means a 2GB aperture
  78         * won't have much chance of finding a place in the lower 4GB of
  79         * memory. Unfortunately we cannot move it up because that would
  80         * make the IOMMU useless.
  81         */
  82        /*
  83         * using 512M as goal, in case kexec will load kernel_big
  84         * that will do the on position decompress, and  could overlap with
  85         * that positon with gart that is used.
  86         * sequende:
  87         * kernel_small
  88         * ==> kexec (with kdump trigger path or previous doesn't shutdown gart)
  89         * ==> kernel_small(gart area become e820_reserved)
  90         * ==> kexec (with kdump trigger path or previous doesn't shutdown gart)
  91         * ==> kerne_big (uncompressed size will be big than 64M or 128M)
  92         * so don't use 512M below as gart iommu, leave the space for kernel
  93         * code for safe
  94         */
  95        p = __alloc_bootmem_nopanic(aper_size, aper_size, 512ULL<<20);
  96        if (!p || __pa(p)+aper_size > 0xffffffff) {
  97                printk(KERN_ERR
  98                        "Cannot allocate aperture memory hole (%p,%uK)\n",
  99                                p, aper_size>>10);
 100                if (p)
 101                        free_bootmem(__pa(p), aper_size);
 102                return 0;
 103        }
 104        printk(KERN_INFO "Mapping aperture over %d KB of RAM @ %lx\n",
 105                        aper_size >> 10, __pa(p));
 106        insert_aperture_resource((u32)__pa(p), aper_size);
 107        register_nosave_region((u32)__pa(p) >> PAGE_SHIFT,
 108                                (u32)__pa(p+aper_size) >> PAGE_SHIFT);
 109
 110        return (u32)__pa(p);
 111}
 112
 113
 114/* Find a PCI capability */
 115static u32 __init find_cap(int bus, int slot, int func, int cap)
 116{
 117        int bytes;
 118        u8 pos;
 119
 120        if (!(read_pci_config_16(bus, slot, func, PCI_STATUS) &
 121                                                PCI_STATUS_CAP_LIST))
 122                return 0;
 123
 124        pos = read_pci_config_byte(bus, slot, func, PCI_CAPABILITY_LIST);
 125        for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) {
 126                u8 id;
 127
 128                pos &= ~3;
 129                id = read_pci_config_byte(bus, slot, func, pos+PCI_CAP_LIST_ID);
 130                if (id == 0xff)
 131                        break;
 132                if (id == cap)
 133                        return pos;
 134                pos = read_pci_config_byte(bus, slot, func,
 135                                                pos+PCI_CAP_LIST_NEXT);
 136        }
 137        return 0;
 138}
 139
 140/* Read a standard AGPv3 bridge header */
 141static u32 __init read_agp(int bus, int slot, int func, int cap, u32 *order)
 142{
 143        u32 apsize;
 144        u32 apsizereg;
 145        int nbits;
 146        u32 aper_low, aper_hi;
 147        u64 aper;
 148        u32 old_order;
 149
 150        printk(KERN_INFO "AGP bridge at %02x:%02x:%02x\n", bus, slot, func);
 151        apsizereg = read_pci_config_16(bus, slot, func, cap + 0x14);
 152        if (apsizereg == 0xffffffff) {
 153                printk(KERN_ERR "APSIZE in AGP bridge unreadable\n");
 154                return 0;
 155        }
 156
 157        /* old_order could be the value from NB gart setting */
 158        old_order = *order;
 159
 160        apsize = apsizereg & 0xfff;
 161        /* Some BIOS use weird encodings not in the AGPv3 table. */
 162        if (apsize & 0xff)
 163                apsize |= 0xf00;
 164        nbits = hweight16(apsize);
 165        *order = 7 - nbits;
 166        if ((int)*order < 0) /* < 32MB */
 167                *order = 0;
 168
 169        aper_low = read_pci_config(bus, slot, func, 0x10);
 170        aper_hi = read_pci_config(bus, slot, func, 0x14);
 171        aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32);
 172
 173        /*
 174         * On some sick chips, APSIZE is 0. It means it wants 4G
 175         * so let double check that order, and lets trust AMD NB settings:
 176         */
 177        printk(KERN_INFO "Aperture from AGP @ %Lx old size %u MB\n",
 178                        aper, 32 << old_order);
 179        if (aper + (32ULL<<(20 + *order)) > 0x100000000ULL) {
 180                printk(KERN_INFO "Aperture size %u MB (APSIZE %x) is not right, using settings from NB\n",
 181                                32 << *order, apsizereg);
 182                *order = old_order;
 183        }
 184
 185        printk(KERN_INFO "Aperture from AGP @ %Lx size %u MB (APSIZE %x)\n",
 186                        aper, 32 << *order, apsizereg);
 187
 188        if (!aperture_valid(aper, (32*1024*1024) << *order, 32<<20))
 189                return 0;
 190        return (u32)aper;
 191}
 192
 193/*
 194 * Look for an AGP bridge. Windows only expects the aperture in the
 195 * AGP bridge and some BIOS forget to initialize the Northbridge too.
 196 * Work around this here.
 197 *
 198 * Do an PCI bus scan by hand because we're running before the PCI
 199 * subsystem.
 200 *
 201 * All K8 AGP bridges are AGPv3 compliant, so we can do this scan
 202 * generically. It's probably overkill to always scan all slots because
 203 * the AGP bridges should be always an own bus on the HT hierarchy,
 204 * but do it here for future safety.
 205 */
 206static u32 __init search_agp_bridge(u32 *order, int *valid_agp)
 207{
 208        int bus, slot, func;
 209
 210        /* Poor man's PCI discovery */
 211        for (bus = 0; bus < 256; bus++) {
 212                for (slot = 0; slot < 32; slot++) {
 213                        for (func = 0; func < 8; func++) {
 214                                u32 class, cap;
 215                                u8 type;
 216                                class = read_pci_config(bus, slot, func,
 217                                                        PCI_CLASS_REVISION);
 218                                if (class == 0xffffffff)
 219                                        break;
 220
 221                                switch (class >> 16) {
 222                                case PCI_CLASS_BRIDGE_HOST:
 223                                case PCI_CLASS_BRIDGE_OTHER: /* needed? */
 224                                        /* AGP bridge? */
 225                                        cap = find_cap(bus, slot, func,
 226                                                        PCI_CAP_ID_AGP);
 227                                        if (!cap)
 228                                                break;
 229                                        *valid_agp = 1;
 230                                        return read_agp(bus, slot, func, cap,
 231                                                        order);
 232                                }
 233
 234                                /* No multi-function device? */
 235                                type = read_pci_config_byte(bus, slot, func,
 236                                                               PCI_HEADER_TYPE);
 237                                if (!(type & 0x80))
 238                                        break;
 239                        }
 240                }
 241        }
 242        printk(KERN_INFO "No AGP bridge found\n");
 243
 244        return 0;
 245}
 246
 247static int gart_fix_e820 __initdata = 1;
 248
 249static int __init parse_gart_mem(char *p)
 250{
 251        if (!p)
 252                return -EINVAL;
 253
 254        if (!strncmp(p, "off", 3))
 255                gart_fix_e820 = 0;
 256        else if (!strncmp(p, "on", 2))
 257                gart_fix_e820 = 1;
 258
 259        return 0;
 260}
 261early_param("gart_fix_e820", parse_gart_mem);
 262
 263void __init early_gart_iommu_check(void)
 264{
 265        /*
 266         * in case it is enabled before, esp for kexec/kdump,
 267         * previous kernel already enable that. memset called
 268         * by allocate_aperture/__alloc_bootmem_nopanic cause restart.
 269         * or second kernel have different position for GART hole. and new
 270         * kernel could use hole as RAM that is still used by GART set by
 271         * first kernel
 272         * or BIOS forget to put that in reserved.
 273         * try to update e820 to make that region as reserved.
 274         */
 275        int i, fix, slot;
 276        u32 ctl;
 277        u32 aper_size = 0, aper_order = 0, last_aper_order = 0;
 278        u64 aper_base = 0, last_aper_base = 0;
 279        int aper_enabled = 0, last_aper_enabled = 0, last_valid = 0;
 280
 281        if (!early_pci_allowed())
 282                return;
 283
 284        /* This is mostly duplicate of iommu_hole_init */
 285        fix = 0;
 286        for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
 287                int bus;
 288                int dev_base, dev_limit;
 289
 290                bus = bus_dev_ranges[i].bus;
 291                dev_base = bus_dev_ranges[i].dev_base;
 292                dev_limit = bus_dev_ranges[i].dev_limit;
 293
 294                for (slot = dev_base; slot < dev_limit; slot++) {
 295                        if (!early_is_k8_nb(read_pci_config(bus, slot, 3, 0x00)))
 296                                continue;
 297
 298                        ctl = read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL);
 299                        aper_enabled = ctl & AMD64_GARTEN;
 300                        aper_order = (ctl >> 1) & 7;
 301                        aper_size = (32 * 1024 * 1024) << aper_order;
 302                        aper_base = read_pci_config(bus, slot, 3, AMD64_GARTAPERTUREBASE) & 0x7fff;
 303                        aper_base <<= 25;
 304
 305                        if (last_valid) {
 306                                if ((aper_order != last_aper_order) ||
 307                                    (aper_base != last_aper_base) ||
 308                                    (aper_enabled != last_aper_enabled)) {
 309                                        fix = 1;
 310                                        break;
 311                                }
 312                        }
 313
 314                        last_aper_order = aper_order;
 315                        last_aper_base = aper_base;
 316                        last_aper_enabled = aper_enabled;
 317                        last_valid = 1;
 318                }
 319        }
 320
 321        if (!fix && !aper_enabled)
 322                return;
 323
 324        if (!aper_base || !aper_size || aper_base + aper_size > 0x100000000UL)
 325                fix = 1;
 326
 327        if (gart_fix_e820 && !fix && aper_enabled) {
 328                if (e820_any_mapped(aper_base, aper_base + aper_size,
 329                                    E820_RAM)) {
 330                        /* reserve it, so we can reuse it in second kernel */
 331                        printk(KERN_INFO "update e820 for GART\n");
 332                        e820_add_region(aper_base, aper_size, E820_RESERVED);
 333                        update_e820();
 334                }
 335        }
 336
 337        if (!fix)
 338                return;
 339
 340        /* different nodes have different setting, disable them all at first*/
 341        for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
 342                int bus;
 343                int dev_base, dev_limit;
 344
 345                bus = bus_dev_ranges[i].bus;
 346                dev_base = bus_dev_ranges[i].dev_base;
 347                dev_limit = bus_dev_ranges[i].dev_limit;
 348
 349                for (slot = dev_base; slot < dev_limit; slot++) {
 350                        if (!early_is_k8_nb(read_pci_config(bus, slot, 3, 0x00)))
 351                                continue;
 352
 353                        ctl = read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL);
 354                        ctl &= ~AMD64_GARTEN;
 355                        write_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL, ctl);
 356                }
 357        }
 358
 359}
 360
 361static int __initdata printed_gart_size_msg;
 362
 363void __init gart_iommu_hole_init(void)
 364{
 365        u32 agp_aper_base = 0, agp_aper_order = 0;
 366        u32 aper_size, aper_alloc = 0, aper_order = 0, last_aper_order = 0;
 367        u64 aper_base, last_aper_base = 0;
 368        int fix, slot, valid_agp = 0;
 369        int i, node;
 370
 371        if (gart_iommu_aperture_disabled || !fix_aperture ||
 372            !early_pci_allowed())
 373                return;
 374
 375        printk(KERN_INFO  "Checking aperture...\n");
 376
 377        if (!fallback_aper_force)
 378                agp_aper_base = search_agp_bridge(&agp_aper_order, &valid_agp);
 379
 380        fix = 0;
 381        node = 0;
 382        for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
 383                int bus;
 384                int dev_base, dev_limit;
 385
 386                bus = bus_dev_ranges[i].bus;
 387                dev_base = bus_dev_ranges[i].dev_base;
 388                dev_limit = bus_dev_ranges[i].dev_limit;
 389
 390                for (slot = dev_base; slot < dev_limit; slot++) {
 391                        if (!early_is_k8_nb(read_pci_config(bus, slot, 3, 0x00)))
 392                                continue;
 393
 394                        iommu_detected = 1;
 395                        gart_iommu_aperture = 1;
 396
 397                        aper_order = (read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL) >> 1) & 7;
 398                        aper_size = (32 * 1024 * 1024) << aper_order;
 399                        aper_base = read_pci_config(bus, slot, 3, AMD64_GARTAPERTUREBASE) & 0x7fff;
 400                        aper_base <<= 25;
 401
 402                        printk(KERN_INFO "Node %d: aperture @ %Lx size %u MB\n",
 403                                        node, aper_base, aper_size >> 20);
 404                        node++;
 405
 406                        if (!aperture_valid(aper_base, aper_size, 64<<20)) {
 407                                if (valid_agp && agp_aper_base &&
 408                                    agp_aper_base == aper_base &&
 409                                    agp_aper_order == aper_order) {
 410                                        /* the same between two setting from NB and agp */
 411                                        if (!no_iommu &&
 412                                            max_pfn > MAX_DMA32_PFN &&
 413                                            !printed_gart_size_msg) {
 414                                                printk(KERN_ERR "you are using iommu with agp, but GART size is less than 64M\n");
 415                                                printk(KERN_ERR "please increase GART size in your BIOS setup\n");
 416                                                printk(KERN_ERR "if BIOS doesn't have that option, contact your HW vendor!\n");
 417                                                printed_gart_size_msg = 1;
 418                                        }
 419                                } else {
 420                                        fix = 1;
 421                                        goto out;
 422                                }
 423                        }
 424
 425                        if ((last_aper_order && aper_order != last_aper_order) ||
 426                            (last_aper_base && aper_base != last_aper_base)) {
 427                                fix = 1;
 428                                goto out;
 429                        }
 430                        last_aper_order = aper_order;
 431                        last_aper_base = aper_base;
 432                }
 433        }
 434
 435out:
 436        if (!fix && !fallback_aper_force) {
 437                if (last_aper_base) {
 438                        unsigned long n = (32 * 1024 * 1024) << last_aper_order;
 439
 440                        insert_aperture_resource((u32)last_aper_base, n);
 441                }
 442                return;
 443        }
 444
 445        if (!fallback_aper_force) {
 446                aper_alloc = agp_aper_base;
 447                aper_order = agp_aper_order;
 448        }
 449
 450        if (aper_alloc) {
 451                /* Got the aperture from the AGP bridge */
 452        } else if (swiotlb && !valid_agp) {
 453                /* Do nothing */
 454        } else if ((!no_iommu && max_pfn > MAX_DMA32_PFN) ||
 455                   force_iommu ||
 456                   valid_agp ||
 457                   fallback_aper_force) {
 458                printk(KERN_INFO
 459                        "Your BIOS doesn't leave a aperture memory hole\n");
 460                printk(KERN_INFO
 461                        "Please enable the IOMMU option in the BIOS setup\n");
 462                printk(KERN_INFO
 463                        "This costs you %d MB of RAM\n",
 464                                32 << fallback_aper_order);
 465
 466                aper_order = fallback_aper_order;
 467                aper_alloc = allocate_aperture();
 468                if (!aper_alloc) {
 469                        /*
 470                         * Could disable AGP and IOMMU here, but it's
 471                         * probably not worth it. But the later users
 472                         * cannot deal with bad apertures and turning
 473                         * on the aperture over memory causes very
 474                         * strange problems, so it's better to panic
 475                         * early.
 476                         */
 477                        panic("Not enough memory for aperture");
 478                }
 479        } else {
 480                return;
 481        }
 482
 483        /* Fix up the north bridges */
 484        for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
 485                int bus;
 486                int dev_base, dev_limit;
 487
 488                bus = bus_dev_ranges[i].bus;
 489                dev_base = bus_dev_ranges[i].dev_base;
 490                dev_limit = bus_dev_ranges[i].dev_limit;
 491                for (slot = dev_base; slot < dev_limit; slot++) {
 492                        if (!early_is_k8_nb(read_pci_config(bus, slot, 3, 0x00)))
 493                                continue;
 494
 495                        /* Don't enable translation yet. That is done later.
 496                           Assume this BIOS didn't initialise the GART so
 497                           just overwrite all previous bits */
 498                        write_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL, aper_order << 1);
 499                        write_pci_config(bus, slot, 3, AMD64_GARTAPERTUREBASE, aper_alloc >> 25);
 500                }
 501        }
 502
 503        set_up_gart_resume(aper_order, aper_alloc);
 504}
 505
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.