linux/arch/x86/kernel/cpu/amd.c
<<
>>
Prefs
   1#include <linux/export.h>
   2#include <linux/init.h>
   3#include <linux/bitops.h>
   4#include <linux/elf.h>
   5#include <linux/mm.h>
   6
   7#include <linux/io.h>
   8#include <asm/processor.h>
   9#include <asm/apic.h>
  10#include <asm/cpu.h>
  11#include <asm/pci-direct.h>
  12
  13#ifdef CONFIG_X86_64
  14# include <asm/numa_64.h>
  15# include <asm/mmconfig.h>
  16# include <asm/cacheflush.h>
  17#endif
  18
  19#include "cpu.h"
  20
  21#ifdef CONFIG_X86_32
  22/*
  23 *      B step AMD K6 before B 9730xxxx have hardware bugs that can cause
  24 *      misexecution of code under Linux. Owners of such processors should
  25 *      contact AMD for precise details and a CPU swap.
  26 *
  27 *      See     http://www.multimania.com/poulot/k6bug.html
  28 *              http://www.amd.com/K6/k6docs/revgd.html
  29 *
  30 *      The following test is erm.. interesting. AMD neglected to up
  31 *      the chip setting when fixing the bug but they also tweaked some
  32 *      performance at the same time..
  33 */
  34
  35extern void vide(void);
  36__asm__(".align 4\nvide: ret");
  37
  38static void __cpuinit init_amd_k5(struct cpuinfo_x86 *c)
  39{
  40/*
  41 * General Systems BIOSen alias the cpu frequency registers
  42 * of the Elan at 0x000df000. Unfortuantly, one of the Linux
  43 * drivers subsequently pokes it, and changes the CPU speed.
  44 * Workaround : Remove the unneeded alias.
  45 */
  46#define CBAR            (0xfffc) /* Configuration Base Address  (32-bit) */
  47#define CBAR_ENB        (0x80000000)
  48#define CBAR_KEY        (0X000000CB)
  49        if (c->x86_model == 9 || c->x86_model == 10) {
  50                if (inl(CBAR) & CBAR_ENB)
  51                        outl(0 | CBAR_KEY, CBAR);
  52        }
  53}
  54
  55
  56static void __cpuinit init_amd_k6(struct cpuinfo_x86 *c)
  57{
  58        u32 l, h;
  59        int mbytes = num_physpages >> (20-PAGE_SHIFT);
  60
  61        if (c->x86_model < 6) {
  62                /* Based on AMD doc 20734R - June 2000 */
  63                if (c->x86_model == 0) {
  64                        clear_cpu_cap(c, X86_FEATURE_APIC);
  65                        set_cpu_cap(c, X86_FEATURE_PGE);
  66                }
  67                return;
  68        }
  69
  70        if (c->x86_model == 6 && c->x86_mask == 1) {
  71                const int K6_BUG_LOOP = 1000000;
  72                int n;
  73                void (*f_vide)(void);
  74                unsigned long d, d2;
  75
  76                printk(KERN_INFO "AMD K6 stepping B detected - ");
  77
  78                /*
  79                 * It looks like AMD fixed the 2.6.2 bug and improved indirect
  80                 * calls at the same time.
  81                 */
  82
  83                n = K6_BUG_LOOP;
  84                f_vide = vide;
  85                rdtscl(d);
  86                while (n--)
  87                        f_vide();
  88                rdtscl(d2);
  89                d = d2-d;
  90
  91                if (d > 20*K6_BUG_LOOP)
  92                        printk(KERN_CONT
  93                                "system stability may be impaired when more than 32 MB are used.\n");
  94                else
  95                        printk(KERN_CONT "probably OK (after B9730xxxx).\n");
  96                printk(KERN_INFO "Please see http://membres.lycos.fr/poulot/k6bug.html\n");
  97        }
  98
  99        /* K6 with old style WHCR */
 100        if (c->x86_model < 8 ||
 101           (c->x86_model == 8 && c->x86_mask < 8)) {
 102                /* We can only write allocate on the low 508Mb */
 103                if (mbytes > 508)
 104                        mbytes = 508;
 105
 106                rdmsr(MSR_K6_WHCR, l, h);
 107                if ((l&0x0000FFFF) == 0) {
 108                        unsigned long flags;
 109                        l = (1<<0)|((mbytes/4)<<1);
 110                        local_irq_save(flags);
 111                        wbinvd();
 112                        wrmsr(MSR_K6_WHCR, l, h);
 113                        local_irq_restore(flags);
 114                        printk(KERN_INFO "Enabling old style K6 write allocation for %d Mb\n",
 115                                mbytes);
 116                }
 117                return;
 118        }
 119
 120        if ((c->x86_model == 8 && c->x86_mask > 7) ||
 121             c->x86_model == 9 || c->x86_model == 13) {
 122                /* The more serious chips .. */
 123
 124                if (mbytes > 4092)
 125                        mbytes = 4092;
 126
 127                rdmsr(MSR_K6_WHCR, l, h);
 128                if ((l&0xFFFF0000) == 0) {
 129                        unsigned long flags;
 130                        l = ((mbytes>>2)<<22)|(1<<16);
 131                        local_irq_save(flags);
 132                        wbinvd();
 133                        wrmsr(MSR_K6_WHCR, l, h);
 134                        local_irq_restore(flags);
 135                        printk(KERN_INFO "Enabling new style K6 write allocation for %d Mb\n",
 136                                mbytes);
 137                }
 138
 139                return;
 140        }
 141
 142        if (c->x86_model == 10) {
 143                /* AMD Geode LX is model 10 */
 144                /* placeholder for any needed mods */
 145                return;
 146        }
 147}
 148
 149static void __cpuinit amd_k7_smp_check(struct cpuinfo_x86 *c)
 150{
 151#ifdef CONFIG_SMP
 152        /* calling is from identify_secondary_cpu() ? */
 153        if (!c->cpu_index)
 154                return;
 155
 156        /*
 157         * Certain Athlons might work (for various values of 'work') in SMP
 158         * but they are not certified as MP capable.
 159         */
 160        /* Athlon 660/661 is valid. */
 161        if ((c->x86_model == 6) && ((c->x86_mask == 0) ||
 162            (c->x86_mask == 1)))
 163                goto valid_k7;
 164
 165        /* Duron 670 is valid */
 166        if ((c->x86_model == 7) && (c->x86_mask == 0))
 167                goto valid_k7;
 168
 169        /*
 170         * Athlon 662, Duron 671, and Athlon >model 7 have capability
 171         * bit. It's worth noting that the A5 stepping (662) of some
 172         * Athlon XP's have the MP bit set.
 173         * See http://www.heise.de/newsticker/data/jow-18.10.01-000 for
 174         * more.
 175         */
 176        if (((c->x86_model == 6) && (c->x86_mask >= 2)) ||
 177            ((c->x86_model == 7) && (c->x86_mask >= 1)) ||
 178             (c->x86_model > 7))
 179                if (cpu_has_mp)
 180                        goto valid_k7;
 181
 182        /* If we get here, not a certified SMP capable AMD system. */
 183
 184        /*
 185         * Don't taint if we are running SMP kernel on a single non-MP
 186         * approved Athlon
 187         */
 188        WARN_ONCE(1, "WARNING: This combination of AMD"
 189                " processors is not suitable for SMP.\n");
 190        if (!test_taint(TAINT_UNSAFE_SMP))
 191                add_taint(TAINT_UNSAFE_SMP);
 192
 193valid_k7:
 194        ;
 195#endif
 196}
 197
 198static void __cpuinit init_amd_k7(struct cpuinfo_x86 *c)
 199{
 200        u32 l, h;
 201
 202        /*
 203         * Bit 15 of Athlon specific MSR 15, needs to be 0
 204         * to enable SSE on Palomino/Morgan/Barton CPU's.
 205         * If the BIOS didn't enable it already, enable it here.
 206         */
 207        if (c->x86_model >= 6 && c->x86_model <= 10) {
 208                if (!cpu_has(c, X86_FEATURE_XMM)) {
 209                        printk(KERN_INFO "Enabling disabled K7/SSE Support.\n");
 210                        rdmsr(MSR_K7_HWCR, l, h);
 211                        l &= ~0x00008000;
 212                        wrmsr(MSR_K7_HWCR, l, h);
 213                        set_cpu_cap(c, X86_FEATURE_XMM);
 214                }
 215        }
 216
 217        /*
 218         * It's been determined by AMD that Athlons since model 8 stepping 1
 219         * are more robust with CLK_CTL set to 200xxxxx instead of 600xxxxx
 220         * As per AMD technical note 27212 0.2
 221         */
 222        if ((c->x86_model == 8 && c->x86_mask >= 1) || (c->x86_model > 8)) {
 223                rdmsr(MSR_K7_CLK_CTL, l, h);
 224                if ((l & 0xfff00000) != 0x20000000) {
 225                        printk(KERN_INFO
 226                            "CPU: CLK_CTL MSR was %x. Reprogramming to %x\n",
 227                                        l, ((l & 0x000fffff)|0x20000000));
 228                        wrmsr(MSR_K7_CLK_CTL, (l & 0x000fffff)|0x20000000, h);
 229                }
 230        }
 231
 232        set_cpu_cap(c, X86_FEATURE_K7);
 233
 234        amd_k7_smp_check(c);
 235}
 236#endif
 237
 238#ifdef CONFIG_NUMA
 239/*
 240 * To workaround broken NUMA config.  Read the comment in
 241 * srat_detect_node().
 242 */
 243static int __cpuinit nearby_node(int apicid)
 244{
 245        int i, node;
 246
 247        for (i = apicid - 1; i >= 0; i--) {
 248                node = __apicid_to_node[i];
 249                if (node != NUMA_NO_NODE && node_online(node))
 250                        return node;
 251        }
 252        for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) {
 253                node = __apicid_to_node[i];
 254                if (node != NUMA_NO_NODE && node_online(node))
 255                        return node;
 256        }
 257        return first_node(node_online_map); /* Shouldn't happen */
 258}
 259#endif
 260
 261/*
 262 * Fixup core topology information for
 263 * (1) AMD multi-node processors
 264 *     Assumption: Number of cores in each internal node is the same.
 265 * (2) AMD processors supporting compute units
 266 */
 267#ifdef CONFIG_X86_HT
 268static void __cpuinit amd_get_topology(struct cpuinfo_x86 *c)
 269{
 270        u32 nodes, cores_per_cu = 1;
 271        u8 node_id;
 272        int cpu = smp_processor_id();
 273
 274        /* get information required for multi-node processors */
 275        if (cpu_has(c, X86_FEATURE_TOPOEXT)) {
 276                u32 eax, ebx, ecx, edx;
 277
 278                cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
 279                nodes = ((ecx >> 8) & 7) + 1;
 280                node_id = ecx & 7;
 281
 282                /* get compute unit information */
 283                smp_num_siblings = ((ebx >> 8) & 3) + 1;
 284                c->compute_unit_id = ebx & 0xff;
 285                cores_per_cu += ((ebx >> 8) & 3);
 286        } else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
 287                u64 value;
 288
 289                rdmsrl(MSR_FAM10H_NODE_ID, value);
 290                nodes = ((value >> 3) & 7) + 1;
 291                node_id = value & 7;
 292        } else
 293                return;
 294
 295        /* fixup multi-node processor information */
 296        if (nodes > 1) {
 297                u32 cores_per_node;
 298                u32 cus_per_node;
 299
 300                set_cpu_cap(c, X86_FEATURE_AMD_DCM);
 301                cores_per_node = c->x86_max_cores / nodes;
 302                cus_per_node = cores_per_node / cores_per_cu;
 303
 304                /* store NodeID, use llc_shared_map to store sibling info */
 305                per_cpu(cpu_llc_id, cpu) = node_id;
 306
 307                /* core id has to be in the [0 .. cores_per_node - 1] range */
 308                c->cpu_core_id %= cores_per_node;
 309                c->compute_unit_id %= cus_per_node;
 310        }
 311}
 312#endif
 313
 314/*
 315 * On a AMD dual core setup the lower bits of the APIC id distingush the cores.
 316 * Assumes number of cores is a power of two.
 317 */
 318static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c)
 319{
 320#ifdef CONFIG_X86_HT
 321        unsigned bits;
 322        int cpu = smp_processor_id();
 323
 324        bits = c->x86_coreid_bits;
 325        /* Low order bits define the core id (index of core in socket) */
 326        c->cpu_core_id = c->initial_apicid & ((1 << bits)-1);
 327        /* Convert the initial APIC ID into the socket ID */
 328        c->phys_proc_id = c->initial_apicid >> bits;
 329        /* use socket ID also for last level cache */
 330        per_cpu(cpu_llc_id, cpu) = c->phys_proc_id;
 331        amd_get_topology(c);
 332#endif
 333}
 334
 335int amd_get_nb_id(int cpu)
 336{
 337        int id = 0;
 338#ifdef CONFIG_SMP
 339        id = per_cpu(cpu_llc_id, cpu);
 340#endif
 341        return id;
 342}
 343EXPORT_SYMBOL_GPL(amd_get_nb_id);
 344
 345static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)
 346{
 347#ifdef CONFIG_NUMA
 348        int cpu = smp_processor_id();
 349        int node;
 350        unsigned apicid = c->apicid;
 351
 352        node = numa_cpu_node(cpu);
 353        if (node == NUMA_NO_NODE)
 354                node = per_cpu(cpu_llc_id, cpu);
 355
 356        if (!node_online(node)) {
 357                /*
 358                 * Two possibilities here:
 359                 *
 360                 * - The CPU is missing memory and no node was created.  In
 361                 *   that case try picking one from a nearby CPU.
 362                 *
 363                 * - The APIC IDs differ from the HyperTransport node IDs
 364                 *   which the K8 northbridge parsing fills in.  Assume
 365                 *   they are all increased by a constant offset, but in
 366                 *   the same order as the HT nodeids.  If that doesn't
 367                 *   result in a usable node fall back to the path for the
 368                 *   previous case.
 369                 *
 370                 * This workaround operates directly on the mapping between
 371                 * APIC ID and NUMA node, assuming certain relationship
 372                 * between APIC ID, HT node ID and NUMA topology.  As going
 373                 * through CPU mapping may alter the outcome, directly
 374                 * access __apicid_to_node[].
 375                 */
 376                int ht_nodeid = c->initial_apicid;
 377
 378                if (ht_nodeid >= 0 &&
 379                    __apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
 380                        node = __apicid_to_node[ht_nodeid];
 381                /* Pick a nearby node */
 382                if (!node_online(node))
 383                        node = nearby_node(apicid);
 384        }
 385        numa_set_node(cpu, node);
 386#endif
 387}
 388
 389static void __cpuinit early_init_amd_mc(struct cpuinfo_x86 *c)
 390{
 391#ifdef CONFIG_X86_HT
 392        unsigned bits, ecx;
 393
 394        /* Multi core CPU? */
 395        if (c->extended_cpuid_level < 0x80000008)
 396                return;
 397
 398        ecx = cpuid_ecx(0x80000008);
 399
 400        c->x86_max_cores = (ecx & 0xff) + 1;
 401
 402        /* CPU telling us the core id bits shift? */
 403        bits = (ecx >> 12) & 0xF;
 404
 405        /* Otherwise recompute */
 406        if (bits == 0) {
 407                while ((1 << bits) < c->x86_max_cores)
 408                        bits++;
 409        }
 410
 411        c->x86_coreid_bits = bits;
 412#endif
 413}
 414
 415static void __cpuinit bsp_init_amd(struct cpuinfo_x86 *c)
 416{
 417        if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
 418
 419                if (c->x86 > 0x10 ||
 420                    (c->x86 == 0x10 && c->x86_model >= 0x2)) {
 421                        u64 val;
 422
 423                        rdmsrl(MSR_K7_HWCR, val);
 424                        if (!(val & BIT(24)))
 425                                printk(KERN_WARNING FW_BUG "TSC doesn't count "
 426                                        "with P0 frequency!\n");
 427                }
 428        }
 429
 430        if (c->x86 == 0x15) {
 431                unsigned long upperbit;
 432                u32 cpuid, assoc;
 433
 434                cpuid    = cpuid_edx(0x80000005);
 435                assoc    = cpuid >> 16 & 0xff;
 436                upperbit = ((cpuid >> 24) << 10) / assoc;
 437
 438                va_align.mask     = (upperbit - 1) & PAGE_MASK;
 439                va_align.flags    = ALIGN_VA_32 | ALIGN_VA_64;
 440        }
 441}
 442
 443static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
 444{
 445        early_init_amd_mc(c);
 446
 447        /*
 448         * c->x86_power is 8000_0007 edx. Bit 8 is TSC runs at constant rate
 449         * with P/T states and does not stop in deep C-states
 450         */
 451        if (c->x86_power & (1 << 8)) {
 452                set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
 453                set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
 454        }
 455
 456#ifdef CONFIG_X86_64
 457        set_cpu_cap(c, X86_FEATURE_SYSCALL32);
 458#else
 459        /*  Set MTRR capability flag if appropriate */
 460        if (c->x86 == 5)
 461                if (c->x86_model == 13 || c->x86_model == 9 ||
 462                    (c->x86_model == 8 && c->x86_mask >= 8))
 463                        set_cpu_cap(c, X86_FEATURE_K6_MTRR);
 464#endif
 465#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_PCI)
 466        /* check CPU config space for extended APIC ID */
 467        if (cpu_has_apic && c->x86 >= 0xf) {
 468                unsigned int val;
 469                val = read_pci_config(0, 24, 0, 0x68);
 470                if ((val & ((1 << 17) | (1 << 18))) == ((1 << 17) | (1 << 18)))
 471                        set_cpu_cap(c, X86_FEATURE_EXTD_APICID);
 472        }
 473#endif
 474}
 475
 476static void __cpuinit init_amd(struct cpuinfo_x86 *c)
 477{
 478        u32 dummy;
 479
 480#ifdef CONFIG_SMP
 481        unsigned long long value;
 482
 483        /*
 484         * Disable TLB flush filter by setting HWCR.FFDIS on K8
 485         * bit 6 of msr C001_0015
 486         *
 487         * Errata 63 for SH-B3 steppings
 488         * Errata 122 for all steppings (F+ have it disabled by default)
 489         */
 490        if (c->x86 == 0xf) {
 491                rdmsrl(MSR_K7_HWCR, value);
 492                value |= 1 << 6;
 493                wrmsrl(MSR_K7_HWCR, value);
 494        }
 495#endif
 496
 497        early_init_amd(c);
 498
 499        /*
 500         * Bit 31 in normal CPUID used for nonstandard 3DNow ID;
 501         * 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway
 502         */
 503        clear_cpu_cap(c, 0*32+31);
 504
 505#ifdef CONFIG_X86_64
 506        /* On C+ stepping K8 rep microcode works well for copy/memset */
 507        if (c->x86 == 0xf) {
 508                u32 level;
 509
 510                level = cpuid_eax(1);
 511                if ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)
 512                        set_cpu_cap(c, X86_FEATURE_REP_GOOD);
 513
 514                /*
 515                 * Some BIOSes incorrectly force this feature, but only K8
 516                 * revision D (model = 0x14) and later actually support it.
 517                 * (AMD Erratum #110, docId: 25759).
 518                 */
 519                if (c->x86_model < 0x14 && cpu_has(c, X86_FEATURE_LAHF_LM)) {
 520                        u64 val;
 521
 522                        clear_cpu_cap(c, X86_FEATURE_LAHF_LM);
 523                        if (!rdmsrl_amd_safe(0xc001100d, &val)) {
 524                                val &= ~(1ULL << 32);
 525                                wrmsrl_amd_safe(0xc001100d, val);
 526                        }
 527                }
 528
 529        }
 530        if (c->x86 >= 0x10)
 531                set_cpu_cap(c, X86_FEATURE_REP_GOOD);
 532
 533        /* get apicid instead of initial apic id from cpuid */
 534        c->apicid = hard_smp_processor_id();
 535#else
 536
 537        /*
 538         *      FIXME: We should handle the K5 here. Set up the write
 539         *      range and also turn on MSR 83 bits 4 and 31 (write alloc,
 540         *      no bus pipeline)
 541         */
 542
 543        switch (c->x86) {
 544        case 4:
 545                init_amd_k5(c);
 546                break;
 547        case 5:
 548                init_amd_k6(c);
 549                break;
 550        case 6: /* An Athlon/Duron */
 551                init_amd_k7(c);
 552                break;
 553        }
 554
 555        /* K6s reports MCEs but don't actually have all the MSRs */
 556        if (c->x86 < 6)
 557                clear_cpu_cap(c, X86_FEATURE_MCE);
 558#endif
 559
 560        /* Enable workaround for FXSAVE leak */
 561        if (c->x86 >= 6)
 562                set_cpu_cap(c, X86_FEATURE_FXSAVE_LEAK);
 563
 564        if (!c->x86_model_id[0]) {
 565                switch (c->x86) {
 566                case 0xf:
 567                        /* Should distinguish Models here, but this is only
 568                           a fallback anyways. */
 569                        strcpy(c->x86_model_id, "Hammer");
 570                        break;
 571                }
 572        }
 573
 574        cpu_detect_cache_sizes(c);
 575
 576        /* Multi core CPU? */
 577        if (c->extended_cpuid_level >= 0x80000008) {
 578                amd_detect_cmp(c);
 579                srat_detect_node(c);
 580        }
 581
 582#ifdef CONFIG_X86_32
 583        detect_ht(c);
 584#endif
 585
 586        if (c->extended_cpuid_level >= 0x80000006) {
 587                if (cpuid_edx(0x80000006) & 0xf000)
 588                        num_cache_leaves = 4;
 589                else
 590                        num_cache_leaves = 3;
 591        }
 592
 593        if (c->x86 >= 0xf)
 594                set_cpu_cap(c, X86_FEATURE_K8);
 595
 596        if (cpu_has_xmm2) {
 597                /* MFENCE stops RDTSC speculation */
 598                set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC);
 599        }
 600
 601#ifdef CONFIG_X86_64
 602        if (c->x86 == 0x10) {
 603                /* do this for boot cpu */
 604                if (c == &boot_cpu_data)
 605                        check_enable_amd_mmconf_dmi();
 606
 607                fam10h_check_enable_mmcfg();
 608        }
 609
 610        if (c == &boot_cpu_data && c->x86 >= 0xf) {
 611                unsigned long long tseg;
 612
 613                /*
 614                 * Split up direct mapping around the TSEG SMM area.
 615                 * Don't do it for gbpages because there seems very little
 616                 * benefit in doing so.
 617                 */
 618                if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg)) {
 619                        printk(KERN_DEBUG "tseg: %010llx\n", tseg);
 620                        if ((tseg>>PMD_SHIFT) <
 621                                (max_low_pfn_mapped>>(PMD_SHIFT-PAGE_SHIFT)) ||
 622                                ((tseg>>PMD_SHIFT) <
 623                                (max_pfn_mapped>>(PMD_SHIFT-PAGE_SHIFT)) &&
 624                                (tseg>>PMD_SHIFT) >= (1ULL<<(32 - PMD_SHIFT))))
 625                                set_memory_4k((unsigned long)__va(tseg), 1);
 626                }
 627        }
 628#endif
 629
 630        /*
 631         * Family 0x12 and above processors have APIC timer
 632         * running in deep C states.
 633         */
 634        if (c->x86 > 0x11)
 635                set_cpu_cap(c, X86_FEATURE_ARAT);
 636
 637        /*
 638         * Disable GART TLB Walk Errors on Fam10h. We do this here
 639         * because this is always needed when GART is enabled, even in a
 640         * kernel which has no MCE support built in.
 641         */
 642        if (c->x86 == 0x10) {
 643                /*
 644                 * BIOS should disable GartTlbWlk Errors themself. If
 645                 * it doesn't do it here as suggested by the BKDG.
 646                 *
 647                 * Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=33012
 648                 */
 649                u64 mask;
 650                int err;
 651
 652                err = rdmsrl_safe(MSR_AMD64_MCx_MASK(4), &mask);
 653                if (err == 0) {
 654                        mask |= (1 << 10);
 655                        checking_wrmsrl(MSR_AMD64_MCx_MASK(4), mask);
 656                }
 657        }
 658
 659        rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy);
 660}
 661
 662#ifdef CONFIG_X86_32
 663static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 *c,
 664                                                        unsigned int size)
 665{
 666        /* AMD errata T13 (order #21922) */
 667        if ((c->x86 == 6)) {
 668                /* Duron Rev A0 */
 669                if (c->x86_model == 3 && c->x86_mask == 0)
 670                        size = 64;
 671                /* Tbird rev A1/A2 */
 672                if (c->x86_model == 4 &&
 673                        (c->x86_mask == 0 || c->x86_mask == 1))
 674                        size = 256;
 675        }
 676        return size;
 677}
 678#endif
 679
 680static const struct cpu_dev __cpuinitconst amd_cpu_dev = {
 681        .c_vendor       = "AMD",
 682        .c_ident        = { "AuthenticAMD" },
 683#ifdef CONFIG_X86_32
 684        .c_models = {
 685                { .vendor = X86_VENDOR_AMD, .family = 4, .model_names =
 686                  {
 687                          [3] = "486 DX/2",
 688                          [7] = "486 DX/2-WB",
 689                          [8] = "486 DX/4",
 690                          [9] = "486 DX/4-WB",
 691                          [14] = "Am5x86-WT",
 692                          [15] = "Am5x86-WB"
 693                  }
 694                },
 695        },
 696        .c_size_cache   = amd_size_cache,
 697#endif
 698        .c_early_init   = early_init_amd,
 699        .c_bsp_init     = bsp_init_amd,
 700        .c_init         = init_amd,
 701        .c_x86_vendor   = X86_VENDOR_AMD,
 702};
 703
 704cpu_dev_register(amd_cpu_dev);
 705
 706/*
 707 * AMD errata checking
 708 *
 709 * Errata are defined as arrays of ints using the AMD_LEGACY_ERRATUM() or
 710 * AMD_OSVW_ERRATUM() macros. The latter is intended for newer errata that
 711 * have an OSVW id assigned, which it takes as first argument. Both take a
 712 * variable number of family-specific model-stepping ranges created by
 713 * AMD_MODEL_RANGE(). Each erratum also has to be declared as extern const
 714 * int[] in arch/x86/include/asm/processor.h.
 715 *
 716 * Example:
 717 *
 718 * const int amd_erratum_319[] =
 719 *      AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0x4, 0x2),
 720 *                         AMD_MODEL_RANGE(0x10, 0x8, 0x0, 0x8, 0x0),
 721 *                         AMD_MODEL_RANGE(0x10, 0x9, 0x0, 0x9, 0x0));
 722 */
 723
 724const int amd_erratum_400[] =
 725        AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf),
 726                            AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf));
 727EXPORT_SYMBOL_GPL(amd_erratum_400);
 728
 729const int amd_erratum_383[] =
 730        AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0, 0, 0xff, 0xf));
 731EXPORT_SYMBOL_GPL(amd_erratum_383);
 732
 733bool cpu_has_amd_erratum(const int *erratum)
 734{
 735        struct cpuinfo_x86 *cpu = __this_cpu_ptr(&cpu_info);
 736        int osvw_id = *erratum++;
 737        u32 range;
 738        u32 ms;
 739
 740        /*
 741         * If called early enough that current_cpu_data hasn't been initialized
 742         * yet, fall back to boot_cpu_data.
 743         */
 744        if (cpu->x86 == 0)
 745                cpu = &boot_cpu_data;
 746
 747        if (cpu->x86_vendor != X86_VENDOR_AMD)
 748                return false;
 749
 750        if (osvw_id >= 0 && osvw_id < 65536 &&
 751            cpu_has(cpu, X86_FEATURE_OSVW)) {
 752                u64 osvw_len;
 753
 754                rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, osvw_len);
 755                if (osvw_id < osvw_len) {
 756                        u64 osvw_bits;
 757
 758                        rdmsrl(MSR_AMD64_OSVW_STATUS + (osvw_id >> 6),
 759                            osvw_bits);
 760                        return osvw_bits & (1ULL << (osvw_id & 0x3f));
 761                }
 762        }
 763
 764        /* OSVW unavailable or ID unknown, match family-model-stepping range */
 765        ms = (cpu->x86_model << 4) | cpu->x86_mask;
 766        while ((range = *erratum++))
 767                if ((cpu->x86 == AMD_MODEL_RANGE_FAMILY(range)) &&
 768                    (ms >= AMD_MODEL_RANGE_START(range)) &&
 769                    (ms <= AMD_MODEL_RANGE_END(range)))
 770                        return true;
 771
 772        return false;
 773}
 774
 775EXPORT_SYMBOL_GPL(cpu_has_amd_erratum);
 776
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.