162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef _ASM_X86_IO_H 362306a36Sopenharmony_ci#define _ASM_X86_IO_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci/* 662306a36Sopenharmony_ci * This file contains the definitions for the x86 IO instructions 762306a36Sopenharmony_ci * inb/inw/inl/outb/outw/outl and the "string versions" of the same 862306a36Sopenharmony_ci * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing" 962306a36Sopenharmony_ci * versions of the single-IO instructions (inb_p/inw_p/..). 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * This file is not meant to be obfuscating: it's just complicated 1262306a36Sopenharmony_ci * to (a) handle it all in a way that makes gcc able to optimize it 1362306a36Sopenharmony_ci * as well as possible and (b) trying to avoid writing the same thing 1462306a36Sopenharmony_ci * over and over again with slight variations and possibly making a 1562306a36Sopenharmony_ci * mistake somewhere. 1662306a36Sopenharmony_ci */ 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/* 1962306a36Sopenharmony_ci * Thanks to James van Artsdalen for a better timing-fix than 2062306a36Sopenharmony_ci * the two short jumps: using outb's to a nonexistent port seems 2162306a36Sopenharmony_ci * to guarantee better timings even on fast machines. 2262306a36Sopenharmony_ci * 2362306a36Sopenharmony_ci * On the other hand, I'd like to be sure of a non-existent port: 2462306a36Sopenharmony_ci * I feel a bit unsafe about using 0x80 (should be safe, though) 2562306a36Sopenharmony_ci * 2662306a36Sopenharmony_ci * Linus 2762306a36Sopenharmony_ci */ 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci /* 3062306a36Sopenharmony_ci * Bit simplified and optimized by Jan Hubicka 3162306a36Sopenharmony_ci * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999. 3262306a36Sopenharmony_ci * 3362306a36Sopenharmony_ci * isa_memset_io, isa_memcpy_fromio, isa_memcpy_toio added, 3462306a36Sopenharmony_ci * isa_read[wl] and isa_write[wl] fixed 3562306a36Sopenharmony_ci * - Arnaldo Carvalho de Melo <acme@conectiva.com.br> 3662306a36Sopenharmony_ci */ 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci#include <linux/string.h> 3962306a36Sopenharmony_ci#include <linux/compiler.h> 4062306a36Sopenharmony_ci#include <linux/cc_platform.h> 4162306a36Sopenharmony_ci#include <asm/page.h> 4262306a36Sopenharmony_ci#include <asm/early_ioremap.h> 4362306a36Sopenharmony_ci#include <asm/pgtable_types.h> 4462306a36Sopenharmony_ci#include <asm/shared/io.h> 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci#define build_mmio_read(name, size, type, reg, barrier) \ 4762306a36Sopenharmony_cistatic inline type name(const volatile void __iomem *addr) \ 4862306a36Sopenharmony_ci{ type ret; asm volatile("mov" size " %1,%0":reg (ret) \ 4962306a36Sopenharmony_ci:"m" (*(volatile type __force *)addr) barrier); return ret; } 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci#define build_mmio_write(name, size, type, reg, barrier) \ 5262306a36Sopenharmony_cistatic inline void name(type val, volatile void __iomem *addr) \ 5362306a36Sopenharmony_ci{ asm volatile("mov" size " %0,%1": :reg (val), \ 5462306a36Sopenharmony_ci"m" (*(volatile type __force *)addr) barrier); } 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_cibuild_mmio_read(readb, "b", unsigned char, "=q", :"memory") 5762306a36Sopenharmony_cibuild_mmio_read(readw, "w", unsigned short, "=r", :"memory") 5862306a36Sopenharmony_cibuild_mmio_read(readl, "l", unsigned int, "=r", :"memory") 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cibuild_mmio_read(__readb, "b", unsigned char, "=q", ) 6162306a36Sopenharmony_cibuild_mmio_read(__readw, "w", unsigned short, "=r", ) 6262306a36Sopenharmony_cibuild_mmio_read(__readl, "l", unsigned int, "=r", ) 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_cibuild_mmio_write(writeb, "b", unsigned char, "q", :"memory") 6562306a36Sopenharmony_cibuild_mmio_write(writew, "w", unsigned short, "r", :"memory") 6662306a36Sopenharmony_cibuild_mmio_write(writel, "l", unsigned int, "r", :"memory") 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_cibuild_mmio_write(__writeb, "b", unsigned char, "q", ) 6962306a36Sopenharmony_cibuild_mmio_write(__writew, "w", unsigned short, "r", ) 7062306a36Sopenharmony_cibuild_mmio_write(__writel, "l", unsigned int, "r", ) 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci#define readb readb 7362306a36Sopenharmony_ci#define readw readw 7462306a36Sopenharmony_ci#define readl readl 7562306a36Sopenharmony_ci#define readb_relaxed(a) __readb(a) 7662306a36Sopenharmony_ci#define readw_relaxed(a) __readw(a) 7762306a36Sopenharmony_ci#define readl_relaxed(a) __readl(a) 7862306a36Sopenharmony_ci#define __raw_readb __readb 7962306a36Sopenharmony_ci#define __raw_readw __readw 8062306a36Sopenharmony_ci#define __raw_readl __readl 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci#define writeb writeb 8362306a36Sopenharmony_ci#define writew writew 8462306a36Sopenharmony_ci#define writel writel 8562306a36Sopenharmony_ci#define writeb_relaxed(v, a) __writeb(v, a) 8662306a36Sopenharmony_ci#define writew_relaxed(v, a) __writew(v, a) 8762306a36Sopenharmony_ci#define writel_relaxed(v, a) __writel(v, a) 8862306a36Sopenharmony_ci#define __raw_writeb __writeb 8962306a36Sopenharmony_ci#define __raw_writew __writew 9062306a36Sopenharmony_ci#define __raw_writel __writel 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci#ifdef CONFIG_X86_64 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_cibuild_mmio_read(readq, "q", u64, "=r", :"memory") 9562306a36Sopenharmony_cibuild_mmio_read(__readq, "q", u64, "=r", ) 9662306a36Sopenharmony_cibuild_mmio_write(writeq, "q", u64, "r", :"memory") 9762306a36Sopenharmony_cibuild_mmio_write(__writeq, "q", u64, "r", ) 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci#define readq_relaxed(a) __readq(a) 10062306a36Sopenharmony_ci#define writeq_relaxed(v, a) __writeq(v, a) 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci#define __raw_readq __readq 10362306a36Sopenharmony_ci#define __raw_writeq __writeq 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci/* Let people know that we have them */ 10662306a36Sopenharmony_ci#define readq readq 10762306a36Sopenharmony_ci#define writeq writeq 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci#endif 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci#define ARCH_HAS_VALID_PHYS_ADDR_RANGE 11262306a36Sopenharmony_ciextern int valid_phys_addr_range(phys_addr_t addr, size_t size); 11362306a36Sopenharmony_ciextern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size); 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci/** 11662306a36Sopenharmony_ci * virt_to_phys - map virtual addresses to physical 11762306a36Sopenharmony_ci * @address: address to remap 11862306a36Sopenharmony_ci * 11962306a36Sopenharmony_ci * The returned physical address is the physical (CPU) mapping for 12062306a36Sopenharmony_ci * the memory address given. It is only valid to use this function on 12162306a36Sopenharmony_ci * addresses directly mapped or allocated via kmalloc. 12262306a36Sopenharmony_ci * 12362306a36Sopenharmony_ci * This function does not give bus mappings for DMA transfers. In 12462306a36Sopenharmony_ci * almost all conceivable cases a device driver should not be using 12562306a36Sopenharmony_ci * this function 12662306a36Sopenharmony_ci */ 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_cistatic inline phys_addr_t virt_to_phys(volatile void *address) 12962306a36Sopenharmony_ci{ 13062306a36Sopenharmony_ci return __pa(address); 13162306a36Sopenharmony_ci} 13262306a36Sopenharmony_ci#define virt_to_phys virt_to_phys 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci/** 13562306a36Sopenharmony_ci * phys_to_virt - map physical address to virtual 13662306a36Sopenharmony_ci * @address: address to remap 13762306a36Sopenharmony_ci * 13862306a36Sopenharmony_ci * The returned virtual address is a current CPU mapping for 13962306a36Sopenharmony_ci * the memory address given. It is only valid to use this function on 14062306a36Sopenharmony_ci * addresses that have a kernel mapping 14162306a36Sopenharmony_ci * 14262306a36Sopenharmony_ci * This function does not handle bus mappings for DMA transfers. In 14362306a36Sopenharmony_ci * almost all conceivable cases a device driver should not be using 14462306a36Sopenharmony_ci * this function 14562306a36Sopenharmony_ci */ 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_cistatic inline void *phys_to_virt(phys_addr_t address) 14862306a36Sopenharmony_ci{ 14962306a36Sopenharmony_ci return __va(address); 15062306a36Sopenharmony_ci} 15162306a36Sopenharmony_ci#define phys_to_virt phys_to_virt 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci/* 15462306a36Sopenharmony_ci * Change "struct page" to physical address. 15562306a36Sopenharmony_ci */ 15662306a36Sopenharmony_ci#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT) 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci/* 15962306a36Sopenharmony_ci * ISA I/O bus memory addresses are 1:1 with the physical address. 16062306a36Sopenharmony_ci * However, we truncate the address to unsigned int to avoid undesirable 16162306a36Sopenharmony_ci * promotions in legacy drivers. 16262306a36Sopenharmony_ci */ 16362306a36Sopenharmony_cistatic inline unsigned int isa_virt_to_bus(volatile void *address) 16462306a36Sopenharmony_ci{ 16562306a36Sopenharmony_ci return (unsigned int)virt_to_phys(address); 16662306a36Sopenharmony_ci} 16762306a36Sopenharmony_ci#define isa_bus_to_virt phys_to_virt 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci/* 17062306a36Sopenharmony_ci * The default ioremap() behavior is non-cached; if you need something 17162306a36Sopenharmony_ci * else, you probably want one of the following. 17262306a36Sopenharmony_ci */ 17362306a36Sopenharmony_ciextern void __iomem *ioremap_uc(resource_size_t offset, unsigned long size); 17462306a36Sopenharmony_ci#define ioremap_uc ioremap_uc 17562306a36Sopenharmony_ciextern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size); 17662306a36Sopenharmony_ci#define ioremap_cache ioremap_cache 17762306a36Sopenharmony_ciextern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size, unsigned long prot_val); 17862306a36Sopenharmony_ci#define ioremap_prot ioremap_prot 17962306a36Sopenharmony_ciextern void __iomem *ioremap_encrypted(resource_size_t phys_addr, unsigned long size); 18062306a36Sopenharmony_ci#define ioremap_encrypted ioremap_encrypted 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci/** 18362306a36Sopenharmony_ci * ioremap - map bus memory into CPU space 18462306a36Sopenharmony_ci * @offset: bus address of the memory 18562306a36Sopenharmony_ci * @size: size of the resource to map 18662306a36Sopenharmony_ci * 18762306a36Sopenharmony_ci * ioremap performs a platform specific sequence of operations to 18862306a36Sopenharmony_ci * make bus memory CPU accessible via the readb/readw/readl/writeb/ 18962306a36Sopenharmony_ci * writew/writel functions and the other mmio helpers. The returned 19062306a36Sopenharmony_ci * address is not guaranteed to be usable directly as a virtual 19162306a36Sopenharmony_ci * address. 19262306a36Sopenharmony_ci * 19362306a36Sopenharmony_ci * If the area you are trying to map is a PCI BAR you should have a 19462306a36Sopenharmony_ci * look at pci_iomap(). 19562306a36Sopenharmony_ci */ 19662306a36Sopenharmony_civoid __iomem *ioremap(resource_size_t offset, unsigned long size); 19762306a36Sopenharmony_ci#define ioremap ioremap 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ciextern void iounmap(volatile void __iomem *addr); 20062306a36Sopenharmony_ci#define iounmap iounmap 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci#ifdef __KERNEL__ 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_civoid memcpy_fromio(void *, const volatile void __iomem *, size_t); 20562306a36Sopenharmony_civoid memcpy_toio(volatile void __iomem *, const void *, size_t); 20662306a36Sopenharmony_civoid memset_io(volatile void __iomem *, int, size_t); 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci#define memcpy_fromio memcpy_fromio 20962306a36Sopenharmony_ci#define memcpy_toio memcpy_toio 21062306a36Sopenharmony_ci#define memset_io memset_io 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci/* 21362306a36Sopenharmony_ci * ISA space is 'always mapped' on a typical x86 system, no need to 21462306a36Sopenharmony_ci * explicitly ioremap() it. The fact that the ISA IO space is mapped 21562306a36Sopenharmony_ci * to PAGE_OFFSET is pure coincidence - it does not mean ISA values 21662306a36Sopenharmony_ci * are physical addresses. The following constant pointer can be 21762306a36Sopenharmony_ci * used as the IO-area pointer (it can be iounmapped as well, so the 21862306a36Sopenharmony_ci * analogy with PCI is quite large): 21962306a36Sopenharmony_ci */ 22062306a36Sopenharmony_ci#define __ISA_IO_base ((char __iomem *)(PAGE_OFFSET)) 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci#endif /* __KERNEL__ */ 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ciextern void native_io_delay(void); 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ciextern int io_delay_type; 22762306a36Sopenharmony_ciextern void io_delay_init(void); 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci#if defined(CONFIG_PARAVIRT) 23062306a36Sopenharmony_ci#include <asm/paravirt.h> 23162306a36Sopenharmony_ci#else 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_cistatic inline void slow_down_io(void) 23462306a36Sopenharmony_ci{ 23562306a36Sopenharmony_ci native_io_delay(); 23662306a36Sopenharmony_ci#ifdef REALLY_SLOW_IO 23762306a36Sopenharmony_ci native_io_delay(); 23862306a36Sopenharmony_ci native_io_delay(); 23962306a36Sopenharmony_ci native_io_delay(); 24062306a36Sopenharmony_ci#endif 24162306a36Sopenharmony_ci} 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci#endif 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci#define BUILDIO(bwl, bw, type) \ 24662306a36Sopenharmony_cistatic inline void out##bwl##_p(type value, u16 port) \ 24762306a36Sopenharmony_ci{ \ 24862306a36Sopenharmony_ci out##bwl(value, port); \ 24962306a36Sopenharmony_ci slow_down_io(); \ 25062306a36Sopenharmony_ci} \ 25162306a36Sopenharmony_ci \ 25262306a36Sopenharmony_cistatic inline type in##bwl##_p(u16 port) \ 25362306a36Sopenharmony_ci{ \ 25462306a36Sopenharmony_ci type value = in##bwl(port); \ 25562306a36Sopenharmony_ci slow_down_io(); \ 25662306a36Sopenharmony_ci return value; \ 25762306a36Sopenharmony_ci} \ 25862306a36Sopenharmony_ci \ 25962306a36Sopenharmony_cistatic inline void outs##bwl(u16 port, const void *addr, unsigned long count) \ 26062306a36Sopenharmony_ci{ \ 26162306a36Sopenharmony_ci if (cc_platform_has(CC_ATTR_GUEST_UNROLL_STRING_IO)) { \ 26262306a36Sopenharmony_ci type *value = (type *)addr; \ 26362306a36Sopenharmony_ci while (count) { \ 26462306a36Sopenharmony_ci out##bwl(*value, port); \ 26562306a36Sopenharmony_ci value++; \ 26662306a36Sopenharmony_ci count--; \ 26762306a36Sopenharmony_ci } \ 26862306a36Sopenharmony_ci } else { \ 26962306a36Sopenharmony_ci asm volatile("rep; outs" #bwl \ 27062306a36Sopenharmony_ci : "+S"(addr), "+c"(count) \ 27162306a36Sopenharmony_ci : "d"(port) : "memory"); \ 27262306a36Sopenharmony_ci } \ 27362306a36Sopenharmony_ci} \ 27462306a36Sopenharmony_ci \ 27562306a36Sopenharmony_cistatic inline void ins##bwl(u16 port, void *addr, unsigned long count) \ 27662306a36Sopenharmony_ci{ \ 27762306a36Sopenharmony_ci if (cc_platform_has(CC_ATTR_GUEST_UNROLL_STRING_IO)) { \ 27862306a36Sopenharmony_ci type *value = (type *)addr; \ 27962306a36Sopenharmony_ci while (count) { \ 28062306a36Sopenharmony_ci *value = in##bwl(port); \ 28162306a36Sopenharmony_ci value++; \ 28262306a36Sopenharmony_ci count--; \ 28362306a36Sopenharmony_ci } \ 28462306a36Sopenharmony_ci } else { \ 28562306a36Sopenharmony_ci asm volatile("rep; ins" #bwl \ 28662306a36Sopenharmony_ci : "+D"(addr), "+c"(count) \ 28762306a36Sopenharmony_ci : "d"(port) : "memory"); \ 28862306a36Sopenharmony_ci } \ 28962306a36Sopenharmony_ci} 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ciBUILDIO(b, b, u8) 29262306a36Sopenharmony_ciBUILDIO(w, w, u16) 29362306a36Sopenharmony_ciBUILDIO(l, , u32) 29462306a36Sopenharmony_ci#undef BUILDIO 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci#define inb_p inb_p 29762306a36Sopenharmony_ci#define inw_p inw_p 29862306a36Sopenharmony_ci#define inl_p inl_p 29962306a36Sopenharmony_ci#define insb insb 30062306a36Sopenharmony_ci#define insw insw 30162306a36Sopenharmony_ci#define insl insl 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci#define outb_p outb_p 30462306a36Sopenharmony_ci#define outw_p outw_p 30562306a36Sopenharmony_ci#define outl_p outl_p 30662306a36Sopenharmony_ci#define outsb outsb 30762306a36Sopenharmony_ci#define outsw outsw 30862306a36Sopenharmony_ci#define outsl outsl 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ciextern void *xlate_dev_mem_ptr(phys_addr_t phys); 31162306a36Sopenharmony_ciextern void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr); 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci#define xlate_dev_mem_ptr xlate_dev_mem_ptr 31462306a36Sopenharmony_ci#define unxlate_dev_mem_ptr unxlate_dev_mem_ptr 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ciextern int ioremap_change_attr(unsigned long vaddr, unsigned long size, 31762306a36Sopenharmony_ci enum page_cache_mode pcm); 31862306a36Sopenharmony_ciextern void __iomem *ioremap_wc(resource_size_t offset, unsigned long size); 31962306a36Sopenharmony_ci#define ioremap_wc ioremap_wc 32062306a36Sopenharmony_ciextern void __iomem *ioremap_wt(resource_size_t offset, unsigned long size); 32162306a36Sopenharmony_ci#define ioremap_wt ioremap_wt 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ciextern bool is_early_ioremap_ptep(pte_t *ptep); 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci#define IO_SPACE_LIMIT 0xffff 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci#include <asm-generic/io.h> 32862306a36Sopenharmony_ci#undef PCI_IOBASE 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci#ifdef CONFIG_MTRR 33162306a36Sopenharmony_ciextern int __must_check arch_phys_wc_index(int handle); 33262306a36Sopenharmony_ci#define arch_phys_wc_index arch_phys_wc_index 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ciextern int __must_check arch_phys_wc_add(unsigned long base, 33562306a36Sopenharmony_ci unsigned long size); 33662306a36Sopenharmony_ciextern void arch_phys_wc_del(int handle); 33762306a36Sopenharmony_ci#define arch_phys_wc_add arch_phys_wc_add 33862306a36Sopenharmony_ci#endif 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci#ifdef CONFIG_X86_PAT 34162306a36Sopenharmony_ciextern int arch_io_reserve_memtype_wc(resource_size_t start, resource_size_t size); 34262306a36Sopenharmony_ciextern void arch_io_free_memtype_wc(resource_size_t start, resource_size_t size); 34362306a36Sopenharmony_ci#define arch_io_reserve_memtype_wc arch_io_reserve_memtype_wc 34462306a36Sopenharmony_ci#endif 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci#ifdef CONFIG_AMD_MEM_ENCRYPT 34762306a36Sopenharmony_ciextern bool arch_memremap_can_ram_remap(resource_size_t offset, 34862306a36Sopenharmony_ci unsigned long size, 34962306a36Sopenharmony_ci unsigned long flags); 35062306a36Sopenharmony_ci#define arch_memremap_can_ram_remap arch_memremap_can_ram_remap 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ciextern bool phys_mem_access_encrypted(unsigned long phys_addr, 35362306a36Sopenharmony_ci unsigned long size); 35462306a36Sopenharmony_ci#else 35562306a36Sopenharmony_cistatic inline bool phys_mem_access_encrypted(unsigned long phys_addr, 35662306a36Sopenharmony_ci unsigned long size) 35762306a36Sopenharmony_ci{ 35862306a36Sopenharmony_ci return true; 35962306a36Sopenharmony_ci} 36062306a36Sopenharmony_ci#endif 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci/** 36362306a36Sopenharmony_ci * iosubmit_cmds512 - copy data to single MMIO location, in 512-bit units 36462306a36Sopenharmony_ci * @dst: destination, in MMIO space (must be 512-bit aligned) 36562306a36Sopenharmony_ci * @src: source 36662306a36Sopenharmony_ci * @count: number of 512 bits quantities to submit 36762306a36Sopenharmony_ci * 36862306a36Sopenharmony_ci * Submit data from kernel space to MMIO space, in units of 512 bits at a 36962306a36Sopenharmony_ci * time. Order of access is not guaranteed, nor is a memory barrier 37062306a36Sopenharmony_ci * performed afterwards. 37162306a36Sopenharmony_ci * 37262306a36Sopenharmony_ci * Warning: Do not use this helper unless your driver has checked that the CPU 37362306a36Sopenharmony_ci * instruction is supported on the platform. 37462306a36Sopenharmony_ci */ 37562306a36Sopenharmony_cistatic inline void iosubmit_cmds512(void __iomem *dst, const void *src, 37662306a36Sopenharmony_ci size_t count) 37762306a36Sopenharmony_ci{ 37862306a36Sopenharmony_ci const u8 *from = src; 37962306a36Sopenharmony_ci const u8 *end = from + count * 64; 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci while (from < end) { 38262306a36Sopenharmony_ci movdir64b(dst, from); 38362306a36Sopenharmony_ci from += 64; 38462306a36Sopenharmony_ci } 38562306a36Sopenharmony_ci} 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci#endif /* _ASM_X86_IO_H */ 388