[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openocd-development
Subject:    [PATCH]: ef4fa4efb0 target/xtensa: add file-IO support
From:       gerrit () openocd ! org
Date:       2023-03-24 0:34:20
Message-ID: 20230324003420.68809FC () openocd ! org
[Download RAW message or body]

This is an automated email from Gerrit.

"Ian Thompson <ianst@cadence.com>" just uploaded a new patch set to Gerrit, which you \
can find at https://review.openocd.org/c/openocd/+/7550

-- gerrit

commit ef4fa4efb032d42a557d1d0f854cdfc3cdb9ddbe
Author: Ian Thompson <ianst@cadence.com>
Date:   Thu Mar 23 17:30:53 2023 -0700

    target/xtensa: add file-IO support
    
    - Manual integration of File-IO support from xt0.2 release
    - Verified with applications linked using gdbio LSP
    - No new clang static analysis warnings
    
    Signed-off-by: Ian Thompson <ianst@cadence.com>
    Change-Id: Iedc5f885b2548097ef4f11ae1a675b5944f5fdf0

diff --git a/src/target/xtensa/Makefile.am b/src/target/xtensa/Makefile.am
index 94c7c4a85b..22504e78b2 100644
--- a/src/target/xtensa/Makefile.am
+++ b/src/target/xtensa/Makefile.am
@@ -8,4 +8,6 @@ noinst_LTLIBRARIES += %D%/libxtensa.la
        %D%/xtensa_chip.h \
        %D%/xtensa_debug_module.c \
        %D%/xtensa_debug_module.h \
+       %D%/xtensa_fileio.c \
+       %D%/xtensa_fileio.h \
        %D%/xtensa_regs.h
diff --git a/src/target/xtensa/xtensa.c b/src/target/xtensa/xtensa.c
index fcd00487c8..7afb439599 100644
--- a/src/target/xtensa/xtensa.c
+++ b/src/target/xtensa/xtensa.c
@@ -1544,6 +1544,7 @@ int xtensa_prepare_resume(struct target *target,
 		LOG_TARGET_WARNING(target, "target not halted");
 		return ERROR_TARGET_NOT_HALTED;
 	}
+	xtensa->halt_request = false;
 
 	if (address && !current) {
 		xtensa_reg_set(target, XT_REG_IDX_PC, address);
diff --git a/src/target/xtensa/xtensa_chip.c b/src/target/xtensa/xtensa_chip.c
index c62992f625..668aa3acc7 100644
--- a/src/target/xtensa/xtensa_chip.c
+++ b/src/target/xtensa/xtensa_chip.c
@@ -15,6 +15,7 @@
 #include <target/arm_adi_v5.h>
 #include <rtos/rtos.h>
 #include "xtensa_chip.h"
+#include "xtensa_fileio.h"
 
 int xtensa_chip_init_arch_info(struct target *target, void *arch_info,
 	struct xtensa_debug_module_config *dm_cfg)
@@ -30,7 +31,10 @@ int xtensa_chip_init_arch_info(struct target *target, void \
*arch_info,  
 int xtensa_chip_target_init(struct command_context *cmd_ctx, struct target *target)
 {
-	return xtensa_target_init(cmd_ctx, target);
+	int ret = xtensa_target_init(cmd_ctx, target);
+	if (ret != ERROR_OK)
+		return ret;
+	return xtensa_fileio_init(target);
 }
 
 int xtensa_chip_arch_state(struct target *target)
@@ -45,10 +49,12 @@ static int xtensa_chip_poll(struct target *target)
 
 	if (old_state != TARGET_HALTED && target->state == TARGET_HALTED) {
 		/*Call any event callbacks that are applicable */
-		if (old_state == TARGET_DEBUG_RUNNING)
+		if (old_state == TARGET_DEBUG_RUNNING) {
 			target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
-		else
+		} else {
+			xtensa_fileio_detect_proc(target);
 			target_call_event_callbacks(target, TARGET_EVENT_HALTED);
+		}
 	}
 
 	return ret;
@@ -193,4 +199,7 @@ struct target_type xtensa_chip_target = {
 	.gdb_query_custom = xtensa_gdb_query_custom,
 
 	.commands = xtensa_command_handlers,
+
+	.get_gdb_fileio_info = xtensa_get_gdb_fileio_info,
+	.gdb_fileio_end = xtensa_gdb_fileio_end,
 };
diff --git a/src/target/xtensa/xtensa_fileio.c b/src/target/xtensa/xtensa_fileio.c
new file mode 100644
index 0000000000..972c9c0860
--- /dev/null
+++ b/src/target/xtensa/xtensa_fileio.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/***************************************************************************
+ *   Xtensa Target File-I/O Support for OpenOCD                            *
+ *   Copyright (C) 2020-2023 Cadence Design Systems, Inc.                  *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xtensa_chip.h"
+#include "xtensa_fileio.h"
+#include "xtensa.h"
+
+#define XTENSA_SYSCALL(x)		XT_INS_BREAK(x, 1, 14)
+#define XTENSA_SYSCALL_SZ		3
+#define XTENSA_SYSCALL_LEN_MAX	255
+
+
+int xtensa_fileio_init(struct target *target)
+{
+	target->fileio_info = malloc(sizeof(struct gdb_fileio_info));
+	target->fileio_info->identifier = malloc(XTENSA_SYSCALL_LEN_MAX + 1);
+	return ERROR_OK;
+}
+
+/**
+ * Checks for and processes an Xtensa File-IO request.
+ *
+ * Return ERROR_OK if request was found and handled; or
+ * return ERROR_FAIL if no request was detected.
+ */
+int xtensa_fileio_detect_proc(struct target *target)
+{
+	struct xtensa *xtensa = target_to_xtensa(target);
+	int retval;
+
+	xtensa_reg_val_t dbg_cause = xtensa_cause_get(target);
+	if ((dbg_cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN)) == 0 || xtensa->halt_request)
+		return ERROR_FAIL;
+
+	uint8_t brk_insn_buf[sizeof(uint32_t)] = {0};
+	xtensa_reg_val_t pc = xtensa_reg_get(target, XT_REG_IDX_PC);
+	retval = target_read_memory(target,
+		pc,
+		XTENSA_SYSCALL_SZ,
+		1,
+		(uint8_t *)brk_insn_buf);
+	if (retval != ERROR_OK) {
+		LOG_ERROR("Failed to read break instruction!");
+		return ERROR_FAIL;
+	}
+	if (buf_get_u32(brk_insn_buf, 0, 32) != XTENSA_SYSCALL(xtensa))
+		return ERROR_FAIL;
+
+	LOG_TARGET_DEBUG(target, "File-I/O: syscall breakpoint found at 0x%x", pc);
+	xtensa->proc_syscall = true;
+	return ERROR_OK;
+}
+
+int xtensa_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info \
*fileio_info) +{
+	/* fill syscall parameters to file-I/O info */
+	if (!fileio_info) {
+		LOG_ERROR("File-I/O data structure uninitialized");
+		return ERROR_FAIL;
+	}
+
+	struct xtensa *xtensa = target_to_xtensa(target);
+	if (!xtensa->proc_syscall)
+		return ERROR_FAIL;
+
+	xtensa_reg_val_t syscall = xtensa_reg_get(target, XTENSA_SYSCALL_OP_REG);
+	xtensa_reg_val_t arg0 = xtensa_reg_get(target, XT_REG_IDX_A6);
+	xtensa_reg_val_t arg1 = xtensa_reg_get(target, XT_REG_IDX_A3);
+	xtensa_reg_val_t arg2 = xtensa_reg_get(target, XT_REG_IDX_A4);
+	xtensa_reg_val_t arg3 = xtensa_reg_get(target, XT_REG_IDX_A5);
+	int retval = ERROR_OK;
+
+	LOG_TARGET_DEBUG(target, "File-I/O: syscall 0x%x 0x%x 0x%x 0x%x 0x%x",
+		syscall, arg0, arg1, arg2, arg3);
+
+	switch (syscall) {
+	case XTENSA_SYSCALL_OPEN:
+		snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "open");
+		fileio_info->param_1 = arg0;	// pathp
+		fileio_info->param_2 = arg3;	// len
+		fileio_info->param_3 = arg1;	// flags
+		fileio_info->param_4 = arg2;	// mode
+		break;
+	case XTENSA_SYSCALL_CLOSE:
+		snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "close");
+		fileio_info->param_1 = arg0;	// fd
+		break;
+	case XTENSA_SYSCALL_READ:
+		snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "read");
+		fileio_info->param_1 = arg0;	// fd
+		fileio_info->param_2 = arg1;	// bufp
+		fileio_info->param_3 = arg2;	// count
+		break;
+	case XTENSA_SYSCALL_WRITE:
+		snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "write");
+		fileio_info->param_1 = arg0;	// fd
+		fileio_info->param_2 = arg1;	// bufp
+		fileio_info->param_3 = arg2;	// count
+		break;
+	case XTENSA_SYSCALL_LSEEK:
+		snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "lseek");
+		fileio_info->param_1 = arg0;	// fd
+		fileio_info->param_2 = arg1;	// offset
+		fileio_info->param_3 = arg2;	// flags
+		break;
+	case XTENSA_SYSCALL_RENAME:
+		snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "rename");
+		fileio_info->param_1 = arg0;	// old pathp
+		fileio_info->param_2 = arg3;	// old len
+		fileio_info->param_3 = arg1;	// new pathp
+		fileio_info->param_4 = arg2;	// new len
+		break;
+	case XTENSA_SYSCALL_UNLINK:
+		snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "unlink");
+		fileio_info->param_1 = arg0;	// pathnamep
+		fileio_info->param_2 = arg1;	// len
+		break;
+	case XTENSA_SYSCALL_STAT:
+		snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "stat");
+		fileio_info->param_1 = arg0;	// pathnamep
+		fileio_info->param_2 = arg2;	// len
+		fileio_info->param_3 = arg1;	// bufp
+		break;
+	case XTENSA_SYSCALL_FSTAT:
+		snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "fstat");
+		fileio_info->param_1 = arg0;	// fd
+		fileio_info->param_2 = arg1;	// bufp
+		break;
+	case XTENSA_SYSCALL_GETTIMEOFDAY:
+		snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "gettimeofday");
+		fileio_info->param_1 = arg0;	// tvp
+		fileio_info->param_2 = arg1;	// tzp
+		break;
+	case XTENSA_SYSCALL_ISATTY:
+		snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "isatty");
+		fileio_info->param_1 = arg0;	// fd
+		break;
+	case XTENSA_SYSCALL_SYSTEM:
+		snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "system");
+		fileio_info->param_1 = arg0;	// cmdp
+		fileio_info->param_2 = arg1;	// len
+		break;
+	default:
+		snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "unknown");
+		LOG_TARGET_DEBUG(target, "File-I/O: syscall unknown (%d), pc=0x%08X",
+			syscall, xtensa_reg_get(target, XT_REG_IDX_PC));
+		LOG_INFO("File-I/O: syscall unknown (%d), pc=0x%08X",
+			syscall, xtensa_reg_get(target, XT_REG_IDX_PC));
+		retval = ERROR_FAIL;
+		break;
+	}
+
+	return retval;
+}
+
+int xtensa_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, bool \
ctrl_c) +{
+	struct xtensa *xtensa = target_to_xtensa(target);
+	if (!xtensa->proc_syscall)
+		return ERROR_FAIL;
+
+	LOG_TARGET_DEBUG(target, "File-I/O: syscall return code: 0x%x, errno: 0x%x , \
ctrl_c: %s", +		retcode, fileio_errno, ctrl_c ? "true" : "false");
+
+	// If interrupt was requested before FIO completion (ERRNO==4), halt and repeat \
syscall +	// Otherwise, set File-I/O Ax and underlying ARx registers, increment PC
+	// NOTE: sporadic cases of ((ERRNO==4) && !ctrl_c) were observed, although most \
have ctrl_c +	if (fileio_errno != 4) {
+		xtensa_reg_set_deep_relgen(target, XTENSA_SYSCALL_RETVAL_REG, retcode);
+		xtensa_reg_set_deep_relgen(target, XTENSA_SYSCALL_ERRNO_REG, fileio_errno);
+
+		xtensa_reg_val_t pc = xtensa_reg_get(target, XT_REG_IDX_PC);
+		xtensa_reg_set(target, XT_REG_IDX_PC, pc + XTENSA_SYSCALL_SZ);
+	}
+
+	xtensa->proc_syscall = false;
+	return ERROR_OK;
+}
+
diff --git a/src/target/xtensa/xtensa_fileio.h b/src/target/xtensa/xtensa_fileio.h
new file mode 100644
index 0000000000..5e1af5f864
--- /dev/null
+++ b/src/target/xtensa/xtensa_fileio.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/***************************************************************************
+ *   Xtensa Target File-I/O Support for OpenOCD                            *
+ *   Copyright (C) 2020-2023 Cadence Design Systems, Inc.                  *
+ ***************************************************************************/
+
+#ifndef OPENOCD_TARGET_XTENSA_FILEIO_H
+#define OPENOCD_TARGET_XTENSA_FILEIO_H
+
+#include <target/target.h>
+#include <helper/command.h>
+#include "xtensa.h"
+
+#define XTENSA_SYSCALL_OP_REG		XT_REG_IDX_A2
+#define XTENSA_SYSCALL_RETVAL_REG	XT_REG_IDX_A2
+#define XTENSA_SYSCALL_ERRNO_REG	XT_REG_IDX_A3
+
+#define XTENSA_SYSCALL_OPEN			(-2)
+#define XTENSA_SYSCALL_CLOSE		(-3)
+#define XTENSA_SYSCALL_READ			(-4)
+#define XTENSA_SYSCALL_WRITE		(-5)
+#define XTENSA_SYSCALL_LSEEK		(-6)
+#define XTENSA_SYSCALL_RENAME		(-7)
+#define XTENSA_SYSCALL_UNLINK		(-8)
+#define XTENSA_SYSCALL_STAT			(-9)
+#define XTENSA_SYSCALL_FSTAT		(-10)
+#define XTENSA_SYSCALL_GETTIMEOFDAY	(-11)
+#define XTENSA_SYSCALL_ISATTY		(-12)
+#define XTENSA_SYSCALL_SYSTEM		(-13)
+
+int xtensa_fileio_init(struct target *target);
+int xtensa_fileio_detect_proc(struct target *target);
+int xtensa_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info \
*fileio_info); +int xtensa_gdb_fileio_end(struct target *target, int retcode, int \
fileio_errno, bool ctrl_c); +
+#endif	/* OPENOCD_TARGET_XTENSA_FILEIO_H */

-- 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic