From b9945de4905c55afcececca4e8f1c7e8c24d46be Mon Sep 17 00:00:00 2001 From: Martin Ling Date: Mon, 16 Dec 2024 18:47:49 +0000 Subject: [PATCH 1/3] Add a shim header to support locking without ldrex/strex. Required to allow the USB queue code to be built for the M0. --- firmware/common/locking.h | 49 +++++++++++++++++++++++++++++++++++++ firmware/common/usb_queue.c | 18 ++++++++------ 2 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 firmware/common/locking.h diff --git a/firmware/common/locking.h b/firmware/common/locking.h new file mode 100644 index 000000000..80fbf12f0 --- /dev/null +++ b/firmware/common/locking.h @@ -0,0 +1,49 @@ +/* + * Copyright 2024 Great Scott Gadgets + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __LOCKING_H__ +#define __LOCKING_H__ + +#include + +#include + +// Use ldrex and strex directly if available. +// Otherwise, disable interrupts to ensure exclusivity. +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) + #define load_exclusive __ldrex + #define store_exclusive __strex +#else +static inline uint32_t load_exclusive(volatile uint32_t* addr) +{ + __disable_irq(); + return *addr; +} + +static inline uint32_t store_exclusive(uint32_t val, volatile uint32_t* addr) +{ + *addr = val; + __enable_irq(); + return 0; +} +#endif + +#endif /* __LOCKING_H__ */ diff --git a/firmware/common/usb_queue.c b/firmware/common/usb_queue.c index 5d19089ee..a4cab94a0 100644 --- a/firmware/common/usb_queue.c +++ b/firmware/common/usb_queue.c @@ -27,8 +27,8 @@ #include #include -#include +#include "locking.h" #include "usb.h" #include "usb_queue.h" @@ -73,10 +73,10 @@ static usb_transfer_t* allocate_transfer(usb_queue_t* const queue) } do { - transfer = (void*) __ldrex((uint32_t*) &queue->free_transfers); - aborted = - __strex((uint32_t) transfer->next, - (uint32_t*) &queue->free_transfers); + transfer = (void*) load_exclusive((uint32_t*) &queue->free_transfers); + aborted = store_exclusive( + (uint32_t) transfer->next, + (uint32_t*) &queue->free_transfers); } while (aborted); transfer->next = NULL; return transfer; @@ -88,9 +88,11 @@ static void free_transfer(usb_transfer_t* const transfer) usb_queue_t* const queue = transfer->queue; bool aborted; do { - transfer->next = (void*) __ldrex((uint32_t*) &queue->free_transfers); - aborted = - __strex((uint32_t) transfer, (uint32_t*) &queue->free_transfers); + transfer->next = + (void*) load_exclusive((uint32_t*) &queue->free_transfers); + aborted = store_exclusive( + (uint32_t) transfer, + (uint32_t*) &queue->free_transfers); } while (aborted); } From a272e97fdae778232ba7318242b7a73e8ff7e5f3 Mon Sep 17 00:00:00 2001 From: Martin Ling Date: Mon, 16 Dec 2024 21:14:16 +0000 Subject: [PATCH 2/3] Include nvic.h via the dispatch headers. --- firmware/common/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/common/usb.c b/firmware/common/usb.c index 60a2982ad..acac63897 100644 --- a/firmware/common/usb.c +++ b/firmware/common/usb.c @@ -29,7 +29,7 @@ #include "usb_standard_request.h" #include -#include +#include #include #include From f3e7d10d076bf53516fcb9a2aa11b00a01ed3bb6 Mon Sep 17 00:00:00 2001 From: Martin Ling Date: Mon, 16 Dec 2024 21:19:12 +0000 Subject: [PATCH 3/3] Add comment about constraints on locking primitives. --- firmware/common/locking.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/firmware/common/locking.h b/firmware/common/locking.h index 80fbf12f0..392b689de 100644 --- a/firmware/common/locking.h +++ b/firmware/common/locking.h @@ -26,6 +26,12 @@ #include +/* Primitives for implementing locking. + * + * Must always be used in a pair, with a call to load_exclusive being + * followed immediately or near-immediately by a call to store_exclusive(). + * Failure to observe this rule may lead to undefined results. */ + // Use ldrex and strex directly if available. // Otherwise, disable interrupts to ensure exclusivity. #if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)