Add xip window alias macros (#566) (#585)

This commit is contained in:
Graham Sanderson 2021-10-07 08:18:02 -05:00 committed by GitHub
parent 62854f5eff
commit 9319ab11d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -55,6 +55,11 @@ extern "C" {
#define check_hw_layout(type, member, offset) static_assert(offsetof(type, member) == (offset), "hw offset mismatch")
#define check_hw_size(type, size) static_assert(sizeof(type) == (size), "hw size mismatch")
// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_ADDRESS_ALIAS, Enable/disable assertions in memory address aliasing macros, type=bool, default=0, group=hardware_base
#ifndef PARAM_ASSERTIONS_ENABLED_ADDRESS_ALIAS
#define PARAM_ASSERTIONS_ENABLED_ADDRESS_ALIAS 0
#endif
typedef volatile uint32_t io_rw_32;
typedef const volatile uint32_t io_ro_32;
typedef volatile uint32_t io_wo_32;
@ -68,15 +73,35 @@ typedef volatile uint8_t io_wo_8;
typedef volatile uint8_t *const ioptr;
typedef ioptr const const_ioptr;
// Helper method used by hw_alias macros to optionally check input validity
static __force_inline uint32_t hw_alias_check_addr(volatile void *addr) {
uint32_t rc = (uintptr_t)addr;
invalid_params_if(ADDRESS_ALIAS, rc < 0x40000000); // catch likely non HW pointer types
return rc;
}
// Helper method used by xip_alias macros to optionally check input validity
static __force_inline uint32_t xip_alias_check_addr(const void *addr) {
uint32_t rc = (uintptr_t)addr;
valid_params_if(ADDRESS_ALIAS, rc >= XIP_MAIN_BASE && rc < XIP_NOALLOC_BASE);
return rc;
}
// Untyped conversion alias pointer generation macros
#define hw_set_alias_untyped(addr) ((void *)(REG_ALIAS_SET_BITS | (uintptr_t)(addr)))
#define hw_clear_alias_untyped(addr) ((void *)(REG_ALIAS_CLR_BITS | (uintptr_t)(addr)))
#define hw_xor_alias_untyped(addr) ((void *)(REG_ALIAS_XOR_BITS | (uintptr_t)(addr)))
#define hw_set_alias_untyped(addr) ((void *)(REG_ALIAS_SET_BITS | hw_alias_check_addr(addr)))
#define hw_clear_alias_untyped(addr) ((void *)(REG_ALIAS_CLR_BITS | hw_alias_check_addr(addr)))
#define hw_xor_alias_untyped(addr) ((void *)(REG_ALIAS_XOR_BITS | hw_alias_check_addr(addr)))
#define xip_noalloc_alias_untyped(addr) ((void *)(XIP_NOALLOC_BASE | xip_alias_check_addr(addr)))
#define xip_nocache_alias_untyped(addr) ((void *)(XIP_NOCACHE_BASE | xip_alias_check_addr(addr)))
#define xip_nocache_noalloc_alias_untyped(addr) ((void *)(XIP_NOCACHE_NOALLOC_BASE | xip_alias_check_addr(addr)))
// Typed conversion alias pointer generation macros
#define hw_set_alias(p) ((typeof(p))hw_set_alias_untyped(p))
#define hw_clear_alias(p) ((typeof(p))hw_clear_alias_untyped(p))
#define hw_xor_alias(p) ((typeof(p))hw_xor_alias_untyped(p))
#define xip_noalloc_alias(p) ((typeof(p))xip_noalloc_alias_untyped(p))
#define xip_nocache_alias(p) ((typeof(p))xip_nocache_alias_untyped(p))
#define xip_nocache_noalloc_alias(p) ((typeof(p))xip_nocache_noalloc_alias_untyped(p))
/*! \brief Atomically set the specified bits to 1 in a HW register
* \ingroup hardware_base