diff options
| author | Andi Kleen <ak@suse.de> | 2004-02-17 19:44:21 -0800 |
|---|---|---|
| committer | Stephen Hemminger <shemminger@osdl.org> | 2004-02-17 19:44:21 -0800 |
| commit | ca92c573507014604d943990d4979af5c08152f0 (patch) | |
| tree | eb122e012044f598fef2f301406027ea8cc1a762 /include | |
| parent | 857bf13c8c7302306a8e642af58d5d9c9d41f3ee (diff) | |
[PATCH] Intel x86-64 support merge
This has all the x86-64 specific changes for Intel Prescott/Nocona
support.
It requires a few minor changes outside arch/x86_64, which I am sending
separately.
This patch is needed to boot an 64bit kernel on a 64-bit capable
Prescott machine.
The ugliest part is probably the swiotlb code. In fact the code for
that is not even included, but just reused from IA64. swiotlb
implements the PCI DMA API using bounce buffering. I don't like this at
all, but there was no other way to support non DAC capable hardware
(like IDE or USB) on machines with >3GB. Please redirect all flames for
that to the Intel chipset designers.
ChangeLog:
- Add Kconfig options for PSC
- Add support to reuse microcode driver from i386 (Suresh B Siddha)
- Try to optimize for the selected CPU
- Fix early CPUID check for Intel CPUs (Suresh B Siddha)
- Fix GDT to use the configured cache line size for padding
- Support monitor/mwait idle loop
- Support HyperThreading
- Support Intel CPUID flags
- Remove all 3dnow prefetches
- Add alternative() for the prefetchw prefetch inline.
- Include P4 driver in oprofile
- Support Intel NOPs in alternative
Diffstat (limited to 'include')
| -rw-r--r-- | include/asm-x86_64/cpufeature.h | 9 | ||||
| -rw-r--r-- | include/asm-x86_64/msr.h | 122 | ||||
| -rw-r--r-- | include/asm-x86_64/pci.h | 32 | ||||
| -rw-r--r-- | include/asm-x86_64/processor.h | 121 | ||||
| -rw-r--r-- | include/asm-x86_64/proto.h | 5 | ||||
| -rw-r--r-- | include/asm-x86_64/segment.h | 4 | ||||
| -rw-r--r-- | include/asm-x86_64/smp.h | 3 | ||||
| -rw-r--r-- | include/asm-x86_64/system.h | 50 |
8 files changed, 307 insertions, 39 deletions
diff --git a/include/asm-x86_64/cpufeature.h b/include/asm-x86_64/cpufeature.h index 3c519311d377..d82d84032838 100644 --- a/include/asm-x86_64/cpufeature.h +++ b/include/asm-x86_64/cpufeature.h @@ -7,7 +7,7 @@ #ifndef __ASM_X8664_CPUFEATURE_H #define __ASM_X8664_CPUFEATURE_H -#define NCAPINTS 4 /* Currently we have 4 32-bit words worth of info */ +#define NCAPINTS 5 /* Currently we have 4 32-bit words worth of info */ /* Intel-defined CPU features, CPUID level 0x00000001, word 0 */ #define X86_FEATURE_FPU (0*32+ 0) /* Onboard FPU */ @@ -37,6 +37,7 @@ #define X86_FEATURE_XMM (0*32+25) /* Streaming SIMD Extensions */ #define X86_FEATURE_XMM2 (0*32+26) /* Streaming SIMD Extensions-2 */ #define X86_FEATURE_SELFSNOOP (0*32+27) /* CPU self snoop */ +#define X86_FEATURE_HT (0*32+28) /* Hyper-Threading */ #define X86_FEATURE_ACC (0*32+29) /* Automatic clock control */ #define X86_FEATURE_IA64 (0*32+30) /* IA-64 processor */ @@ -61,6 +62,10 @@ #define X86_FEATURE_CENTAUR_MCR (3*32+ 3) /* Centaur MCRs (= MTRRs) */ #define X86_FEATURE_K8_C (3*32+ 4) /* C stepping K8 */ +/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ +#define X86_FEATURE_EST (4*32+ 7) /* Enhanced SpeedStep */ +#define X86_FEATURE_MWAIT (4*32+ 3) /* Monitor/Mwait support */ + #define cpu_has(c, bit) test_bit(bit, (c)->x86_capability) #define boot_cpu_has(bit) test_bit(bit, boot_cpu_data.x86_capability) @@ -76,7 +81,7 @@ #define cpu_has_mmx 1 #define cpu_has_fxsr 1 #define cpu_has_xmm 1 -#define cpu_has_ht 0 /* you need to report the support from i386. sorry */ +#define cpu_has_ht boot_cpu_has(X86_FEATURE_HT) #define cpu_has_mp 1 /* XXX */ #define cpu_has_k6_mtrr 0 #define cpu_has_cyrix_arr 0 diff --git a/include/asm-x86_64/msr.h b/include/asm-x86_64/msr.h index 342b46885ec9..9620309e6539 100644 --- a/include/asm-x86_64/msr.h +++ b/include/asm-x86_64/msr.h @@ -121,6 +121,9 @@ extern inline unsigned int cpuid_edx(unsigned int op) return edx; } +#define MSR_IA32_UCODE_WRITE 0x79 +#define MSR_IA32_UCODE_REV 0x8b + #endif @@ -243,4 +246,123 @@ extern inline unsigned int cpuid_edx(unsigned int op) #define MSR_IA32_APICBASE_ENABLE (1<<11) #define MSR_IA32_APICBASE_BASE (0xfffff<<12) +/* P4/Xeon+ specific */ +#define MSR_IA32_MCG_EAX 0x180 +#define MSR_IA32_MCG_EBX 0x181 +#define MSR_IA32_MCG_ECX 0x182 +#define MSR_IA32_MCG_EDX 0x183 +#define MSR_IA32_MCG_ESI 0x184 +#define MSR_IA32_MCG_EDI 0x185 +#define MSR_IA32_MCG_EBP 0x186 +#define MSR_IA32_MCG_ESP 0x187 +#define MSR_IA32_MCG_EFLAGS 0x188 +#define MSR_IA32_MCG_EIP 0x189 +#define MSR_IA32_MCG_RESERVED 0x18A + +#define MSR_P6_EVNTSEL0 0x186 +#define MSR_P6_EVNTSEL1 0x187 + +#define MSR_IA32_PERF_STATUS 0x198 +#define MSR_IA32_PERF_CTL 0x199 + +#define MSR_IA32_THERM_CONTROL 0x19a +#define MSR_IA32_THERM_INTERRUPT 0x19b +#define MSR_IA32_THERM_STATUS 0x19c +#define MSR_IA32_MISC_ENABLE 0x1a0 + +#define MSR_IA32_DEBUGCTLMSR 0x1d9 +#define MSR_IA32_LASTBRANCHFROMIP 0x1db +#define MSR_IA32_LASTBRANCHTOIP 0x1dc +#define MSR_IA32_LASTINTFROMIP 0x1dd +#define MSR_IA32_LASTINTTOIP 0x1de + +#define MSR_IA32_MC0_CTL 0x400 +#define MSR_IA32_MC0_STATUS 0x401 +#define MSR_IA32_MC0_ADDR 0x402 +#define MSR_IA32_MC0_MISC 0x403 + +/* Pentium IV performance counter MSRs */ +#define MSR_P4_BPU_PERFCTR0 0x300 +#define MSR_P4_BPU_PERFCTR1 0x301 +#define MSR_P4_BPU_PERFCTR2 0x302 +#define MSR_P4_BPU_PERFCTR3 0x303 +#define MSR_P4_MS_PERFCTR0 0x304 +#define MSR_P4_MS_PERFCTR1 0x305 +#define MSR_P4_MS_PERFCTR2 0x306 +#define MSR_P4_MS_PERFCTR3 0x307 +#define MSR_P4_FLAME_PERFCTR0 0x308 +#define MSR_P4_FLAME_PERFCTR1 0x309 +#define MSR_P4_FLAME_PERFCTR2 0x30a +#define MSR_P4_FLAME_PERFCTR3 0x30b +#define MSR_P4_IQ_PERFCTR0 0x30c +#define MSR_P4_IQ_PERFCTR1 0x30d +#define MSR_P4_IQ_PERFCTR2 0x30e +#define MSR_P4_IQ_PERFCTR3 0x30f +#define MSR_P4_IQ_PERFCTR4 0x310 +#define MSR_P4_IQ_PERFCTR5 0x311 +#define MSR_P4_BPU_CCCR0 0x360 +#define MSR_P4_BPU_CCCR1 0x361 +#define MSR_P4_BPU_CCCR2 0x362 +#define MSR_P4_BPU_CCCR3 0x363 +#define MSR_P4_MS_CCCR0 0x364 +#define MSR_P4_MS_CCCR1 0x365 +#define MSR_P4_MS_CCCR2 0x366 +#define MSR_P4_MS_CCCR3 0x367 +#define MSR_P4_FLAME_CCCR0 0x368 +#define MSR_P4_FLAME_CCCR1 0x369 +#define MSR_P4_FLAME_CCCR2 0x36a +#define MSR_P4_FLAME_CCCR3 0x36b +#define MSR_P4_IQ_CCCR0 0x36c +#define MSR_P4_IQ_CCCR1 0x36d +#define MSR_P4_IQ_CCCR2 0x36e +#define MSR_P4_IQ_CCCR3 0x36f +#define MSR_P4_IQ_CCCR4 0x370 +#define MSR_P4_IQ_CCCR5 0x371 +#define MSR_P4_ALF_ESCR0 0x3ca +#define MSR_P4_ALF_ESCR1 0x3cb +#define MSR_P4_BPU_ESCR0 0x3b2 +#define MSR_P4_BPU_ESCR1 0x3b3 +#define MSR_P4_BSU_ESCR0 0x3a0 +#define MSR_P4_BSU_ESCR1 0x3a1 +#define MSR_P4_CRU_ESCR0 0x3b8 +#define MSR_P4_CRU_ESCR1 0x3b9 +#define MSR_P4_CRU_ESCR2 0x3cc +#define MSR_P4_CRU_ESCR3 0x3cd +#define MSR_P4_CRU_ESCR4 0x3e0 +#define MSR_P4_CRU_ESCR5 0x3e1 +#define MSR_P4_DAC_ESCR0 0x3a8 +#define MSR_P4_DAC_ESCR1 0x3a9 +#define MSR_P4_FIRM_ESCR0 0x3a4 +#define MSR_P4_FIRM_ESCR1 0x3a5 +#define MSR_P4_FLAME_ESCR0 0x3a6 +#define MSR_P4_FLAME_ESCR1 0x3a7 +#define MSR_P4_FSB_ESCR0 0x3a2 +#define MSR_P4_FSB_ESCR1 0x3a3 +#define MSR_P4_IQ_ESCR0 0x3ba +#define MSR_P4_IQ_ESCR1 0x3bb +#define MSR_P4_IS_ESCR0 0x3b4 +#define MSR_P4_IS_ESCR1 0x3b5 +#define MSR_P4_ITLB_ESCR0 0x3b6 +#define MSR_P4_ITLB_ESCR1 0x3b7 +#define MSR_P4_IX_ESCR0 0x3c8 +#define MSR_P4_IX_ESCR1 0x3c9 +#define MSR_P4_MOB_ESCR0 0x3aa +#define MSR_P4_MOB_ESCR1 0x3ab +#define MSR_P4_MS_ESCR0 0x3c0 +#define MSR_P4_MS_ESCR1 0x3c1 +#define MSR_P4_PMH_ESCR0 0x3ac +#define MSR_P4_PMH_ESCR1 0x3ad +#define MSR_P4_RAT_ESCR0 0x3bc +#define MSR_P4_RAT_ESCR1 0x3bd +#define MSR_P4_SAAT_ESCR0 0x3ae +#define MSR_P4_SAAT_ESCR1 0x3af +#define MSR_P4_SSU_ESCR0 0x3be +#define MSR_P4_SSU_ESCR1 0x3bf /* guess: not defined in manual */ +#define MSR_P4_TBPU_ESCR0 0x3c2 +#define MSR_P4_TBPU_ESCR1 0x3c3 +#define MSR_P4_TC_ESCR0 0x3c4 +#define MSR_P4_TC_ESCR1 0x3c5 +#define MSR_P4_U2L_ESCR0 0x3b0 +#define MSR_P4_U2L_ESCR1 0x3b1 + #endif diff --git a/include/asm-x86_64/pci.h b/include/asm-x86_64/pci.h index 1ba95e06f32f..e7bd000cf81f 100644 --- a/include/asm-x86_64/pci.h +++ b/include/asm-x86_64/pci.h @@ -72,6 +72,23 @@ extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle); +#ifdef CONFIG_SWIOTLB +extern int swiotlb; +extern dma_addr_t swiotlb_map_single (struct device *hwdev, void *ptr, size_t size, + int dir); +extern void swiotlb_unmap_single (struct device *hwdev, dma_addr_t dev_addr, + size_t size, int dir); +extern void swiotlb_sync_single (struct device *hwdev, dma_addr_t dev_addr, + size_t size, int dir); +extern void swiotlb_sync_sg (struct device *hwdev, struct scatterlist *sg, int nelems, + int dir); +extern int swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, + int nents, int direction); +extern void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, + int nents, int direction); + +#endif + #ifdef CONFIG_GART_IOMMU /* Map a single buffer of the indicated size for DMA in streaming mode. @@ -113,6 +130,13 @@ static inline void pci_dma_sync_single(struct pci_dev *hwdev, size_t size, int direction) { BUG_ON(direction == PCI_DMA_NONE); + +#ifdef CONFIG_SWIOTLB + if (swiotlb) + return swiotlb_sync_single(&hwdev->dev,dma_handle,size,direction); +#endif + + flush_write_buffers(); } static inline void pci_dma_sync_sg(struct pci_dev *hwdev, @@ -120,6 +144,12 @@ static inline void pci_dma_sync_sg(struct pci_dev *hwdev, int nelems, int direction) { BUG_ON(direction == PCI_DMA_NONE); + +#ifdef CONFIG_SWIOTLB + if (swiotlb) + return swiotlb_sync_sg(&hwdev->dev,sg,nelems,direction); +#endif + flush_write_buffers(); } /* The PCI address space does equal the physical memory @@ -272,4 +302,6 @@ static inline void pcibios_add_platform_entries(struct pci_dev *dev) /* generic pci stuff */ #include <asm-generic/pci.h> +#include <linux/dma-mapping.h> + #endif /* __x8664_PCI_H */ diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h index bc0e5e430fec..1b22db24284b 100644 --- a/include/asm-x86_64/processor.h +++ b/include/asm-x86_64/processor.h @@ -303,6 +303,67 @@ extern unsigned long get_wchan(struct task_struct *p); (((struct pt_regs *)(tsk->thread.rsp0 - sizeof(struct pt_regs)))->rip) #define KSTK_ESP(tsk) -1 /* sorry. doesn't work for syscall. */ + +struct microcode_header { + unsigned int hdrver; + unsigned int rev; + unsigned int date; + unsigned int sig; + unsigned int cksum; + unsigned int ldrver; + unsigned int pf; + unsigned int datasize; + unsigned int totalsize; + unsigned int reserved[3]; +}; + +struct microcode { + struct microcode_header hdr; + unsigned int bits[0]; +}; + +typedef struct microcode microcode_t; +typedef struct microcode_header microcode_header_t; + +/* microcode format is extended from prescott processors */ +struct extended_signature { + unsigned int sig; + unsigned int pf; + unsigned int cksum; +}; + +struct extended_sigtable { + unsigned int count; + unsigned int cksum; + unsigned int reserved[3]; + struct extended_signature sigs[0]; +}; + +/* '6' because it used to be for P6 only (but now covers Pentium 4 as well) */ +#define MICROCODE_IOCFREE _IO('6',0) + + +#define ASM_NOP1 K8_NOP1 +#define ASM_NOP2 K8_NOP2 +#define ASM_NOP3 K8_NOP3 +#define ASM_NOP4 K8_NOP4 +#define ASM_NOP5 K8_NOP5 +#define ASM_NOP6 K8_NOP6 +#define ASM_NOP7 K8_NOP7 +#define ASM_NOP8 K8_NOP8 + +/* Opteron nops */ +#define K8_NOP1 ".byte 0x90\n" +#define K8_NOP2 ".byte 0x66,0x90\n" +#define K8_NOP3 ".byte 0x66,0x66,0x90\n" +#define K8_NOP4 ".byte 0x66,0x66,0x66,0x90\n" +#define K8_NOP5 K8_NOP3 K8_NOP2 +#define K8_NOP6 K8_NOP3 K8_NOP3 +#define K8_NOP7 K8_NOP4 K8_NOP3 +#define K8_NOP8 K8_NOP4 K8_NOP4 + +#define ASM_NOP_MAX 8 + /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ extern inline void rep_nop(void) { @@ -318,31 +379,25 @@ extern inline void sync_core(void) #define cpu_has_fpu 1 -/* Some early Opteron versions incorrectly fault on prefetch (errata #91). - If this happens just jump back. */ #define ARCH_HAS_PREFETCH static inline void prefetch(void *x) { - asm volatile("2: prefetcht0 %0\n1:\t" - ".section __ex_table,\"a\"\n\t" - " .align 8\n\t" - " .quad 2b,1b\n\t" - ".previous" :: "m" (*(unsigned long *)x)); + asm volatile("prefetcht0 %0" :: "m" (*(unsigned long *)x)); } -#define ARCH_HAS_PREFETCHW +#define ARCH_HAS_PREFETCHW 1 static inline void prefetchw(void *x) { - asm volatile("2: prefetchw %0\n1:\t" - ".section __ex_table,\"a\"\n\t" - " .align 8\n\t" - " .quad 2b,1b\n\t" - ".previous" :: "m" (*(unsigned long *)x)); + alternative_input(ASM_NOP4, + "prefetchw (%1)", + X86_FEATURE_3DNOW, + "r" (x)); } -#define ARCH_HAS_SPINLOCK_PREFETCH +#define ARCH_HAS_SPINLOCK_PREFETCH 1 #define spin_lock_prefetch(x) prefetchw(x) + #define cpu_relax() rep_nop() /* @@ -372,6 +427,23 @@ static inline void prefetchw(void *x) outb((data), 0x23); \ } while (0) +static inline void __monitor(const void *eax, unsigned long ecx, + unsigned long edx) +{ + /* "monitor %eax,%ecx,%edx;" */ + asm volatile( + ".byte 0x0f,0x01,0xc8;" + : :"a" (eax), "c" (ecx), "d"(edx)); +} + +static inline void __mwait(unsigned long eax, unsigned long ecx) +{ + /* "mwait %eax,%ecx;" */ + asm volatile( + ".byte 0x0f,0x01,0xc9;" + : :"a" (eax), "c" (ecx)); +} + #define stack_current() \ ({ \ struct thread_info *ti; \ @@ -379,25 +451,4 @@ static inline void prefetchw(void *x) ti->task; \ }) -#define ASM_NOP1 K8_NOP1 -#define ASM_NOP2 K8_NOP2 -#define ASM_NOP3 K8_NOP3 -#define ASM_NOP4 K8_NOP4 -#define ASM_NOP5 K8_NOP5 -#define ASM_NOP6 K8_NOP6 -#define ASM_NOP7 K8_NOP7 -#define ASM_NOP8 K8_NOP8 - -/* Opteron nops */ -#define K8_NOP1 ".byte 0x90\n" -#define K8_NOP2 ".byte 0x66,0x90\n" -#define K8_NOP3 ".byte 0x66,0x66,0x90\n" -#define K8_NOP4 ".byte 0x66,0x66,0x66,0x90\n" -#define K8_NOP5 K8_NOP3 K8_NOP2 -#define K8_NOP6 K8_NOP3 K8_NOP3 -#define K8_NOP7 K8_NOP4 K8_NOP3 -#define K8_NOP8 K8_NOP4 K8_NOP4 - -#define ASM_NOP_MAX 8 - #endif /* __ASM_X86_64_PROCESSOR_H */ diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h index bd1cdd4222b0..9f35d4d1a494 100644 --- a/include/asm-x86_64/proto.h +++ b/include/asm-x86_64/proto.h @@ -76,6 +76,10 @@ extern void check_ioapic(void); extern int unhandled_signal(struct task_struct *tsk, int sig); +extern void select_idle_routine(const struct cpuinfo_x86 *c); +extern void swiotlb_init(void); +extern int swiotlb; + extern unsigned long max_mapnr; extern unsigned long end_pfn; extern unsigned long table_start, table_end; @@ -92,6 +96,7 @@ extern int acpi_disabled; extern int fallback_aper_order; extern int fallback_aper_force; +extern int iommu_aperture; extern void smp_local_timer_interrupt(struct pt_regs * regs); diff --git a/include/asm-x86_64/segment.h b/include/asm-x86_64/segment.h index 848141b81158..91c59738f3cc 100644 --- a/include/asm-x86_64/segment.h +++ b/include/asm-x86_64/segment.h @@ -1,6 +1,8 @@ #ifndef _ASM_SEGMENT_H #define _ASM_SEGMENT_H +#include <asm/cache.h> + #define __KERNEL_CS 0x10 #define __KERNEL_DS 0x18 @@ -38,7 +40,7 @@ #define FS_TLS_SEL ((GDT_ENTRY_TLS_MIN+FS_TLS)*8 + 3) #define IDT_ENTRIES 256 -#define GDT_ENTRIES 16 +#define GDT_ENTRIES (L1_CACHE_BYTES / 8) #define GDT_SIZE (GDT_ENTRIES * 8) #define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8) diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h index 41484cb03424..155ab10141b7 100644 --- a/include/asm-x86_64/smp.h +++ b/include/asm-x86_64/smp.h @@ -39,6 +39,7 @@ extern void smp_alloc_memory(void); extern cpumask_t cpu_online_map; extern volatile unsigned long smp_invalidate_needed; extern int pic_mode; +extern int smp_num_siblings; extern void smp_flush_tlb(void); extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); extern void smp_send_reschedule(int cpu); @@ -46,7 +47,7 @@ extern void smp_invalidate_rcv(void); /* Process an NMI */ extern void (*mtrr_hook) (void); extern void zap_low_mappings(void); void smp_stop_cpu(void); - +extern int cpu_sibling_map[]; #define SMP_TRAMPOLINE_BASE 0x6000 diff --git a/include/asm-x86_64/system.h b/include/asm-x86_64/system.h index 8427821efbfd..358de44d6325 100644 --- a/include/asm-x86_64/system.h +++ b/include/asm-x86_64/system.h @@ -88,6 +88,56 @@ struct alt_instr { #endif /* + * Alternative instructions for different CPU types or capabilities. + * + * This allows to use optimized instructions even on generic binary + * kernels. + * + * length of oldinstr must be longer or equal the length of newinstr + * It can be padded with nops as needed. + * + * For non barrier like inlines please define new variants + * without volatile and memory clobber. + */ +#define alternative(oldinstr, newinstr, feature) \ + asm volatile ("661:\n\t" oldinstr "\n662:\n" \ + ".section .altinstructions,\"a\"\n" \ + " .align 8\n" \ + " .quad 661b\n" /* label */ \ + " .quad 663f\n" /* new instruction */ \ + " .byte %c0\n" /* feature bit */ \ + " .byte 662b-661b\n" /* sourcelen */ \ + " .byte 664f-663f\n" /* replacementlen */ \ + ".previous\n" \ + ".section .altinstr_replacement,\"ax\"\n" \ + "663:\n\t" newinstr "\n664:\n" /* replacement */ \ + ".previous" :: "i" (feature) : "memory") + +/* + * Alternative inline assembly with input. + * + * Pecularities: + * No memory clobber here. + * Argument numbers start with 1. + * Best is to use constraints that are fixed size (like (%1) ... "r") + * If you use variable sized constraints like "m" or "g" in the + * replacement maake sure to pad to the worst case length. + */ +#define alternative_input(oldinstr, newinstr, feature, input) \ + asm volatile ("661:\n\t" oldinstr "\n662:\n" \ + ".section .altinstructions,\"a\"\n" \ + " .align 8\n" \ + " .quad 661b\n" /* label */ \ + " .quad 663f\n" /* new instruction */ \ + " .byte %c0\n" /* feature bit */ \ + " .byte 662b-661b\n" /* sourcelen */ \ + " .byte 664f-663f\n" /* replacementlen */ \ + ".previous\n" \ + ".section .altinstr_replacement,\"ax\"\n" \ + "663:\n\t" newinstr "\n664:\n" /* replacement */ \ + ".previous" :: "i" (feature), input) + +/* * Clear and set 'TS' bit respectively */ #define clts() __asm__ __volatile__ ("clts") |
