nb/intel/common/fixed_bars.h: Add new read/write accessors

The {MCH,DMI,EP}BAR macros can be used for both reading and writing.
While this can sometimes be useful, compile-time overflow checking is
limited. Moreover, and-masks need to be bit-wise negated, which is easy
to forget and may result in spurious overflow warnings, and silencing
them with a cast also suppresses true integer overflow issues.

To address these limitations and for consistency with the existing MMIO
API (arch/mmio.h and device/mmio.h), these macros will be replaced with
prefixed wrappers around MMIO API functions. However, existing platform
code needs to be refactored, and the risk of introducing regressions is
substantial. To minimize the risk of breakage, the bulk of the platform
code changes will be verified using reproducible builds.

This patch introduces the new accessors, to be put to use in follow-ups.
These accessors are implemented as macros so that subsequent commits can
be verified using reproducible builds. They will be replaced with actual
functions after refactoring all platforms.

Change-Id: I85376a9e2f6cd042b41036f90de7f9edc7ad4508
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/51864
Reviewed-by: Nico Huber <nico.h@gmx.de>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/northbridge/intel/common/fixed_bars.h b/src/northbridge/intel/common/fixed_bars.h
index e9c63c5..8a0d9dc 100644
--- a/src/northbridge/intel/common/fixed_bars.h
+++ b/src/northbridge/intel/common/fixed_bars.h
@@ -9,6 +9,7 @@
 
 #include <stdint.h>
 
+/* Deprecated in favor of the read/write accessors below */
 #define MCHBAR8(x)	(*((volatile u8  *)((uintptr_t)CONFIG_FIXED_MCHBAR_MMIO_BASE + (x))))
 #define MCHBAR16(x)	(*((volatile u16 *)((uintptr_t)CONFIG_FIXED_MCHBAR_MMIO_BASE + (x))))
 #define MCHBAR32(x)	(*((volatile u32 *)((uintptr_t)CONFIG_FIXED_MCHBAR_MMIO_BASE + (x))))
@@ -31,4 +32,69 @@
 #define EPBAR16(x)	(*((volatile u16 *)((uintptr_t)CONFIG_FIXED_EPBAR_MMIO_BASE + (x))))
 #define EPBAR32(x)	(*((volatile u32 *)((uintptr_t)CONFIG_FIXED_EPBAR_MMIO_BASE + (x))))
 
+/* The *bar_{read,write}X macros will be replaced with functions in follow-ups */
+#define _bar_clrsetbits_impl(base, addr, clear, set, bits)				\
+		base##bar_write##bits(addr,						\
+			(base##bar_read##bits(addr) & ~(uint##bits##_t)(clear)) | (set))
+
+#define mchbar_read8(addr)		MCHBAR8(addr)
+#define mchbar_read16(addr)		MCHBAR16(addr)
+#define mchbar_read32(addr)		MCHBAR32(addr)
+
+#define mchbar_write8(addr, value)	(MCHBAR8(addr) = (value))
+#define mchbar_write16(addr, value)	(MCHBAR16(addr) = (value))
+#define mchbar_write32(addr, value)	(MCHBAR32(addr) = (value))
+
+#define mchbar_clrsetbits8(addr, clear, set)	_bar_clrsetbits_impl(mch, addr, clear, set, 8)
+#define mchbar_clrsetbits16(addr, clear, set)	_bar_clrsetbits_impl(mch, addr, clear, set, 16)
+#define mchbar_clrsetbits32(addr, clear, set)	_bar_clrsetbits_impl(mch, addr, clear, set, 32)
+
+#define mchbar_setbits8(addr, set)		mchbar_clrsetbits8(addr, 0, set)
+#define mchbar_setbits16(addr, set)		mchbar_clrsetbits16(addr, 0, set)
+#define mchbar_setbits32(addr, set)		mchbar_clrsetbits32(addr, 0, set)
+
+#define mchbar_clrbits8(addr, clear)		mchbar_clrsetbits8(addr, clear, 0)
+#define mchbar_clrbits16(addr, clear)		mchbar_clrsetbits16(addr, clear, 0)
+#define mchbar_clrbits32(addr, clear)		mchbar_clrsetbits32(addr, clear, 0)
+
+#define dmibar_read8(addr)		DMIBAR8(addr)
+#define dmibar_read16(addr)		DMIBAR16(addr)
+#define dmibar_read32(addr)		DMIBAR32(addr)
+
+#define dmibar_write8(addr, value)	(DMIBAR8(addr) = (value))
+#define dmibar_write16(addr, value)	(DMIBAR16(addr) = (value))
+#define dmibar_write32(addr, value)	(DMIBAR32(addr) = (value))
+
+#define dmibar_clrsetbits8(addr, clear, set)	_bar_clrsetbits_impl(dmi, addr, clear, set, 8)
+#define dmibar_clrsetbits16(addr, clear, set)	_bar_clrsetbits_impl(dmi, addr, clear, set, 16)
+#define dmibar_clrsetbits32(addr, clear, set)	_bar_clrsetbits_impl(dmi, addr, clear, set, 32)
+
+#define dmibar_setbits8(addr, set)		dmibar_clrsetbits8(addr, 0, set)
+#define dmibar_setbits16(addr, set)		dmibar_clrsetbits16(addr, 0, set)
+#define dmibar_setbits32(addr, set)		dmibar_clrsetbits32(addr, 0, set)
+
+#define dmibar_clrbits8(addr, clear)		dmibar_clrsetbits8(addr, clear, 0)
+#define dmibar_clrbits16(addr, clear)		dmibar_clrsetbits16(addr, clear, 0)
+#define dmibar_clrbits32(addr, clear)		dmibar_clrsetbits32(addr, clear, 0)
+
+#define epbar_read8(addr)		EPBAR8(addr)
+#define epbar_read16(addr)		EPBAR16(addr)
+#define epbar_read32(addr)		EPBAR32(addr)
+
+#define epbar_write8(addr, value)	(EPBAR8(addr) = (value))
+#define epbar_write16(addr, value)	(EPBAR16(addr) = (value))
+#define epbar_write32(addr, value)	(EPBAR32(addr) = (value))
+
+#define epbar_clrsetbits8(addr, clear, set)	_bar_clrsetbits_impl(ep, addr, clear, set, 8)
+#define epbar_clrsetbits16(addr, clear, set)	_bar_clrsetbits_impl(ep, addr, clear, set, 16)
+#define epbar_clrsetbits32(addr, clear, set)	_bar_clrsetbits_impl(ep, addr, clear, set, 32)
+
+#define epbar_setbits8(addr, set)		epbar_clrsetbits8(addr, 0, set)
+#define epbar_setbits16(addr, set)		epbar_clrsetbits16(addr, 0, set)
+#define epbar_setbits32(addr, set)		epbar_clrsetbits32(addr, 0, set)
+
+#define epbar_clrbits8(addr, clear)		epbar_clrsetbits8(addr, clear, 0)
+#define epbar_clrbits16(addr, clear)		epbar_clrsetbits16(addr, clear, 0)
+#define epbar_clrbits32(addr, clear)		epbar_clrsetbits32(addr, clear, 0)
+
 #endif	/* ! NORTHBRIDGE_INTEL_COMMON_FIXED_BARS_H */