Patrick Georgi (patrick@georgi-clan.de) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6493
-gerrit
commit bcbbaca957aaf3bfafeb1d2cac06440b96bcf93a Author: Patrick Georgi patrick@georgi-clan.de Date: Mon Aug 4 17:18:06 2014 +0200
resource: Provide interface for indexed resource access
Provide means to read, write and read/modify/write registers behind resources.
This is compatible with what reg_scripts is now doing, but should be replaced with something more efficient.
Change-Id: Ic40f2d9e2e20f22a2a3f9838d5eacca63b0da6b0 Signed-off-by: Patrick Georgi patrick@georgi-clan.de --- src/include/device/resource.h | 163 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+)
diff --git a/src/include/device/resource.h b/src/include/device/resource.h index 2d64c80..5c6f010 100644 --- a/src/include/device/resource.h +++ b/src/include/device/resource.h @@ -3,6 +3,7 @@
#include <stdint.h> #include <stddef.h> +#include <arch/io.h>
#define IORESOURCE_BITS 0x000000ff /* Bus-specific bits */
@@ -74,4 +75,166 @@ extern void search_global_resources( #define RESOURCE_TYPE_MAX 20 extern const char *resource_type(struct resource *resource);
+/* temporary API for simplified resource access + FIXME: we should work from struct resource *, instead of + resolving these all the time. + for now, that's what the ex-reg_script stuff is using, + so we'll have to live with it for a while +*/ +static inline u8 read_res8(struct device *dev, unsigned index, u32 offset) +{ + struct resource *res = find_resource(dev, index); + if (res == NULL) return 0; +#if CONFIG_ARCH_X86 + if (res->flags & IORESOURCE_IO) { + return inb(res->base + offset); + } else +#endif + if (res->flags & IORESOURCE_MEM) { +#if CONFIG_ARCH_X86 + return read8(res->base + offset); +#endif +#if CONFIG_ARCH_ARMV7 + return read8((void*)(u32)res->base + offset); +#endif + } + return 0; +} + +static inline u16 read_res16(struct device *dev, unsigned index, u32 offset) +{ + struct resource *res = find_resource(dev, index); + if (res == NULL) return 0; +#if CONFIG_ARCH_X86 + if (res->flags & IORESOURCE_IO) { + return inw(res->base + offset); + } else +#endif + if (res->flags & IORESOURCE_MEM) { +#if CONFIG_ARCH_X86 + return read16(res->base + offset); +#endif +#if CONFIG_ARCH_ARMV7 + return read16((void*)(u32)res->base + offset); +#endif + } + return 0; +} + +static inline u32 read_res32(struct device *dev, unsigned index, u32 offset) +{ + struct resource *res = find_resource(dev, index); + if (res == NULL) return 0; +#if CONFIG_ARCH_X86 + if (res->flags & IORESOURCE_IO) { + return inl(res->base + offset); + } else +#endif + if (res->flags & IORESOURCE_MEM) { +#if CONFIG_ARCH_X86 + return read32(res->base + offset); +#endif +#if CONFIG_ARCH_ARMV7 + return read32((void*)(u32)res->base + offset); +#endif + } + return 0; +} + +static inline void write_res8(struct device *dev, unsigned index, u32 offset, u8 val) +{ + struct resource *res = find_resource(dev, index); + if (res == NULL) return; +#if CONFIG_ARCH_X86 + if (res->flags & IORESOURCE_IO) { + outb(val, res->base + offset); + } else +#endif + if (res->flags & IORESOURCE_MEM) { +#if CONFIG_ARCH_X86 + write8(res->base + offset, val); +#endif +#if CONFIG_ARCH_ARMV7 + write8(val, (void*)(u32)res->base + offset); +#endif + } +} + +static inline void write_res16(struct device *dev, unsigned index, u32 offset, u16 val) +{ + struct resource *res = find_resource(dev, index); + if (res == NULL) return; +#if CONFIG_ARCH_X86 + if (res->flags & IORESOURCE_IO) { + outw(val, res->base + offset); + } else +#endif + if (res->flags & IORESOURCE_MEM) { +#if CONFIG_ARCH_X86 + write16(res->base + offset, val); +#endif +#if CONFIG_ARCH_ARMV7 + write16(val, (void*)(u32)res->base + offset); +#endif + } +} + +static inline void write_res32(struct device *dev, unsigned index, u32 offset, u32 val) +{ + struct resource *res = find_resource(dev, index); + if (res == NULL) return; +#if CONFIG_ARCH_X86 + if (res->flags & IORESOURCE_IO) { + outl(val, res->base + offset); + } else +#endif + if (res->flags & IORESOURCE_MEM) { +#if CONFIG_ARCH_X86 + write32(res->base + offset, val); +#endif +#if CONFIG_ARCH_ARMV7 + write32(val, (void*)(u32)res->base + offset); +#endif + } +} + +static inline void rmw_res8(struct device *dev, unsigned index, u32 offset, u8 mask, u8 val) +{ + u8 tmp = read_res8(dev, index, offset); + tmp &= mask; + tmp |= val; + write_res8(dev, index, offset, tmp); +} + +static inline void rmw_res16(struct device *dev, unsigned index, u32 offset, u16 mask, u16 val) +{ + u16 tmp = read_res16(dev, index, offset); + tmp &= mask; + tmp |= val; + write_res16(dev, index, offset, tmp); +} + +static inline void rmw_res32(struct device *dev, unsigned index, u32 offset, u32 mask, u32 val) +{ + u32 tmp = read_res32(dev, index, offset); + tmp &= mask; + tmp |= val; + write_res32(dev, index, offset, tmp); +} + +static inline void or_res8(struct device *dev, unsigned index, u32 offset, u8 val) +{ + rmw_res8(dev, index, offset, ~0, val); +} + +static inline void or_res16(struct device *dev, unsigned index, u32 offset, u16 val) +{ + rmw_res16(dev, index, offset, ~0, val); +} + +static inline void or_res32(struct device *dev, unsigned index, u32 offset, u32 val) +{ + rmw_res32(dev, index, offset, ~0, val); +} + #endif /* DEVICE_RESOURCE_H */