blob: 1e6fef69bb01c26286df9ea7963d092b442e66ab [file] [log] [blame]
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _ASM_IA64_IO_H
3#define _ASM_IA64_IO_H
4
5/*
6 * This file contains the definitions for the emulated IO instructions
7 * inb/inw/inl/outb/outw/outl and the "string versions" of the same
8 * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
9 * versions of the single-IO instructions (inb_p/inw_p/..).
10 *
11 * This file is not meant to be obfuscating: it's just complicated to
12 * (a) handle it all in a way that makes gcc able to optimize it as
13 * well as possible and (b) trying to avoid writing the same thing
14 * over and over again with slight variations and possibly making a
15 * mistake somewhere.
16 *
17 * Copyright (C) 1998-2003 Hewlett-Packard Co
18 * David Mosberger-Tang <davidm@hpl.hp.com>
19 * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
20 * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
21 */
22
23#include <asm/unaligned.h>
24#include <asm/early_ioremap.h>
25
26/* We don't use IO slowdowns on the ia64, but.. */
27#define __SLOW_DOWN_IO do { } while (0)
28#define SLOW_DOWN_IO do { } while (0)
29
30#define __IA64_UNCACHED_OFFSET RGN_BASE(RGN_UNCACHED)
31
32/*
33 * The legacy I/O space defined by the ia64 architecture supports only 65536 ports, but
34 * large machines may have multiple other I/O spaces so we can't place any a priori limit
35 * on IO_SPACE_LIMIT. These additional spaces are described in ACPI.
36 */
37#define IO_SPACE_LIMIT 0xffffffffffffffffUL
38
39#define MAX_IO_SPACES_BITS 8
40#define MAX_IO_SPACES (1UL << MAX_IO_SPACES_BITS)
41#define IO_SPACE_BITS 24
42#define IO_SPACE_SIZE (1UL << IO_SPACE_BITS)
43
44#define IO_SPACE_NR(port) ((port) >> IO_SPACE_BITS)
45#define IO_SPACE_BASE(space) ((space) << IO_SPACE_BITS)
46#define IO_SPACE_PORT(port) ((port) & (IO_SPACE_SIZE - 1))
47
48#define IO_SPACE_SPARSE_ENCODING(p) ((((p) >> 2) << 12) | ((p) & 0xfff))
49
50struct io_space {
51 unsigned long mmio_base; /* base in MMIO space */
52 int sparse;
53};
54
55extern struct io_space io_space[];
56extern unsigned int num_io_spaces;
57
58# ifdef __KERNEL__
59
60/*
61 * All MMIO iomem cookies are in region 6; anything less is a PIO cookie:
62 * 0xCxxxxxxxxxxxxxxx MMIO cookie (return from ioremap)
63 * 0x000000001SPPPPPP PIO cookie (S=space number, P..P=port)
64 *
65 * ioread/writeX() uses the leading 1 in PIO cookies (PIO_OFFSET) to catch
66 * code that uses bare port numbers without the prerequisite pci_iomap().
67 */
68#define PIO_OFFSET (1UL << (MAX_IO_SPACES_BITS + IO_SPACE_BITS))
69#define PIO_MASK (PIO_OFFSET - 1)
70#define PIO_RESERVED __IA64_UNCACHED_OFFSET
71#define HAVE_ARCH_PIO_SIZE
72
73#include <asm/intrinsics.h>
74#include <asm/machvec.h>
75#include <asm/page.h>
76#include <asm-generic/iomap.h>
77
78/*
79 * Change virtual addresses to physical addresses and vv.
80 */
81static inline unsigned long
82virt_to_phys (volatile void *address)
83{
84 return (unsigned long) address - PAGE_OFFSET;
85}
86#define virt_to_phys virt_to_phys
87
88static inline void*
89phys_to_virt (unsigned long address)
90{
91 return (void *) (address + PAGE_OFFSET);
92}
93#define phys_to_virt phys_to_virt
94
95#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
96extern u64 kern_mem_attribute (unsigned long phys_addr, unsigned long size);
97extern int valid_phys_addr_range (phys_addr_t addr, size_t count); /* efi.c */
98extern int valid_mmap_phys_addr_range (unsigned long pfn, size_t count);
99
100/*
101 * The following two macros are deprecated and scheduled for removal.
102 * Please use the PCI-DMA interface defined in <asm/pci.h> instead.
103 */
104#define bus_to_virt phys_to_virt
105#define virt_to_bus virt_to_phys
106#define page_to_bus page_to_phys
107
108# endif /* KERNEL */
109
110/*
111 * Memory fence w/accept. This should never be used in code that is
112 * not IA-64 specific.
113 */
114#define __ia64_mf_a() ia64_mfa()
115
116/**
117 * ___ia64_mmiowb - I/O write barrier
118 *
119 * Ensure ordering of I/O space writes. This will make sure that writes
120 * following the barrier will arrive after all previous writes. For most
121 * ia64 platforms, this is a simple 'mf.a' instruction.
122 *
123 * See Documentation/driver-api/device-io.rst for more information.
124 */
125static inline void ___ia64_mmiowb(void)
126{
127 ia64_mfa();
128}
129
130static inline void*
131__ia64_mk_io_addr (unsigned long port)
132{
133 struct io_space *space;
134 unsigned long offset;
135
136 space = &io_space[IO_SPACE_NR(port)];
137 port = IO_SPACE_PORT(port);
138 if (space->sparse)
139 offset = IO_SPACE_SPARSE_ENCODING(port);
140 else
141 offset = port;
142
143 return (void *) (space->mmio_base | offset);
144}
145
146#define __ia64_inb ___ia64_inb
147#define __ia64_inw ___ia64_inw
148#define __ia64_inl ___ia64_inl
149#define __ia64_outb ___ia64_outb
150#define __ia64_outw ___ia64_outw
151#define __ia64_outl ___ia64_outl
152#define __ia64_readb ___ia64_readb
153#define __ia64_readw ___ia64_readw
154#define __ia64_readl ___ia64_readl
155#define __ia64_readq ___ia64_readq
156#define __ia64_readb_relaxed ___ia64_readb
157#define __ia64_readw_relaxed ___ia64_readw
158#define __ia64_readl_relaxed ___ia64_readl
159#define __ia64_readq_relaxed ___ia64_readq
160#define __ia64_writeb ___ia64_writeb
161#define __ia64_writew ___ia64_writew
162#define __ia64_writel ___ia64_writel
163#define __ia64_writeq ___ia64_writeq
164#define __ia64_mmiowb ___ia64_mmiowb
165
166/*
167 * For the in/out routines, we need to do "mf.a" _after_ doing the I/O access to ensure
168 * that the access has completed before executing other I/O accesses. Since we're doing
169 * the accesses through an uncachable (UC) translation, the CPU will execute them in
170 * program order. However, we still need to tell the compiler not to shuffle them around
171 * during optimization, which is why we use "volatile" pointers.
172 */
173
174static inline unsigned int
175___ia64_inb (unsigned long port)
176{
177 volatile unsigned char *addr = __ia64_mk_io_addr(port);
178 unsigned char ret;
179
180 ret = *addr;
181 __ia64_mf_a();
182 return ret;
183}
184
185static inline unsigned int
186___ia64_inw (unsigned long port)
187{
188 volatile unsigned short *addr = __ia64_mk_io_addr(port);
189 unsigned short ret;
190
191 ret = *addr;
192 __ia64_mf_a();
193 return ret;
194}
195
196static inline unsigned int
197___ia64_inl (unsigned long port)
198{
199 volatile unsigned int *addr = __ia64_mk_io_addr(port);
200 unsigned int ret;
201
202 ret = *addr;
203 __ia64_mf_a();
204 return ret;
205}
206
207static inline void
208___ia64_outb (unsigned char val, unsigned long port)
209{
210 volatile unsigned char *addr = __ia64_mk_io_addr(port);
211
212 *addr = val;
213 __ia64_mf_a();
214}
215
216static inline void
217___ia64_outw (unsigned short val, unsigned long port)
218{
219 volatile unsigned short *addr = __ia64_mk_io_addr(port);
220
221 *addr = val;
222 __ia64_mf_a();
223}
224
225static inline void
226___ia64_outl (unsigned int val, unsigned long port)
227{
228 volatile unsigned int *addr = __ia64_mk_io_addr(port);
229
230 *addr = val;
231 __ia64_mf_a();
232}
233
234static inline void
235__insb (unsigned long port, void *dst, unsigned long count)
236{
237 unsigned char *dp = dst;
238
239 while (count--)
240 *dp++ = platform_inb(port);
241}
242
243static inline void
244__insw (unsigned long port, void *dst, unsigned long count)
245{
246 unsigned short *dp = dst;
247
248 while (count--)
249 put_unaligned(platform_inw(port), dp++);
250}
251
252static inline void
253__insl (unsigned long port, void *dst, unsigned long count)
254{
255 unsigned int *dp = dst;
256
257 while (count--)
258 put_unaligned(platform_inl(port), dp++);
259}
260
261static inline void
262__outsb (unsigned long port, const void *src, unsigned long count)
263{
264 const unsigned char *sp = src;
265
266 while (count--)
267 platform_outb(*sp++, port);
268}
269
270static inline void
271__outsw (unsigned long port, const void *src, unsigned long count)
272{
273 const unsigned short *sp = src;
274
275 while (count--)
276 platform_outw(get_unaligned(sp++), port);
277}
278
279static inline void
280__outsl (unsigned long port, const void *src, unsigned long count)
281{
282 const unsigned int *sp = src;
283
284 while (count--)
285 platform_outl(get_unaligned(sp++), port);
286}
287
288/*
289 * Unfortunately, some platforms are broken and do not follow the IA-64 architecture
290 * specification regarding legacy I/O support. Thus, we have to make these operations
291 * platform dependent...
292 */
293#define __inb platform_inb
294#define __inw platform_inw
295#define __inl platform_inl
296#define __outb platform_outb
297#define __outw platform_outw
298#define __outl platform_outl
299#define __mmiowb platform_mmiowb
300
301#define inb(p) __inb(p)
302#define inw(p) __inw(p)
303#define inl(p) __inl(p)
304#define insb(p,d,c) __insb(p,d,c)
305#define insw(p,d,c) __insw(p,d,c)
306#define insl(p,d,c) __insl(p,d,c)
307#define outb(v,p) __outb(v,p)
308#define outw(v,p) __outw(v,p)
309#define outl(v,p) __outl(v,p)
310#define outsb(p,s,c) __outsb(p,s,c)
311#define outsw(p,s,c) __outsw(p,s,c)
312#define outsl(p,s,c) __outsl(p,s,c)
313#define mmiowb() __mmiowb()
314
315/*
316 * The address passed to these functions are ioremap()ped already.
317 *
318 * We need these to be machine vectors since some platforms don't provide
319 * DMA coherence via PIO reads (PCI drivers and the spec imply that this is
320 * a good idea). Writes are ok though for all existing ia64 platforms (and
321 * hopefully it'll stay that way).
322 */
323static inline unsigned char
324___ia64_readb (const volatile void __iomem *addr)
325{
326 return *(volatile unsigned char __force *)addr;
327}
328
329static inline unsigned short
330___ia64_readw (const volatile void __iomem *addr)
331{
332 return *(volatile unsigned short __force *)addr;
333}
334
335static inline unsigned int
336___ia64_readl (const volatile void __iomem *addr)
337{
338 return *(volatile unsigned int __force *) addr;
339}
340
341static inline unsigned long
342___ia64_readq (const volatile void __iomem *addr)
343{
344 return *(volatile unsigned long __force *) addr;
345}
346
347static inline void
348__writeb (unsigned char val, volatile void __iomem *addr)
349{
350 *(volatile unsigned char __force *) addr = val;
351}
352
353static inline void
354__writew (unsigned short val, volatile void __iomem *addr)
355{
356 *(volatile unsigned short __force *) addr = val;
357}
358
359static inline void
360__writel (unsigned int val, volatile void __iomem *addr)
361{
362 *(volatile unsigned int __force *) addr = val;
363}
364
365static inline void
366__writeq (unsigned long val, volatile void __iomem *addr)
367{
368 *(volatile unsigned long __force *) addr = val;
369}
370
371#define __readb platform_readb
372#define __readw platform_readw
373#define __readl platform_readl
374#define __readq platform_readq
375#define __readb_relaxed platform_readb_relaxed
376#define __readw_relaxed platform_readw_relaxed
377#define __readl_relaxed platform_readl_relaxed
378#define __readq_relaxed platform_readq_relaxed
379
380#define readb(a) __readb((a))
381#define readw(a) __readw((a))
382#define readl(a) __readl((a))
383#define readq(a) __readq((a))
384#define readb_relaxed(a) __readb_relaxed((a))
385#define readw_relaxed(a) __readw_relaxed((a))
386#define readl_relaxed(a) __readl_relaxed((a))
387#define readq_relaxed(a) __readq_relaxed((a))
388#define __raw_readb readb
389#define __raw_readw readw
390#define __raw_readl readl
391#define __raw_readq readq
392#define __raw_readb_relaxed readb_relaxed
393#define __raw_readw_relaxed readw_relaxed
394#define __raw_readl_relaxed readl_relaxed
395#define __raw_readq_relaxed readq_relaxed
396#define writeb(v,a) __writeb((v), (a))
397#define writew(v,a) __writew((v), (a))
398#define writel(v,a) __writel((v), (a))
399#define writeq(v,a) __writeq((v), (a))
400#define writeb_relaxed(v,a) __writeb((v), (a))
401#define writew_relaxed(v,a) __writew((v), (a))
402#define writel_relaxed(v,a) __writel((v), (a))
403#define writeq_relaxed(v,a) __writeq((v), (a))
404#define __raw_writeb writeb
405#define __raw_writew writew
406#define __raw_writel writel
407#define __raw_writeq writeq
408
409#ifndef inb_p
410# define inb_p inb
411#endif
412#ifndef inw_p
413# define inw_p inw
414#endif
415#ifndef inl_p
416# define inl_p inl
417#endif
418
419#ifndef outb_p
420# define outb_p outb
421#endif
422#ifndef outw_p
423# define outw_p outw
424#endif
425#ifndef outl_p
426# define outl_p outl
427#endif
428
429# ifdef __KERNEL__
430
431extern void __iomem * ioremap(unsigned long offset, unsigned long size);
432extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
433extern void iounmap (volatile void __iomem *addr);
434static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned long size)
435{
436 return ioremap(phys_addr, size);
437}
438#define ioremap ioremap
439#define ioremap_nocache ioremap_nocache
440#define ioremap_cache ioremap_cache
441#define ioremap_uc ioremap_nocache
442#define iounmap iounmap
443
444/*
445 * String version of IO memory access ops:
446 */
447extern void memcpy_fromio(void *dst, const volatile void __iomem *src, long n);
448extern void memcpy_toio(volatile void __iomem *dst, const void *src, long n);
449extern void memset_io(volatile void __iomem *s, int c, long n);
450
451#define memcpy_fromio memcpy_fromio
452#define memcpy_toio memcpy_toio
453#define memset_io memset_io
454#define xlate_dev_kmem_ptr xlate_dev_kmem_ptr
455#define xlate_dev_mem_ptr xlate_dev_mem_ptr
456#include <asm-generic/io.h>
457#undef PCI_IOBASE
458
459# endif /* __KERNEL__ */
460
461#endif /* _ASM_IA64_IO_H */