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