Loading...
Searching...
No Matches
boot_lock.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef _HARDWARE_BOOT_LOCK_H
8#define _HARDWARE_BOOT_LOCK_H
9
10#include "pico.h"
11
17
18#ifdef __cplusplus
19extern "C" {
20#endif
21
22// 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
23#ifndef PARAM_ASSERTIONS_ENABLED_HARDWARE_BOOT_LOCK
24#define PARAM_ASSERTIONS_ENABLED_HARDWARE_BOOT_LOCK 0
25#endif
26
27#if NUM_BOOT_LOCKS > 0
28#include "hardware/sync.h"
29#include "hardware/structs/bootram.h"
30
34typedef volatile uint32_t boot_lock_t;
35
43 invalid_params_if(HARDWARE_BOOT_LOCK, lock_num >= NUM_BOOT_LOCKS);
44 return (boot_lock_t *) (BOOTRAM_BASE + BOOTRAM_BOOTLOCK0_OFFSET + lock_num * 4);
45}
46
54 invalid_params_if(HARDWARE_BOOT_LOCK, (uint) lock < BOOTRAM_BASE + BOOTRAM_BOOTLOCK0_OFFSET ||
55 (uint) lock >= NUM_BOOT_LOCKS * sizeof(boot_lock_t) + BOOTRAM_BASE + BOOTRAM_BOOTLOCK0_OFFSET ||
56 ((uint) lock - BOOTRAM_BASE + BOOTRAM_BOOTLOCK0_OFFSET) % sizeof(boot_lock_t) != 0);
57 return (uint) (lock - (boot_lock_t *) (BOOTRAM_BASE + BOOTRAM_BOOTLOCK0_OFFSET));
58}
59
66 // Note we don't do a wfe or anything, because by convention these boot_locks are VERY SHORT LIVED and NEVER BLOCK and run
67 // with INTERRUPTS disabled (to ensure that)... therefore nothing on our core could be blocking us, so we just need to wait on another core
68 // anyway which should be finished soon
69 while (__builtin_expect(!*lock, 0)) { // read from bootlock register (tries to acquire the lock)
71 }
73}
74
81 if (*lock) {
83 return true;
84 }
85 return false;
86}
87
95 *lock = 0; // write to bootlock register (release lock)
96}
97
107 uint32_t save = save_and_disable_interrupts();
109 return save;
110}
111
117inline static bool is_boot_locked(boot_lock_t *lock) {
118 check_hw_size(boot_lock_t, 4);
119 uint lock_num = boot_lock_get_num(lock);
120 return 0 != (*(io_ro_32 *) (BOOTRAM_BASE + BOOTRAM_BOOTLOCK_STAT_OFFSET) & (1u << lock_num));
121}
122
133__force_inline static void boot_unlock(boot_lock_t *lock, uint32_t saved_irq) {
134 boot_unlock_unsafe(lock);
136}
137
146boot_lock_t *boot_lock_init(uint lock_num);
147
151void boot_locks_reset(void);
152
153#endif
154
155#ifdef __cplusplus
156}
157#endif
158
159#endif
static __force_inline uint32_t save_and_disable_interrupts(void)
Disable interrupts on the calling core, returning the previous interrupt state.
Definition sync.h:252
static __force_inline void __mem_fence_release(void)
Release a memory fence.
Definition sync.h:204
boot_lock_t * boot_lock_init(uint lock_num)
Initialise a boot lock.
Definition boot_lock.c:17
static bool is_boot_locked(boot_lock_t *lock)
Check to see if a bootlock is currently acquired elsewhere.
Definition boot_lock.h:117
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:295
static __force_inline uint boot_lock_get_num(boot_lock_t *lock)
Get HW Bootlock number from instance.
Definition boot_lock.h:53
static __force_inline bool boot_try_lock_unsafe(boot_lock_t *lock)
try to acquire a boot lock without disabling interrupts (hence unsafe)
Definition boot_lock.h:80
void boot_locks_reset(void)
Release all boot locks.
Definition boot_lock.c:10
static __force_inline void __mem_fence_acquire(void)
Acquire a memory fence.
Definition sync.h:188
volatile uint32_t boot_lock_t
A boot lock identifier.
Definition boot_lock.h:34
static __force_inline void boot_lock_unsafe_blocking(boot_lock_t *lock)
Acquire a boot lock without disabling interrupts (hence unsafe).
Definition boot_lock.h:65
static __force_inline void boot_unlock(boot_lock_t *lock, uint32_t saved_irq)
Release a boot lock safely.
Definition boot_lock.h:133
static __force_inline void boot_unlock_unsafe(boot_lock_t *lock)
Release a boot lock without re-enabling interrupts.
Definition boot_lock.h:93
static __force_inline boot_lock_t * boot_lock_instance(uint lock_num)
Get HW Bootlock instance from number.
Definition boot_lock.h:42
static __force_inline uint32_t boot_lock_blocking(boot_lock_t *lock)
Acquire a boot lock safely.
Definition boot_lock.h:106
#define __force_inline
Attribute to force inlining of a function regardless of optimization level.
Definition compiler.h:128
static __force_inline void tight_loop_contents(void)
No-op function for the body of tight loops.
Definition common.h:79