xref: /openbmc/qemu/include/hw/registerfields.h (revision 2f44bea9)
1 /*
2  * Register Definition API: field macros
3  *
4  * Copyright (c) 2016 Xilinx Inc.
5  * Copyright (c) 2013 Peter Crosthwaite <peter.crosthwaite@xilinx.com>
6  *
7  * This work is licensed under the terms of the GNU GPL, version 2.  See
8  * the COPYING file in the top-level directory.
9  */
10 
11 #ifndef REGISTERFIELDS_H
12 #define REGISTERFIELDS_H
13 
14 #include "qemu/bitops.h"
15 
16 /* Define constants for a 32 bit register */
17 
18 /* This macro will define A_FOO, for the byte address of a register
19  * as well as R_FOO for the uint32_t[] register number (A_FOO / 4).
20  */
21 #define REG32(reg, addr)                                                  \
22     enum { A_ ## reg = (addr) };                                          \
23     enum { R_ ## reg = (addr) / 4 };
24 
25 #define REG8(reg, addr)                                                   \
26     enum { A_ ## reg = (addr) };                                          \
27     enum { R_ ## reg = (addr) };
28 
29 #define REG16(reg, addr)                                                  \
30     enum { A_ ## reg = (addr) };                                          \
31     enum { R_ ## reg = (addr) / 2 };
32 
33 #define REG64(reg, addr)                                                  \
34     enum { A_ ## reg = (addr) };                                          \
35     enum { R_ ## reg = (addr) / 8 };
36 
37 /* Define SHIFT, LENGTH and MASK constants for a field within a register */
38 
39 /* This macro will define R_FOO_BAR_MASK, R_FOO_BAR_SHIFT and R_FOO_BAR_LENGTH
40  * constants for field BAR in register FOO.
41  */
42 #define FIELD(reg, field, shift, length)                                  \
43     enum { R_ ## reg ## _ ## field ## _SHIFT = (shift)};                  \
44     enum { R_ ## reg ## _ ## field ## _LENGTH = (length)};                \
45     enum { R_ ## reg ## _ ## field ## _MASK =                             \
46                                         MAKE_64BIT_MASK(shift, length)};
47 
48 /* Extract a field from a register */
49 #define FIELD_EX8(storage, reg, field)                                    \
50     extract8((storage), R_ ## reg ## _ ## field ## _SHIFT,                \
51               R_ ## reg ## _ ## field ## _LENGTH)
52 #define FIELD_EX16(storage, reg, field)                                   \
53     extract16((storage), R_ ## reg ## _ ## field ## _SHIFT,               \
54               R_ ## reg ## _ ## field ## _LENGTH)
55 #define FIELD_EX32(storage, reg, field)                                   \
56     extract32((storage), R_ ## reg ## _ ## field ## _SHIFT,               \
57               R_ ## reg ## _ ## field ## _LENGTH)
58 #define FIELD_EX64(storage, reg, field)                                   \
59     extract64((storage), R_ ## reg ## _ ## field ## _SHIFT,               \
60               R_ ## reg ## _ ## field ## _LENGTH)
61 
62 /* Extract a field from an array of registers */
63 #define ARRAY_FIELD_EX32(regs, reg, field)                                \
64     FIELD_EX32((regs)[R_ ## reg], reg, field)
65 #define ARRAY_FIELD_EX64(regs, reg, field)                                \
66     FIELD_EX64((regs)[R_ ## reg], reg, field)
67 
68 /* Deposit a register field.
69  * Assigning values larger then the target field will result in
70  * compilation warnings.
71  */
72 #define FIELD_DP8(storage, reg, field, val) ({                            \
73     struct {                                                              \
74         unsigned int v:R_ ## reg ## _ ## field ## _LENGTH;                \
75     } _v = { .v = val };                                                  \
76     uint8_t _d;                                                           \
77     _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT,          \
78                   R_ ## reg ## _ ## field ## _LENGTH, _v.v);              \
79     _d; })
80 #define FIELD_DP16(storage, reg, field, val) ({                           \
81     struct {                                                              \
82         unsigned int v:R_ ## reg ## _ ## field ## _LENGTH;                \
83     } _v = { .v = val };                                                  \
84     uint16_t _d;                                                          \
85     _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT,          \
86                   R_ ## reg ## _ ## field ## _LENGTH, _v.v);              \
87     _d; })
88 #define FIELD_DP32(storage, reg, field, val) ({                           \
89     struct {                                                              \
90         unsigned int v:R_ ## reg ## _ ## field ## _LENGTH;                \
91     } _v = { .v = val };                                                  \
92     uint32_t _d;                                                          \
93     _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT,          \
94                   R_ ## reg ## _ ## field ## _LENGTH, _v.v);              \
95     _d; })
96 #define FIELD_DP64(storage, reg, field, val) ({                           \
97     struct {                                                              \
98         uint64_t v:R_ ## reg ## _ ## field ## _LENGTH;                \
99     } _v = { .v = val };                                                  \
100     uint64_t _d;                                                          \
101     _d = deposit64((storage), R_ ## reg ## _ ## field ## _SHIFT,          \
102                   R_ ## reg ## _ ## field ## _LENGTH, _v.v);              \
103     _d; })
104 
105 /* Deposit a field to array of registers.  */
106 #define ARRAY_FIELD_DP32(regs, reg, field, val)                           \
107     (regs)[R_ ## reg] = FIELD_DP32((regs)[R_ ## reg], reg, field, val);
108 #define ARRAY_FIELD_DP64(regs, reg, field, val)                           \
109     (regs)[R_ ## reg] = FIELD_DP64((regs)[R_ ## reg], reg, field, val);
110 
111 #endif
112