cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

io.h (7527B)


      1/* 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/page.h>
     75#include <asm-generic/iomap.h>
     76
     77/*
     78 * Change virtual addresses to physical addresses and vv.
     79 */
     80static inline unsigned long
     81virt_to_phys (volatile void *address)
     82{
     83	return (unsigned long) address - PAGE_OFFSET;
     84}
     85#define virt_to_phys virt_to_phys
     86
     87static inline void*
     88phys_to_virt (unsigned long address)
     89{
     90	return (void *) (address + PAGE_OFFSET);
     91}
     92#define phys_to_virt phys_to_virt
     93
     94#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
     95extern u64 kern_mem_attribute (unsigned long phys_addr, unsigned long size);
     96extern int valid_phys_addr_range (phys_addr_t addr, size_t count); /* efi.c */
     97extern int valid_mmap_phys_addr_range (unsigned long pfn, size_t count);
     98
     99/*
    100 * The following two macros are deprecated and scheduled for removal.
    101 * Please use the PCI-DMA interface defined in <asm/pci.h> instead.
    102 */
    103#define bus_to_virt	phys_to_virt
    104#define virt_to_bus	virt_to_phys
    105#define page_to_bus	page_to_phys
    106
    107# endif /* KERNEL */
    108
    109/*
    110 * Memory fence w/accept.  This should never be used in code that is
    111 * not IA-64 specific.
    112 */
    113#define __ia64_mf_a()	ia64_mfa()
    114
    115static inline void*
    116__ia64_mk_io_addr (unsigned long port)
    117{
    118	struct io_space *space;
    119	unsigned long offset;
    120
    121	space = &io_space[IO_SPACE_NR(port)];
    122	port = IO_SPACE_PORT(port);
    123	if (space->sparse)
    124		offset = IO_SPACE_SPARSE_ENCODING(port);
    125	else
    126		offset = port;
    127
    128	return (void *) (space->mmio_base | offset);
    129}
    130
    131/*
    132 * For the in/out routines, we need to do "mf.a" _after_ doing the I/O access to ensure
    133 * that the access has completed before executing other I/O accesses.  Since we're doing
    134 * the accesses through an uncachable (UC) translation, the CPU will execute them in
    135 * program order.  However, we still need to tell the compiler not to shuffle them around
    136 * during optimization, which is why we use "volatile" pointers.
    137 */
    138
    139#define inb inb
    140static inline unsigned int inb(unsigned long port)
    141{
    142	volatile unsigned char *addr = __ia64_mk_io_addr(port);
    143	unsigned char ret;
    144
    145	ret = *addr;
    146	__ia64_mf_a();
    147	return ret;
    148}
    149
    150#define inw inw
    151static inline unsigned int inw(unsigned long port)
    152{
    153	volatile unsigned short *addr = __ia64_mk_io_addr(port);
    154	unsigned short ret;
    155
    156	ret = *addr;
    157	__ia64_mf_a();
    158	return ret;
    159}
    160
    161#define inl inl
    162static inline unsigned int inl(unsigned long port)
    163{
    164	volatile unsigned int *addr = __ia64_mk_io_addr(port);
    165	unsigned int ret;
    166
    167	ret = *addr;
    168	__ia64_mf_a();
    169	return ret;
    170}
    171
    172#define outb outb
    173static inline void outb(unsigned char val, unsigned long port)
    174{
    175	volatile unsigned char *addr = __ia64_mk_io_addr(port);
    176
    177	*addr = val;
    178	__ia64_mf_a();
    179}
    180
    181#define outw outw
    182static inline void outw(unsigned short val, unsigned long port)
    183{
    184	volatile unsigned short *addr = __ia64_mk_io_addr(port);
    185
    186	*addr = val;
    187	__ia64_mf_a();
    188}
    189
    190#define outl outl
    191static inline void outl(unsigned int val, unsigned long port)
    192{
    193	volatile unsigned int *addr = __ia64_mk_io_addr(port);
    194
    195	*addr = val;
    196	__ia64_mf_a();
    197}
    198
    199#define insb insb
    200static inline void insb(unsigned long port, void *dst, unsigned long count)
    201{
    202	unsigned char *dp = dst;
    203
    204	while (count--)
    205		*dp++ = inb(port);
    206}
    207
    208#define insw insw
    209static inline void insw(unsigned long port, void *dst, unsigned long count)
    210{
    211	unsigned short *dp = dst;
    212
    213	while (count--)
    214		put_unaligned(inw(port), dp++);
    215}
    216
    217#define insl insl
    218static inline void insl(unsigned long port, void *dst, unsigned long count)
    219{
    220	unsigned int *dp = dst;
    221
    222	while (count--)
    223		put_unaligned(inl(port), dp++);
    224}
    225
    226#define outsb outsb
    227static inline void outsb(unsigned long port, const void *src,
    228		unsigned long count)
    229{
    230	const unsigned char *sp = src;
    231
    232	while (count--)
    233		outb(*sp++, port);
    234}
    235
    236#define outsw outsw
    237static inline void outsw(unsigned long port, const void *src,
    238		unsigned long count)
    239{
    240	const unsigned short *sp = src;
    241
    242	while (count--)
    243		outw(get_unaligned(sp++), port);
    244}
    245
    246#define outsl outsl
    247static inline void outsl(unsigned long port, const void *src,
    248		unsigned long count)
    249{
    250	const unsigned int *sp = src;
    251
    252	while (count--)
    253		outl(get_unaligned(sp++), port);
    254}
    255
    256# ifdef __KERNEL__
    257
    258extern void __iomem * ioremap(unsigned long offset, unsigned long size);
    259extern void __iomem * ioremap_uc(unsigned long offset, unsigned long size);
    260extern void iounmap (volatile void __iomem *addr);
    261static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned long size)
    262{
    263	return ioremap(phys_addr, size);
    264}
    265#define ioremap ioremap
    266#define ioremap_cache ioremap_cache
    267#define ioremap_uc ioremap_uc
    268#define iounmap iounmap
    269
    270/*
    271 * String version of IO memory access ops:
    272 */
    273extern void memcpy_fromio(void *dst, const volatile void __iomem *src, long n);
    274extern void memcpy_toio(volatile void __iomem *dst, const void *src, long n);
    275extern void memset_io(volatile void __iomem *s, int c, long n);
    276
    277#define memcpy_fromio memcpy_fromio
    278#define memcpy_toio memcpy_toio
    279#define memset_io memset_io
    280#define xlate_dev_mem_ptr xlate_dev_mem_ptr
    281#include <asm-generic/io.h>
    282#undef PCI_IOBASE
    283
    284# endif /* __KERNEL__ */
    285
    286#endif /* _ASM_IA64_IO_H */