diff options
Diffstat (limited to 'include/asm-i386/processor.h')
-rw-r--r-- | include/asm-i386/processor.h | 94 |
1 files changed, 73 insertions, 21 deletions
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index 80f7e8a1e878..96edfdfe32d1 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h | |||
@@ -147,7 +147,7 @@ static inline void detect_ht(struct cpuinfo_x86 *c) {} | |||
147 | #define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */ | 147 | #define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */ |
148 | #define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */ | 148 | #define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */ |
149 | 149 | ||
150 | static inline fastcall void native_cpuid(unsigned int *eax, unsigned int *ebx, | 150 | static inline void native_cpuid(unsigned int *eax, unsigned int *ebx, |
151 | unsigned int *ecx, unsigned int *edx) | 151 | unsigned int *ecx, unsigned int *edx) |
152 | { | 152 | { |
153 | /* ecx is often an input as well as an output. */ | 153 | /* ecx is often an input as well as an output. */ |
@@ -545,13 +545,7 @@ static inline void rep_nop(void) | |||
545 | 545 | ||
546 | #define cpu_relax() rep_nop() | 546 | #define cpu_relax() rep_nop() |
547 | 547 | ||
548 | #ifdef CONFIG_PARAVIRT | 548 | static inline void native_load_esp0(struct tss_struct *tss, struct thread_struct *thread) |
549 | #include <asm/paravirt.h> | ||
550 | #else | ||
551 | #define paravirt_enabled() 0 | ||
552 | #define __cpuid native_cpuid | ||
553 | |||
554 | static inline void load_esp0(struct tss_struct *tss, struct thread_struct *thread) | ||
555 | { | 549 | { |
556 | tss->esp0 = thread->esp0; | 550 | tss->esp0 = thread->esp0; |
557 | /* This can only happen when SEP is enabled, no need to test "SEP"arately */ | 551 | /* This can only happen when SEP is enabled, no need to test "SEP"arately */ |
@@ -561,24 +555,60 @@ static inline void load_esp0(struct tss_struct *tss, struct thread_struct *threa | |||
561 | } | 555 | } |
562 | } | 556 | } |
563 | 557 | ||
564 | /* | ||
565 | * These special macros can be used to get or set a debugging register | ||
566 | */ | ||
567 | #define get_debugreg(var, register) \ | ||
568 | __asm__("movl %%db" #register ", %0" \ | ||
569 | :"=r" (var)) | ||
570 | #define set_debugreg(value, register) \ | ||
571 | __asm__("movl %0,%%db" #register \ | ||
572 | : /* no output */ \ | ||
573 | :"r" (value)) | ||
574 | 558 | ||
575 | #define set_iopl_mask native_set_iopl_mask | 559 | static inline unsigned long native_get_debugreg(int regno) |
576 | #endif /* CONFIG_PARAVIRT */ | 560 | { |
561 | unsigned long val = 0; /* Damn you, gcc! */ | ||
562 | |||
563 | switch (regno) { | ||
564 | case 0: | ||
565 | asm("movl %%db0, %0" :"=r" (val)); break; | ||
566 | case 1: | ||
567 | asm("movl %%db1, %0" :"=r" (val)); break; | ||
568 | case 2: | ||
569 | asm("movl %%db2, %0" :"=r" (val)); break; | ||
570 | case 3: | ||
571 | asm("movl %%db3, %0" :"=r" (val)); break; | ||
572 | case 6: | ||
573 | asm("movl %%db6, %0" :"=r" (val)); break; | ||
574 | case 7: | ||
575 | asm("movl %%db7, %0" :"=r" (val)); break; | ||
576 | default: | ||
577 | BUG(); | ||
578 | } | ||
579 | return val; | ||
580 | } | ||
581 | |||
582 | static inline void native_set_debugreg(int regno, unsigned long value) | ||
583 | { | ||
584 | switch (regno) { | ||
585 | case 0: | ||
586 | asm("movl %0,%%db0" : /* no output */ :"r" (value)); | ||
587 | break; | ||
588 | case 1: | ||
589 | asm("movl %0,%%db1" : /* no output */ :"r" (value)); | ||
590 | break; | ||
591 | case 2: | ||
592 | asm("movl %0,%%db2" : /* no output */ :"r" (value)); | ||
593 | break; | ||
594 | case 3: | ||
595 | asm("movl %0,%%db3" : /* no output */ :"r" (value)); | ||
596 | break; | ||
597 | case 6: | ||
598 | asm("movl %0,%%db6" : /* no output */ :"r" (value)); | ||
599 | break; | ||
600 | case 7: | ||
601 | asm("movl %0,%%db7" : /* no output */ :"r" (value)); | ||
602 | break; | ||
603 | default: | ||
604 | BUG(); | ||
605 | } | ||
606 | } | ||
577 | 607 | ||
578 | /* | 608 | /* |
579 | * Set IOPL bits in EFLAGS from given mask | 609 | * Set IOPL bits in EFLAGS from given mask |
580 | */ | 610 | */ |
581 | static fastcall inline void native_set_iopl_mask(unsigned mask) | 611 | static inline void native_set_iopl_mask(unsigned mask) |
582 | { | 612 | { |
583 | unsigned int reg; | 613 | unsigned int reg; |
584 | __asm__ __volatile__ ("pushfl;" | 614 | __asm__ __volatile__ ("pushfl;" |
@@ -591,6 +621,28 @@ static fastcall inline void native_set_iopl_mask(unsigned mask) | |||
591 | : "i" (~X86_EFLAGS_IOPL), "r" (mask)); | 621 | : "i" (~X86_EFLAGS_IOPL), "r" (mask)); |
592 | } | 622 | } |
593 | 623 | ||
624 | #ifdef CONFIG_PARAVIRT | ||
625 | #include <asm/paravirt.h> | ||
626 | #else | ||
627 | #define paravirt_enabled() 0 | ||
628 | #define __cpuid native_cpuid | ||
629 | |||
630 | static inline void load_esp0(struct tss_struct *tss, struct thread_struct *thread) | ||
631 | { | ||
632 | native_load_esp0(tss, thread); | ||
633 | } | ||
634 | |||
635 | /* | ||
636 | * These special macros can be used to get or set a debugging register | ||
637 | */ | ||
638 | #define get_debugreg(var, register) \ | ||
639 | (var) = native_get_debugreg(register) | ||
640 | #define set_debugreg(value, register) \ | ||
641 | native_set_debugreg(register, value) | ||
642 | |||
643 | #define set_iopl_mask native_set_iopl_mask | ||
644 | #endif /* CONFIG_PARAVIRT */ | ||
645 | |||
594 | /* | 646 | /* |
595 | * Generic CPUID function | 647 | * Generic CPUID function |
596 | * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx | 648 | * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx |