|
From: openocd-gerrit <ope...@us...> - 2026-05-30 18:13:50
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 56d91e42e30585358a03e9f31c0a9f4253fb3f3c (commit)
from f92f577cc0dcc14c63ff31fd7bd5144b3120443b (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 56d91e42e30585358a03e9f31c0a9f4253fb3f3c
Author: hhoang308 <huy...@gm...>
Date: Fri Apr 10 14:25:43 2026 +0700
target/rtt: support 64-bit targets by using dynamic offsets
The current RTT implementation hardcodes the channel structure size to
24 bytes and uses fixed offsets for control block members. This conforms
to the ILP32 (32-bit) layout but fails on LP64 (64-bit) targets such as
RISC-V 64-bit or AArch64.
On 64-bit targets:
- Pointers are 8 bytes, increasing the channel struct size to 32 bytes.
- Member offsets are shifted due to alignment.
- Critically, the 'read_pos' offset moves from 0x10 (32-bit) to 0x18
(64-bit).
The existing code writes to offset 0x10 to update the read position. On
a 64-bit target, offset 0x10 corresponds to 'SizeOfBuffer'. This
overwrites the buffer size with the read position value, causing memory
corruption and immediate firmware crashes (boot loops).
This patch introduces a dynamic parameter structure that selects the
correct offsets and sizes at runtime based on 'target->address_bits'.
It has been verified on a RISC-V 64-bit target running Zephyr RTOS.
Change-Id: If839cb531042f4e6f135743462be932ac881ab4c
Signed-off-by: hhoang308 <huy...@gm...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9396
Reviewed-by: Antonio Borneo <bor...@gm...>
Reviewed-by: zapb <de...@za...>
Tested-by: jenkins
diff --git a/src/rtt/rtt.h b/src/rtt/rtt.h
index d84fdb40b..b716dfff9 100644
--- a/src/rtt/rtt.h
+++ b/src/rtt/rtt.h
@@ -21,8 +21,11 @@
/* Control block size in bytes. */
#define RTT_CB_SIZE (RTT_CB_MAX_ID_LENGTH + 2 * sizeof(uint32_t))
-/* Channel structure size in bytes. */
-#define RTT_CHANNEL_SIZE 24
+/* Channel structure size in bytes (32-bit architecture). */
+#define RTT_CHANNEL_SIZE_32 24
+
+/* Channel structure size in bytes (64-bit architecture). */
+#define RTT_CHANNEL_SIZE_64 32
/* Minimal channel buffer size in bytes. */
#define RTT_CHANNEL_BUFFER_MIN_SIZE 2
@@ -44,9 +47,9 @@ struct rtt_channel {
/** Channel structure address on the target. */
target_addr_t address;
/** Channel name address on the target. */
- uint32_t name_addr;
+ target_addr_t name_addr;
/** Buffer address on the target. */
- uint32_t buffer_addr;
+ target_addr_t buffer_addr;
/** Channel buffer size in bytes. */
uint32_t size;
/** Write position within the buffer in bytes. */
diff --git a/src/target/rtt.c b/src/target/rtt.c
index a8ab24a60..5b7fdda40 100644
--- a/src/target/rtt.c
+++ b/src/target/rtt.c
@@ -18,32 +18,74 @@
#include "target.h"
+// Offsets for RTT control block parameters.
+struct rtt_control_params {
+ unsigned int channel_size;
+ unsigned int buffer_addr_offset;
+ unsigned int size_offset;
+ unsigned int write_pos_offset;
+ unsigned int read_pos_offset;
+ unsigned int flags_offset;
+};
+
+// Offsets for 32-bit architecture.
+static const struct rtt_control_params rtt_params_32 = {
+ .channel_size = RTT_CHANNEL_SIZE_32,
+ .buffer_addr_offset = 4,
+ .size_offset = 8,
+ .write_pos_offset = 12,
+ .read_pos_offset = 16,
+ .flags_offset = 20
+};
+
+// Offsets for 64-bit architecture.
+static const struct rtt_control_params rtt_params_64 = {
+ .channel_size = RTT_CHANNEL_SIZE_64,
+ .buffer_addr_offset = 8,
+ .size_offset = 16,
+ .write_pos_offset = 20,
+ .read_pos_offset = 24,
+ .flags_offset = 28
+};
+
+static const struct rtt_control_params *get_rtt_params(struct target *target)
+{
+ if (target_address_bits(target) == 64)
+ return &rtt_params_64;
+ return &rtt_params_32;
+}
+
static int read_rtt_channel(struct target *target,
const struct rtt_control *ctrl, unsigned int channel_index,
enum rtt_channel_type type, struct rtt_channel *channel)
{
int ret;
- uint8_t buf[RTT_CHANNEL_SIZE];
+ uint8_t buf[RTT_CHANNEL_SIZE_64];
target_addr_t address;
+ const struct rtt_control_params *params = get_rtt_params(target);
- address = ctrl->address + RTT_CB_SIZE + (channel_index * RTT_CHANNEL_SIZE);
+ address = ctrl->address + RTT_CB_SIZE + (channel_index * params->channel_size);
if (type == RTT_CHANNEL_TYPE_DOWN)
- address += ctrl->num_up_channels * RTT_CHANNEL_SIZE;
+ address += ctrl->num_up_channels * params->channel_size;
- ret = target_read_buffer(target, address, RTT_CHANNEL_SIZE, buf);
+ ret = target_read_buffer(target, address, params->channel_size, buf);
if (ret != ERROR_OK)
return ret;
channel->address = address;
- channel->name_addr = target_buffer_get_u32(target, buf + 0);
- channel->buffer_addr = target_buffer_get_u32(target, buf + 4);
- channel->size = target_buffer_get_u32(target, buf + 8);
- channel->write_pos = target_buffer_get_u32(target, buf + 12);
- channel->read_pos = target_buffer_get_u32(target, buf + 16);
- channel->flags = target_buffer_get_u32(target, buf + 20);
-
+ if (target_address_bits(target) == 64) {
+ channel->name_addr = target_buffer_get_u64(target, buf + 0);
+ channel->buffer_addr = target_buffer_get_u64(target, buf + params->buffer_addr_offset);
+ } else {
+ channel->name_addr = target_buffer_get_u32(target, buf + 0);
+ channel->buffer_addr = target_buffer_get_u32(target, buf + params->buffer_addr_offset);
+ }
+ channel->size = target_buffer_get_u32(target, buf + params->size_offset);
+ channel->write_pos = target_buffer_get_u32(target, buf + params->write_pos_offset);
+ channel->read_pos = target_buffer_get_u32(target, buf + params->read_pos_offset);
+ channel->flags = target_buffer_get_u32(target, buf + params->flags_offset);
return ERROR_OK;
}
@@ -157,7 +199,8 @@ static int write_to_channel(struct target *target,
return ret;
}
- ret = target_write_u32(target, channel->address + 12,
+ const struct rtt_control_params *params = get_rtt_params(target);
+ ret = target_write_u32(target, channel->address + params->write_pos_offset,
(channel->write_pos + len) % channel->size);
if (ret != ERROR_OK)
@@ -349,7 +392,8 @@ static int read_from_channel(struct target *target,
}
if (len > 0) {
- ret = target_write_u32(target, channel->address + 16,
+ const struct rtt_control_params *params = get_rtt_params(target);
+ ret = target_write_u32(target, channel->address + params->read_pos_offset,
(channel->read_pos + len) % channel->size);
if (ret != ERROR_OK)
-----------------------------------------------------------------------
Summary of changes:
src/rtt/rtt.h | 11 +++++----
src/target/rtt.c | 70 +++++++++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 64 insertions(+), 17 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|