/* Copyright (C) 2018 RDA Technologies Limited and/or its affiliates("RDA"). * All rights reserved. * * This software is supplied "AS IS" without any warranties. * RDA assumes no responsibility or liability for the use of the software, * conveys no license or title under any patent, copyright, or mask work * right to the product. RDA reserves the right to make changes in the * software without notification. RDA also make no representation or * warranty that such application will be suitable for the specified use * without further testing or modification. */ #ifndef _HWREG_ACCESS_H_ #define _HWREG_ACCESS_H_ #include #include "hal_config.h" #ifdef __cplusplus extern "C" { #endif #define EXP2(n) (1 << (n)) typedef uint32_t REG32; typedef uint16_t REG16; typedef uint8_t REG8; typedef uint8_t UINT8; #define REG_BIT(n) (1U << (n)) #define REG_BIT0 (1U << 0) #define REG_BIT1 (1U << 1) #define REG_BIT2 (1U << 2) #define REG_BIT3 (1U << 3) #define REG_BIT4 (1U << 4) #define REG_BIT5 (1U << 5) #define REG_BIT6 (1U << 6) #define REG_BIT7 (1U << 7) #define REG_BIT8 (1U << 8) #define REG_BIT9 (1U << 9) #define REG_BIT10 (1U << 10) #define REG_BIT11 (1U << 11) #define REG_BIT12 (1U << 12) #define REG_BIT13 (1U << 13) #define REG_BIT14 (1U << 14) #define REG_BIT15 (1U << 15) #define REG_BIT16 (1U << 16) #define REG_BIT17 (1U << 17) #define REG_BIT18 (1U << 18) #define REG_BIT19 (1U << 19) #define REG_BIT20 (1U << 20) #define REG_BIT21 (1U << 21) #define REG_BIT22 (1U << 22) #define REG_BIT23 (1U << 23) #define REG_BIT24 (1U << 24) #define REG_BIT25 (1U << 25) #define REG_BIT26 (1U << 26) #define REG_BIT27 (1U << 27) #define REG_BIT28 (1U << 28) #define REG_BIT29 (1U << 29) #define REG_BIT30 (1U << 30) #define REG_BIT31 (1U << 31) // Mask for [hi:lo]. REG_BIT(hi + 1) will cause -Wshift-count-overflow #define REG_BIT_RANGE_MASK(hi, lo) ({ unsigned _h = (hi) + 1; unsigned _hm = (_h >= 32)? 0 : REG_BIT(_h); _hm - REG_BIT(lo); }) #ifdef CONFIG_SOC_8910 #define HAL_SYSIRQ_NUM(irq) ((irq) + 32) #define REG_ADDRESS_FOR_ARM #define REG_ACCESS_ADDRESS(addr) (addr) #endif #ifdef CONFIG_SOC_8811 #define HAL_SYSIRQ_NUM(irq) (irq) #define REG_ADDRESS_FOR_ARM #define REG_ACCESS_ADDRESS(addr) (addr) #endif #ifdef CONFIG_SOC_8850 #define HAL_SYSIRQ_NUM(irq) ((irq) + 32) #define REG_ADDRESS_FOR_ARM #define REG_ACCESS_ADDRESS(addr) (addr) #endif #ifdef __mips__ #define OSI_KSEG0(addr) (((unsigned long)(addr)&0x1fffffff) | 0x80000000) #define OSI_KSEG1(addr) (((unsigned long)(addr)&0x1fffffff) | 0xa0000000) #define OSI_IS_KSEG0(addr) (((unsigned long)(addr)&0xe0000000) == 0x80000000) #define OSI_IS_KSEG1(addr) (((unsigned long)(addr)&0xe0000000) == 0xa0000000) #define MEM_ACCESS_CACHED(addr) ((UINT32 *)OSI_KSEG0(addr)) #define MEM_ACCESS_UNCACHED(addr) ((UINT32 *)OSI_KSEG1(addr)) #endif #ifdef __arm__ #define HAL_READ_CP(...) _HAL_READ_CP(__VA_ARGS__) #define HAL_WRITE_CP(...) _HAL_WRITE_CP(__VA_ARGS__) #define _HAL_READ_CP(cp, CRn, opc1, CRm, opc2) __HAL_READ_CP(cp, CRn, opc1, CRm, opc2) #define _HAL_WRITE_CP(v, cp, CRn, opc1, CRm, opc2) __HAL_WRITE_CP(v, cp, CRn, opc1, CRm, opc2) #define HAL_CP_MIDR 15, c0, 0, c0, 0 // Main ID Register #define HAL_CP_CTR 15, c0, 0, c0, 1 // Cache Type Register #define HAL_CP_TCMTR 15, c0, 0, c0, 2 // TCM Type Register #define HAL_CP_TLBTR 15, c0, 0, c0, 3 // TLB Type Register #define HAL_CP_MPIDR 15, c0, 0, c0, 5 // Multiprocessor Affinity Register #define HAL_CP_PFR0 15, c0, 0, c1, 0 // Processor Feature Register 0 #define HAL_CP_PFR1 15, c0, 0, c1, 1 // Processor Feature Register 1 #define HAL_CP_DFR0 15, c0, 0, c1, 2 // Debug Feature Register 0 #define HAL_CP_AFR0 15, c0, 0, c1, 3 // Auxiliary Feature Register 0 #define HAL_CP_MMFR0 15, c0, 0, c1, 4 // Memory Model Feature Register 0 #define HAL_CP_MMFR1 15, c0, 0, c1, 5 // Memory Model Feature Register 1 #define HAL_CP_MMFR2 15, c0, 0, c1, 6 // Memory Model Feature Register 2 #define HAL_CP_MMFR3 15, c0, 0, c1, 7 // Memory Model Feature Register 3 #define HAL_CP_ISAR0 15, c0, 0, c2, 0 // ISA Feature Register 0 #define HAL_CP_ISAR1 15, c0, 0, c2, 1 // ISA Feature Register 1 #define HAL_CP_ISAR2 15, c0, 0, c2, 2 // ISA Feature Register 2 #define HAL_CP_ISAR3 15, c0, 0, c2, 3 // ISA Feature Register 3 #define HAL_CP_ISAR4 15, c0, 0, c2, 4 // ISA Feature Register 4 #define HAL_CP_ISAR5 15, c0, 0, c0, 5 // ISA Feature Register 5 #define HAL_CP_CCSIDR 15, c0, 1, c0, 0 // Cache Level ID Register #define HAL_CP_CLIDR 15, c0, 1, c0, 1 // Cache Size ID Registers #define HAL_CP_AIDR 15, c0, 1, c0, 7 // Auxiliary ID Register #define HAL_CP_CSSELR 15, c0, 2, c0, 0 // Cache Size Selection Register #define HAL_CP_SCTLR 15, c1, 0, c0, 0 // System Control Register #define HAL_CP_ACTLR 15, c1, 0, c0, 1 // Auxiliary Control Register #define HAL_CP_CPACR 15, c1, 0, c0, 2 // Coprocessor Access Control Register #define HAL_CP_SCR 15, c1, 0, c1, 0 // Secure Configuration Register #define HAL_CP_SDER 15, c1, 0, c1, 1 // Secure Debug Enable Register #define HAL_CP_NSACR 15, c1, 0, c1, 2 // Non-Secure Access Control Register #define HAL_CP_VCR 15, c1, 0, c1, 3 // Virtualization Control Register #define HAL_CP_TTBR0 15, c2, 0, c0, 0 // Translation Table Base Register 0 #define HAL_CP_TTBR1 15, c2, 0, c0, 1 // Translation Table Base Register 1 #define HAL_CP_TTBCR 15, c2, 0, c0, 2 // Translation Table Base Control Register #define HAL_CP_DACR 15, c3, 0, c0, 0 // Domain Access Control Register #define HAL_CP_DFSR 15, c5, 0, c0, 0 // Data Fault Status Register #define HAL_CP_IFSR 15, c5, 0, c0, 1 // Instruction Fault Status Register #define HAL_CP_ADFSR 15, c5, 0, c1, 0 // Auxiliary Data Fault Status Register #define HAL_CP_AIFSR 15, c5, 0, c1, 1 // Auxiliary Instruction Fault Status Register #define HAL_CP_DFAR 15, c6, 0, c0, 0 // Data Fault Address Register #define HAL_CP_IFAR 15, c6, 0, c0, 2 // Instruction Fault Address Register #define HAL_CP_PAR 15, c7, 0, c4, 0 // Physical Address Register #define HAL_CP_ICIALLU 15, c7, 0, c5, 0 // Instruction Cache Invalidate All to PoU #define HAL_CP_ICIMVAU 15, c7, 0, c5, 1 // Instruction Cache Invalidate by MVA to PoU #define HAL_CP_DCIMVAC 15, c7, 0, c6, 1 // Data Cache Invalidate by MVA to PoC #define HAL_CP_DCISW 15, c7, 0, c6, 2 // Data Cache Invalidate by Set/Way #define HAL_CP_DCCMVAC 15, c7, 0, c10, 1 // Data Cache Clean by MVA to PoC #define HAL_CP_DCCSW 15, c7, 0, c10, 2 // Data Cache Clean by Set/Way #define HAL_CP_DCCIMVAC 15, c7, 0, c14, 1 // Data Cache Clean and Invalidate by MVA to PoC #define HAL_CP_DCCISW 15, c7, 0, c14, 2 // Data Cache Clean and Invalidate by Set/Way #define HAL_CP_PRRR 15, c10, 0, c2, 0 // Primary Region Remap Register #define HAL_CP_NMRR 15, c10, 0, c2, 1 // Normal Region Remap Register #define HAL_CP_VBAR 15, c12, 0, c0, 0 // Vector Base Address Register #define HAL_CP_MVBAR 15, c12, 0, c0, 1 // Monitor Vector Base Address Register #define HAL_CP_ISR 15, c12, 0, c1, 0 // Interrupt Status Register #define HAL_CP_VIR 15, c12, 0, c1, 1 // Virtualization Interrupt Register #define HAL_CP_CONTEXT 15, c13, 0, c0, 1 // Context ID Register #define HAL_CP_TPIDRURW 15, c13, 0, c0, 2 // User Read/Write Thread ID Register #define HAL_CP_TPIDRURO 15, c13, 0, c0, 3 // User Read-Only Thread ID Register #define HAL_CP_TPIDRPRW 15, c13, 0, c0, 4 // PL1 only Thread ID Register #define HAL_CP_CBAR 15, c15, 4, c0, 0 // Configuration Base Address #define HAL_CP_TLBHR 15, c15, 5, c0, 0 // TLB Hitmap #define __HAL_READ_CP(cp, CRn, opc1, CRm, opc2) ({ \ uint32_t result; \ asm volatile("MRC p" #cp ", " #opc1 ", %0, " #CRn ", " #CRm ", " #opc2 \ : "=r"(result) \ : \ : "memory"); \ result; \ }) #define __HAL_WRITE_CP(value, cp, CRn, opc1, CRm, opc2) \ do \ { \ asm volatile("MCR p" #cp ", " #opc1 ", %0, " #CRn ", " #CRm ", " #opc2 \ : \ : "r"(value) \ : "memory"); \ } while (0) #endif // Range in [start, end] #define HWP_ADDRESS_RANGE(hwp) (uintptr_t)(hwp), (uintptr_t)(hwp) + sizeof(*(hwp)) - 1 /** * \brief register value by fields */ #define REGT_VAL(type, ...) __REGT_VAL(type, ##__VA_ARGS__) /** * \brief pair of (mask, value) */ #define REGT_MASKVAL(type, ...) __REGT_MASK(type, ##__VA_ARGS__), __REGT_VAL(type, ##__VA_ARGS__) /** * \brief write register fields by register type * * All other fields not listed are write to 0. Now, at most 9 fields are supported. * The return value is the value to be written to register. * * Example: * \code{.cpp} * unsigned val = REGT_FIELD_WRITE(hwp_sysCtrl->sel_clock, REG_SYS_CTRL_SEL_CLOCK_T, * sys_sel_fast, 1, soft_sel_spiflash, 1); * \endcode */ #define REGT_FIELD_WRITE(reg, type, ...) __REGT_FIELD_WRITE(reg, type, ##__VA_ARGS__) /** * \brief change register fields by register type * * Similar to \p REGT_FIELD_WRITE, just all other fields not listed will be kept. * Inside, it is read-modify-write. */ #define REGT_FIELD_CHANGE(reg, type, ...) __REGT_FIELD_CHANGE(reg, type, ##__VA_ARGS__) /** * \brief get register field */ #define REGT_FIELD_GET(reg, type, field) __REGT_FIELD_GET(reg, type, field) /** * \brief write ADI register fields by register type * * Similar to \p REGT_FIELD_WRITE, just the register is ADI register. */ #define REGT_ADI_FIELD_WRITE(reg, type, ...) __REGT_ADI_FIELD_WRITE(reg, type, ##__VA_ARGS__) /** * \brief change ADI register fields by register type * * Similar to \p REGT_FIELD_CHANGE, just the register is ADI register. */ #define REGT_ADI_FIELD_CHANGE(reg, type, ...) __REGT_ADI_FIELD_CHANGE(reg, type, ##__VA_ARGS__) /** * \brief get ADI register field */ #define REGT_ADI_FIELD_GET(reg, type, field) __REGT_ADI_FIELD_GET(reg, type, field) /** * \brief write register fields by a variable * * Similar to \p REGT_FIELD_WRITE, just the second parameter is a variable with * type of the register. * * Example: * \code{.cpp} * REG_SYS_CTRL_SEL_CLOCK_T sel_clock; * unsigned val = REGV_FIELD_WRITE(hwp_sysCtrl->sel_clock, sel_clock, * sys_sel_fast, 1, soft_sel_spiflash, 1); * \endcode */ #define REGV_FIELD_WRITE(reg, var, ...) __REGV_FIELD_WRITE(reg, var, ##__VA_ARGS__) /** * \brief change register fields by a variable * * Similar to \p REGT_FIELD_CHANGE, just the second parameter is a variable with * type of the register. */ #define REGV_FIELD_CHANGE(reg, var, ...) __REGV_FIELD_CHANGE(reg, var, ##__VA_ARGS__) /** * \brief get register field */ #define REGV_FIELD_GET(reg, var, field) __REGV_FIELD_GET(reg, var, field) /** * \brief write ADI register fields by a variable * * Similar to \p REGT_ADI_FIELD_WRITE, just the second parameter is a variable with * type of the register. */ #define REGV_ADI_FIELD_WRITE(reg, var, ...) __REGV_ADI_FIELD_WRITE(reg, var, ##__VA_ARGS__) /** * \brief change ADI register fields by a variable * * Similar to \p REGT_ADI_FIELD_CHANGE, just the second parameter is a variable with * type of the register. */ #define REGV_ADI_FIELD_CHANGE(reg, var, ...) __REGV_ADI_FIELD_CHANGE(reg, var, ##__VA_ARGS__) /** * \brief get register field */ #define REGV_ADI_FIELD_GET(reg, var, field) __REGV_ADI_FIELD_GET(reg, var, field) /** * \brief loop wait register field to meet a condition by register type * * Example: * \code{.cpp} * REGT_WAIT_FIELD_NEZ(hwp_sysCtrl->sel_clock, REG_SYS_CTRL_SEL_CLOCK_T, pll_locked); * \endcode */ #define REGT_WAIT_FIELD_EQ(reg, type, field, expected) _REGT_WAIT_FIELD(reg, type, field, expected, _REG_WAIT_OP_EQ) #define REGT_WAIT_FIELD_NE(reg, type, field, expected) _REGT_WAIT_FIELD(reg, type, field, expected, _REG_WAIT_OP_NE) #define REGT_WAIT_FIELD_GT(reg, type, field, expected) _REGT_WAIT_FIELD(reg, type, field, expected, _REG_WAIT_OP_GT) #define REGT_WAIT_FIELD_GE(reg, type, field, expected) _REGT_WAIT_FIELD(reg, type, field, expected, _REG_WAIT_OP_GE) #define REGT_WAIT_FIELD_LT(reg, type, field, expected) _REGT_WAIT_FIELD(reg, type, field, expected, _REG_WAIT_OP_LT) #define REGT_WAIT_FIELD_LE(reg, type, field, expected) _REGT_WAIT_FIELD(reg, type, field, expected, _REG_WAIT_OP_LE) #define REGT_WAIT_FIELD_EQZ(reg, type, field) REGT_WAIT_FIELD_EQ(reg, type, field, 0) #define REGT_WAIT_FIELD_NEZ(reg, type, field) REGT_WAIT_FIELD_NE(reg, type, field, 0) /** * \brief loop wait ADI register field to meet a condition by register type */ #define REGT_ADI_WAIT_FIELD_EQ(reg, type, field, expected) _REGT_ADI_WAIT_FIELD(reg, type, field, expected, _REG_WAIT_OP_EQ) #define REGT_ADI_WAIT_FIELD_NE(reg, type, field, expected) _REGT_ADI_WAIT_FIELD(reg, type, field, expected, _REG_WAIT_OP_NE) #define REGT_ADI_WAIT_FIELD_GT(reg, type, field, expected) _REGT_ADI_WAIT_FIELD(reg, type, field, expected, _REG_WAIT_OP_GT) #define REGT_ADI_WAIT_FIELD_GE(reg, type, field, expected) _REGT_ADI_WAIT_FIELD(reg, type, field, expected, _REG_WAIT_OP_GE) #define REGT_ADI_WAIT_FIELD_LT(reg, type, field, expected) _REGT_ADI_WAIT_FIELD(reg, type, field, expected, _REG_WAIT_OP_LT) #define REGT_ADI_WAIT_FIELD_LE(reg, type, field, expected) _REGT_ADI_WAIT_FIELD(reg, type, field, expected, _REG_WAIT_OP_LE) #define REGT_ADI_WAIT_FIELD_EQZ(reg, type, field) REGT_ADI_WAIT_FIELD_EQ(reg, type, field, 0) #define REGT_ADI_WAIT_FIELD_NEZ(reg, type, field) REGT_ADI_WAIT_FIELD_NE(reg, type, field, 0) /** * \brief loop wait register field to meet a condition by a variable * * Example: * \code{.cpp} * REG_SYS_CTRL_SEL_CLOCK_T sel_clock; * REG_WAIT_FIELD_NEZ(sel_clock, hwp_sysCtrl->sel_clock, pll_locked); * \endcode */ #define REGV_WAIT_FIELD_EQ(reg, var, field, expected) _REGV_WAIT_FIELD(reg, var, field, expected, _REG_WAIT_OP_EQ) #define REGV_WAIT_FIELD_NE(reg, var, field, expected) _REGV_WAIT_FIELD(reg, var, field, expected, _REG_WAIT_OP_NE) #define REGV_WAIT_FIELD_GT(reg, var, field, expected) _REGV_WAIT_FIELD(reg, var, field, expected, _REG_WAIT_OP_GT) #define REGV_WAIT_FIELD_GE(reg, var, field, expected) _REGV_WAIT_FIELD(reg, var, field, expected, _REG_WAIT_OP_GE) #define REGV_WAIT_FIELD_LT(reg, var, field, expected) _REGV_WAIT_FIELD(reg, var, field, expected, _REG_WAIT_OP_LT) #define REGV_WAIT_FIELD_LE(reg, var, field, expected) _REGV_WAIT_FIELD(reg, var, field, expected, _REG_WAIT_OP_LE) #define REGV_WAIT_FIELD_EQZ(reg, var, field) REGV_WAIT_FIELD_EQ(reg, var, field, 0) #define REGV_WAIT_FIELD_NEZ(reg, var, field) REGV_WAIT_FIELD_NE(reg, var, field, 0) /** * \brief loop wait ADI register field to meet a condition by a variable */ #define REGV_ADI_WAIT_FIELD_EQ(reg, var, field, expected) _REGV_ADI_WAIT_FIELD(reg, var, field, expected, _REG_WAIT_OP_EQ) #define REGV_ADI_WAIT_FIELD_NE(reg, var, field, expected) _REGV_ADI_WAIT_FIELD(reg, var, field, expected, _REG_WAIT_OP_NE) #define REGV_ADI_WAIT_FIELD_GT(reg, var, field, expected) _REGV_ADI_WAIT_FIELD(reg, var, field, expected, _REG_WAIT_OP_GT) #define REGV_ADI_WAIT_FIELD_GE(reg, var, field, expected) _REGV_ADI_WAIT_FIELD(reg, var, field, expected, _REG_WAIT_OP_GE) #define REGV_ADI_WAIT_FIELD_LT(reg, var, field, expected) _REGV_ADI_WAIT_FIELD(reg, var, field, expected, _REG_WAIT_OP_LT) #define REGV_ADI_WAIT_FIELD_LE(reg, var, field, expected) _REGV_ADI_WAIT_FIELD(reg, var, field, expected, _REG_WAIT_OP_LE) #define REGV_ADI_WAIT_FIELD_EQZ(reg, var, field) REGV_ADI_WAIT_FIELD_EQ(reg, var, field, 0) #define REGV_ADI_WAIT_FIELD_NEZ(reg, var, field) REGV_ADI_WAIT_FIELD_NE(reg, var, field, 0) // ============================================================================ // Implementation // ============================================================================ #define _REGT_WAIT_FIELD(reg, type, field, expected, op) \ do \ { \ type var; \ for (;;) \ { \ (var).v = (reg); \ if (op((var).b.field, (expected))) \ break; \ } \ } while (0) #define _REGT_ADI_WAIT_FIELD(reg, type, field, expected, op) \ do \ { \ type var; \ for (;;) \ { \ (var).v = halAdiBusRead(&(reg)); \ if (op((var).b.field, (expected))) \ break; \ } \ } while (0) #define _REGV_WAIT_FIELD(reg, var, field, expected, op) \ do \ { \ for (;;) \ { \ (var).v = (reg); \ if (op((var).b.field, (expected))) \ break; \ } \ } while (0) #define _REGV_ADI_WAIT_FIELD(reg, var, field, expected, op) \ do \ { \ for (;;) \ { \ (var).v = halAdiBusRead(&(reg)); \ if (op((var).b.field, (expected))) \ break; \ } \ } while (0) #define _REG_WAIT_OP_EQ(a, b) ((a) == (b)) #define _REG_WAIT_OP_NE(a, b) ((a) != (b)) #define _REG_WAIT_OP_GT(a, b) ((a) > (b)) #define _REG_WAIT_OP_GE(a, b) ((a) >= (b)) #define _REG_WAIT_OP_LT(a, b) ((a) < (b)) #define _REG_WAIT_OP_LE(a, b) ((a) <= (b)) #define __REGT_FIELD_WRITE(reg, type, ...) ({ \ type _val = {}; \ __REGV_SET(_val, __VA_ARGS__); \ reg = _val.v; \ _val.v; \ }) #define __REGT_FIELD_CHANGE(reg, type, ...) ({ \ type _val = {.v = reg}; \ __REGV_SET(_val, __VA_ARGS__); \ reg = _val.v; \ _val.v; \ }) #define __REGT_FIELD_GET(reg, type, f) ({ \ type _val = {.v = reg}; \ _val.b.f; \ }) #define __REGT_ADI_FIELD_WRITE(reg, type, ...) ({ \ type _val = {}; \ __REGV_SET(_val, __VA_ARGS__); \ halAdiBusWrite(&(reg), _val.v); \ _val.v; \ }) #define __REGT_ADI_FIELD_CHANGE(reg, type, ...) ({ \ type _val = {}; \ __REGV_SET(_val, __VA_ARGS__); \ type _maskoff = {0xffffffff}; \ __REGV_MASKOFF(_maskoff, __VA_ARGS__); \ halAdiBusChange(&(reg), ~_maskoff.v, _val.v); \ }) #define __REGT_ADI_FIELD_GET(reg, type, f) ({ \ type _val = {.v = halAdiBusRead(&(reg))}; \ _val.b.f; \ }) #define __REGV_FIELD_WRITE(reg, var, ...) ({ \ var.v = 0; \ __REGV_SET(var, __VA_ARGS__); \ reg = var.v; \ var.v; \ }) #define __REGV_FIELD_CHANGE(reg, var, ...) ({ \ var.v = reg; \ __REGV_SET(var, __VA_ARGS__); \ reg = var.v; \ var.v; \ }) #define __REGV_FIELD_GET(reg, var, f) ({ \ var.v = reg; \ var.b.f; \ }) #define __REGV_ADI_FIELD_WRITE(reg, var, ...) ({ \ var.v = 0; \ __REGV_SET(var, __VA_ARGS__); \ halAdiBusWrite(&(reg), var.v); \ var.v; \ }) #define __REGV_ADI_FIELD_CHANGE(reg, var, ...) ({ \ var.v = 0xffffffff; \ __REGV_MASKOFF(var, __VA_ARGS__); \ unsigned _maskoff = var.v; \ var.v = 0; \ __REGV_SET(var, __VA_ARGS__); \ unsigned _val = var.v; \ halAdiBusChange(&(reg), ~_maskoff, _val); \ }) #define __REGV_ADI_FIELD_GET(reg, var, f) ({ \ var.v = halAdiBusRead(&(reg)); \ var.b.f; \ }) #define __REGT_MASK(type, ...) ({ type _val = {0xffffffff}; __REGV_MASKOFF(_val, __VA_ARGS__); ~_val.v; }) #define __REGT_VAL(type, ...) ({ type _val = {0}; __REGV_SET(_val, __VA_ARGS__); _val.v; }) #define __REGV_SET_IMP2(count, ...) __REGV_SET_##count(__VA_ARGS__) #define __REGV_SET_IMP1(count, ...) __REGV_SET_IMP2(count, __VA_ARGS__) #define __REGV_SET(...) __REGV_SET_IMP1(OSI_VA_NARGS(__VA_ARGS__), __VA_ARGS__) #define __REGV_MASKOFF_IMP2(count, ...) __REGV_MASKOFF_##count(__VA_ARGS__) #define __REGV_MASKOFF_IMP1(count, ...) __REGV_MASKOFF_IMP2(count, __VA_ARGS__) #define __REGV_MASKOFF(...) __REGV_MASKOFF_IMP1(OSI_VA_NARGS(__VA_ARGS__), __VA_ARGS__) #define __REGV_SET_3(v, f1, v1) ({ v.b.f1 = v1; }) #define __REGV_SET_5(v, f1, v1, ...) ({ v.b.f1 = v1; __REGV_SET_3(v, __VA_ARGS__); }) #define __REGV_SET_7(v, f1, v1, ...) ({ v.b.f1 = v1; __REGV_SET_5(v, __VA_ARGS__); }) #define __REGV_SET_9(v, f1, v1, ...) ({ v.b.f1 = v1; __REGV_SET_7(v, __VA_ARGS__); }) #define __REGV_SET_11(v, f1, v1, ...) ({ v.b.f1 = v1; __REGV_SET_9(v, __VA_ARGS__); }) #define __REGV_SET_13(v, f1, v1, ...) ({ v.b.f1 = v1; __REGV_SET_11(v, __VA_ARGS__); }) #define __REGV_SET_15(v, f1, v1, ...) ({ v.b.f1 = v1; __REGV_SET_13(v, __VA_ARGS__); }) #define __REGV_SET_17(v, f1, v1, ...) ({ v.b.f1 = v1; __REGV_SET_15(v, __VA_ARGS__); }) #define __REGV_SET_19(v, f1, v1, ...) ({ v.b.f1 = v1; __REGV_SET_17(v, __VA_ARGS__); }) #define __REGV_MASKOFF_3(v, f1, v1) ({ v.b.f1 = 0; }) #define __REGV_MASKOFF_5(v, f1, v1, ...) ({ v.b.f1 = 0; __REGV_MASKOFF_3(v, __VA_ARGS__); }) #define __REGV_MASKOFF_7(v, f1, v1, ...) ({ v.b.f1 = 0; __REGV_MASKOFF_5(v, __VA_ARGS__); }) #define __REGV_MASKOFF_9(v, f1, v1, ...) ({ v.b.f1 = 0; __REGV_MASKOFF_7(v, __VA_ARGS__); }) #define __REGV_MASKOFF_11(v, f1, v1, ...) ({ v.b.f1 = 0; __REGV_MASKOFF_9(v, __VA_ARGS__); }) #define __REGV_MASKOFF_13(v, f1, v1, ...) ({ v.b.f1 = 0; __REGV_MASKOFF_11(v, __VA_ARGS__); }) #define __REGV_MASKOFF_15(v, f1, v1, ...) ({ v.b.f1 = 0; __REGV_MASKOFF_13(v, __VA_ARGS__); }) #define __REGV_MASKOFF_17(v, f1, v1, ...) ({ v.b.f1 = 0; __REGV_MASKOFF_15(v, __VA_ARGS__); }) #define __REGV_MASKOFF_19(v, f1, v1, ...) ({ v.b.f1 = 0; __REGV_MASKOFF_17(v, __VA_ARGS__); }) // ============================================================================ // Oboleted // ============================================================================ // hardware registers are defined as union. The template of union is // union { // uint32_t v; // struct { // uint32_t f1 : 1; // uint32_t f2 : 2; // uint32_t f3 : 3; // ...... // } b; // }; // // The following macros are helpers for bit field operations: // * REG_FIELD_GET: read the register, and return the value of specified field. // * REG_WAIT_FIELD_EQ/NE/GT/GE/LT/LE/EQZ/NEZ: wait until the register fields // meet the condition. // * REG_FIELD_MASK: return a mask (1 for the specified fields) of one or more // fields. In the above example, mask for f1 and f3 is 0x00000039 // * REG_FIELD_VALUE: return a value with specified fields, other fields are 0. // * REG_FIELD_MASKVAL: return "mask, value" // * REG_FIELD_CHANGE: change the specified fields, and other fields are // untouched. The changed value is returned // * REG_FIELD_WRITE: write register with specified fields, and other fields // are 0, return the value to be written to register #define REGTYPE_FIELD_GET(type, var, f1) ({ type _var = {(var)}; _var.b.f1; }) #define REGTYPE_FIELD_VAL(type, f1, v1) ({ type _var = {.b={.f1=(v1)}}; _var.v; }) #define REGTYPE_FIELD_MASK(type, f1) ({ type _var = {0xffffffff}; _var.b.f1 = 0; ~_var.v; }) #define REG_FIELD_GET(r, var, f) ({ var.v = r; var.b.f; }) #define REG_WAIT_FIELD_EQ(var, reg, field, expected) _REG_WAIT_FIELD(var, reg, field, expected, _REG_WAIT_OP_EQ) #define REG_WAIT_FIELD_NE(var, reg, field, expected) _REG_WAIT_FIELD(var, reg, field, expected, _REG_WAIT_OP_NE) #define REG_WAIT_FIELD_GT(var, reg, field, expected) _REG_WAIT_FIELD(var, reg, field, expected, _REG_WAIT_OP_GT) #define REG_WAIT_FIELD_GE(var, reg, field, expected) _REG_WAIT_FIELD(var, reg, field, expected, _REG_WAIT_OP_GE) #define REG_WAIT_FIELD_LT(var, reg, field, expected) _REG_WAIT_FIELD(var, reg, field, expected, _REG_WAIT_OP_LT) #define REG_WAIT_FIELD_LE(var, reg, field, expected) _REG_WAIT_FIELD(var, reg, field, expected, _REG_WAIT_OP_LE) #define REG_WAIT_FIELD_EQZ(var, reg, field) REG_WAIT_FIELD_EQ(var, reg, field, 0) #define REG_WAIT_FIELD_NEZ(var, reg, field) REG_WAIT_FIELD_NE(var, reg, field, 0) #define REG_WAIT_COND(cond) \ do \ { \ while (!(cond)) \ ; \ } while (0) #define REG_FIELD_MASK1(var, f1) ({ var.v = 0xffffffff; var.b.f1 = 0; var.v = ~var.v; var.v; }) #define REG_FIELD_MASK2(var, f1, f2) ({ var.v = 0xffffffff; var.b.f1 = 0; var.b.f2 = 0; var.v = ~var.v; var.v; }) #define REG_FIELD_MASK3(var, f1, f2, f3) ({ var.v = 0xffffffff; var.b.f1 = 0; var.b.f2 = 0; var.b.f3 = 0; var.v = ~var.v; var.v; }) #define REG_FIELD_MASK4(var, f1, f2, f3, f4) ({ var.v = 0xffffffff; var.b.f1 = 0; var.b.f2 = 0; var.b.f3 = 0; var.b.f4 = 0; var.v = ~var.v; var.v; }) #define REG_FIELD_MASK5(var, f1, f2, f3, f4, f5) ({ var.v = 0xffffffff; var.b.f1 = 0; var.b.f2 = 0; var.b.f3 = 0; var.b.f4 = 0; var.b.f5 = 0; var.v = ~var.v; var.v; }) #define REG_FIELD_MASK6(var, f1, f2, f3, f4, f5, f6) ({ var.v = 0xffffffff; var.b.f1 = 0; var.b.f2 = 0; var.b.f3 = 0; var.b.f4 = 0; var.b.f5 = 0; var.b.f6 = 0; var.v = ~var.v; var.v; }) #define REG_FIELD_VALUE1(var, f1, v1) ({ var.v = 0; var.b.f1 = v1; var.v; }) #define REG_FIELD_VALUE2(var, f1, v1, f2, v2) ({ var.v = 0; var.b.f1 = v1; var.b.f2 = v2; var.v; }) #define REG_FIELD_VALUE3(var, f1, v1, f2, v2, f3, v3) ({ var.v = 0; var.b.f1 = v1; var.b.f2 = v2; var.b.f3 = v3; var.v; }) #define REG_FIELD_VALUE4(var, f1, v1, f2, v2, f3, v3, f4, v4) ({ var.v = 0; var.b.f1 = v1; var.b.f2 = v2; var.b.f3 = v3; var.b.f4 = v4; var.v; }) #define REG_FIELD_VALUE5(var, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) ({ var.v = 0; var.b.f1 = v1; var.b.f2 = v2; var.b.f3 = v3; var.b.f4 = v4; var.b.f5 = v5; var.v; }) #define REG_FIELD_VALUE6(var, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) ({ var.v = 0; var.b.f1 = v1; var.b.f2 = v2; var.b.f3 = v3; var.b.f4 = v4; var.b.f5 = v5; var.b.f6 = v6; var.v; }) #define REG_FIELD_MASKVAL1(var, f1, v1) REG_FIELD_MASK1(var, f1), REG_FIELD_VALUE1(var, f1, v1) #define REG_FIELD_MASKVAL2(var, f1, v1, f2, v2) REG_FIELD_MASK2(var, f1, f2), REG_FIELD_VALUE2(var, f1, v1, f2, v2) #define REG_FIELD_MASKVAL3(var, f1, v1, f2, v2, f3, v3) REG_FIELD_MASK3(var, f1, f2, f3), REG_FIELD_VALUE3(var, f1, v1, f2, v2, f3, v3) #define REG_FIELD_MASKVAL4(var, f1, v1, f2, v2, f3, v3, f4, v4) REG_FIELD_MASK4(var, f1, f2, f3, f4), REG_FIELD_VALUE4(var, f1, v1, f2, v2, f3, v3, f4, v4) #define REG_FIELD_MASKVAL5(var, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) REG_FIELD_MASK5(var, f1, f2, f3, f4, f5), REG_FIELD_VALUE5(var, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) #define REG_FIELD_MASKVAL6(var, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) REG_FIELD_MASK6(var, f1, f2, f3, f4, f5, f6), REG_FIELD_VALUE6(var, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) #define REG_FIELD_CHANGE1(r, var, f1, v1) ({ var.v = r; var.b.f1 = v1; r = var.v; var.v; }) #define REG_FIELD_CHANGE2(r, var, f1, v1, f2, v2) ({ var.v = r; var.b.f1 = v1; var.b.f2 = v2; r = var.v; var.v; }) #define REG_FIELD_CHANGE3(r, var, f1, v1, f2, v2, f3, v3) ({ var.v = r; var.b.f1 = v1; var.b.f2 = v2; var.b.f3 = v3; r = var.v; var.v; }) #define REG_FIELD_CHANGE4(r, var, f1, v1, f2, v2, f3, v3, f4, v4) ({ var.v = r; var.b.f1 = v1; var.b.f2 = v2; var.b.f3 = v3; var.b.f4 = v4; r = var.v; var.v; }) #define REG_FIELD_CHANGE5(r, var, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) ({ var.v = r; var.b.f1 = v1; var.b.f2 = v2; var.b.f3 = v3; var.b.f4 = v4; var.b.f5 = v5; r = var.v; var.v; }) #define REG_FIELD_CHANGE6(r, var, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) ({ var.v = r; var.b.f1 = v1; var.b.f2 = v2; var.b.f3 = v3; var.b.f4 = v4; var.b.f5 = v5; var.b.f6 = v6; r = var.v; var.v; }) #define REG_FIELD_WRITE1(r, var, f1, v1) ({ var.v = 0; var.b.f1 = v1; r = var.v; var.v; }) #define REG_FIELD_WRITE2(r, var, f1, v1, f2, v2) ({ var.v = 0; var.b.f1 = v1; var.b.f2 = v2; r = var.v; var.v; }) #define REG_FIELD_WRITE3(r, var, f1, v1, f2, v2, f3, v3) ({ var.v = 0; var.b.f1 = v1; var.b.f2 = v2; var.b.f3 = v3; r = var.v; var.v; }) #define REG_FIELD_WRITE4(r, var, f1, v1, f2, v2, f3, v3, f4, v4) ({ var.v = 0; var.b.f1 = v1; var.b.f2 = v2; var.b.f3 = v3; var.b.f4 = v4; r = var.v; var.v; }) #define REG_FIELD_WRITE5(r, var, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) ({ var.v = 0; var.b.f1 = v1; var.b.f2 = v2; var.b.f3 = v3; var.b.f4 = v4; var.b.f5 = v5; r = var.v; var.v; }) #define REG_FIELD_WRITE6(r, var, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) ({ var.v = 0; var.b.f1 = v1; var.b.f2 = v2; var.b.f3 = v3; var.b.f4 = v4; var.b.f5 = v5; var.b.f6 = v6; r = var.v; var.v; }) #define REG_ADI_CHANGE1(r, var, f1, v1) halAdiBusChange(&(r), REG_FIELD_MASKVAL1(var, f1, v1)) #define REG_ADI_CHANGE2(r, var, f1, v1, f2, v2) halAdiBusChange(&(r), REG_FIELD_MASKVAL2(var, f1, v1, f2, v2)) #define REG_ADI_CHANGE3(r, var, f1, v1, f2, v2, f3, v3) halAdiBusChange(&(r), REG_FIELD_MASKVAL3(var, f1, v1, f2, v2, f3, v3)) #define REG_ADI_CHANGE4(r, var, f1, v1, f2, v2, f3, v3, f4, v4) halAdiBusChange(&(r), REG_FIELD_MASKVAL4(var, f1, v1, f2, v2, f3, v3, f4, v4)) #define REG_ADI_CHANGE5(r, var, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) halAdiBusChange(&(r), REG_FIELD_MASKVAL5(var, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5)) #define REG_ADI_CHANGE6(r, var, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) halAdiBusChange(&(r), REG_FIELD_MASKVAL6(var, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6)) #define REG_ADI_WRITE1(r, var, f1, v1) halAdiBusWrite(&(r), REG_FIELD_VALUE1(var, f1, v1)) #define REG_ADI_WRITE2(r, var, f1, v1, f2, v2) halAdiBusWrite(&(r), REG_FIELD_VALUE2(var, f1, v1, f2, v2)) #define REG_ADI_WRITE3(r, var, f1, v1, f2, v2, f3, v3) halAdiBusWrite(&(r), REG_FIELD_VALUE3(var, f1, v1, f2, v2, f3, v3)) #define REG_ADI_WRITE4(r, var, f1, v1, f2, v2, f3, v3, f4, v4) halAdiBusWrite(&(r), REG_FIELD_VALUE4(var, f1, v1, f2, v2, f3, v3, f4, v4)) #define REG_ADI_WRITE5(r, var, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) halAdiBusWrite(&(r), REG_FIELD_VALUE5(var, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5)) #define REG_ADI_WRITE6(r, var, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) halAdiBusWrite(&(r), REG_FIELD_VALUE6(var, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6)) #define REG_ADI_WAIT_FIELD_EQ(var, reg, field, expected) _REG_ADI_WAIT_FIELD(var, reg, field, expected, _REG_WAIT_OP_EQ) #define REG_ADI_WAIT_FIELD_NE(var, reg, field, expected) _REG_ADI_WAIT_FIELD(var, reg, field, expected, _REG_WAIT_OP_NE) #define REG_ADI_WAIT_FIELD_GT(var, reg, field, expected) _REG_ADI_WAIT_FIELD(var, reg, field, expected, _REG_WAIT_OP_GT) #define REG_ADI_WAIT_FIELD_GE(var, reg, field, expected) _REG_ADI_WAIT_FIELD(var, reg, field, expected, _REG_WAIT_OP_GE) #define REG_ADI_WAIT_FIELD_LT(var, reg, field, expected) _REG_ADI_WAIT_FIELD(var, reg, field, expected, _REG_WAIT_OP_LT) #define REG_ADI_WAIT_FIELD_LE(var, reg, field, expected) _REG_ADI_WAIT_FIELD(var, reg, field, expected, _REG_WAIT_OP_LE) #define REG_ADI_WAIT_FIELD_EQZ(var, reg, field) REG_ADI_WAIT_FIELD_EQ(var, reg, field, 0) #define REG_ADI_WAIT_FIELD_NEZ(var, reg, field) REG_ADI_WAIT_FIELD_NE(var, reg, field, 0) #define _REG_WAIT_FIELD(var, reg, field, expected, op) \ do \ { \ for (;;) \ { \ (var).v = (reg); \ if (op((var).b.field, (expected))) \ break; \ } \ } while (0) #define _REG_ADI_WAIT_FIELD(var, reg, field, expected, op) \ do \ { \ for (;;) \ { \ (var).v = halAdiBusRead(&(reg)); \ if (op((var).b.field, (expected))) \ break; \ } \ } while (0) #ifdef __cplusplus } #endif #endif