X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Farm_semihosting.c;h=21b7809c285b04d09294df1c8606e6cfdec67e00;hb=a6c4eb03455f6e97fc25183aae249d6ccdcbfb0f;hp=fba580b48bea97b2df25b60e4080e742cf038ff6;hpb=3f8f5839641f79ae1983ac55e7f7d866a971976c;p=openocd.git diff --git a/src/target/arm_semihosting.c b/src/target/arm_semihosting.c index fba580b48b..21b7809c28 100644 --- a/src/target/arm_semihosting.c +++ b/src/target/arm_semihosting.c @@ -18,7 +18,7 @@ * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * ***************************************************************************/ /** @@ -48,7 +48,7 @@ #include #include -static int open_modeflags[12] = { +static const int open_modeflags[12] = { O_RDONLY, O_RDONLY | O_BINARY, O_RDWR, @@ -323,7 +323,7 @@ static int do_semihosting(struct target *target) if (l < s) result = -1; else { - retval = target_write_buffer(target, a, s, (void*)arg); + retval = target_write_buffer(target, a, s, (uint8_t *)arg); if (retval != ERROR_OK) return retval; result = 0; @@ -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 */ @@ -392,8 +417,7 @@ static int do_semihosting(struct target *target) /* REVISIT this looks wrong ... ARM11 and Cortex-A8 * should work this way at least sometimes. */ - if (is_arm7_9(target_to_arm7_9(target))) - { + if (is_arm7_9(target_to_arm7_9(target))) { uint32_t spsr; /* return value in R0 */ @@ -402,7 +426,7 @@ static int do_semihosting(struct target *target) /* LR --> PC */ buf_set_u32(arm->core_cache->reg_list[15].value, 0, 32, - buf_get_u32(arm_reg_current(arm,14)->value, 0, 32)); + buf_get_u32(arm_reg_current(arm, 14)->value, 0, 32)); arm->core_cache->reg_list[15].dirty = 1; /* saved PSR --> current PSR */ @@ -418,9 +442,7 @@ static int do_semihosting(struct target *target) if (spsr & 0x20) arm->core_state = ARM_STATE_THUMB; - } - else - { + } else { /* resume execution, this will be pc+2 to skip over the * bkpt instruction */ @@ -454,8 +476,7 @@ int arm_semihosting(struct target *target, int *retval) if (!arm->is_semihosting) return 0; - if (is_arm7_9(target_to_arm7_9(target))) - { + if (is_arm7_9(target_to_arm7_9(target))) { if (arm->core_mode != ARM_MODE_SVC) return 0; @@ -510,9 +531,7 @@ int arm_semihosting(struct target *target, int *retval) if (insn != 0xEF123456) return 0; } - } - else if (is_armv7m(target_to_armv7m(target))) - { + } else if (is_armv7m(target_to_armv7m(target))) { uint16_t insn; if (target->debug_reason != DBG_REASON_BREAKPOINT) @@ -529,9 +548,7 @@ int arm_semihosting(struct target *target, int *retval) /* bkpt 0xAB */ if (insn != 0xBEAB) return 0; - } - else - { + } else { LOG_ERROR("Unsupported semi-hosting Target"); return 0; }