coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
mmio.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #ifndef __DEVICE_MMIO_H__
4 #define __DEVICE_MMIO_H__
5 
6 #include <arch/mmio.h>
7 #include <commonlib/helpers.h>
8 #include <endian.h>
9 #include <types.h>
10 
11 #define __clrsetbits_impl(bits, addr, clear, set) write##bits(addr, \
12  (read##bits(addr) & ~((uint##bits##_t)(clear))) | (set))
13 
14 #define clrsetbits8(addr, clear, set) __clrsetbits_impl(8, addr, clear, set)
15 #define clrsetbits16(addr, clear, set) __clrsetbits_impl(16, addr, clear, set)
16 #define clrsetbits32(addr, clear, set) __clrsetbits_impl(32, addr, clear, set)
17 #define clrsetbits64(addr, clear, set) __clrsetbits_impl(64, addr, clear, set)
18 
19 #define setbits8(addr, set) clrsetbits8(addr, 0, set)
20 #define setbits16(addr, set) clrsetbits16(addr, 0, set)
21 #define setbits32(addr, set) clrsetbits32(addr, 0, set)
22 #define setbits64(addr, set) clrsetbits64(addr, 0, set)
23 
24 #define clrbits8(addr, clear) clrsetbits8(addr, clear, 0)
25 #define clrbits16(addr, clear) clrsetbits16(addr, clear, 0)
26 #define clrbits32(addr, clear) clrsetbits32(addr, clear, 0)
27 #define clrbits64(addr, clear) clrsetbits64(addr, clear, 0)
28 
29 /*
30  * Reads a transfer buffer from 32-bit FIFO registers. fifo_stride is the
31  * distance in bytes between registers (e.g. pass 4 for a normal array of 32-bit
32  * registers or 0 to read everything from the same register). fifo_width is
33  * the amount of bytes read per register (can be 1 through 4).
34  */
35 void buffer_from_fifo32(void *buffer, size_t size, void *fifo,
36  int fifo_stride, int fifo_width);
37 
38 /*
39  * Version of buffer_to_fifo32() that can prepend a prefix of up to fifo_width
40  * size to the transfer. This is often useful for protocols where a command word
41  * precedes the actual payload data. The prefix must be packed in the low-order
42  * bytes of the 'prefix' u32 parameter and any high-order bytes exceeding prefsz
43  * must be 0. Note that 'size' counts total bytes written, including 'prefsz'.
44  */
45 void buffer_to_fifo32_prefix(const void *buffer, u32 prefix, int prefsz, size_t size,
46  void *fifo, int fifo_stride, int fifo_width);
47 
48 /*
49  * Writes a transfer buffer into 32-bit FIFO registers. fifo_stride is the
50  * distance in bytes between registers (e.g. pass 4 for a normal array of 32-bit
51  * registers or 0 to write everything into the same register). fifo_width is
52  * the amount of bytes written per register (can be 1 through 4).
53  */
54 static inline void buffer_to_fifo32(const void *buffer, size_t size, void *fifo,
55  int fifo_stride, int fifo_width)
56 {
57  buffer_to_fifo32_prefix(buffer, 0, 0, size, fifo,
58  fifo_stride, fifo_width);
59 }
60 
61 /*
62  * Utilities to help processing bit fields.
63  *
64  * To define a bit field (usually inside a register), do:
65  *
66  * DEFINE_BITFIELD(name, high_bit, low_bit)
67  *
68  * - name: Name of the field to access.
69  * - high_bit: highest bit that's part of the bit field.
70  * - low_bit: lowest bit in the bit field.
71  *
72  * To define a field with a single bit:
73  *
74  * DEFINE_BIT(name, bit)
75  *
76  * To extract one field value from a raw reg value:
77  *
78  * EXTRACT_BITFIELD(value, name);
79  *
80  * To read from an MMIO register and extract one field from it:
81  *
82  * READ32_BITFIELD(&reg, name);
83  *
84  * To write into an MMIO register, set given fields (by names) to specified
85  * values, and all other bits to zero (usually used for resetting a register):
86  *
87  * WRITE32_BITFIELDS(&reg, name, value, [name, value, ...])
88  *
89  * To write into an MMIO register, set given fields (by names) to specified
90  * values, and leaving all others "unchanged" (usually used for updating some
91  * settings):
92  *
93  * SET32_BITFIELDS(&reg, name, value, [name, value, ...])
94  *
95  * Examples:
96  *
97  * DEFINE_BITFIELD(DISP_TYPE, 2, 1)
98  * DEFINE_BIT(DISP_EN, 0)
99  *
100  * SET32_BITFIELDS(&disp_regs.ctrl, DISP_TYPE, 2);
101  * SET32_BITFIELDS(&disp_regs.ctrl, DISP_EN, 0);
102  *
103  * SET32_BITFIELDS(&disp_regs.ctrl, DISP_TYPE, 1, DISP_EN, 1);
104  * WRITE32_BITFIELDS(&disp_regs.ctrl, DISP_TYPE, 1, DISP_EN, 1);
105  *
106  * READ32_BITFIELD(&reg, DISP_TYPE)
107  * EXTRACT_BITFIELD(value, DISP_TYPE)
108  *
109  * These will be translated to:
110  *
111  * clrsetbits32(&disp_regs.ctrl, 0x6, 0x4);
112  * clrsetbits32(&disp_regs.ctrl, 0x1, 0x0);
113  *
114  * clrsetbits32(&disp_regs.ctrl, 0x7, 0x3);
115  * write32(&disp_regs.ctrl, 0x3);
116  *
117  * (read32(&reg) & 0x6) >> 1
118  * (value & 0x6) >> 1
119  *
120  * The {WRITE,SET}32_BITFIELDS currently only allows setting up to 8 fields at
121  * one invocation.
122  */
123 
124 #define DEFINE_BITFIELD(name, high_bit, low_bit) \
125  _Static_assert(high_bit >= low_bit, "invalid bit field range"); \
126  enum { \
127  name##_BITFIELD_SHIFT = (low_bit), \
128  name##_BITFIELD_SIZE = (high_bit) - (low_bit) + 1, \
129  };
130 
131 #define DEFINE_BIT(name, bit) DEFINE_BITFIELD(name, bit, bit)
132 
133 #define _BF_MASK(name, value) \
134  ((u32)GENMASK(name##_BITFIELD_SHIFT + name##_BITFIELD_SIZE - 1, \
135  name##_BITFIELD_SHIFT))
136 
137 #define _BF_VALUE(name, value) \
138  (((u32)(value) << name##_BITFIELD_SHIFT) & _BF_MASK(name, 0))
139 
140 #define _BF_APPLY1(op, name, value, ...) (op(name, value))
141 #define _BF_APPLY2(op, name, value, ...) ((op(name, value)) | \
142  _BF_APPLY1(op, __VA_ARGS__))
143 #define _BF_APPLY3(op, name, value, ...) ((op(name, value)) | \
144  _BF_APPLY2(op, __VA_ARGS__))
145 #define _BF_APPLY4(op, name, value, ...) ((op(name, value)) | \
146  _BF_APPLY3(op, __VA_ARGS__))
147 #define _BF_APPLY5(op, name, value, ...) ((op(name, value)) | \
148  _BF_APPLY4(op, __VA_ARGS__))
149 #define _BF_APPLY6(op, name, value, ...) ((op(name, value)) | \
150  _BF_APPLY5(op, __VA_ARGS__))
151 #define _BF_APPLY7(op, name, value, ...) ((op(name, value)) | \
152  _BF_APPLY6(op, __VA_ARGS__))
153 #define _BF_APPLY8(op, name, value, ...) ((op(name, value)) | \
154  _BF_APPLY7(op, __VA_ARGS__))
155 #define _BF_APPLY9(op, name, value, ...) ((op(name, value)) | \
156  _BF_APPLY8(op, __VA_ARGS__))
157 #define _BF_APPLY10(op, name, value, ...) ((op(name, value)) | \
158  _BF_APPLY9(op, __VA_ARGS__))
159 #define _BF_APPLY11(op, name, value, ...) ((op(name, value)) | \
160  _BF_APPLY10(op, __VA_ARGS__))
161 #define _BF_APPLY12(op, name, value, ...) ((op(name, value)) | \
162  _BF_APPLY11(op, __VA_ARGS__))
163 #define _BF_APPLY13(op, name, value, ...) ((op(name, value)) | \
164  _BF_APPLY12(op, __VA_ARGS__))
165 #define _BF_APPLY14(op, name, value, ...) ((op(name, value)) | \
166  _BF_APPLY13(op, __VA_ARGS__))
167 #define _BF_APPLY15(op, name, value, ...) ((op(name, value)) | \
168  _BF_APPLY14(op, __VA_ARGS__))
169 #define _BF_APPLY16(op, name, value, ...) ((op(name, value)) | \
170  _BF_APPLY15(op, __VA_ARGS__))
171 #define _BF_APPLYINVALID(...) \
172  _Static_assert(0, "Invalid arguments for {WRITE,SET}*_BITFIELDS")
173 
174 #define _BF_IMPL2(op, addr, \
175  n1, v1, n2, v2, n3, v3, n4, v4, n5, v5, n6, v6, n7, v7, n8, v8, \
176  n9, v9, n10, v10, n11, v11, n12, v12, n13, v13, n14, v14, n15, v15, n16, v16, \
177  NARGS, ...) \
178  \
179  op(addr, \
180  _BF_APPLY##NARGS(_BF_MASK, n1, v1, n2, v2, n3, v3, n4, v4, \
181  n5, v5, n6, v6, n7, v7, n8, v8, \
182  n9, v9, n10, v10, n11, v11, n12, v12, \
183  n13, v13, n14, v14, n15, v15, n16, v16), \
184  _BF_APPLY##NARGS(_BF_VALUE, n1, v1, n2, v2, n3, v3, n4, v4, \
185  n5, v5, n6, v6, n7, v7, n8, v8,\
186  n9, v9, n10, v10, n11, v11, n12, v12, \
187  n13, v13, n14, v14, n15, v15, n16, v16))
188 
189 #define _BF_IMPL(op, addr, ...) \
190  _BF_IMPL2(op, addr, __VA_ARGS__, \
191  16, INVALID, 15, INVALID, 14, INVALID, 13, INVALID, \
192  12, INVALID, 11, INVALID, 10, INVALID, 9, INVALID, \
193  8, INVALID, 7, INVALID, 6, INVALID, 5, INVALID, \
194  4, INVALID, 3, INVALID, 2, INVALID, 1, INVALID)
195 
196 #define _WRITE32_BITFIELDS_IMPL(addr, masks, values) write32(addr, values)
197 
198 #define WRITE32_BITFIELDS(addr, ...) \
199  _BF_IMPL(_WRITE32_BITFIELDS_IMPL, addr, __VA_ARGS__)
200 
201 #define SET32_BITFIELDS(addr, ...) \
202  _BF_IMPL(clrsetbits32, addr, __VA_ARGS__)
203 
204 #define EXTRACT_BITFIELD(value, name) \
205  (((value) & _BF_MASK(name, 0)) >> name##_BITFIELD_SHIFT)
206 
207 #define READ32_BITFIELD(addr, name) \
208  EXTRACT_BITFIELD(read32(addr), name)
209 
211 {
212  return read8((void *)addr);
213 }
214 
216 {
217  return read16((void *)addr);
218 }
219 
221 {
222  return read32((void *)addr);
223 }
224 
226 {
227  return read64((void *)addr);
228 }
229 
231 {
232  write8((void *)addr, value);
233 }
234 
236 {
237  write16((void *)addr, value);
238 }
239 
241 {
242  write32((void *)addr, value);
243 }
244 
246 {
247  write64((void *)addr, value);
248 }
249 
250 #endif /* __DEVICE_MMIO_H__ */
pte_t value
Definition: mmu.c:91
static void write8(void *addr, uint8_t val)
Definition: mmio.h:30
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint16_t read16(const void *addr)
Definition: mmio.h:17
void write64(void *addr, uint64_t val)
static uint32_t read32(const void *addr)
Definition: mmio.h:22
uint64_t read64(const void *addr)
static uint8_t read8(const void *addr)
Definition: mmio.h:12
static void write16(void *addr, uint16_t val)
Definition: mmio.h:35
static u32 addr
Definition: cirrus.c:14
#define __always_inline
Definition: compiler.h:35
static __always_inline uint64_t read64p(const uintptr_t addr)
Definition: mmio.h:225
static __always_inline void write64p(const uintptr_t addr, const uint64_t value)
Definition: mmio.h:245
static __always_inline void write8p(const uintptr_t addr, const uint8_t value)
Definition: mmio.h:230
void buffer_from_fifo32(void *buffer, size_t size, void *fifo, int fifo_stride, int fifo_width)
Definition: mmio.c:8
static __always_inline void write16p(const uintptr_t addr, const uint16_t value)
Definition: mmio.h:235
void buffer_to_fifo32_prefix(const void *buffer, u32 prefix, int prefsz, size_t size, void *fifo, int fifo_stride, int fifo_width)
Definition: mmio.c:24
static __always_inline uint32_t read32p(const uintptr_t addr)
Definition: mmio.h:220
static __always_inline void write32p(const uintptr_t addr, const uint32_t value)
Definition: mmio.h:240
static __always_inline uint8_t read8p(const uintptr_t addr)
Definition: mmio.h:210
static void buffer_to_fifo32(const void *buffer, size_t size, void *fifo, int fifo_stride, int fifo_width)
Definition: mmio.h:54
static __always_inline uint16_t read16p(const uintptr_t addr)
Definition: mmio.h:215
u8 buffer[C2P_BUFFER_MAXSIZE]
Definition: psp_smm.c:18
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14
uint32_t u32
Definition: stdint.h:51
unsigned long uintptr_t
Definition: stdint.h:21
unsigned long long uint64_t
Definition: stdint.h:17
unsigned char uint8_t
Definition: stdint.h:8