Added functionality to the SYS_SYSTEM semihosting call.
authorBrandon Warhurst <roboknight@gmail.com>
Thu, 18 Apr 2013 18:05:26 +0000 (14:05 -0400)
committerSpencer Oliver <spen@spen-soft.co.uk>
Fri, 10 May 2013 14:20:08 +0000 (14:20 +0000)
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

index 115c7d4e498b44f2fc75b974b57b3d7e66e5d854..65fd18893a7a50f0701ebd668399e9abe093effb 100644 (file)
@@ -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 */