linux/include/asm-i386/processor.h
<<
>>
Prefs
   1/*
   2 * include/asm-i386/processor.h
   3 *
   4 * Copyright (C) 1994 Linus Torvalds
   5 */
   6
   7#ifndef __ASM_I386_PROCESSOR_H
   8#define __ASM_I386_PROCESSOR_H
   9
  10#include <asm/vm86.h>
  11#include <asm/math_emu.h>
  12#include <asm/segment.h>
  13#include <asm/page.h>
  14#include <asm/types.h>
  15#include <asm/sigcontext.h>
  16#include <asm/cpufeature.h>
  17#include <asm/msr.h>
  18#include <asm/system.h>
  19#include <linux/cache.h>
  20#include <linux/threads.h>
  21#include <asm/percpu.h>
  22#include <linux/cpumask.h>
  23#include <linux/init.h>
  24#include <asm/processor-flags.h>
  25
  26/* flag for disabling the tsc */
  27extern int tsc_disable;
  28
  29struct desc_struct {
  30        unsigned long a,b;
  31};
  32
  33#define desc_empty(desc) \
  34                (!((desc)->a | (desc)->b))
  35
  36#define desc_equal(desc1, desc2) \
  37                (((desc1)->a == (desc2)->a) && ((desc1)->b == (desc2)->b))
  38/*
  39 * Default implementation of macro that returns current
  40 * instruction pointer ("program counter").
  41 */
  42#define current_text_addr() ({ void *pc; __asm__("movl $1f,%0\n1:":"=g" (pc)); pc; })
  43
  44/*
  45 *  CPU type and hardware bug flags. Kept separately for each CPU.
  46 *  Members of this structure are referenced in head.S, so think twice
  47 *  before touching them. [mj]
  48 */
  49
  50struct cpuinfo_x86 {
  51        __u8    x86;            /* CPU family */
  52        __u8    x86_vendor;     /* CPU vendor */
  53        __u8    x86_model;
  54        __u8    x86_mask;
  55        char    wp_works_ok;    /* It doesn't on 386's */
  56        char    hlt_works_ok;   /* Problems on some 486Dx4's and old 386's */
  57        char    hard_math;
  58        char    rfu;
  59        int     cpuid_level;    /* Maximum supported CPUID level, -1=no CPUID */
  60        unsigned long   x86_capability[NCAPINTS];
  61        char    x86_vendor_id[16];
  62        char    x86_model_id[64];
  63        int     x86_cache_size;  /* in KB - valid for CPUS which support this
  64                                    call  */
  65        int     x86_cache_alignment;    /* In bytes */
  66        char    fdiv_bug;
  67        char    f00f_bug;
  68        char    coma_bug;
  69        char    pad0;
  70        int     x86_power;
  71        unsigned long loops_per_jiffy;
  72#ifdef CONFIG_SMP
  73        cpumask_t llc_shared_map;       /* cpus sharing the last level cache */
  74#endif
  75        unsigned char x86_max_cores;    /* cpuid returned max cores value */
  76        unsigned char apicid;
  77        unsigned short x86_clflush_size;
  78#ifdef CONFIG_SMP
  79        unsigned char booted_cores;     /* number of cores as seen by OS */
  80        __u8 phys_proc_id;              /* Physical processor id. */
  81        __u8 cpu_core_id;               /* Core id */
  82#endif
  83} __attribute__((__aligned__(SMP_CACHE_BYTES)));
  84
  85#define X86_VENDOR_INTEL 0
  86#define X86_VENDOR_CYRIX 1
  87#define X86_VENDOR_AMD 2
  88#define X86_VENDOR_UMC 3
  89#define X86_VENDOR_NEXGEN 4
  90#define X86_VENDOR_CENTAUR 5
  91#define X86_VENDOR_RISE 6
  92#define X86_VENDOR_TRANSMETA 7
  93#define X86_VENDOR_NSC 8
  94#define X86_VENDOR_NUM 9
  95#define X86_VENDOR_UNKNOWN 0xff
  96
  97/*
  98 * capabilities of CPUs
  99 */
 100
 101extern struct cpuinfo_x86 boot_cpu_data;
 102extern struct cpuinfo_x86 new_cpu_data;
 103extern struct tss_struct doublefault_tss;
 104DECLARE_PER_CPU(struct tss_struct, init_tss);
 105
 106#ifdef CONFIG_SMP
 107extern struct cpuinfo_x86 cpu_data[];
 108#define current_cpu_data cpu_data[smp_processor_id()]
 109#else
 110#define cpu_data (&boot_cpu_data)
 111#define current_cpu_data boot_cpu_data
 112#endif
 113
 114extern  int cpu_llc_id[NR_CPUS];
 115extern char ignore_fpu_irq;
 116
 117void __init cpu_detect(struct cpuinfo_x86 *c);
 118
 119extern void identify_boot_cpu(void);
 120extern void identify_secondary_cpu(struct cpuinfo_x86 *);
 121extern void print_cpu_info(struct cpuinfo_x86 *);
 122extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
 123extern unsigned short num_cache_leaves;
 124
 125#ifdef CONFIG_X86_HT
 126extern void detect_ht(struct cpuinfo_x86 *c);
 127#else
 128static inline void detect_ht(struct cpuinfo_x86 *c) {}
 129#endif
 130
 131static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
 132                                         unsigned int *ecx, unsigned int *edx)
 133{
 134        /* ecx is often an input as well as an output. */
 135        __asm__("cpuid"
 136                : "=a" (*eax),
 137                  "=b" (*ebx),
 138                  "=c" (*ecx),
 139                  "=d" (*edx)
 140                : "0" (*eax), "2" (*ecx));
 141}
 142
 143#define load_cr3(pgdir) write_cr3(__pa(pgdir))
 144
 145/*
 146 * Save the cr4 feature set we're using (ie
 147 * Pentium 4MB enable and PPro Global page
 148 * enable), so that any CPU's that boot up
 149 * after us can get the correct flags.
 150 */
 151extern unsigned long mmu_cr4_features;
 152
 153static inline void set_in_cr4 (unsigned long mask)
 154{
 155        unsigned cr4;
 156        mmu_cr4_features |= mask;
 157        cr4 = read_cr4();
 158        cr4 |= mask;
 159        write_cr4(cr4);
 160}
 161
 162static inline void clear_in_cr4 (unsigned long mask)
 163{
 164        unsigned cr4;
 165        mmu_cr4_features &= ~mask;
 166        cr4 = read_cr4();
 167        cr4 &= ~mask;
 168        write_cr4(cr4);
 169}
 170
 171/*
 172 *      NSC/Cyrix CPU indexed register access macros
 173 */
 174
 175#define getCx86(reg) ({ outb((reg), 0x22); inb(0x23); })
 176
 177#define setCx86(reg, data) do { \
 178        outb((reg), 0x22); \
 179        outb((data), 0x23); \
 180} while (0)
 181
 182/* Stop speculative execution */
 183static inline void sync_core(void)
 184{
 185        int tmp;
 186        asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
 187}
 188
 189static inline void __monitor(const void *eax, unsigned long ecx,
 190                unsigned long edx)
 191{
 192        /* "monitor %eax,%ecx,%edx;" */
 193        asm volatile(
 194                ".byte 0x0f,0x01,0xc8;"
 195                : :"a" (eax), "c" (ecx), "d"(edx));
 196}
 197
 198static inline void __mwait(unsigned long eax, unsigned long ecx)
 199{
 200        /* "mwait %eax,%ecx;" */
 201        asm volatile(
 202                ".byte 0x0f,0x01,0xc9;"
 203                : :"a" (eax), "c" (ecx));
 204}
 205
 206extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
 207
 208/* from system description table in BIOS.  Mostly for MCA use, but
 209others may find it useful. */
 210extern unsigned int machine_id;
 211extern unsigned int machine_submodel_id;
 212extern unsigned int BIOS_revision;
 213extern unsigned int mca_pentium_flag;
 214
 215/* Boot loader type from the setup header */
 216extern int bootloader_type;
 217
 218/*
 219 * User space process size: 3GB (default).
 220 */
 221#define TASK_SIZE       (PAGE_OFFSET)
 222
 223/* This decides where the kernel will search for a free chunk of vm
 224 * space during mmap's.
 225 */
 226#define TASK_UNMAPPED_BASE      (PAGE_ALIGN(TASK_SIZE / 3))
 227
 228#define HAVE_ARCH_PICK_MMAP_LAYOUT
 229
 230/*
 231 * Size of io_bitmap.
 232 */
 233#define IO_BITMAP_BITS  65536
 234#define IO_BITMAP_BYTES (IO_BITMAP_BITS/8)
 235#define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long))
 236#define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
 237#define INVALID_IO_BITMAP_OFFSET 0x8000
 238#define INVALID_IO_BITMAP_OFFSET_LAZY 0x9000
 239
 240struct i387_fsave_struct {
 241        long    cwd;
 242        long    swd;
 243        long    twd;
 244        long    fip;
 245        long    fcs;
 246        long    foo;
 247        long    fos;
 248        long    st_space[20];   /* 8*10 bytes for each FP-reg = 80 bytes */
 249        long    status;         /* software status information */
 250};
 251
 252struct i387_fxsave_struct {
 253        unsigned short  cwd;
 254        unsigned short  swd;
 255        unsigned short  twd;
 256        unsigned short  fop;
 257        long    fip;
 258        long    fcs;
 259        long    foo;
 260        long    fos;
 261        long    mxcsr;
 262        long    mxcsr_mask;
 263        long    st_space[32];   /* 8*16 bytes for each FP-reg = 128 bytes */
 264        long    xmm_space[32];  /* 8*16 bytes for each XMM-reg = 128 bytes */
 265        long    padding[56];
 266} __attribute__ ((aligned (16)));
 267
 268struct i387_soft_struct {
 269        long    cwd;
 270        long    swd;
 271        long    twd;
 272        long    fip;
 273        long    fcs;
 274        long    foo;
 275        long    fos;
 276        long    st_space[20];   /* 8*10 bytes for each FP-reg = 80 bytes */
 277        unsigned char   ftop, changed, lookahead, no_update, rm, alimit;
 278        struct info     *info;
 279        unsigned long   entry_eip;
 280};
 281
 282union i387_union {
 283        struct i387_fsave_struct        fsave;
 284        struct i387_fxsave_struct       fxsave;
 285        struct i387_soft_struct soft;
 286};
 287
 288typedef struct {
 289        unsigned long seg;
 290} mm_segment_t;
 291
 292struct thread_struct;
 293
 294/* This is the TSS defined by the hardware. */
 295struct i386_hw_tss {
 296        unsigned short  back_link,__blh;
 297        unsigned long   esp0;
 298        unsigned short  ss0,__ss0h;
 299        unsigned long   esp1;
 300        unsigned short  ss1,__ss1h;     /* ss1 is used to cache MSR_IA32_SYSENTER_CS */
 301        unsigned long   esp2;
 302        unsigned short  ss2,__ss2h;
 303        unsigned long   __cr3;
 304        unsigned long   eip;
 305        unsigned long   eflags;
 306        unsigned long   eax,ecx,edx,ebx;
 307        unsigned long   esp;
 308        unsigned long   ebp;
 309        unsigned long   esi;
 310        unsigned long   edi;
 311        unsigned short  es, __esh;
 312        unsigned short  cs, __csh;
 313        unsigned short  ss, __ssh;
 314        unsigned short  ds, __dsh;
 315        unsigned short  fs, __fsh;
 316        unsigned short  gs, __gsh;
 317        unsigned short  ldt, __ldth;
 318        unsigned short  trace, io_bitmap_base;
 319} __attribute__((packed));
 320
 321struct tss_struct {
 322        struct i386_hw_tss x86_tss;
 323
 324        /*
 325         * The extra 1 is there because the CPU will access an
 326         * additional byte beyond the end of the IO permission
 327         * bitmap. The extra byte must be all 1 bits, and must
 328         * be within the limit.
 329         */
 330        unsigned long   io_bitmap[IO_BITMAP_LONGS + 1];
 331        /*
 332         * Cache the current maximum and the last task that used the bitmap:
 333         */
 334        unsigned long io_bitmap_max;
 335        struct thread_struct *io_bitmap_owner;
 336        /*
 337         * pads the TSS to be cacheline-aligned (size is 0x100)
 338         */
 339        unsigned long __cacheline_filler[35];
 340        /*
 341         * .. and then another 0x100 bytes for emergency kernel stack
 342         */
 343        unsigned long stack[64];
 344} __attribute__((packed));
 345
 346#define ARCH_MIN_TASKALIGN      16
 347
 348struct thread_struct {
 349/* cached TLS descriptors. */
 350        struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
 351        unsigned long   esp0;
 352        unsigned long   sysenter_cs;
 353        unsigned long   eip;
 354        unsigned long   esp;
 355        unsigned long   fs;
 356        unsigned long   gs;
 357/* Hardware debugging registers */
 358        unsigned long   debugreg[8];  /* %%db0-7 debug registers */
 359/* fault info */
 360        unsigned long   cr2, trap_no, error_code;
 361/* floating point info */
 362        union i387_union        i387;
 363/* virtual 86 mode info */
 364        struct vm86_struct __user * vm86_info;
 365        unsigned long           screen_bitmap;
 366        unsigned long           v86flags, v86mask, saved_esp0;
 367        unsigned int            saved_fs, saved_gs;
 368/* IO permissions */
 369        unsigned long   *io_bitmap_ptr;
 370        unsigned long   iopl;
 371/* max allowed port in the bitmap, in bytes: */
 372        unsigned long   io_bitmap_max;
 373};
 374
 375#define INIT_THREAD  {                                                  \
 376        .esp0 = sizeof(init_stack) + (long)&init_stack,                 \
 377        .vm86_info = NULL,                                              \
 378        .sysenter_cs = __KERNEL_CS,                                     \
 379        .io_bitmap_ptr = NULL,                                          \
 380        .fs = __KERNEL_PERCPU,                                          \
 381}
 382
 383/*
 384 * Note that the .io_bitmap member must be extra-big. This is because
 385 * the CPU will access an additional byte beyond the end of the IO
 386 * permission bitmap. The extra byte must be all 1 bits, and must
 387 * be within the limit.
 388 */
 389#define INIT_TSS  {                                                     \
 390        .x86_tss = {                                                    \
 391                .esp0           = sizeof(init_stack) + (long)&init_stack, \
 392                .ss0            = __KERNEL_DS,                          \
 393                .ss1            = __KERNEL_CS,                          \
 394                .io_bitmap_base = INVALID_IO_BITMAP_OFFSET,             \
 395         },                                                             \
 396        .io_bitmap      = { [ 0 ... IO_BITMAP_LONGS] = ~0 },            \
 397}
 398
 399#define start_thread(regs, new_eip, new_esp) do {               \
 400        __asm__("movl %0,%%gs": :"r" (0));                      \
 401        regs->xfs = 0;                                          \
 402        set_fs(USER_DS);                                        \
 403        regs->xds = __USER_DS;                                  \
 404        regs->xes = __USER_DS;                                  \
 405        regs->xss = __USER_DS;                                  \
 406        regs->xcs = __USER_CS;                                  \
 407        regs->eip = new_eip;                                    \
 408        regs->esp = new_esp;                                    \
 409} while (0)
 410
 411/* Forward declaration, a strange C thing */
 412struct task_struct;
 413struct mm_struct;
 414
 415/* Free all resources held by a thread. */
 416extern void release_thread(struct task_struct *);
 417
 418/* Prepare to copy thread state - unlazy all lazy status */
 419extern void prepare_to_copy(struct task_struct *tsk);
 420
 421/*
 422 * create a kernel thread without removing it from tasklists
 423 */
 424extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 425
 426extern unsigned long thread_saved_pc(struct task_struct *tsk);
 427void show_trace(struct task_struct *task, struct pt_regs *regs, unsigned long *stack);
 428
 429unsigned long get_wchan(struct task_struct *p);
 430
 431#define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
 432#define KSTK_TOP(info)                                                 \
 433({                                                                     \
 434       unsigned long *__ptr = (unsigned long *)(info);                 \
 435       (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
 436})
 437
 438/*
 439 * The below -8 is to reserve 8 bytes on top of the ring0 stack.
 440 * This is necessary to guarantee that the entire "struct pt_regs"
 441 * is accessable even if the CPU haven't stored the SS/ESP registers
 442 * on the stack (interrupt gate does not save these registers
 443 * when switching to the same priv ring).
 444 * Therefore beware: accessing the xss/esp fields of the
 445 * "struct pt_regs" is possible, but they may contain the
 446 * completely wrong values.
 447 */
 448#define task_pt_regs(task)                                             \
 449({                                                                     \
 450       struct pt_regs *__regs__;                                       \
 451       __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
 452       __regs__ - 1;                                                   \
 453})
 454
 455#define KSTK_EIP(task) (task_pt_regs(task)->eip)
 456#define KSTK_ESP(task) (task_pt_regs(task)->esp)
 457
 458
 459struct microcode_header {
 460        unsigned int hdrver;
 461        unsigned int rev;
 462        unsigned int date;
 463        unsigned int sig;
 464        unsigned int cksum;
 465        unsigned int ldrver;
 466        unsigned int pf;
 467        unsigned int datasize;
 468        unsigned int totalsize;
 469        unsigned int reserved[3];
 470};
 471
 472struct microcode {
 473        struct microcode_header hdr;
 474        unsigned int bits[0];
 475};
 476
 477typedef struct microcode microcode_t;
 478typedef struct microcode_header microcode_header_t;
 479
 480/* microcode format is extended from prescott processors */
 481struct extended_signature {
 482        unsigned int sig;
 483        unsigned int pf;
 484        unsigned int cksum;
 485};
 486
 487struct extended_sigtable {
 488        unsigned int count;
 489        unsigned int cksum;
 490        unsigned int reserved[3];
 491        struct extended_signature sigs[0];
 492};
 493
 494/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
 495static inline void rep_nop(void)
 496{
 497        __asm__ __volatile__("rep;nop": : :"memory");
 498}
 499
 500#define cpu_relax()     rep_nop()
 501
 502static inline void native_load_esp0(struct tss_struct *tss, struct thread_struct *thread)
 503{
 504        tss->x86_tss.esp0 = thread->esp0;
 505        /* This can only happen when SEP is enabled, no need to test "SEP"arately */
 506        if (unlikely(tss->x86_tss.ss1 != thread->sysenter_cs)) {
 507                tss->x86_tss.ss1 = thread->sysenter_cs;
 508                wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0);
 509        }
 510}
 511
 512
 513static inline unsigned long native_get_debugreg(int regno)
 514{
 515        unsigned long val = 0;  /* Damn you, gcc! */
 516
 517        switch (regno) {
 518        case 0:
 519                asm("movl %%db0, %0" :"=r" (val)); break;
 520        case 1:
 521                asm("movl %%db1, %0" :"=r" (val)); break;
 522        case 2:
 523                asm("movl %%db2, %0" :"=r" (val)); break;
 524        case 3:
 525                asm("movl %%db3, %0" :"=r" (val)); break;
 526        case 6:
 527                asm("movl %%db6, %0" :"=r" (val)); break;
 528        case 7:
 529                asm("movl %%db7, %0" :"=r" (val)); break;
 530        default:
 531                BUG();
 532        }
 533        return val;
 534}
 535
 536static inline void native_set_debugreg(int regno, unsigned long value)
 537{
 538        switch (regno) {
 539        case 0:
 540                asm("movl %0,%%db0"     : /* no output */ :"r" (value));
 541                break;
 542        case 1:
 543                asm("movl %0,%%db1"     : /* no output */ :"r" (value));
 544                break;
 545        case 2:
 546                asm("movl %0,%%db2"     : /* no output */ :"r" (value));
 547                break;
 548        case 3:
 549                asm("movl %0,%%db3"     : /* no output */ :"r" (value));
 550                break;
 551        case 6:
 552                asm("movl %0,%%db6"     : /* no output */ :"r" (value));
 553                break;
 554        case 7:
 555                asm("movl %0,%%db7"     : /* no output */ :"r" (value));
 556                break;
 557        default:
 558                BUG();
 559        }
 560}
 561
 562/*
 563 * Set IOPL bits in EFLAGS from given mask
 564 */
 565static inline void native_set_iopl_mask(unsigned mask)
 566{
 567        unsigned int reg;
 568        __asm__ __volatile__ ("pushfl;"
 569                              "popl %0;"
 570                              "andl %1, %0;"
 571                              "orl %2, %0;"
 572                              "pushl %0;"
 573                              "popfl"
 574                                : "=&r" (reg)
 575                                : "i" (~X86_EFLAGS_IOPL), "r" (mask));
 576}
 577
 578#ifdef CONFIG_PARAVIRT
 579#include <asm/paravirt.h>
 580#else
 581#define paravirt_enabled() 0
 582#define __cpuid native_cpuid
 583
 584static inline void load_esp0(struct tss_struct *tss, struct thread_struct *thread)
 585{
 586        native_load_esp0(tss, thread);
 587}
 588
 589/*
 590 * These special macros can be used to get or set a debugging register
 591 */
 592#define get_debugreg(var, register)                             \
 593        (var) = native_get_debugreg(register)
 594#define set_debugreg(value, register)                           \
 595        native_set_debugreg(register, value)
 596
 597#define set_iopl_mask native_set_iopl_mask
 598#endif /* CONFIG_PARAVIRT */
 599
 600/*
 601 * Generic CPUID function
 602 * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
 603 * resulting in stale register contents being returned.
 604 */
 605static inline void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx)
 606{
 607        *eax = op;
 608        *ecx = 0;
 609        __cpuid(eax, ebx, ecx, edx);
 610}
 611
 612/* Some CPUID calls want 'count' to be placed in ecx */
 613static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx,
 614                               int *edx)
 615{
 616        *eax = op;
 617        *ecx = count;
 618        __cpuid(eax, ebx, ecx, edx);
 619}
 620
 621/*
 622 * CPUID functions returning a single datum
 623 */
 624static inline unsigned int cpuid_eax(unsigned int op)
 625{
 626        unsigned int eax, ebx, ecx, edx;
 627
 628        cpuid(op, &eax, &ebx, &ecx, &edx);
 629        return eax;
 630}
 631static inline unsigned int cpuid_ebx(unsigned int op)
 632{
 633        unsigned int eax, ebx, ecx, edx;
 634
 635        cpuid(op, &eax, &ebx, &ecx, &edx);
 636        return ebx;
 637}
 638static inline unsigned int cpuid_ecx(unsigned int op)
 639{
 640        unsigned int eax, ebx, ecx, edx;
 641
 642        cpuid(op, &eax, &ebx, &ecx, &edx);
 643        return ecx;
 644}
 645static inline unsigned int cpuid_edx(unsigned int op)
 646{
 647        unsigned int eax, ebx, ecx, edx;
 648
 649        cpuid(op, &eax, &ebx, &ecx, &edx);
 650        return edx;
 651}
 652
 653/* generic versions from gas */
 654#define GENERIC_NOP1    ".byte 0x90\n"
 655#define GENERIC_NOP2            ".byte 0x89,0xf6\n"
 656#define GENERIC_NOP3        ".byte 0x8d,0x76,0x00\n"
 657#define GENERIC_NOP4        ".byte 0x8d,0x74,0x26,0x00\n"
 658#define GENERIC_NOP5        GENERIC_NOP1 GENERIC_NOP4
 659#define GENERIC_NOP6    ".byte 0x8d,0xb6,0x00,0x00,0x00,0x00\n"
 660#define GENERIC_NOP7    ".byte 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00\n"
 661#define GENERIC_NOP8    GENERIC_NOP1 GENERIC_NOP7
 662
 663/* Opteron nops */
 664#define K8_NOP1 GENERIC_NOP1
 665#define K8_NOP2 ".byte 0x66,0x90\n" 
 666#define K8_NOP3 ".byte 0x66,0x66,0x90\n" 
 667#define K8_NOP4 ".byte 0x66,0x66,0x66,0x90\n" 
 668#define K8_NOP5 K8_NOP3 K8_NOP2 
 669#define K8_NOP6 K8_NOP3 K8_NOP3
 670#define K8_NOP7 K8_NOP4 K8_NOP3
 671#define K8_NOP8 K8_NOP4 K8_NOP4
 672
 673/* K7 nops */
 674/* uses eax dependencies (arbitary choice) */
 675#define K7_NOP1  GENERIC_NOP1
 676#define K7_NOP2 ".byte 0x8b,0xc0\n" 
 677#define K7_NOP3 ".byte 0x8d,0x04,0x20\n"
 678#define K7_NOP4 ".byte 0x8d,0x44,0x20,0x00\n"
 679#define K7_NOP5 K7_NOP4 ASM_NOP1
 680#define K7_NOP6 ".byte 0x8d,0x80,0,0,0,0\n"
 681#define K7_NOP7        ".byte 0x8D,0x04,0x05,0,0,0,0\n"
 682#define K7_NOP8        K7_NOP7 ASM_NOP1
 683
 684#ifdef CONFIG_MK8
 685#define ASM_NOP1 K8_NOP1
 686#define ASM_NOP2 K8_NOP2
 687#define ASM_NOP3 K8_NOP3
 688#define ASM_NOP4 K8_NOP4
 689#define ASM_NOP5 K8_NOP5
 690#define ASM_NOP6 K8_NOP6
 691#define ASM_NOP7 K8_NOP7
 692#define ASM_NOP8 K8_NOP8
 693#elif defined(CONFIG_MK7)
 694#define ASM_NOP1 K7_NOP1
 695#define ASM_NOP2 K7_NOP2
 696#define ASM_NOP3 K7_NOP3
 697#define ASM_NOP4 K7_NOP4
 698#define ASM_NOP5 K7_NOP5
 699#define ASM_NOP6 K7_NOP6
 700#define ASM_NOP7 K7_NOP7
 701#define ASM_NOP8 K7_NOP8
 702#else
 703#define ASM_NOP1 GENERIC_NOP1
 704#define ASM_NOP2 GENERIC_NOP2
 705#define ASM_NOP3 GENERIC_NOP3
 706#define ASM_NOP4 GENERIC_NOP4
 707#define ASM_NOP5 GENERIC_NOP5
 708#define ASM_NOP6 GENERIC_NOP6
 709#define ASM_NOP7 GENERIC_NOP7
 710#define ASM_NOP8 GENERIC_NOP8
 711#endif
 712
 713#define ASM_NOP_MAX 8
 714
 715/* Prefetch instructions for Pentium III and AMD Athlon */
 716/* It's not worth to care about 3dnow! prefetches for the K6
 717   because they are microcoded there and very slow.
 718   However we don't do prefetches for pre XP Athlons currently
 719   That should be fixed. */
 720#define ARCH_HAS_PREFETCH
 721static inline void prefetch(const void *x)
 722{
 723        alternative_input(ASM_NOP4,
 724                          "prefetchnta (%1)",
 725                          X86_FEATURE_XMM,
 726                          "r" (x));
 727}
 728
 729#define ARCH_HAS_PREFETCH
 730#define ARCH_HAS_PREFETCHW
 731#define ARCH_HAS_SPINLOCK_PREFETCH
 732
 733/* 3dnow! prefetch to get an exclusive cache line. Useful for 
 734   spinlocks to avoid one state transition in the cache coherency protocol. */
 735static inline void prefetchw(const void *x)
 736{
 737        alternative_input(ASM_NOP4,
 738                          "prefetchw (%1)",
 739                          X86_FEATURE_3DNOW,
 740                          "r" (x));
 741}
 742#define spin_lock_prefetch(x)   prefetchw(x)
 743
 744extern void select_idle_routine(const struct cpuinfo_x86 *c);
 745
 746#define cache_line_size() (boot_cpu_data.x86_cache_alignment)
 747
 748extern unsigned long boot_option_idle_override;
 749extern void enable_sep_cpu(void);
 750extern int sysenter_setup(void);
 751
 752/* Defined in head.S */
 753extern struct Xgt_desc_struct early_gdt_descr;
 754
 755extern void cpu_set_gdt(int);
 756extern void switch_to_new_gdt(void);
 757extern void cpu_init(void);
 758extern void init_gdt(int cpu);
 759
 760extern int force_mwait;
 761
 762#endif /* __ASM_I386_PROCESSOR_H */
 763
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.