mirror of
https://github.com/raspberrypi/pico-sdk.git
synced 2025-12-10 07:14:36 +01:00
minor tidying of hardware_rcp header; add an rcp_is_true() that is safe to use on RISC-V too (#2568)
This commit is contained in:
parent
820a33a39f
commit
d32d315624
2 changed files with 130 additions and 112 deletions
|
|
@ -15,15 +15,17 @@
|
|||
*/
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// RCP masks
|
||||
#if !PICO_RP2040
|
||||
// RCP instructions (this header is Arm-only)
|
||||
#if HAS_REDUNDANCY_COPROCESSOR
|
||||
#ifdef __riscv
|
||||
#error "HAS_REDUNDANCY_COPROCESSOR should be false on RISC-V"
|
||||
#endif
|
||||
|
||||
#define rcp_is_true(x) ((x) == RCP_MASK_TRUE)
|
||||
#define RCP_MASK_TRUE _u(0xa500a500)
|
||||
#define RCP_MASK_FALSE _u(0x00c300c3)
|
||||
#define RCP_MASK_INTXOR _u(0x96009600)
|
||||
|
||||
// RCP instructions (these instructions are Arm-only)
|
||||
#if HAS_REDUNDANCY_COPROCESSOR
|
||||
// ----------------------------------------------------------------------------
|
||||
// Macros and inline functions for use in C files
|
||||
#ifndef __ASSEMBLER__
|
||||
|
|
@ -86,6 +88,7 @@ static __rcpinline void rcp_salt_core1_nodelay(uint64_t salt) {
|
|||
|
||||
// Get a 32-bit canary value. `tag` must be a constant expression.
|
||||
#define rcp_canary_get(tag) ({ \
|
||||
static_assert(!((tag) & ~0xffu), "Tag out of range"); \
|
||||
uint32_t __canary_u32; \
|
||||
rcp_asm ( \
|
||||
"mrc p7, #0, %0, c%c1, c%c2, #1\n" \
|
||||
|
|
@ -96,6 +99,7 @@ static __rcpinline void rcp_salt_core1_nodelay(uint64_t salt) {
|
|||
})
|
||||
|
||||
#define rcp_canary_get_nodelay(tag) ({ \
|
||||
static_assert(!((tag) & ~0xffu), "Tag out of range"); \
|
||||
uint32_t __canary_u32; \
|
||||
rcp_asm ( \
|
||||
"mrc2 p7, #0, %0, c%c1, c%c2, #1\n" \
|
||||
|
|
@ -107,6 +111,7 @@ static __rcpinline void rcp_salt_core1_nodelay(uint64_t salt) {
|
|||
|
||||
// Assert that canary matches result of rcp_canary_get with the same tags:
|
||||
#define rcp_canary_check(tag, canary) ({ \
|
||||
static_assert(!((tag) & ~0xffu), "Tag out of range"); \
|
||||
rcp_asm ( \
|
||||
"mcr p7, #0, %0, c%c1, c%c2, #1\n" \
|
||||
: : "r" (canary), \
|
||||
|
|
@ -115,6 +120,7 @@ static __rcpinline void rcp_salt_core1_nodelay(uint64_t salt) {
|
|||
})
|
||||
|
||||
#define rcp_canary_check_nodelay(tag, canary) ({ \
|
||||
static_assert(!((tag) & ~0xffu), "Tag out of range"); \
|
||||
rcp_asm ( \
|
||||
"mcr2 p7, #0, %0, c%c1, c%c2, #1\n" \
|
||||
: : "r" (canary), \
|
||||
|
|
@ -141,6 +147,9 @@ static __rcpinline uint32_t rcp_canary_status_nodelay(void) {
|
|||
// ----------------------------------------------------------------------------
|
||||
// RCP Boolean instructions
|
||||
|
||||
// These instructions assert that all their arguments are valid booleans, in
|
||||
// addition to any other logical conditions
|
||||
|
||||
// Assert b is a valid boolean (0xa500a500u or 0x00c300c3u)
|
||||
static __rcpinline void rcp_bvalid(uint32_t b) {
|
||||
rcp_asm ("mcr p7, #1, %0, c0, c0, #0\n" : : "r" (b));
|
||||
|
|
@ -308,106 +317,8 @@ static __rcpinline __attribute__((noreturn)) void rcp_panic(void) {
|
|||
#else // __ASSEMBLER__
|
||||
#ifndef __riscv
|
||||
|
||||
// Assert b is a valid boolean (0xa500a500u or 0x00c300c3u)
|
||||
.macro rcp_bvalid r
|
||||
mcr p7, #1, \r , c0, c0, #0
|
||||
.endm
|
||||
|
||||
.macro rcp_bvalid_nodelay r
|
||||
mcr2 p7, #1, \r , c0, c0, #0
|
||||
.endm
|
||||
|
||||
// Assert b is true (0xa500a500u)
|
||||
.macro rcp_btrue r
|
||||
mcr p7, #2, \r , c0, c0, #0
|
||||
.endm
|
||||
|
||||
.macro rcp_btrue_nodelay r
|
||||
mcr2 p7, #2, \r , c0, c0, #0
|
||||
.endm
|
||||
|
||||
// Assert b is false (0x00c300c3u)
|
||||
.macro rcp_bfalse r
|
||||
mcr p7, #3, \r , c0, c0, #1
|
||||
.endm
|
||||
|
||||
.macro rcp_bfalse_nodelay r
|
||||
mcr2 p7, #3, \r , c0, c0, #1
|
||||
.endm
|
||||
|
||||
// Assert b0 and b1 are both valid booleans
|
||||
.macro rcp_b2valid b0, b1
|
||||
mcrr p7, #0, \b0 , \b1 , c8
|
||||
.endm
|
||||
|
||||
.macro rcp_b2valid_nodelay b0, b1
|
||||
mcrr2 p7, #0, \b0 , \b1 , c8
|
||||
.endm
|
||||
|
||||
// Assert b0 and b1 are both true
|
||||
.macro rcp_b2and b0, b1
|
||||
mcrr p7, #1, \b0 , \b1 , c0
|
||||
.endm
|
||||
|
||||
.macro rcp_b2and_nodelay b0, b1
|
||||
mcrr2 p7, #1, \b0 , \b1 , c0
|
||||
.endm
|
||||
|
||||
// Assert b0 and b1 are valid, and at least one is true
|
||||
.macro rcp_b2or b0, b1
|
||||
mcrr p7, #2, \b0 , \b1 , c0
|
||||
.endm
|
||||
|
||||
.macro rcp_b2or_nodelay b0, b1
|
||||
mcrr2 p7, #2, \b0 , \b1 , c0
|
||||
.endm
|
||||
|
||||
// Assert (b ^ mask) is a valid boolean
|
||||
.macro rcp_bxorvalid b, mask
|
||||
mcrr p7, #3, \b , \mask , c8
|
||||
.endm
|
||||
|
||||
.macro rcp_bxorvalid_nodelay b, mask
|
||||
mcrr2 p7, #3, \b , \mask , c8
|
||||
.endm
|
||||
|
||||
// Assert (b ^ mask) is true
|
||||
.macro rcp_bxortrue b, mask
|
||||
mcrr p7, #4, \b , \mask , c0
|
||||
.endm
|
||||
|
||||
.macro rcp_bxortrue_nodelay b, mask
|
||||
mcrr2 p7, #4, \b , \mask , c0
|
||||
.endm
|
||||
|
||||
// Assert (b ^ mask) is false
|
||||
.macro rcp_bxorfalse b, mask
|
||||
mcrr p7, #5, \b , \mask , c8
|
||||
.endm
|
||||
|
||||
.macro rcp_bxorfalse_nodelay b, mask
|
||||
mcrr2 p7, #5, \b , \mask , c8
|
||||
.endm
|
||||
|
||||
// Assert (x ^ parity) == 0x96009600u
|
||||
.macro rcp_ivalid x, parity
|
||||
mcrr p7, #6, \x , \parity , c8
|
||||
.endm
|
||||
|
||||
.macro rcp_ivalid_nodelay x, parity
|
||||
mcrr2 p7, #6, \x , \parity , c8
|
||||
.endm
|
||||
|
||||
// Assert x == y
|
||||
.macro rcp_iequal x, y
|
||||
mcrr p7, #7, \x , \y , c0
|
||||
.endm
|
||||
|
||||
.macro rcp_iequal_nodelay x, y
|
||||
mcrr2 p7, #7, \x , \y , c0
|
||||
.endm
|
||||
|
||||
// They call this "metaprogramming" I think
|
||||
// Meta-macro for evaluating assembler constant expressions and encoding as
|
||||
// coprocessor register pairs:
|
||||
.macro rcp_switch_u8_to_ch_cl macro_name, x, args:vararg
|
||||
.if (\x) == 0
|
||||
\macro_name c0, c0, \args
|
||||
|
|
@ -926,6 +837,114 @@ static __rcpinline __attribute__((noreturn)) void rcp_panic(void) {
|
|||
.endif
|
||||
.endm
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// RCP Boolean instructions
|
||||
|
||||
// Assert b is a valid boolean (0xa500a500u or 0x00c300c3u)
|
||||
.macro rcp_bvalid r
|
||||
mcr p7, #1, \r , c0, c0, #0
|
||||
.endm
|
||||
|
||||
.macro rcp_bvalid_nodelay r
|
||||
mcr2 p7, #1, \r , c0, c0, #0
|
||||
.endm
|
||||
|
||||
// Assert b is true (0xa500a500u)
|
||||
.macro rcp_btrue r
|
||||
mcr p7, #2, \r , c0, c0, #0
|
||||
.endm
|
||||
|
||||
.macro rcp_btrue_nodelay r
|
||||
mcr2 p7, #2, \r , c0, c0, #0
|
||||
.endm
|
||||
|
||||
// Assert b is false (0x00c300c3u)
|
||||
.macro rcp_bfalse r
|
||||
mcr p7, #3, \r , c0, c0, #1
|
||||
.endm
|
||||
|
||||
.macro rcp_bfalse_nodelay r
|
||||
mcr2 p7, #3, \r , c0, c0, #1
|
||||
.endm
|
||||
|
||||
// Assert b0 and b1 are both valid booleans
|
||||
.macro rcp_b2valid b0, b1
|
||||
mcrr p7, #0, \b0 , \b1 , c8
|
||||
.endm
|
||||
|
||||
.macro rcp_b2valid_nodelay b0, b1
|
||||
mcrr2 p7, #0, \b0 , \b1 , c8
|
||||
.endm
|
||||
|
||||
// Assert b0 and b1 are both true
|
||||
.macro rcp_b2and b0, b1
|
||||
mcrr p7, #1, \b0 , \b1 , c0
|
||||
.endm
|
||||
|
||||
.macro rcp_b2and_nodelay b0, b1
|
||||
mcrr2 p7, #1, \b0 , \b1 , c0
|
||||
.endm
|
||||
|
||||
// Assert b0 and b1 are valid, and at least one is true
|
||||
.macro rcp_b2or b0, b1
|
||||
mcrr p7, #2, \b0 , \b1 , c0
|
||||
.endm
|
||||
|
||||
.macro rcp_b2or_nodelay b0, b1
|
||||
mcrr2 p7, #2, \b0 , \b1 , c0
|
||||
.endm
|
||||
|
||||
// Assert (b ^ mask) is a valid boolean
|
||||
.macro rcp_bxorvalid b, mask
|
||||
mcrr p7, #3, \b , \mask , c8
|
||||
.endm
|
||||
|
||||
.macro rcp_bxorvalid_nodelay b, mask
|
||||
mcrr2 p7, #3, \b , \mask , c8
|
||||
.endm
|
||||
|
||||
// Assert (b ^ mask) is true
|
||||
.macro rcp_bxortrue b, mask
|
||||
mcrr p7, #4, \b , \mask , c0
|
||||
.endm
|
||||
|
||||
.macro rcp_bxortrue_nodelay b, mask
|
||||
mcrr2 p7, #4, \b , \mask , c0
|
||||
.endm
|
||||
|
||||
// Assert (b ^ mask) is false
|
||||
.macro rcp_bxorfalse b, mask
|
||||
mcrr p7, #5, \b , \mask , c8
|
||||
.endm
|
||||
|
||||
.macro rcp_bxorfalse_nodelay b, mask
|
||||
mcrr2 p7, #5, \b , \mask , c8
|
||||
.endm
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// RCP Integer instructions
|
||||
|
||||
// Assert (x ^ parity) == 0x96009600u
|
||||
.macro rcp_ivalid x, parity
|
||||
mcrr p7, #6, \x , \parity , c8
|
||||
.endm
|
||||
|
||||
.macro rcp_ivalid_nodelay x, parity
|
||||
mcrr2 p7, #6, \x , \parity , c8
|
||||
.endm
|
||||
|
||||
// Assert x == y
|
||||
.macro rcp_iequal x, y
|
||||
mcrr p7, #7, \x , \y , c0
|
||||
.endm
|
||||
|
||||
.macro rcp_iequal_nodelay x, y
|
||||
mcrr2 p7, #7, \x , \y , c0
|
||||
.endm
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// RCP Sequence count instructions
|
||||
|
||||
// Directly write 8-bit constant expression cnt to the sequence counter.
|
||||
.macro rcp_count_set_impl h, l
|
||||
mcr p7, #4, r0, \h , \l , #0
|
||||
|
|
@ -957,20 +976,20 @@ rcp_switch_u8_to_ch_cl rcp_count_check_impl, \cnt
|
|||
rcp_switch_u8_to_ch_cl rcp_count_check_nodelay_impl, \cnt
|
||||
.endm
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// RCP Canary instructions
|
||||
|
||||
// Get a 32-bit canary value. `tag` must be a constant expression.
|
||||
.macro rcp_canary_get_impl h, l, x
|
||||
mrc p7, #0, \x, \h, \l, #1
|
||||
.endm
|
||||
|
||||
.macro rcp_canary_get x, tag
|
||||
rcp_switch_u8_to_ch_cl rcp_canary_get_impl \tag, \x
|
||||
.endm
|
||||
|
||||
// Get a 32-bit canary value. `tag` must be a constant expression.
|
||||
.macro rcp_canary_get_nodelay_impl h, l, x
|
||||
mrc2 p7, #0, \x, \h, \l, #1
|
||||
.endm
|
||||
|
||||
.macro rcp_canary_get_nodelay x, tag
|
||||
rcp_switch_u8_to_ch_cl rcp_canary_get_nodelay_impl \tag, \x
|
||||
.endm
|
||||
|
|
@ -979,7 +998,6 @@ rcp_switch_u8_to_ch_cl rcp_canary_get_nodelay_impl \tag, \x
|
|||
.macro rcp_canary_check_impl h, l, x
|
||||
mcr p7, #0, \x, \h, \l, #1
|
||||
.endm
|
||||
|
||||
.macro rcp_canary_check x, tag
|
||||
rcp_switch_u8_to_ch_cl rcp_canary_check_impl \tag, \x
|
||||
.endm
|
||||
|
|
@ -987,7 +1005,6 @@ rcp_switch_u8_to_ch_cl rcp_canary_check_impl \tag, \x
|
|||
.macro rcp_canary_check_nodelay_impl h, l, x
|
||||
mcr2 p7, #0, \x, \h, \l, #1
|
||||
.endm
|
||||
|
||||
.macro rcp_canary_check_nodelay x, tag
|
||||
rcp_switch_u8_to_ch_cl rcp_canary_check_nodelay_impl \tag, \x
|
||||
.endm
|
||||
|
|
@ -996,13 +1013,14 @@ rcp_switch_u8_to_ch_cl rcp_canary_check_nodelay_impl \tag, \x
|
|||
cdp p7, #0, c0, c0, c0, #1
|
||||
.endm
|
||||
|
||||
#endif // HAS_REDUNDANCY_COPROCESSOR
|
||||
#endif // !PICO_RP2040
|
||||
#endif // !__riscv
|
||||
#endif // __ASSEMBLER__
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#define rcp_is_true(x) ((int32_t)(x) < 0)
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ int rom_pick_ab_update_partition(uint32_t *workarea_base, uint32_t workarea_size
|
|||
|
||||
int rc = rom_pick_ab_partition((uint8_t*)workarea_base, workarea_size, partition_a_num, flash_update_base);
|
||||
|
||||
if (IMAGE_DEF_VERIFIED(workarea_base) != RCP_MASK_TRUE) {
|
||||
if (!rcp_is_true(IMAGE_DEF_VERIFIED(workarea_base))) {
|
||||
// Chosen partition failed verification
|
||||
return BOOTROM_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue