[U-Boot] [PATCH v3 20/31] x86: Implement arch-specific io accessor routines

Bin Meng bmeng.cn at gmail.com
Mon Oct 15 09:21:16 UTC 2018


At present the generic io{read,write}{8,16,32} routines only support
MMIO access. With architecture like x86 that has a separate IO space,
these routines cannot be used to access I/O ports.

Implement x86-specific version to support both PIO and MMIO access,
so that drivers for multiple architectures can use these accessors
without the need to know whether it's MMIO or PIO.

These are ported from Linux kernel lib/iomap.c, with slight changes.

Signed-off-by: Bin Meng <bmeng.cn at gmail.com>
Reviewed-by: Simon Glass <sjg at chromium.org>
---

Changes in v3: None
Changes in v2: None

 arch/Kconfig              |  1 +
 arch/x86/include/asm/io.h | 66 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)

diff --git a/arch/Kconfig b/arch/Kconfig
index 1f2f407..e822a0b 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -120,6 +120,7 @@ config X86
 	select CREATE_ARCH_SYMLINK
 	select DM
 	select DM_PCI
+	select HAVE_ARCH_IOMAP
 	select HAVE_PRIVATE_LIBGCC
 	select OF_CONTROL
 	select PCI
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index c05c6bf..81def0a 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -241,6 +241,72 @@ static inline void sync(void)
 #define __iormb()	dmb()
 #define __iowmb()	dmb()
 
+/*
+ * Read/write from/to an (offsettable) iomem cookie. It might be a PIO
+ * access or a MMIO access, these functions don't care. The info is
+ * encoded in the hardware mapping set up by the mapping functions
+ * (or the cookie itself, depending on implementation and hw).
+ *
+ * The generic routines don't assume any hardware mappings, and just
+ * encode the PIO/MMIO as part of the cookie. They coldly assume that
+ * the MMIO IO mappings are not in the low address range.
+ *
+ * Architectures for which this is not true can't use this generic
+ * implementation and should do their own copy.
+ */
+
+/*
+ * We assume that all the low physical PIO addresses (0-0xffff) always
+ * PIO. That means we can do some sanity checks on the low bits, and
+ * don't need to just take things for granted.
+ */
+#define PIO_RESERVED	0x10000UL
+
+/*
+ * Ugly macros are a way of life.
+ */
+#define IO_COND(addr, is_pio, is_mmio) do {			\
+	unsigned long port = (unsigned long __force)addr;	\
+	if (port >= PIO_RESERVED) {				\
+		is_mmio;					\
+	} else {						\
+		is_pio;						\
+	}							\
+} while (0)
+
+static inline u8 ioread8(const volatile void __iomem *addr)
+{
+	IO_COND(addr, return inb(port), return readb(addr));
+	return 0xff;
+}
+
+static inline u16 ioread16(const volatile void __iomem *addr)
+{
+	IO_COND(addr, return inw(port), return readw(addr));
+	return 0xffff;
+}
+
+static inline u32 ioread32(const volatile void __iomem *addr)
+{
+	IO_COND(addr, return inl(port), return readl(addr));
+	return 0xffffffff;
+}
+
+static inline void iowrite8(u8 value, volatile void __iomem *addr)
+{
+	IO_COND(addr, outb(value, port), writeb(value, addr));
+}
+
+static inline void iowrite16(u16 value, volatile void __iomem *addr)
+{
+	IO_COND(addr, outw(value, port), writew(value, addr));
+}
+
+static inline void iowrite32(u32 value, volatile void __iomem *addr)
+{
+	IO_COND(addr, outl(value, port), writel(value, addr));
+}
+
 #include <asm-generic/io.h>
 
 #endif /* _ASM_IO_H */
-- 
2.7.4



More information about the U-Boot mailing list