0001
0002 #ifndef _ASM_X86_IO_H
0003 #define _ASM_X86_IO_H
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 #define ARCH_HAS_IOREMAP_WC
0039 #define ARCH_HAS_IOREMAP_WT
0040
0041 #include <linux/string.h>
0042 #include <linux/compiler.h>
0043 #include <linux/cc_platform.h>
0044 #include <asm/page.h>
0045 #include <asm/early_ioremap.h>
0046 #include <asm/pgtable_types.h>
0047 #include <asm/shared/io.h>
0048
0049 #define build_mmio_read(name, size, type, reg, barrier) \
0050 static inline type name(const volatile void __iomem *addr) \
0051 { type ret; asm volatile("mov" size " %1,%0":reg (ret) \
0052 :"m" (*(volatile type __force *)addr) barrier); return ret; }
0053
0054 #define build_mmio_write(name, size, type, reg, barrier) \
0055 static inline void name(type val, volatile void __iomem *addr) \
0056 { asm volatile("mov" size " %0,%1": :reg (val), \
0057 "m" (*(volatile type __force *)addr) barrier); }
0058
0059 build_mmio_read(readb, "b", unsigned char, "=q", :"memory")
0060 build_mmio_read(readw, "w", unsigned short, "=r", :"memory")
0061 build_mmio_read(readl, "l", unsigned int, "=r", :"memory")
0062
0063 build_mmio_read(__readb, "b", unsigned char, "=q", )
0064 build_mmio_read(__readw, "w", unsigned short, "=r", )
0065 build_mmio_read(__readl, "l", unsigned int, "=r", )
0066
0067 build_mmio_write(writeb, "b", unsigned char, "q", :"memory")
0068 build_mmio_write(writew, "w", unsigned short, "r", :"memory")
0069 build_mmio_write(writel, "l", unsigned int, "r", :"memory")
0070
0071 build_mmio_write(__writeb, "b", unsigned char, "q", )
0072 build_mmio_write(__writew, "w", unsigned short, "r", )
0073 build_mmio_write(__writel, "l", unsigned int, "r", )
0074
0075 #define readb readb
0076 #define readw readw
0077 #define readl readl
0078 #define readb_relaxed(a) __readb(a)
0079 #define readw_relaxed(a) __readw(a)
0080 #define readl_relaxed(a) __readl(a)
0081 #define __raw_readb __readb
0082 #define __raw_readw __readw
0083 #define __raw_readl __readl
0084
0085 #define writeb writeb
0086 #define writew writew
0087 #define writel writel
0088 #define writeb_relaxed(v, a) __writeb(v, a)
0089 #define writew_relaxed(v, a) __writew(v, a)
0090 #define writel_relaxed(v, a) __writel(v, a)
0091 #define __raw_writeb __writeb
0092 #define __raw_writew __writew
0093 #define __raw_writel __writel
0094
0095 #ifdef CONFIG_X86_64
0096
0097 build_mmio_read(readq, "q", u64, "=r", :"memory")
0098 build_mmio_read(__readq, "q", u64, "=r", )
0099 build_mmio_write(writeq, "q", u64, "r", :"memory")
0100 build_mmio_write(__writeq, "q", u64, "r", )
0101
0102 #define readq_relaxed(a) __readq(a)
0103 #define writeq_relaxed(v, a) __writeq(v, a)
0104
0105 #define __raw_readq __readq
0106 #define __raw_writeq __writeq
0107
0108
0109 #define readq readq
0110 #define writeq writeq
0111
0112 #endif
0113
0114 #define ARCH_HAS_VALID_PHYS_ADDR_RANGE
0115 extern int valid_phys_addr_range(phys_addr_t addr, size_t size);
0116 extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131 static inline phys_addr_t virt_to_phys(volatile void *address)
0132 {
0133 return __pa(address);
0134 }
0135 #define virt_to_phys virt_to_phys
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150 static inline void *phys_to_virt(phys_addr_t address)
0151 {
0152 return __va(address);
0153 }
0154 #define phys_to_virt phys_to_virt
0155
0156
0157
0158
0159 #define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
0160
0161
0162
0163
0164
0165
0166 static inline unsigned int isa_virt_to_bus(volatile void *address)
0167 {
0168 return (unsigned int)virt_to_phys(address);
0169 }
0170 #define isa_bus_to_virt phys_to_virt
0171
0172
0173
0174
0175
0176 extern void __iomem *ioremap_uc(resource_size_t offset, unsigned long size);
0177 #define ioremap_uc ioremap_uc
0178 extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
0179 #define ioremap_cache ioremap_cache
0180 extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size, unsigned long prot_val);
0181 #define ioremap_prot ioremap_prot
0182 extern void __iomem *ioremap_encrypted(resource_size_t phys_addr, unsigned long size);
0183 #define ioremap_encrypted ioremap_encrypted
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199 void __iomem *ioremap(resource_size_t offset, unsigned long size);
0200 #define ioremap ioremap
0201
0202 extern void iounmap(volatile void __iomem *addr);
0203 #define iounmap iounmap
0204
0205 #ifdef __KERNEL__
0206
0207 void memcpy_fromio(void *, const volatile void __iomem *, size_t);
0208 void memcpy_toio(volatile void __iomem *, const void *, size_t);
0209 void memset_io(volatile void __iomem *, int, size_t);
0210
0211 #define memcpy_fromio memcpy_fromio
0212 #define memcpy_toio memcpy_toio
0213 #define memset_io memset_io
0214
0215 #include <asm-generic/iomap.h>
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225 #define __ISA_IO_base ((char __iomem *)(PAGE_OFFSET))
0226
0227 #endif
0228
0229 extern void native_io_delay(void);
0230
0231 extern int io_delay_type;
0232 extern void io_delay_init(void);
0233
0234 #if defined(CONFIG_PARAVIRT)
0235 #include <asm/paravirt.h>
0236 #else
0237
0238 static inline void slow_down_io(void)
0239 {
0240 native_io_delay();
0241 #ifdef REALLY_SLOW_IO
0242 native_io_delay();
0243 native_io_delay();
0244 native_io_delay();
0245 #endif
0246 }
0247
0248 #endif
0249
0250 #define BUILDIO(bwl, bw, type) \
0251 static inline void out##bwl##_p(type value, u16 port) \
0252 { \
0253 out##bwl(value, port); \
0254 slow_down_io(); \
0255 } \
0256 \
0257 static inline type in##bwl##_p(u16 port) \
0258 { \
0259 type value = in##bwl(port); \
0260 slow_down_io(); \
0261 return value; \
0262 } \
0263 \
0264 static inline void outs##bwl(u16 port, const void *addr, unsigned long count) \
0265 { \
0266 if (cc_platform_has(CC_ATTR_GUEST_UNROLL_STRING_IO)) { \
0267 type *value = (type *)addr; \
0268 while (count) { \
0269 out##bwl(*value, port); \
0270 value++; \
0271 count--; \
0272 } \
0273 } else { \
0274 asm volatile("rep; outs" #bwl \
0275 : "+S"(addr), "+c"(count) \
0276 : "d"(port) : "memory"); \
0277 } \
0278 } \
0279 \
0280 static inline void ins##bwl(u16 port, void *addr, unsigned long count) \
0281 { \
0282 if (cc_platform_has(CC_ATTR_GUEST_UNROLL_STRING_IO)) { \
0283 type *value = (type *)addr; \
0284 while (count) { \
0285 *value = in##bwl(port); \
0286 value++; \
0287 count--; \
0288 } \
0289 } else { \
0290 asm volatile("rep; ins" #bwl \
0291 : "+D"(addr), "+c"(count) \
0292 : "d"(port) : "memory"); \
0293 } \
0294 }
0295
0296 BUILDIO(b, b, u8)
0297 BUILDIO(w, w, u16)
0298 BUILDIO(l, , u32)
0299 #undef BUILDIO
0300
0301 #define inb_p inb_p
0302 #define inw_p inw_p
0303 #define inl_p inl_p
0304 #define insb insb
0305 #define insw insw
0306 #define insl insl
0307
0308 #define outb_p outb_p
0309 #define outw_p outw_p
0310 #define outl_p outl_p
0311 #define outsb outsb
0312 #define outsw outsw
0313 #define outsl outsl
0314
0315 extern void *xlate_dev_mem_ptr(phys_addr_t phys);
0316 extern void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr);
0317
0318 #define xlate_dev_mem_ptr xlate_dev_mem_ptr
0319 #define unxlate_dev_mem_ptr unxlate_dev_mem_ptr
0320
0321 extern int ioremap_change_attr(unsigned long vaddr, unsigned long size,
0322 enum page_cache_mode pcm);
0323 extern void __iomem *ioremap_wc(resource_size_t offset, unsigned long size);
0324 #define ioremap_wc ioremap_wc
0325 extern void __iomem *ioremap_wt(resource_size_t offset, unsigned long size);
0326 #define ioremap_wt ioremap_wt
0327
0328 extern bool is_early_ioremap_ptep(pte_t *ptep);
0329
0330 #define IO_SPACE_LIMIT 0xffff
0331
0332 #include <asm-generic/io.h>
0333 #undef PCI_IOBASE
0334
0335 #ifdef CONFIG_MTRR
0336 extern int __must_check arch_phys_wc_index(int handle);
0337 #define arch_phys_wc_index arch_phys_wc_index
0338
0339 extern int __must_check arch_phys_wc_add(unsigned long base,
0340 unsigned long size);
0341 extern void arch_phys_wc_del(int handle);
0342 #define arch_phys_wc_add arch_phys_wc_add
0343 #endif
0344
0345 #ifdef CONFIG_X86_PAT
0346 extern int arch_io_reserve_memtype_wc(resource_size_t start, resource_size_t size);
0347 extern void arch_io_free_memtype_wc(resource_size_t start, resource_size_t size);
0348 #define arch_io_reserve_memtype_wc arch_io_reserve_memtype_wc
0349 #endif
0350
0351 #ifdef CONFIG_AMD_MEM_ENCRYPT
0352 extern bool arch_memremap_can_ram_remap(resource_size_t offset,
0353 unsigned long size,
0354 unsigned long flags);
0355 #define arch_memremap_can_ram_remap arch_memremap_can_ram_remap
0356
0357 extern bool phys_mem_access_encrypted(unsigned long phys_addr,
0358 unsigned long size);
0359 #else
0360 static inline bool phys_mem_access_encrypted(unsigned long phys_addr,
0361 unsigned long size)
0362 {
0363 return true;
0364 }
0365 #endif
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380 static inline void iosubmit_cmds512(void __iomem *dst, const void *src,
0381 size_t count)
0382 {
0383 const u8 *from = src;
0384 const u8 *end = from + count * 64;
0385
0386 while (from < end) {
0387 movdir64b(dst, from);
0388 from += 64;
0389 }
0390 }
0391
0392 #endif