linux/arch/x86/kernel/cpu/mtrr/main.c
<<
>>
Prefs
   1/*  Generic MTRR (Memory Type Range Register) driver.
   2
   3    Copyright (C) 1997-2000  Richard Gooch
   4    Copyright (c) 2002       Patrick Mochel
   5
   6    This library is free software; you can redistribute it and/or
   7    modify it under the terms of the GNU Library General Public
   8    License as published by the Free Software Foundation; either
   9    version 2 of the License, or (at your option) any later version.
  10
  11    This library is distributed in the hope that it will be useful,
  12    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14    Library General Public License for more details.
  15
  16    You should have received a copy of the GNU Library General Public
  17    License along with this library; if not, write to the Free
  18    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19
  20    Richard Gooch may be reached by email at  rgooch@atnf.csiro.au
  21    The postal address is:
  22      Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
  23
  24    Source: "Pentium Pro Family Developer's Manual, Volume 3:
  25    Operating System Writer's Guide" (Intel document number 242692),
  26    section 11.11.7
  27
  28    This was cleaned and made readable by Patrick Mochel <mochel@osdl.org>
  29    on 6-7 March 2002.
  30    Source: Intel Architecture Software Developers Manual, Volume 3:
  31    System Programming Guide; Section 9.11. (1997 edition - PPro).
  32*/
  33
  34#define DEBUG
  35
  36#include <linux/types.h> /* FIXME: kvm_para.h needs this */
  37
  38#include <linux/stop_machine.h>
  39#include <linux/kvm_para.h>
  40#include <linux/uaccess.h>
  41#include <linux/module.h>
  42#include <linux/mutex.h>
  43#include <linux/init.h>
  44#include <linux/sort.h>
  45#include <linux/cpu.h>
  46#include <linux/pci.h>
  47#include <linux/smp.h>
  48#include <linux/syscore_ops.h>
  49
  50#include <asm/processor.h>
  51#include <asm/e820.h>
  52#include <asm/mtrr.h>
  53#include <asm/msr.h>
  54
  55#include "mtrr.h"
  56
  57u32 num_var_ranges;
  58
  59unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES];
  60static DEFINE_MUTEX(mtrr_mutex);
  61
  62u64 size_or_mask, size_and_mask;
  63static bool mtrr_aps_delayed_init;
  64
  65static const struct mtrr_ops *mtrr_ops[X86_VENDOR_NUM];
  66
  67const struct mtrr_ops *mtrr_if;
  68
  69static void set_mtrr(unsigned int reg, unsigned long base,
  70                     unsigned long size, mtrr_type type);
  71
  72void set_mtrr_ops(const struct mtrr_ops *ops)
  73{
  74        if (ops->vendor && ops->vendor < X86_VENDOR_NUM)
  75                mtrr_ops[ops->vendor] = ops;
  76}
  77
  78/*  Returns non-zero if we have the write-combining memory type  */
  79static int have_wrcomb(void)
  80{
  81        struct pci_dev *dev;
  82
  83        dev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, NULL);
  84        if (dev != NULL) {
  85                /*
  86                 * ServerWorks LE chipsets < rev 6 have problems with
  87                 * write-combining. Don't allow it and leave room for other
  88                 * chipsets to be tagged
  89                 */
  90                if (dev->vendor == PCI_VENDOR_ID_SERVERWORKS &&
  91                    dev->device == PCI_DEVICE_ID_SERVERWORKS_LE &&
  92                    dev->revision <= 5) {
  93                        pr_info("mtrr: Serverworks LE rev < 6 detected. Write-combining disabled.\n");
  94                        pci_dev_put(dev);
  95                        return 0;
  96                }
  97                /*
  98                 * Intel 450NX errata # 23. Non ascending cacheline evictions to
  99                 * write combining memory may resulting in data corruption
 100                 */
 101                if (dev->vendor == PCI_VENDOR_ID_INTEL &&
 102                    dev->device == PCI_DEVICE_ID_INTEL_82451NX) {
 103                        pr_info("mtrr: Intel 450NX MMC detected. Write-combining disabled.\n");
 104                        pci_dev_put(dev);
 105                        return 0;
 106                }
 107                pci_dev_put(dev);
 108        }
 109        return mtrr_if->have_wrcomb ? mtrr_if->have_wrcomb() : 0;
 110}
 111
 112/*  This function returns the number of variable MTRRs  */
 113static void __init set_num_var_ranges(void)
 114{
 115        unsigned long config = 0, dummy;
 116
 117        if (use_intel())
 118                rdmsr(MSR_MTRRcap, config, dummy);
 119        else if (is_cpu(AMD))
 120                config = 2;
 121        else if (is_cpu(CYRIX) || is_cpu(CENTAUR))
 122                config = 8;
 123
 124        num_var_ranges = config & 0xff;
 125}
 126
 127static void __init init_table(void)
 128{
 129        int i, max;
 130
 131        max = num_var_ranges;
 132        for (i = 0; i < max; i++)
 133                mtrr_usage_table[i] = 1;
 134}
 135
 136struct set_mtrr_data {
 137        unsigned long   smp_base;
 138        unsigned long   smp_size;
 139        unsigned int    smp_reg;
 140        mtrr_type       smp_type;
 141};
 142
 143/**
 144 * mtrr_rendezvous_handler - Work done in the synchronization handler. Executed
 145 * by all the CPUs.
 146 * @info: pointer to mtrr configuration data
 147 *
 148 * Returns nothing.
 149 */
 150static int mtrr_rendezvous_handler(void *info)
 151{
 152        struct set_mtrr_data *data = info;
 153
 154        /*
 155         * We use this same function to initialize the mtrrs during boot,
 156         * resume, runtime cpu online and on an explicit request to set a
 157         * specific MTRR.
 158         *
 159         * During boot or suspend, the state of the boot cpu's mtrrs has been
 160         * saved, and we want to replicate that across all the cpus that come
 161         * online (either at the end of boot or resume or during a runtime cpu
 162         * online). If we're doing that, @reg is set to something special and on
 163         * all the cpu's we do mtrr_if->set_all() (On the logical cpu that
 164         * started the boot/resume sequence, this might be a duplicate
 165         * set_all()).
 166         */
 167        if (data->smp_reg != ~0U) {
 168                mtrr_if->set(data->smp_reg, data->smp_base,
 169                             data->smp_size, data->smp_type);
 170        } else if (mtrr_aps_delayed_init || !cpu_online(smp_processor_id())) {
 171                mtrr_if->set_all();
 172        }
 173        return 0;
 174}
 175
 176static inline int types_compatible(mtrr_type type1, mtrr_type type2)
 177{
 178        return type1 == MTRR_TYPE_UNCACHABLE ||
 179               type2 == MTRR_TYPE_UNCACHABLE ||
 180               (type1 == MTRR_TYPE_WRTHROUGH && type2 == MTRR_TYPE_WRBACK) ||
 181               (type1 == MTRR_TYPE_WRBACK && type2 == MTRR_TYPE_WRTHROUGH);
 182}
 183
 184/**
 185 * set_mtrr - update mtrrs on all processors
 186 * @reg:        mtrr in question
 187 * @base:       mtrr base
 188 * @size:       mtrr size
 189 * @type:       mtrr type
 190 *
 191 * This is kinda tricky, but fortunately, Intel spelled it out for us cleanly:
 192 *
 193 * 1. Queue work to do the following on all processors:
 194 * 2. Disable Interrupts
 195 * 3. Wait for all procs to do so
 196 * 4. Enter no-fill cache mode
 197 * 5. Flush caches
 198 * 6. Clear PGE bit
 199 * 7. Flush all TLBs
 200 * 8. Disable all range registers
 201 * 9. Update the MTRRs
 202 * 10. Enable all range registers
 203 * 11. Flush all TLBs and caches again
 204 * 12. Enter normal cache mode and reenable caching
 205 * 13. Set PGE
 206 * 14. Wait for buddies to catch up
 207 * 15. Enable interrupts.
 208 *
 209 * What does that mean for us? Well, stop_machine() will ensure that
 210 * the rendezvous handler is started on each CPU. And in lockstep they
 211 * do the state transition of disabling interrupts, updating MTRR's
 212 * (the CPU vendors may each do it differently, so we call mtrr_if->set()
 213 * callback and let them take care of it.) and enabling interrupts.
 214 *
 215 * Note that the mechanism is the same for UP systems, too; all the SMP stuff
 216 * becomes nops.
 217 */
 218static void
 219set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type type)
 220{
 221        struct set_mtrr_data data = { .smp_reg = reg,
 222                                      .smp_base = base,
 223                                      .smp_size = size,
 224                                      .smp_type = type
 225                                    };
 226
 227        stop_machine(mtrr_rendezvous_handler, &data, cpu_online_mask);
 228}
 229
 230static void set_mtrr_from_inactive_cpu(unsigned int reg, unsigned long base,
 231                                      unsigned long size, mtrr_type type)
 232{
 233        struct set_mtrr_data data = { .smp_reg = reg,
 234                                      .smp_base = base,
 235                                      .smp_size = size,
 236                                      .smp_type = type
 237                                    };
 238
 239        stop_machine_from_inactive_cpu(mtrr_rendezvous_handler, &data,
 240                                       cpu_callout_mask);
 241}
 242
 243/**
 244 * mtrr_add_page - Add a memory type region
 245 * @base: Physical base address of region in pages (in units of 4 kB!)
 246 * @size: Physical size of region in pages (4 kB)
 247 * @type: Type of MTRR desired
 248 * @increment: If this is true do usage counting on the region
 249 *
 250 * Memory type region registers control the caching on newer Intel and
 251 * non Intel processors. This function allows drivers to request an
 252 * MTRR is added. The details and hardware specifics of each processor's
 253 * implementation are hidden from the caller, but nevertheless the
 254 * caller should expect to need to provide a power of two size on an
 255 * equivalent power of two boundary.
 256 *
 257 * If the region cannot be added either because all regions are in use
 258 * or the CPU cannot support it a negative value is returned. On success
 259 * the register number for this entry is returned, but should be treated
 260 * as a cookie only.
 261 *
 262 * On a multiprocessor machine the changes are made to all processors.
 263 * This is required on x86 by the Intel processors.
 264 *
 265 * The available types are
 266 *
 267 * %MTRR_TYPE_UNCACHABLE - No caching
 268 *
 269 * %MTRR_TYPE_WRBACK - Write data back in bursts whenever
 270 *
 271 * %MTRR_TYPE_WRCOMB - Write data back soon but allow bursts
 272 *
 273 * %MTRR_TYPE_WRTHROUGH - Cache reads but not writes
 274 *
 275 * BUGS: Needs a quiet flag for the cases where drivers do not mind
 276 * failures and do not wish system log messages to be sent.
 277 */
 278int mtrr_add_page(unsigned long base, unsigned long size,
 279                  unsigned int type, bool increment)
 280{
 281        unsigned long lbase, lsize;
 282        int i, replace, error;
 283        mtrr_type ltype;
 284
 285        if (!mtrr_if)
 286                return -ENXIO;
 287
 288        error = mtrr_if->validate_add_page(base, size, type);
 289        if (error)
 290                return error;
 291
 292        if (type >= MTRR_NUM_TYPES) {
 293                pr_warning("mtrr: type: %u invalid\n", type);
 294                return -EINVAL;
 295        }
 296
 297        /* If the type is WC, check that this processor supports it */
 298        if ((type == MTRR_TYPE_WRCOMB) && !have_wrcomb()) {
 299                pr_warning("mtrr: your processor doesn't support write-combining\n");
 300                return -ENOSYS;
 301        }
 302
 303        if (!size) {
 304                pr_warning("mtrr: zero sized request\n");
 305                return -EINVAL;
 306        }
 307
 308        if (base & size_or_mask || size & size_or_mask) {
 309                pr_warning("mtrr: base or size exceeds the MTRR width\n");
 310                return -EINVAL;
 311        }
 312
 313        error = -EINVAL;
 314        replace = -1;
 315
 316        /* No CPU hotplug when we change MTRR entries */
 317        get_online_cpus();
 318
 319        /* Search for existing MTRR  */
 320        mutex_lock(&mtrr_mutex);
 321        for (i = 0; i < num_var_ranges; ++i) {
 322                mtrr_if->get(i, &lbase, &lsize, &ltype);
 323                if (!lsize || base > lbase + lsize - 1 ||
 324                    base + size - 1 < lbase)
 325                        continue;
 326                /*
 327                 * At this point we know there is some kind of
 328                 * overlap/enclosure
 329                 */
 330                if (base < lbase || base + size - 1 > lbase + lsize - 1) {
 331                        if (base <= lbase &&
 332                            base + size - 1 >= lbase + lsize - 1) {
 333                                /*  New region encloses an existing region  */
 334                                if (type == ltype) {
 335                                        replace = replace == -1 ? i : -2;
 336                                        continue;
 337                                } else if (types_compatible(type, ltype))
 338                                        continue;
 339                        }
 340                        pr_warning("mtrr: 0x%lx000,0x%lx000 overlaps existing"
 341                                " 0x%lx000,0x%lx000\n", base, size, lbase,
 342                                lsize);
 343                        goto out;
 344                }
 345                /* New region is enclosed by an existing region */
 346                if (ltype != type) {
 347                        if (types_compatible(type, ltype))
 348                                continue;
 349                        pr_warning("mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n",
 350                                base, size, mtrr_attrib_to_str(ltype),
 351                                mtrr_attrib_to_str(type));
 352                        goto out;
 353                }
 354                if (increment)
 355                        ++mtrr_usage_table[i];
 356                error = i;
 357                goto out;
 358        }
 359        /* Search for an empty MTRR */
 360        i = mtrr_if->get_free_region(base, size, replace);
 361        if (i >= 0) {
 362                set_mtrr(i, base, size, type);
 363                if (likely(replace < 0)) {
 364                        mtrr_usage_table[i] = 1;
 365                } else {
 366                        mtrr_usage_table[i] = mtrr_usage_table[replace];
 367                        if (increment)
 368                                mtrr_usage_table[i]++;
 369                        if (unlikely(replace != i)) {
 370                                set_mtrr(replace, 0, 0, 0);
 371                                mtrr_usage_table[replace] = 0;
 372                        }
 373                }
 374        } else {
 375                pr_info("mtrr: no more MTRRs available\n");
 376        }
 377        error = i;
 378 out:
 379        mutex_unlock(&mtrr_mutex);
 380        put_online_cpus();
 381        return error;
 382}
 383
 384static int mtrr_check(unsigned long base, unsigned long size)
 385{
 386        if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
 387                pr_warning("mtrr: size and base must be multiples of 4 kiB\n");
 388                pr_debug("mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
 389                dump_stack();
 390                return -1;
 391        }
 392        return 0;
 393}
 394
 395/**
 396 * mtrr_add - Add a memory type region
 397 * @base: Physical base address of region
 398 * @size: Physical size of region
 399 * @type: Type of MTRR desired
 400 * @increment: If this is true do usage counting on the region
 401 *
 402 * Memory type region registers control the caching on newer Intel and
 403 * non Intel processors. This function allows drivers to request an
 404 * MTRR is added. The details and hardware specifics of each processor's
 405 * implementation are hidden from the caller, but nevertheless the
 406 * caller should expect to need to provide a power of two size on an
 407 * equivalent power of two boundary.
 408 *
 409 * If the region cannot be added either because all regions are in use
 410 * or the CPU cannot support it a negative value is returned. On success
 411 * the register number for this entry is returned, but should be treated
 412 * as a cookie only.
 413 *
 414 * On a multiprocessor machine the changes are made to all processors.
 415 * This is required on x86 by the Intel processors.
 416 *
 417 * The available types are
 418 *
 419 * %MTRR_TYPE_UNCACHABLE - No caching
 420 *
 421 * %MTRR_TYPE_WRBACK - Write data back in bursts whenever
 422 *
 423 * %MTRR_TYPE_WRCOMB - Write data back soon but allow bursts
 424 *
 425 * %MTRR_TYPE_WRTHROUGH - Cache reads but not writes
 426 *
 427 * BUGS: Needs a quiet flag for the cases where drivers do not mind
 428 * failures and do not wish system log messages to be sent.
 429 */
 430int mtrr_add(unsigned long base, unsigned long size, unsigned int type,
 431             bool increment)
 432{
 433        if (mtrr_check(base, size))
 434                return -EINVAL;
 435        return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type,
 436                             increment);
 437}
 438EXPORT_SYMBOL(mtrr_add);
 439
 440/**
 441 * mtrr_del_page - delete a memory type region
 442 * @reg: Register returned by mtrr_add
 443 * @base: Physical base address
 444 * @size: Size of region
 445 *
 446 * If register is supplied then base and size are ignored. This is
 447 * how drivers should call it.
 448 *
 449 * Releases an MTRR region. If the usage count drops to zero the
 450 * register is freed and the region returns to default state.
 451 * On success the register is returned, on failure a negative error
 452 * code.
 453 */
 454int mtrr_del_page(int reg, unsigned long base, unsigned long size)
 455{
 456        int i, max;
 457        mtrr_type ltype;
 458        unsigned long lbase, lsize;
 459        int error = -EINVAL;
 460
 461        if (!mtrr_if)
 462                return -ENXIO;
 463
 464        max = num_var_ranges;
 465        /* No CPU hotplug when we change MTRR entries */
 466        get_online_cpus();
 467        mutex_lock(&mtrr_mutex);
 468        if (reg < 0) {
 469                /*  Search for existing MTRR  */
 470                for (i = 0; i < max; ++i) {
 471                        mtrr_if->get(i, &lbase, &lsize, &ltype);
 472                        if (lbase == base && lsize == size) {
 473                                reg = i;
 474                                break;
 475                        }
 476                }
 477                if (reg < 0) {
 478                        pr_debug("mtrr: no MTRR for %lx000,%lx000 found\n",
 479                                 base, size);
 480                        goto out;
 481                }
 482        }
 483        if (reg >= max) {
 484                pr_warning("mtrr: register: %d too big\n", reg);
 485                goto out;
 486        }
 487        mtrr_if->get(reg, &lbase, &lsize, &ltype);
 488        if (lsize < 1) {
 489                pr_warning("mtrr: MTRR %d not used\n", reg);
 490                goto out;
 491        }
 492        if (mtrr_usage_table[reg] < 1) {
 493                pr_warning("mtrr: reg: %d has count=0\n", reg);
 494                goto out;
 495        }
 496        if (--mtrr_usage_table[reg] < 1)
 497                set_mtrr(reg, 0, 0, 0);
 498        error = reg;
 499 out:
 500        mutex_unlock(&mtrr_mutex);
 501        put_online_cpus();
 502        return error;
 503}
 504
 505/**
 506 * mtrr_del - delete a memory type region
 507 * @reg: Register returned by mtrr_add
 508 * @base: Physical base address
 509 * @size: Size of region
 510 *
 511 * If register is supplied then base and size are ignored. This is
 512 * how drivers should call it.
 513 *
 514 * Releases an MTRR region. If the usage count drops to zero the
 515 * register is freed and the region returns to default state.
 516 * On success the register is returned, on failure a negative error
 517 * code.
 518 */
 519int mtrr_del(int reg, unsigned long base, unsigned long size)
 520{
 521        if (mtrr_check(base, size))
 522                return -EINVAL;
 523        return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT);
 524}
 525EXPORT_SYMBOL(mtrr_del);
 526
 527/*
 528 * HACK ALERT!
 529 * These should be called implicitly, but we can't yet until all the initcall
 530 * stuff is done...
 531 */
 532static void __init init_ifs(void)
 533{
 534#ifndef CONFIG_X86_64
 535        amd_init_mtrr();
 536        cyrix_init_mtrr();
 537        centaur_init_mtrr();
 538#endif
 539}
 540
 541/* The suspend/resume methods are only for CPU without MTRR. CPU using generic
 542 * MTRR driver doesn't require this
 543 */
 544struct mtrr_value {
 545        mtrr_type       ltype;
 546        unsigned long   lbase;
 547        unsigned long   lsize;
 548};
 549
 550static struct mtrr_value mtrr_value[MTRR_MAX_VAR_RANGES];
 551
 552static int mtrr_save(void)
 553{
 554        int i;
 555
 556        for (i = 0; i < num_var_ranges; i++) {
 557                mtrr_if->get(i, &mtrr_value[i].lbase,
 558                                &mtrr_value[i].lsize,
 559                                &mtrr_value[i].ltype);
 560        }
 561        return 0;
 562}
 563
 564static void mtrr_restore(void)
 565{
 566        int i;
 567
 568        for (i = 0; i < num_var_ranges; i++) {
 569                if (mtrr_value[i].lsize) {
 570                        set_mtrr(i, mtrr_value[i].lbase,
 571                                    mtrr_value[i].lsize,
 572                                    mtrr_value[i].ltype);
 573                }
 574        }
 575}
 576
 577
 578
 579static struct syscore_ops mtrr_syscore_ops = {
 580        .suspend        = mtrr_save,
 581        .resume         = mtrr_restore,
 582};
 583
 584int __initdata changed_by_mtrr_cleanup;
 585
 586/**
 587 * mtrr_bp_init - initialize mtrrs on the boot CPU
 588 *
 589 * This needs to be called early; before any of the other CPUs are
 590 * initialized (i.e. before smp_init()).
 591 *
 592 */
 593void __init mtrr_bp_init(void)
 594{
 595        u32 phys_addr;
 596
 597        init_ifs();
 598
 599        phys_addr = 32;
 600
 601        if (cpu_has_mtrr) {
 602                mtrr_if = &generic_mtrr_ops;
 603                size_or_mask = 0xff000000;                      /* 36 bits */
 604                size_and_mask = 0x00f00000;
 605                phys_addr = 36;
 606
 607                /*
 608                 * This is an AMD specific MSR, but we assume(hope?) that
 609                 * Intel will implement it to when they extend the address
 610                 * bus of the Xeon.
 611                 */
 612                if (cpuid_eax(0x80000000) >= 0x80000008) {
 613                        phys_addr = cpuid_eax(0x80000008) & 0xff;
 614                        /* CPUID workaround for Intel 0F33/0F34 CPU */
 615                        if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
 616                            boot_cpu_data.x86 == 0xF &&
 617                            boot_cpu_data.x86_model == 0x3 &&
 618                            (boot_cpu_data.x86_mask == 0x3 ||
 619                             boot_cpu_data.x86_mask == 0x4))
 620                                phys_addr = 36;
 621
 622                        size_or_mask = ~((1ULL << (phys_addr - PAGE_SHIFT)) - 1);
 623                        size_and_mask = ~size_or_mask & 0xfffff00000ULL;
 624                } else if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR &&
 625                           boot_cpu_data.x86 == 6) {
 626                        /*
 627                         * VIA C* family have Intel style MTRRs,
 628                         * but don't support PAE
 629                         */
 630                        size_or_mask = 0xfff00000;              /* 32 bits */
 631                        size_and_mask = 0;
 632                        phys_addr = 32;
 633                }
 634        } else {
 635                switch (boot_cpu_data.x86_vendor) {
 636                case X86_VENDOR_AMD:
 637                        if (cpu_has_k6_mtrr) {
 638                                /* Pre-Athlon (K6) AMD CPU MTRRs */
 639                                mtrr_if = mtrr_ops[X86_VENDOR_AMD];
 640                                size_or_mask = 0xfff00000;      /* 32 bits */
 641                                size_and_mask = 0;
 642                        }
 643                        break;
 644                case X86_VENDOR_CENTAUR:
 645                        if (cpu_has_centaur_mcr) {
 646                                mtrr_if = mtrr_ops[X86_VENDOR_CENTAUR];
 647                                size_or_mask = 0xfff00000;      /* 32 bits */
 648                                size_and_mask = 0;
 649                        }
 650                        break;
 651                case X86_VENDOR_CYRIX:
 652                        if (cpu_has_cyrix_arr) {
 653                                mtrr_if = mtrr_ops[X86_VENDOR_CYRIX];
 654                                size_or_mask = 0xfff00000;      /* 32 bits */
 655                                size_and_mask = 0;
 656                        }
 657                        break;
 658                default:
 659                        break;
 660                }
 661        }
 662
 663        if (mtrr_if) {
 664                set_num_var_ranges();
 665                init_table();
 666                if (use_intel()) {
 667                        get_mtrr_state();
 668
 669                        if (mtrr_cleanup(phys_addr)) {
 670                                changed_by_mtrr_cleanup = 1;
 671                                mtrr_if->set_all();
 672                        }
 673                }
 674        }
 675}
 676
 677void mtrr_ap_init(void)
 678{
 679        if (!use_intel() || mtrr_aps_delayed_init)
 680                return;
 681        /*
 682         * Ideally we should hold mtrr_mutex here to avoid mtrr entries
 683         * changed, but this routine will be called in cpu boot time,
 684         * holding the lock breaks it.
 685         *
 686         * This routine is called in two cases:
 687         *
 688         *   1. very earily time of software resume, when there absolutely
 689         *      isn't mtrr entry changes;
 690         *
 691         *   2. cpu hotadd time. We let mtrr_add/del_page hold cpuhotplug
 692         *      lock to prevent mtrr entry changes
 693         */
 694        set_mtrr_from_inactive_cpu(~0U, 0, 0, 0);
 695}
 696
 697/**
 698 * Save current fixed-range MTRR state of the BSP
 699 */
 700void mtrr_save_state(void)
 701{
 702        smp_call_function_single(0, mtrr_save_fixed_ranges, NULL, 1);
 703}
 704
 705void set_mtrr_aps_delayed_init(void)
 706{
 707        if (!use_intel())
 708                return;
 709
 710        mtrr_aps_delayed_init = true;
 711}
 712
 713/*
 714 * Delayed MTRR initialization for all AP's
 715 */
 716void mtrr_aps_init(void)
 717{
 718        if (!use_intel())
 719                return;
 720
 721        /*
 722         * Check if someone has requested the delay of AP MTRR initialization,
 723         * by doing set_mtrr_aps_delayed_init(), prior to this point. If not,
 724         * then we are done.
 725         */
 726        if (!mtrr_aps_delayed_init)
 727                return;
 728
 729        set_mtrr(~0U, 0, 0, 0);
 730        mtrr_aps_delayed_init = false;
 731}
 732
 733void mtrr_bp_restore(void)
 734{
 735        if (!use_intel())
 736                return;
 737
 738        mtrr_if->set_all();
 739}
 740
 741static int __init mtrr_init_finialize(void)
 742{
 743        if (!mtrr_if)
 744                return 0;
 745
 746        if (use_intel()) {
 747                if (!changed_by_mtrr_cleanup)
 748                        mtrr_state_warn();
 749                return 0;
 750        }
 751
 752        /*
 753         * The CPU has no MTRR and seems to not support SMP. They have
 754         * specific drivers, we use a tricky method to support
 755         * suspend/resume for them.
 756         *
 757         * TBD: is there any system with such CPU which supports
 758         * suspend/resume? If no, we should remove the code.
 759         */
 760        register_syscore_ops(&mtrr_syscore_ops);
 761
 762        return 0;
 763}
 764subsys_initcall(mtrr_init_finialize);
 765
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.