This is an automated email from Gerrit.

"Erhan Kurubas <erhankuru...@gmail.com>" just uploaded a new patch set to 
Gerrit, which you can find at https://review.openocd.org/c/openocd/+/6889

-- gerrit

commit f1e80481d8ae9e63d9ff1f54661a8b5c6c2b8c1c
Author: erhankur <erhankuru...@gmail.com>
Date:   Tue Apr 5 14:26:08 2022 +0300

    semihosting: add custom user command handler
    
    Custom user syscalls can be handled with target events in the TCL scripts.
    This patch gives another opportunity to handle custom syscalls in the c 
files.
    Besides that some utility functions are also exported for the custom 
handlers.
    
    Signed-off-by: erhankur <erhankuru...@gmail.com>
    Change-Id: Ice13d527540a0de0b2a8abda912ae3dcff3834b7

diff --git a/src/target/semihosting_common.c b/src/target/semihosting_common.c
index bc1f417ef0..cfef7c490c 100644
--- a/src/target/semihosting_common.c
+++ b/src/target/semihosting_common.c
@@ -103,16 +103,6 @@ static int semihosting_common_fileio_info(struct target 
*target,
 static int semihosting_common_fileio_end(struct target *target, int result,
        int fileio_errno, bool ctrl_c);
 
-static int semihosting_read_fields(struct target *target, size_t number,
-       uint8_t *fields);
-static int semihosting_write_fields(struct target *target, size_t number,
-       uint8_t *fields);
-static uint64_t semihosting_get_field(struct target *target, size_t index,
-       uint8_t *fields);
-static void semihosting_set_field(struct target *target, uint64_t value,
-       size_t index,
-       uint8_t *fields);
-
 /* Attempts to include gdb_server.h failed. */
 extern int gdb_actual_connections;
 
@@ -165,6 +155,7 @@ int semihosting_common_init(struct target *target, void 
*setup,
 
        semihosting->setup = setup;
        semihosting->post_result = post_result;
+       semihosting->user_command_handler = NULL;
 
        target->semihosting = semihosting;
 
@@ -936,8 +927,13 @@ int semihosting_common(struct target *target)
                                                        /* cygwin requires the 
permission setting
                                                         * otherwise it will 
fail to reopen a previously
                                                         * written file */
+                                                       uint32_t flags = 
open_host_modeflags[mode];
+                                                       #ifdef _WIN32
+                                                               /* Windows 
needs O_BINARY flag for proper handling of EOLs */
+                                                               flags |= 
O_BINARY;
+                                                       #endif
                                                        semihosting->result = 
open((char *)fn,
-                                                                       
open_host_modeflags[mode],
+                                                                       flags,
                                                                        0644);
                                                        semihosting->sys_errno 
= errno;
                                                        
LOG_DEBUG("open('%s')=%d", fn,
@@ -1461,51 +1457,53 @@ int semihosting_common(struct target *target)
                         * On exit, the RETURN REGISTER contains the return 
status.
                         */
                {
-                       assert(!semihosting_user_op_params);
+                       if (semihosting->user_command_handler)
+                               retval = 
semihosting->user_command_handler(target);
+                       else {
 
-                       retval = semihosting_read_fields(target, 2, fields);
-                       if (retval != ERROR_OK) {
-                               LOG_ERROR("Failed to read fields for user 
defined command"
-                                               " op=0x%x", semihosting->op);
-                               return retval;
-                       }
+                               assert(!semihosting_user_op_params);
 
-                       uint64_t addr = semihosting_get_field(target, 0, 
fields);
+                               retval = semihosting_read_fields(target, 2, 
fields);
+                               if (retval != ERROR_OK) {
+                                       LOG_ERROR("Failed to read fields for 
user defined command"
+                                                       " op=0x%x", 
semihosting->op);
+                                       return retval;
+                               }
 
-                       size_t len = semihosting_get_field(target, 1, fields);
-                       if (len > SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH) {
-                               LOG_ERROR("The maximum length for user defined 
command "
-                                               "parameter is %u, received 
length is %zu (op=0x%x)",
-                                               
SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH,
-                                               len,
-                                               semihosting->op);
-                               return ERROR_FAIL;
-                       }
+                               uint64_t addr = semihosting_get_field(target, 
0, fields);
 
-                       semihosting_user_op_params = malloc(len + 1);
-                       if (!semihosting_user_op_params)
-                               return ERROR_FAIL;
-                       semihosting_user_op_params[len] = 0;
+                               size_t len = semihosting_get_field(target, 1, 
fields);
+                               if (len > 
SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH) {
+                                       LOG_ERROR("The maximum length for user 
defined command "
+                                                       "parameter is %u, 
received length is %zu (op=0x%x)",
+                                                       
SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH,
+                                                       len,
+                                                       semihosting->op);
+                                       return ERROR_FAIL;
+                               }
+
+                               semihosting_user_op_params = malloc(len + 1);
+                               if (!semihosting_user_op_params)
+                                       return ERROR_FAIL;
+                               semihosting_user_op_params[len] = 0;
+
+                               retval = target_read_buffer(target, addr, len,
+                                               (uint8_t 
*)(semihosting_user_op_params));
+                               if (retval != ERROR_OK) {
+                                       LOG_ERROR("Failed to read from target, 
semihosting op=0x%x",
+                                                       semihosting->op);
+                                       free(semihosting_user_op_params);
+                                       semihosting_user_op_params = NULL;
+                                       return retval;
+                               }
 
-                       retval = target_read_buffer(target, addr, len,
-                                       (uint8_t 
*)(semihosting_user_op_params));
-                       if (retval != ERROR_OK) {
-                               LOG_ERROR("Failed to read from target, 
semihosting op=0x%x",
-                                               semihosting->op);
+                               target_handle_event(target, semihosting->op);
                                free(semihosting_user_op_params);
                                semihosting_user_op_params = NULL;
-                               return retval;
+                               semihosting->result = 0;
                        }
-
-                       target_handle_event(target, semihosting->op);
-                       free(semihosting_user_op_params);
-                       semihosting_user_op_params = NULL;
-
-                       semihosting->result = 0;
-                       break;
                }
-
-
+                       break;
                case SEMIHOSTING_SYS_ELAPSED:   /* 0x30 */
                /*
                 * Returns the number of elapsed target ticks since execution
@@ -1663,10 +1661,13 @@ static int semihosting_common_fileio_end(struct target 
*target, int result,
        return semihosting->post_result(target);
 }
 
+/* -------------------------------------------------------------------------
+ * Utility functions. */
+
 /**
  * Read all fields of a command from target to buffer.
  */
-static int semihosting_read_fields(struct target *target, size_t number,
+int semihosting_read_fields(struct target *target, size_t number,
        uint8_t *fields)
 {
        struct semihosting *semihosting = target->semihosting;
@@ -1678,7 +1679,7 @@ static int semihosting_read_fields(struct target *target, 
size_t number,
 /**
  * Write all fields of a command from buffer to target.
  */
-static int semihosting_write_fields(struct target *target, size_t number,
+int semihosting_write_fields(struct target *target, size_t number,
        uint8_t *fields)
 {
        struct semihosting *semihosting = target->semihosting;
@@ -1690,7 +1691,7 @@ static int semihosting_write_fields(struct target 
*target, size_t number,
 /**
  * Extract a field from the buffer, considering register size and endianness.
  */
-static uint64_t semihosting_get_field(struct target *target, size_t index,
+uint64_t semihosting_get_field(struct target *target, size_t index,
        uint8_t *fields)
 {
        struct semihosting *semihosting = target->semihosting;
@@ -1703,7 +1704,7 @@ static uint64_t semihosting_get_field(struct target 
*target, size_t index,
 /**
  * Store a field in the buffer, considering register size and endianness.
  */
-static void semihosting_set_field(struct target *target, uint64_t value,
+void semihosting_set_field(struct target *target, uint64_t value,
        size_t index,
        uint8_t *fields)
 {
diff --git a/src/target/semihosting_common.h b/src/target/semihosting_common.h
index 459faf656a..c14201408c 100644
--- a/src/target/semihosting_common.h
+++ b/src/target/semihosting_common.h
@@ -176,6 +176,7 @@ struct semihosting {
        /** The current time when 'execution starts' */
        clock_t setup_time;
 
+       int (*user_command_handler)(struct target *target);
        int (*setup)(struct target *target, int enable);
        int (*post_result)(struct target *target);
 };
@@ -184,4 +185,15 @@ int semihosting_common_init(struct target *target, void 
*setup,
        void *post_result);
 int semihosting_common(struct target *target);
 
+/* utility functions which may also be used by semihosting extensions (custom 
vendor-defined syscalls) */
+int semihosting_read_fields(struct target *target, size_t number,
+       uint8_t *fields);
+int semihosting_write_fields(struct target *target, size_t number,
+       uint8_t *fields);
+uint64_t semihosting_get_field(struct target *target, size_t index,
+       uint8_t *fields);
+void semihosting_set_field(struct target *target, uint64_t value,
+       size_t index,
+       uint8_t *fields);
+
 #endif /* OPENOCD_TARGET_SEMIHOSTING_COMMON_H */

-- 

Reply via email to