refactor(core): move tsqueue to io layer
What changed, and why it matters
This commit is a pure code reorganization: it moves a small queue utility (tsqueue) from one internal directory to another and updates the include paths in the files that use it. No functionality was changed, no bugs were fixed, and no security behavior was altered.
No security action needed. Treat as routine maintenance/refactoring.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change relocates the timestamped queue module from core/embed/util/tsqueue to core/embed/io/tsqueue. The header include path changes from
Changed components
core/embed/io/ble/stm32/ble.ccore/embed/io/nrf/nrf_internal.hcore/embed/io/nrf/stm32u5/nrf.ccore/embed/io/nrf/stm32u5/nrf_spi.ccore/embed/io/tsqueue/inc/io/tsqueue.hcore/embed/io/tsqueue/tsqueue.ccore/site_scons/models/stm32f4_common.pycore/site_scons/models/stm32u5_common.pyInspect captured patch +262 / −262
diff --git a/core/embed/io/ble/stm32/ble.c b/core/embed/io/ble/stm32/ble.c
index fb734c3e1..fdc05c3a3 100644
--- a/core/embed/io/ble/stm32/ble.c
+++ b/core/embed/io/ble/stm32/ble.c
@@ -27,13 +27,13 @@
#include <io/ble.h>
#include <io/nrf.h>
+#include <io/tsqueue.h>
#include <sec/backup_ram.h>
#include <sec/unit_properties.h>
#include <sys/irq.h>
#include <sys/sysevent_source.h>
#include <sys/systick.h>
#include <sys/systimer.h>
-#include <util/tsqueue.h>
#ifdef USE_POWER_MANAGER
#include <io/power_manager.h>
diff --git a/core/embed/io/nrf/nrf_internal.h b/core/embed/io/nrf/nrf_internal.h
index 5c7add563..4b2dd94f6 100644
--- a/core/embed/io/nrf/nrf_internal.h
+++ b/core/embed/io/nrf/nrf_internal.h
@@ -22,8 +22,8 @@
#include <trezor_types.h>
#include <io/nrf.h>
+#include <io/tsqueue.h>
#include <sys/systimer.h>
-#include <util/tsqueue.h>
#define TX_QUEUE_SIZE (8)
diff --git a/core/embed/io/nrf/stm32u5/nrf.c b/core/embed/io/nrf/stm32u5/nrf.c
index dfcd32e63..b4b0aaab2 100644
--- a/core/embed/io/nrf/stm32u5/nrf.c
+++ b/core/embed/io/nrf/stm32u5/nrf.c
@@ -23,13 +23,13 @@
#include <trezor_rtl.h>
#include <io/nrf.h>
+#include <io/tsqueue.h>
#include <sec/secret_keys.h>
#include <sys/irq.h>
#include <sys/mpu.h>
#include <sys/rng.h>
#include <sys/systick.h>
#include <sys/systimer.h>
-#include <util/tsqueue.h>
#ifdef USE_SUSPEND
#include <sys/suspend.h>
diff --git a/core/embed/io/nrf/stm32u5/nrf_spi.c b/core/embed/io/nrf/stm32u5/nrf_spi.c
index 866ad579e..d611ee21f 100644
--- a/core/embed/io/nrf/stm32u5/nrf_spi.c
+++ b/core/embed/io/nrf/stm32u5/nrf_spi.c
@@ -22,10 +22,10 @@
#include <trezor_bsp.h>
#include <trezor_rtl.h>
+#include <io/tsqueue.h>
#include <sys/irq.h>
#include <sys/mpu.h>
#include <sys/systick.h>
-#include <util/tsqueue.h>
#include "../crc8.h"
#include "../nrf_internal.h"
diff --git a/core/embed/io/tsqueue/inc/io/tsqueue.h b/core/embed/io/tsqueue/inc/io/tsqueue.h
new file mode 100644
index 000000000..653ce7d91
--- /dev/null
+++ b/core/embed/io/tsqueue/inc/io/tsqueue.h
@@ -0,0 +1,67 @@
+/*
+ * This file is part of the Trezor project, https://trezor.io/
+ *
+ * Copyright (c) SatoshiLabs
+ *
+ * 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 3 of the License, 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. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TREZORHAL_TSQUEUE_H
+#define TREZORHAL_TSQUEUE_H
+
+#include <trezor_types.h>
+
+typedef struct {
+ uint8_t *buffer; // Pointer to the data buffer
+ uint16_t len; // Length of data in the buffer
+ int32_t id; // ID of the entry
+ bool used; // Used flag
+ bool aborted; // Aborted flag
+} tsqueue_entry_t;
+
+typedef struct {
+ tsqueue_entry_t *entries; // Array of queue entries
+ uint16_t rix; // Read index
+ uint16_t wix; // Write index
+ uint16_t qlen; // Queue length
+ uint16_t size; // Size of each buffer
+ int32_t next_id; // ID of the next item
+} tsqueue_t;
+
+// Initialize the queue
+void tsqueue_init(tsqueue_t *queue, tsqueue_entry_t *entries,
+ uint8_t *buffer_mem, uint16_t size, uint16_t qlen);
+
+void tsqueue_reset(tsqueue_t *queue);
+
+// Insert data into the queue
+bool tsqueue_enqueue(tsqueue_t *queue, const uint8_t *data, uint16_t len,
+ int32_t *id);
+
+// Read data from the queue
+bool tsqueue_dequeue(tsqueue_t *queue, uint8_t *data, uint16_t max_len,
+ uint16_t *len, int32_t *id);
+
+// Checks if the queue is full
+bool tsqueue_full(tsqueue_t *queue);
+
+// Checks if the queue is empty
+bool tsqueue_empty(tsqueue_t *queue);
+
+// Aborts item in the queue
+// The space in the queue is not freed until the item is attempted to be read
+bool tsqueue_abort(tsqueue_t *queue, int32_t id, uint8_t *data,
+ uint16_t max_len, uint16_t *len);
+
+#endif
diff --git a/core/embed/io/tsqueue/tsqueue.c b/core/embed/io/tsqueue/tsqueue.c
new file mode 100644
index 000000000..4951a4190
--- /dev/null
+++ b/core/embed/io/tsqueue/tsqueue.c
@@ -0,0 +1,187 @@
+/*
+ * This file is part of the Trezor project, https://trezor.io/
+ *
+ * Copyright (c) SatoshiLabs
+ *
+ * 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 3 of the License, 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. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <trezor_rtl.h>
+
+#include <io/tsqueue.h>
+#include <sys/irq.h>
+
+// Initialize the queue
+void tsqueue_init(tsqueue_t *queue, tsqueue_entry_t *entries,
+ uint8_t *buffer_mem, uint16_t size, uint16_t qlen) {
+ irq_key_t key = irq_lock();
+ queue->entries = entries;
+ queue->qlen = qlen;
+ queue->size = size;
+
+ for (int i = 0; i < qlen; i++) {
+ queue->entries[i].buffer = buffer_mem + i * size;
+ }
+
+ tsqueue_reset(queue);
+
+ irq_unlock(key);
+}
+
+static void tsqueue_entry_reset(tsqueue_entry_t *entry, uint32_t data_size) {
+ entry->len = 0;
+ entry->used = 0;
+ entry->aborted = false;
+ entry->id = 0;
+ memset(entry->buffer, 0, data_size);
+}
+
+void tsqueue_reset(tsqueue_t *queue) {
+ irq_key_t key = irq_lock();
+ queue->rix = 0;
+ queue->wix = 0;
+ queue->next_id = 1;
+
+ for (int i = 0; i < queue->qlen; i++) {
+ tsqueue_entry_reset(&queue->entries[i], queue->size);
+ }
+
+ irq_unlock(key);
+}
+
+static int32_t get_next_id(tsqueue_t *queue) {
+ int val = 1;
+ if (queue->next_id < INT32_MAX) {
+ val = queue->next_id;
+ queue->next_id++;
+ } else {
+ queue->next_id = 2;
+ }
+ return val;
+}
+
+bool tsqueue_enqueue(tsqueue_t *queue, const uint8_t *data, uint16_t len,
+ int32_t *id) {
+ irq_key_t key = irq_lock();
+
+ if (queue->entries[queue->wix].used) {
+ // Full queue
+ irq_unlock(key);
+ return false;
+ }
+
+ if (len > queue->size) {
+ irq_unlock(key);
+ return false;
+ }
+
+ memcpy(queue->entries[queue->wix].buffer, data, len);
+ queue->entries[queue->wix].id = get_next_id(queue);
+ queue->entries[queue->wix].len = len;
+ queue->entries[queue->wix].used = true;
+
+ if (id != NULL) {
+ *id = queue->entries[queue->wix].id;
+ }
+ queue->wix = (queue->wix + 1) % queue->qlen;
+
+ irq_unlock(key);
+ return true;
+}
+
+static void tsqueue_discard_aborted(tsqueue_t *queue) {
+ while (queue->entries[queue->rix].aborted) {
+ tsqueue_entry_reset(&queue->entries[queue->rix], queue->size);
+ queue->rix = (queue->rix + 1) % queue->qlen;
+ }
+}
+
+bool tsqueue_dequeue(tsqueue_t *queue, uint8_t *data, uint16_t max_len,
+ uint16_t *len, int32_t *id) {
+ irq_key_t key = irq_lock();
+
+ tsqueue_discard_aborted(queue);
+
+ if (!queue->entries[queue->rix].used) {
+ irq_unlock(key);
+ return false;
+ }
+
+ if (len != NULL) {
+ *len = queue->entries[queue->rix].len;
+ }
+
+ if (id != NULL) {
+ *id = queue->entries[queue->rix].id;
+ }
+
+ memcpy(data, queue->entries[queue->rix].buffer,
+ MIN(queue->entries[queue->rix].len, max_len));
+
+ tsqueue_entry_reset(queue->entries + queue->rix, queue->size);
+ queue->rix = (queue->rix + 1) % queue->qlen;
+
+ tsqueue_discard_aborted(queue);
+
+ irq_unlock(key);
+ return true;
+}
+
+// Check if the queue is full
+bool tsqueue_full(tsqueue_t *queue) {
+ irq_key_t key = irq_lock();
+
+ tsqueue_discard_aborted(queue);
+
+ bool full = queue->entries[queue->wix].used;
+ irq_unlock(key);
+ return full;
+}
+
+bool tsqueue_empty(tsqueue_t *queue) {
+ irq_key_t key = irq_lock();
+
+ tsqueue_discard_aborted(queue);
+
+ bool empty = !queue->entries[queue->rix].used;
+
+ irq_unlock(key);
+
+ return empty;
+}
+
+bool tsqueue_abort(tsqueue_t *queue, int32_t id, uint8_t *data,
+ uint16_t max_len, uint16_t *len) {
+ bool found = false;
+ irq_key_t key = irq_lock();
+
+ for (int i = 0; i < queue->qlen; i++) {
+ if (queue->entries[i].used && queue->entries[i].id == id) {
+ queue->entries[i].aborted = true;
+ if (len != NULL) {
+ *len = queue->entries[i].len;
+ }
+
+ if (data != NULL) {
+ memcpy(data, queue->entries[i].buffer,
+ MIN(queue->entries[i].len, max_len));
+ }
+
+ found = true;
+ }
+ }
+
+ irq_unlock(key);
+ return found;
+}
diff --git a/core/embed/util/tsqueue/inc/util/tsqueue.h b/core/embed/util/tsqueue/inc/util/tsqueue.h
deleted file mode 100644
index 653ce7d91..000000000
--- a/core/embed/util/tsqueue/inc/util/tsqueue.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * This file is part of the Trezor project, https://trezor.io/
- *
- * Copyright (c) SatoshiLabs
- *
- * 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 3 of the License, 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. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TREZORHAL_TSQUEUE_H
-#define TREZORHAL_TSQUEUE_H
-
-#include <trezor_types.h>
-
-typedef struct {
- uint8_t *buffer; // Pointer to the data buffer
- uint16_t len; // Length of data in the buffer
- int32_t id; // ID of the entry
- bool used; // Used flag
- bool aborted; // Aborted flag
-} tsqueue_entry_t;
-
-typedef struct {
- tsqueue_entry_t *entries; // Array of queue entries
- uint16_t rix; // Read index
- uint16_t wix; // Write index
- uint16_t qlen; // Queue length
- uint16_t size; // Size of each buffer
- int32_t next_id; // ID of the next item
-} tsqueue_t;
-
-// Initialize the queue
-void tsqueue_init(tsqueue_t *queue, tsqueue_entry_t *entries,
- uint8_t *buffer_mem, uint16_t size, uint16_t qlen);
-
-void tsqueue_reset(tsqueue_t *queue);
-
-// Insert data into the queue
-bool tsqueue_enqueue(tsqueue_t *queue, const uint8_t *data, uint16_t len,
- int32_t *id);
-
-// Read data from the queue
-bool tsqueue_dequeue(tsqueue_t *queue, uint8_t *data, uint16_t max_len,
- uint16_t *len, int32_t *id);
-
-// Checks if the queue is full
-bool tsqueue_full(tsqueue_t *queue);
-
-// Checks if the queue is empty
-bool tsqueue_empty(tsqueue_t *queue);
-
-// Aborts item in the queue
-// The space in the queue is not freed until the item is attempted to be read
-bool tsqueue_abort(tsqueue_t *queue, int32_t id, uint8_t *data,
- uint16_t max_len, uint16_t *len);
-
-#endif
diff --git a/core/embed/util/tsqueue/tsqueue.c b/core/embed/util/tsqueue/tsqueue.c
deleted file mode 100644
index d0fb408c2..000000000
--- a/core/embed/util/tsqueue/tsqueue.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * This file is part of the Trezor project, https://trezor.io/
- *
- * Copyright (c) SatoshiLabs
- *
- * 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 3 of the License, 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. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <trezor_rtl.h>
-
-#include <sys/irq.h>
-#include <util/tsqueue.h>
-
-// Initialize the queue
-void tsqueue_init(tsqueue_t *queue, tsqueue_entry_t *entries,
- uint8_t *buffer_mem, uint16_t size, uint16_t qlen) {
- irq_key_t key = irq_lock();
- queue->entries = entries;
- queue->qlen = qlen;
- queue->size = size;
-
- for (int i = 0; i < qlen; i++) {
- queue->entries[i].buffer = buffer_mem + i * size;
- }
-
- tsqueue_reset(queue);
-
- irq_unlock(key);
-}
-
-static void tsqueue_entry_reset(tsqueue_entry_t *entry, uint32_t data_size) {
- entry->len = 0;
- entry->used = 0;
- entry->aborted = false;
- entry->id = 0;
- memset(entry->buffer, 0, data_size);
-}
-
-void tsqueue_reset(tsqueue_t *queue) {
- irq_key_t key = irq_lock();
- queue->rix = 0;
- queue->wix = 0;
- queue->next_id = 1;
-
- for (int i = 0; i < queue->qlen; i++) {
- tsqueue_entry_reset(&queue->entries[i], queue->size);
- }
-
- irq_unlock(key);
-}
-
-static int32_t get_next_id(tsqueue_t *queue) {
- int val = 1;
- if (queue->next_id < INT32_MAX) {
- val = queue->next_id;
- queue->next_id++;
- } else {
- queue->next_id = 2;
- }
- return val;
-}
-
-bool tsqueue_enqueue(tsqueue_t *queue, const uint8_t *data, uint16_t len,
- int32_t *id) {
- irq_key_t key = irq_lock();
-
- if (queue->entries[queue->wix].used) {
- // Full queue
- irq_unlock(key);
- return false;
- }
-
- if (len > queue->size) {
- irq_unlock(key);
- return false;
- }
-
- memcpy(queue->entries[queue->wix].buffer, data, len);
- queue->entries[queue->wix].id = get_next_id(queue);
- queue->entries[queue->wix].len = len;
- queue->entries[queue->wix].used = true;
-
- if (id != NULL) {
- *id = queue->entries[queue->wix].id;
- }
- queue->wix = (queue->wix + 1) % queue->qlen;
-
- irq_unlock(key);
- return true;
-}
-
-static void tsqueue_discard_aborted(tsqueue_t *queue) {
- while (queue->entries[queue->rix].aborted) {
- tsqueue_entry_reset(&queue->entries[queue->rix], queue->size);
- queue->rix = (queue->rix + 1) % queue->qlen;
- }
-}
-
-bool tsqueue_dequeue(tsqueue_t *queue, uint8_t *data, uint16_t max_len,
- uint16_t *len, int32_t *id) {
- irq_key_t key = irq_lock();
-
- tsqueue_discard_aborted(queue);
-
- if (!queue->entries[queue->rix].used) {
- irq_unlock(key);
- return false;
- }
-
- if (len != NULL) {
- *len = queue->entries[queue->rix].len;
- }
-
- if (id != NULL) {
- *id = queue->entries[queue->rix].id;
- }
-
- memcpy(data, queue->entries[queue->rix].buffer,
- MIN(queue->entries[queue->rix].len, max_len));
-
- tsqueue_entry_reset(queue->entries + queue->rix, queue->size);
- queue->rix = (queue->rix + 1) % queue->qlen;
-
- tsqueue_discard_aborted(queue);
-
- irq_unlock(key);
- return true;
-}
-
-// Check if the queue is full
-bool tsqueue_full(tsqueue_t *queue) {
- irq_key_t key = irq_lock();
-
- tsqueue_discard_aborted(queue);
-
- bool full = queue->entries[queue->wix].used;
- irq_unlock(key);
- return full;
-}
-
-bool tsqueue_empty(tsqueue_t *queue) {
- irq_key_t key = irq_lock();
-
- tsqueue_discard_aborted(queue);
-
- bool empty = !queue->entries[queue->rix].used;
-
- irq_unlock(key);
-
- return empty;
-}
-
-bool tsqueue_abort(tsqueue_t *queue, int32_t id, uint8_t *data,
- uint16_t max_len, uint16_t *len) {
- bool found = false;
- irq_key_t key = irq_lock();
-
- for (int i = 0; i < queue->qlen; i++) {
- if (queue->entries[i].used && queue->entries[i].id == id) {
- queue->entries[i].aborted = true;
- if (len != NULL) {
- *len = queue->entries[i].len;
- }
-
- if (data != NULL) {
- memcpy(data, queue->entries[i].buffer,
- MIN(queue->entries[i].len, max_len));
- }
-
- found = true;
- }
- }
-
- irq_unlock(key);
- return found;
-}
diff --git a/core/site_scons/models/stm32f4_common.py b/core/site_scons/models/stm32f4_common.py
index 6e8193a25..db8e51d51 100644
--- a/core/site_scons/models/stm32f4_common.py
+++ b/core/site_scons/models/stm32f4_common.py
@@ -12,6 +12,7 @@ def stm32f4_common_files(env, features_wanted, defines, sources, paths):
paths += [
"embed/io/notify/inc",
+ "embed/io/tsqueue/inc",
"embed/sec/monoctr/inc",
"embed/sec/random_delays/inc",
"embed/sec/rng/inc",
@@ -36,7 +37,6 @@ def stm32f4_common_files(env, features_wanted, defines, sources, paths):
"embed/util/flash/inc",
"embed/util/fwutils/inc",
"embed/util/option_bytes/inc",
- "embed/util/tsqueue/inc",
"vendor/micropython/lib/cmsis/inc",
"vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Inc",
"vendor/micropython/lib/stm32lib/CMSIS/STM32F4xx/Include",
@@ -67,6 +67,7 @@ def stm32f4_common_files(env, features_wanted, defines, sources, paths):
sources += [
"embed/io/notify/notify.c",
+ "embed/io/tsqueue/tsqueue.c",
"embed/sec/monoctr/stm32f4/monoctr.c",
"embed/sec/random_delays/stm32/random_delays.c",
"embed/sec/rng/rng_strong.c",
@@ -107,7 +108,6 @@ def stm32f4_common_files(env, features_wanted, defines, sources, paths):
"embed/util/flash/stm32f4/flash_otp.c",
"embed/util/fwutils/fwutils.c",
"embed/util/option_bytes/stm32f4/option_bytes.c",
- "embed/util/tsqueue/tsqueue.c",
]
if "dbg_console" in features_wanted:
diff --git a/core/site_scons/models/stm32u5_common.py b/core/site_scons/models/stm32u5_common.py
index 3b4adb939..9ac455fb1 100644
--- a/core/site_scons/models/stm32u5_common.py
+++ b/core/site_scons/models/stm32u5_common.py
@@ -12,6 +12,7 @@ def stm32u5_common_files(env, features_wanted, defines, sources, paths):
paths += [
"embed/io/notify/inc",
+ "embed/io/tsqueue/inc",
"embed/sec/hash_processor/inc",
"embed/sec/monoctr/inc",
"embed/sec/random_delays/inc",
@@ -39,7 +40,6 @@ def stm32u5_common_files(env, features_wanted, defines, sources, paths):
"embed/util/flash/inc",
"embed/util/fwutils/inc",
"embed/util/option_bytes/inc",
- "embed/util/tsqueue/inc",
"vendor/stm32u5xx_hal_driver/Inc",
"vendor/cmsis_device_u5/Include",
"vendor/cmsis_5/CMSIS/Core/Include",
@@ -89,6 +89,7 @@ def stm32u5_common_files(env, features_wanted, defines, sources, paths):
sources += [
"embed/io/notify/notify.c",
+ "embed/io/tsqueue/tsqueue.c",
"embed/sec/hash_processor/stm32u5/hash_processor.c",
"embed/sec/monoctr/stm32u5/monoctr.c",
"embed/sec/random_delays/stm32/random_delays.c",
@@ -136,7 +137,6 @@ def stm32u5_common_files(env, features_wanted, defines, sources, paths):
"embed/util/flash/stm32u5/flash_otp.c",
"embed/util/fwutils/fwutils.c",
"embed/util/option_bytes/stm32u5/option_bytes.c",
- "embed/util/tsqueue/tsqueue.c",
]
if "dbg_console" in features_wanted:
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.