/* * 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"// 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#ifndefPARAM_ASSERTIONS_ENABLED_HARDWARE_BOOT_LOCK#definePARAM_ASSERTIONS_ENABLED_HARDWARE_BOOT_LOCK0#endif#ifNUM_BOOT_LOCKS>0#include"hardware/sync.h"#include"hardware/structs/bootram.h"/** \brief A boot lock identifier * \ingroup hardware_sync *//* ... */typedefvolatileuint32_tboot_lock_t;/*! \brief Get HW Bootlock instance from number * \ingroup hardware_sync * * \param lock_num Bootlock ID * \return The bootlock instance *//* ... */__force_inlinestaticboot_lock_t*boot_lock_instance(uintlock_num){invalid_params_if(HARDWARE_BOOT_LOCK,lock_num>=NUM_BOOT_LOCKS);return(boot_lock_t*)(BOOTRAM_BASE+BOOTRAM_BOOTLOCK0_OFFSET+lock_num*4);}{ ... }/*! \brief Get HW Bootlock number from instance * \ingroup hardware_sync * * \param lock The Bootlock instance * \return The Bootlock ID *//* ... */__force_inlinestaticuintboot_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));}{ ... }/*! \brief Acquire a boot lock without disabling interrupts (hence unsafe) * \ingroup hardware_sync * * \param lock Bootlock instance *//* ... */__force_inlinestaticvoidboot_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 soonwhile(__builtin_expect(!*lock,0)){// read from bootlock register (tries to acquire the lock)tight_loop_contents();}while (__builtin_expect(!*lock, 0)) { ... }__mem_fence_acquire();}{ ... }/*! \brief try to acquire a boot lock without disabling interrupts (hence unsafe) * \ingroup hardware_sync * * \param lock Bootlock instance *//* ... */__force_inlinestaticboolboot_try_lock_unsafe(boot_lock_t*lock){if(*lock){__mem_fence_acquire();returntrue;}if (*lock) { ... }returnfalse;}{ ... }/*! \brief Release a boot lock without re-enabling interrupts * \ingroup hardware_sync * * \param lock Bootlock instance *//* ... */__force_inlinestaticvoidboot_unlock_unsafe(boot_lock_t*lock){__mem_fence_release();*lock=0;// write to bootlock register (release lock)}{ ... }/*! \brief Acquire a boot lock safely * \ingroup hardware_sync * * This function will disable interrupts prior to acquiring the bootlock * * \param lock Bootlock instance * \return interrupt status to be used when unlocking, to restore to original state *//* ... */__force_inlinestaticuint32_tboot_lock_blocking(boot_lock_t*lock){uint32_tsave=save_and_disable_interrupts();boot_lock_unsafe_blocking(lock);returnsave;}{ ... }/*! \brief Check to see if a bootlock is currently acquired elsewhere. * \ingroup hardware_sync * * \param lock Bootlock instance *//* ... */inlinestaticboolis_boot_locked(boot_lock_t*lock){check_hw_size(boot_lock_t,4);uintlock_num=boot_lock_get_num(lock);return0!=(*(io_ro_32*)(BOOTRAM_BASE+BOOTRAM_BOOTLOCK_STAT_OFFSET)&(1u<<lock_num));}{ ... }/*! \brief Release a boot lock safely * \ingroup hardware_sync * * This function will re-enable interrupts according to the parameters. * * \param lock Bootlock instance * \param saved_irq Return value from the \ref boot_lock_blocking() function. * * \sa boot_lock_blocking() *//* ... */__force_inlinestaticvoidboot_unlock(boot_lock_t*lock,uint32_tsaved_irq){boot_unlock_unsafe(lock);restore_interrupts_from_disabled(saved_irq);}{ ... }/*! \brief Initialise a boot lock * \ingroup hardware_sync * * The boot lock is initially unlocked * * \param lock_num The boot lock number * \return The boot lock instance *//* ... */boot_lock_t*boot_lock_init(uintlock_num);/*! \brief Release all boot locks * \ingroup hardware_sync *//* ... */voidboot_locks_reset(void);/* ... */#endif/* ... */#endif
Details
Show: from
Types: Columns:
All items filtered out
All items filtered out
This file uses the notable symbols shown below. Click anywhere in the file to view more details.