diff --git a/include/hw/register.h b/include/hw/register.h index 5b6dc3209165a094af2bd3435d8784cf892071b1..de2414e6b482057b1dcef3fc9eb60b67a66f9e6b 100644 --- a/include/hw/register.h +++ b/include/hw/register.h @@ -13,6 +13,7 @@ #include "hw/qdev-core.h" #include "exec/memory.h" +#include "hw/registerfields.h" typedef struct RegisterInfo RegisterInfo; typedef struct RegisterAccessInfo RegisterAccessInfo; @@ -206,50 +207,4 @@ RegisterInfoArray *register_init_block32(DeviceState *owner, void register_finalize_block(RegisterInfoArray *r_array); -/* Define constants for a 32 bit register */ - -/* This macro will define A_FOO, for the byte address of a register - * as well as R_FOO for the uint32_t[] register number (A_FOO / 4). - */ -#define REG32(reg, addr) \ - enum { A_ ## reg = (addr) }; \ - enum { R_ ## reg = (addr) / 4 }; - -/* Define SHIFT, LENGTH and MASK constants for a field within a register */ - -/* This macro will define FOO_BAR_MASK, FOO_BAR_SHIFT and FOO_BAR_LENGTH - * constants for field BAR in register FOO. - */ -#define FIELD(reg, field, shift, length) \ - enum { R_ ## reg ## _ ## field ## _SHIFT = (shift)}; \ - enum { R_ ## reg ## _ ## field ## _LENGTH = (length)}; \ - enum { R_ ## reg ## _ ## field ## _MASK = \ - MAKE_64BIT_MASK(shift, length)}; - -/* Extract a field from a register */ -#define FIELD_EX32(storage, reg, field) \ - extract32((storage), R_ ## reg ## _ ## field ## _SHIFT, \ - R_ ## reg ## _ ## field ## _LENGTH) - -/* Extract a field from an array of registers */ -#define ARRAY_FIELD_EX32(regs, reg, field) \ - FIELD_EX32((regs)[R_ ## reg], reg, field) - -/* Deposit a register field. - * Assigning values larger then the target field will result in - * compilation warnings. - */ -#define FIELD_DP32(storage, reg, field, val) ({ \ - struct { \ - unsigned int v:R_ ## reg ## _ ## field ## _LENGTH; \ - } v = { .v = val }; \ - uint32_t d; \ - d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \ - R_ ## reg ## _ ## field ## _LENGTH, v.v); \ - d; }) - -/* Deposit a field to array of registers. */ -#define ARRAY_FIELD_DP32(regs, reg, field, val) \ - (regs)[R_ ## reg] = FIELD_DP32((regs)[R_ ## reg], reg, field, val); - #endif diff --git a/include/hw/registerfields.h b/include/hw/registerfields.h new file mode 100644 index 0000000000000000000000000000000000000000..af101d5ae6d21f265303d3edf95523aca46da341 --- /dev/null +++ b/include/hw/registerfields.h @@ -0,0 +1,60 @@ +/* + * Register Definition API: field macros + * + * Copyright (c) 2016 Xilinx Inc. + * Copyright (c) 2013 Peter Crosthwaite + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ + +#ifndef REGISTERFIELDS_H +#define REGISTERFIELDS_H + +/* Define constants for a 32 bit register */ + +/* This macro will define A_FOO, for the byte address of a register + * as well as R_FOO for the uint32_t[] register number (A_FOO / 4). + */ +#define REG32(reg, addr) \ + enum { A_ ## reg = (addr) }; \ + enum { R_ ## reg = (addr) / 4 }; + +/* Define SHIFT, LENGTH and MASK constants for a field within a register */ + +/* This macro will define FOO_BAR_MASK, FOO_BAR_SHIFT and FOO_BAR_LENGTH + * constants for field BAR in register FOO. + */ +#define FIELD(reg, field, shift, length) \ + enum { R_ ## reg ## _ ## field ## _SHIFT = (shift)}; \ + enum { R_ ## reg ## _ ## field ## _LENGTH = (length)}; \ + enum { R_ ## reg ## _ ## field ## _MASK = \ + MAKE_64BIT_MASK(shift, length)}; + +/* Extract a field from a register */ +#define FIELD_EX32(storage, reg, field) \ + extract32((storage), R_ ## reg ## _ ## field ## _SHIFT, \ + R_ ## reg ## _ ## field ## _LENGTH) + +/* Extract a field from an array of registers */ +#define ARRAY_FIELD_EX32(regs, reg, field) \ + FIELD_EX32((regs)[R_ ## reg], reg, field) + +/* Deposit a register field. + * Assigning values larger then the target field will result in + * compilation warnings. + */ +#define FIELD_DP32(storage, reg, field, val) ({ \ + struct { \ + unsigned int v:R_ ## reg ## _ ## field ## _LENGTH; \ + } v = { .v = val }; \ + uint32_t d; \ + d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \ + R_ ## reg ## _ ## field ## _LENGTH, v.v); \ + d; }) + +/* Deposit a field to array of registers. */ +#define ARRAY_FIELD_DP32(regs, reg, field, val) \ + (regs)[R_ ## reg] = FIELD_DP32((regs)[R_ ## reg], reg, field, val); + +#endif