From 232af6cc9bae571d74838dd1d7ce52544c0b6380 Mon Sep 17 00:00:00 2001
From: Brandon Warhurst <roboknight@gmail.com>
Date: Thu, 18 Apr 2013 14:05:26 -0400
Subject: [PATCH] Added functionality to the SYS_SYSTEM semihosting call.

There seems to be a few missing semihosting calls.  I
am not sure why this one is actually missing, since it
seems simple enough to implement.  It was tested using
an HTC HD7 connected to openocd through a "home brew"
ftdi 4232H board.

Change-Id: Ie17dc96c6d48227a3dc9ff1e21201a85498a10b1
Signed-off-by: Brandon Warhurst <roboknight@gmail.com>
Reviewed-on: http://openocd.zylin.com/1345
Tested-by: jenkins
Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
---
 src/target/arm_semihosting.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/src/target/arm_semihosting.c b/src/target/arm_semihosting.c
index 115c7d4e4..65fd18893 100644
--- a/src/target/arm_semihosting.c
+++ b/src/target/arm_semihosting.c
@@ -374,9 +374,34 @@ static int do_semihosting(struct target *target)
 		}
 		return target_call_event_callbacks(target, TARGET_EVENT_HALTED);
 
+	case 0x12:	/* SYS_SYSTEM */
+		/* Provide SYS_SYSTEM functionality.  Uses the
+		 * libc system command, there may be a reason *NOT*
+		 * to use this, but as I can't think of one, I
+		 * implemented it this way.
+		 */
+		retval = target_read_memory(target, r1, 4, 2, params);
+		if (retval != ERROR_OK)
+			return retval;
+		else {
+			uint32_t len = target_buffer_get_u32(target, params+4);
+			uint32_t c_ptr = target_buffer_get_u32(target, params);
+			uint8_t cmd[256];
+			if (len > 255) {
+				result = -1;
+				arm->semihosting_errno = EINVAL;
+			} else {
+				memset(cmd, 0x0, 256);
+				retval = target_read_memory(target, c_ptr, 1, len, cmd);
+				if (retval != ERROR_OK)
+					return retval;
+				else
+					result = system((const char *)cmd);
+			}
+		}
+		break;
 	case 0x0d:	/* SYS_TMPNAM */
 	case 0x10:	/* SYS_CLOCK */
-	case 0x12:	/* SYS_SYSTEM */
 	case 0x17:	/* angel_SWIreason_EnterSVC */
 	case 0x30:	/* SYS_ELAPSED */
 	case 0x31:	/* SYS_TICKFREQ */
-- 
GitLab