@web-font-path: "roboto-debian.css";
v2.2.0 (RP2040)
Loading...
Searching...
No Matches
boot_lock.h
/*
* Copyright (c) 2024 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _HARDWARE_BOOT_LOCK_H
#define _HARDWARE_BOOT_LOCK_H
#include "pico.h"
#ifdef __cplusplus
extern "C" {
#endif
// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_HARDWARE_BOOT_LOCK, Enable/disable assertions in the hardware_boot_lock module, type=bool, default=0, group=hardware_boot_lock
#ifndef PARAM_ASSERTIONS_ENABLED_HARDWARE_BOOT_LOCK
#define PARAM_ASSERTIONS_ENABLED_HARDWARE_BOOT_LOCK 0
#endif
#if NUM_BOOT_LOCKS > 0
#include "hardware/sync.h"
#include "hardware/structs/bootram.h"
typedef volatile uint32_t boot_lock_t;
__force_inline static boot_lock_t *boot_lock_instance(uint lock_num) {
invalid_params_if(HARDWARE_BOOT_LOCK, lock_num >= NUM_BOOT_LOCKS);
return (boot_lock_t *) (BOOTRAM_BASE + BOOTRAM_BOOTLOCK0_OFFSET + lock_num * 4);
}
__force_inline static uint boot_lock_get_num(boot_lock_t *lock) {
invalid_params_if(HARDWARE_BOOT_LOCK, (uint) lock < BOOTRAM_BASE + BOOTRAM_BOOTLOCK0_OFFSET ||
(uint) lock >= NUM_BOOT_LOCKS * sizeof(boot_lock_t) + BOOTRAM_BASE + BOOTRAM_BOOTLOCK0_OFFSET ||
((uint) lock - BOOTRAM_BASE + BOOTRAM_BOOTLOCK0_OFFSET) % sizeof(boot_lock_t) != 0);
return (uint) (lock - (boot_lock_t *) (BOOTRAM_BASE + BOOTRAM_BOOTLOCK0_OFFSET));
}
__force_inline static void boot_lock_unsafe_blocking(boot_lock_t *lock) {
// Note we don't do a wfe or anything, because by convention these boot_locks are VERY SHORT LIVED and NEVER BLOCK and run
// with INTERRUPTS disabled (to ensure that)... therefore nothing on our core could be blocking us, so we just need to wait on another core
// anyway which should be finished soon
while (__builtin_expect(!*lock, 0)) { // read from bootlock register (tries to acquire the lock)
tight_loop_contents();
}
__mem_fence_acquire();
}
__force_inline static bool boot_try_lock_unsafe(boot_lock_t *lock) {
if (*lock) {
__mem_fence_acquire();
return true;
}
return false;
}
__force_inline static void boot_unlock_unsafe(boot_lock_t *lock) {
__mem_fence_release();
*lock = 0; // write to bootlock register (release lock)
}
__force_inline static uint32_t boot_lock_blocking(boot_lock_t *lock) {
uint32_t save = save_and_disable_interrupts();
boot_lock_unsafe_blocking(lock);
return save;
}
inline static bool is_boot_locked(boot_lock_t *lock) {
check_hw_size(boot_lock_t, 4);
uint lock_num = boot_lock_get_num(lock);
return 0 != (*(io_ro_32 *) (BOOTRAM_BASE + BOOTRAM_BOOTLOCK_STAT_OFFSET) & (1u << lock_num));
}
__force_inline static void boot_unlock(boot_lock_t *lock, uint32_t saved_irq) {
boot_unlock_unsafe(lock);
restore_interrupts_from_disabled(saved_irq);
}
boot_lock_t *boot_lock_init(uint lock_num);
void boot_locks_reset(void);
#endif
#ifdef __cplusplus
}
#endif
#endif
save_and_disable_interrupts
static __force_inline uint32_t save_and_disable_interrupts(void)
Disable interrupts on the calling core, returning the previous interrupt state.
Definition sync.h:237
__mem_fence_release
static __force_inline void __mem_fence_release(void)
Release a memory fence.
Definition sync.h:189
restore_interrupts_from_disabled
static __force_inline void restore_interrupts_from_disabled(uint32_t status)
Restore interrupts to a specified state on the calling core with restricted transitions.
Definition sync.h:280
__mem_fence_acquire
static __force_inline void __mem_fence_acquire(void)
Acquire a memory fence.
Definition sync.h:173
__force_inline
#define __force_inline
Attribute to force inlining of a function regardless of optimization level.
Definition compiler.h:128
tight_loop_contents
static __force_inline void tight_loop_contents(void)
No-op function for the body of tight loops.
Definition common.h:74
pico.h
sync.h