Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/host/hardware_sync/include/hardware/sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,6 @@ extern "C" {

void __sev();

void __wev();

void __wfi();

void __wfe();
Expand Down
35 changes: 28 additions & 7 deletions src/host/hardware_sync/sync_core0_only.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,23 +93,44 @@ void PICO_WEAK_FUNCTION_IMPL_NAME(spin_unlock)(spin_lock_t *lock, uint32_t saved
spin_unlock_unsafe(lock);
}

PICO_WEAK_FUNCTION_DEF(__sev)
// These are defined on ARM hosts, but don't do what we want for the host
// since this is a simulated build.

#if PICO_C_COMPILER_IS_GNU || !__has_builtin(__sev)
#define __sev_c __sev
#else
#pragma redefine_extname __sev_c __sev
#endif

#if PICO_C_COMPILER_IS_GNU || !__has_builtin(__wfi)
#define __wfi_c __wfi
#else
#pragma redefine_extname __wfi_c __wfi
#endif

#if PICO_C_COMPILER_IS_GNU || !__has_builtin(__wfe)
#define __wfe_c __wfe
#else
#pragma redefine_extname __wfe_c __wfe
#endif

PICO_WEAK_FUNCTION_DEF(__sev_c)

volatile bool event_fired;

void PICO_WEAK_FUNCTION_IMPL_NAME(__sev)() {
void PICO_WEAK_FUNCTION_IMPL_NAME(__sev_c)() {
event_fired = true;
}

PICO_WEAK_FUNCTION_DEF(__wfi)
PICO_WEAK_FUNCTION_DEF(__wfi_c)

void PICO_WEAK_FUNCTION_IMPL_NAME(__wfi)() {
void PICO_WEAK_FUNCTION_IMPL_NAME(__wfi_c)() {
panic("Can't wait on irq for host core0 only implementation");
}

PICO_WEAK_FUNCTION_DEF(__wfe)
PICO_WEAK_FUNCTION_DEF(__wfe_c)

void PICO_WEAK_FUNCTION_IMPL_NAME(__wfe)() {
void PICO_WEAK_FUNCTION_IMPL_NAME(__wfe_c)() {
while (!event_fired) tight_loop_contents();
}

Expand Down Expand Up @@ -146,4 +167,4 @@ int PICO_WEAK_FUNCTION_IMPL_NAME(spin_lock_claim_unused)(bool required) {
PICO_WEAK_FUNCTION_DEF(spin_lock_num)
uint PICO_WEAK_FUNCTION_IMPL_NAME(spin_lock_num)(spin_lock_t *lock) {
return 0;
}
}
4 changes: 2 additions & 2 deletions src/rp2_common/hardware_exception/exception.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ static inline exception_handler_t *get_exception_table(void) {
static void set_raw_exception_handler_and_restore_interrupts(enum exception_number num, exception_handler_t handler, uint32_t save) {
// update vtable (vtable_handler may be same or updated depending on cases, but we do it anyway for compactness)
get_exception_table()[num] = handler;
__dmb();
__DMB();
restore_interrupts_from_disabled(save);
}
#endif
Expand Down Expand Up @@ -108,4 +108,4 @@ uint exception_get_priority(uint num) {
}
return PICO_LOWEST_EXCEPTION_PRIORITY;
}
#endif
#endif
4 changes: 2 additions & 2 deletions src/rp2_common/hardware_irq/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ void irq_set_pending(uint num) {
static void set_raw_irq_handler_and_unlock(uint num, irq_handler_t handler, uint32_t save) {
// update vtable (vtable_handler may be same or updated depending on cases, but we do it anyway for compactness)
get_vtable()[VTABLE_FIRST_IRQ + num] = handler;
__dmb();
__DMB();
spin_unlock(spin_lock_instance(PICO_SPINLOCK_ID_IRQ), save);
}
#endif
Expand Down Expand Up @@ -498,7 +498,7 @@ void irq_remove_handler(uint num, irq_handler_t handler) {
// Note that a irq handler chain is local to our own core, so we don't need to worry about the other core
bool was_enabled = irq_is_enabled(num);
irq_set_enabled(num, false);
__dmb();
__DMB();

// It is possible we are being called while an IRQ for this chain is already in progress.
// The issue we have here is that we must not free a slot that is currently being executed, because
Expand Down
38 changes: 33 additions & 5 deletions src/rp2_common/hardware_sync/include/hardware/sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,19 @@ extern "C" {
#endif
#endif

#if (__ARM_ACLE >= 200)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kilograham I imagine this will be true for most compilers. Would you like an escape-hatch to make this branch testable?

// If the compiler offers arm_acle.h, don't try to re-define symbols from
// the header.
#include <arm_acle.h>
#else

/*! \brief Insert a NOP instruction in to the code path.
* \ingroup hardware_sync
*
* NOP does nothing for one cycle. On RP2350 Arm binaries this is forced to be
* a 32-bit instruction to avoid dual-issue of NOPs.
*/
#if !__has_builtin(__nop)
__force_inline static void __nop(void) {
#if !__ARM_ARCH_6M__
#ifdef __riscv
Expand All @@ -79,6 +86,7 @@ __force_inline static void __nop(void) {
__asm volatile ("nop");
#endif
}
#endif


/*! \brief Insert a SEV instruction in to the code path.
Expand Down Expand Up @@ -129,13 +137,15 @@ __force_inline static void __wfi(void) {
* The DMB (data memory barrier) acts as a memory barrier, all memory accesses prior to this
* instruction will be observed before any explicit access after the instruction.
*/
__force_inline static void __dmb(void) {
#if !__has_builtin(__dmb)
__force_inline static void __dmb(unsigned int) {
#ifdef __riscv
__asm volatile ("fence rw, rw" : : : "memory");
#else
pico_default_asm_volatile ("dmb" : : : "memory");
#endif
}
#endif

/*! \brief Insert a DSB instruction in to the code path.
* \ingroup hardware_sync
Expand All @@ -144,13 +154,15 @@ __force_inline static void __dmb(void) {
* memory barrier (DMB). The DSB operation completes when all explicit memory
* accesses before this instruction complete.
*/
__force_inline static void __dsb(void) {
#if !__has_builtin(__dsb)
__force_inline static void __dsb(unsigned int) {
#ifdef __riscv
__asm volatile ("fence rw, rw" : : : "memory");
#else
pico_default_asm_volatile ("dsb" : : : "memory");
#endif
}
#endif

/*! \brief Insert a ISB instruction in to the code path.
* \ingroup hardware_sync
Expand All @@ -159,13 +171,29 @@ __force_inline static void __dsb(void) {
* so that all instructions following the ISB are fetched from cache or memory again, after
* the ISB instruction has been completed.
*/
__force_inline static void __isb(void) {
#if !__has_builtin(__isb)
__force_inline static void __isb(unsigned int) {
#ifdef __riscv
__asm volatile ("fence.i" : : : "memory");
#else
pico_default_asm_volatile("isb" ::: "memory");
#endif
}
#endif

#endif /* (__ARM_ACLE >= 200) */

#ifndef __DMB
#define __DMB() __dmb(0xf)
#endif

#ifndef __DSB
#define __DSB() __dsb(0xf)
#endif

#ifndef __ISB
#define __ISB() __isb(0xf)
#endif

/*! \brief Acquire a memory fence
* \ingroup hardware_sync
Expand All @@ -174,7 +202,7 @@ __force_inline static void __mem_fence_acquire(void) {
// the original code below makes it hard for us to be included from C++ via a header
// which itself is in an extern "C", so just use __dmb instead, which is what
// is required on Cortex M0+
__dmb();
__DMB();
//#ifndef __cplusplus
// atomic_thread_fence(memory_order_acquire);
//#else
Expand All @@ -190,7 +218,7 @@ __force_inline static void __mem_fence_release(void) {
// the original code below makes it hard for us to be included from C++ via a header
// which itself is in an extern "C", so just use __dmb instead, which is what
// is required on Cortex M0+
__dmb();
__DMB();
//#ifndef __cplusplus
// atomic_thread_fence(memory_order_release);
//#else
Expand Down
2 changes: 1 addition & 1 deletion src/rp2_common/hardware_xip_cache/xip_cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ typedef enum {
#endif

// Used to ensure subsequent accesses observe the new state of the maintained cache lines
#define __post_maintenance_barrier() do {__dsb(); __isb();} while (0)
#define __post_maintenance_barrier() do {__DSB(); __ISB();} while (0)

// All functions in this file are marked non-flash, even though they themselves may be executed
// safely from flash, because they are likely to be called during a flash programming operation
Expand Down