Browse Source

ARM: remove semihosting globals

Store a flag and errno in in "struct arm".
Have "poll" output report when semihosting is active.
Shrink some of the affected lines.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
tags/v0.4.0-rc1
David Brownell 14 years ago
parent
commit
bdde9460b9
5 changed files with 48 additions and 33 deletions
  1. +16
    -6
      src/target/arm7_9_common.c
  2. +18
    -21
      src/target/arm_semihosting.c
  3. +0
    -2
      src/target/arm_semihosting.h
  4. +8
    -4
      src/target/armv4_5.c
  5. +6
    -0
      src/target/armv4_5.h

+ 16
- 6
src/target/arm7_9_common.c View File

@@ -2831,22 +2831,32 @@ COMMAND_HANDLER(handle_arm7_9_semihosting_command)

if (CMD_ARGC > 0)
{
COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting_active);
int semihosting;

COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting);

/* TODO: support other methods if vector catch is unavailable */
if (arm7_9->has_vector_catch) {
struct reg *vector_catch = &arm7_9->eice_cache->reg_list[EICE_VEC_CATCH];
struct reg *vector_catch = &arm7_9->eice_cache
->reg_list[EICE_VEC_CATCH];

if (!vector_catch->valid)
embeddedice_read_reg(vector_catch);
buf_set_u32(vector_catch->value, 2, 1, semihosting_active);
buf_set_u32(vector_catch->value, 2, 1, semihosting);
embeddedice_store_reg(vector_catch);
} else if (semihosting_active) {

/* FIXME never let that "catch" be dropped! */

arm7_9->armv4_5_common.is_semihosting = semihosting;

} else if (semihosting) {
command_print(CMD_CTX, "vector catch unavailable");
semihosting_active = 0;
}
}

command_print(CMD_CTX, "semihosting is %s", (semihosting_active) ? "enabled" : "disabled");
command_print(CMD_CTX, "semihosting is %s",
arm7_9->armv4_5_common.is_semihosting
? "enabled" : "disabled");

return ERROR_OK;
}


+ 18
- 21
src/target/arm_semihosting.c View File

@@ -40,9 +40,6 @@
#include <helper/binarybuffer.h>
#include <helper/log.h>

/* TODO: this needs to be per target */
int semihosting_active;
int semihosting_errno;

static int do_semihosting(struct target *target)
{
@@ -93,10 +90,10 @@ static int do_semihosting(struct target *target)
result = dup(1);
} else
result = open((char *)fn, mode);
semihosting_errno = errno;
armv4_5->semihosting_errno = errno;
} else {
result = -1;
semihosting_errno = EINVAL;
armv4_5->semihosting_errno = EINVAL;
}
}
break;
@@ -108,7 +105,7 @@ static int do_semihosting(struct target *target)
else {
int fd = target_buffer_get_u32(target, params+0);
result = close(fd);
semihosting_errno = errno;
armv4_5->semihosting_errno = errno;
}
break;

@@ -147,7 +144,7 @@ static int do_semihosting(struct target *target)
uint8_t *buf = malloc(l);
if (!buf) {
result = -1;
semihosting_errno = ENOMEM;
armv4_5->semihosting_errno = ENOMEM;
} else {
retval = target_read_buffer(target, a, l, buf);
if (retval != ERROR_OK) {
@@ -155,7 +152,7 @@ static int do_semihosting(struct target *target)
return retval;
}
result = write(fd, buf, l);
semihosting_errno = errno;
armv4_5->semihosting_errno = errno;
if (result >= 0)
result = l - result;
free(buf);
@@ -174,10 +171,10 @@ static int do_semihosting(struct target *target)
uint8_t *buf = malloc(l);
if (!buf) {
result = -1;
semihosting_errno = ENOMEM;
armv4_5->semihosting_errno = ENOMEM;
} else {
result = read(fd, buf, l);
semihosting_errno = errno;
armv4_5->semihosting_errno = errno;
if (result > 0) {
retval = target_write_buffer(target, a, result, buf);
if (retval != ERROR_OK) {
@@ -217,7 +214,7 @@ static int do_semihosting(struct target *target)
int fd = target_buffer_get_u32(target, params+0);
off_t pos = target_buffer_get_u32(target, params+4);
result = lseek(fd, pos, SEEK_SET);
semihosting_errno = errno;
armv4_5->semihosting_errno = errno;
if (result == pos)
result = 0;
}
@@ -231,14 +228,14 @@ static int do_semihosting(struct target *target)
int fd = target_buffer_get_u32(target, params+0);
off_t cur = lseek(fd, 0, SEEK_CUR);
if (cur == (off_t)-1) {
semihosting_errno = errno;
armv4_5->semihosting_errno = errno;
result = -1;
break;
}
result = lseek(fd, 0, SEEK_END);
semihosting_errno = errno;
armv4_5->semihosting_errno = errno;
if (lseek(fd, cur, SEEK_SET) == (off_t)-1) {
semihosting_errno = errno;
armv4_5->semihosting_errno = errno;
result = -1;
}
}
@@ -258,10 +255,10 @@ static int do_semihosting(struct target *target)
return retval;
fn[l] = 0;
result = remove((char *)fn);
semihosting_errno = errno;
armv4_5->semihosting_errno = errno;
} else {
result = -1;
semihosting_errno = EINVAL;
armv4_5->semihosting_errno = EINVAL;
}
}
break;
@@ -286,10 +283,10 @@ static int do_semihosting(struct target *target)
fn1[l1] = 0;
fn2[l2] = 0;
result = rename((char *)fn1, (char *)fn2);
semihosting_errno = errno;
armv4_5->semihosting_errno = errno;
} else {
result = -1;
semihosting_errno = EINVAL;
armv4_5->semihosting_errno = EINVAL;
}
}
break;
@@ -299,7 +296,7 @@ static int do_semihosting(struct target *target)
break;

case 0x13: /* SYS_ERRNO */
result = semihosting_errno;
result = armv4_5->semihosting_errno;
break;

case 0x15: /* SYS_GET_CMDLINE */
@@ -375,7 +372,7 @@ static int do_semihosting(struct target *target)
fprintf(stderr, "semihosting: unsupported call %#x\n",
(unsigned) r0);
result = -1;
semihosting_errno = ENOTSUP;
armv4_5->semihosting_errno = ENOTSUP;
}

/* resume execution to the original mode */
@@ -408,7 +405,7 @@ int arm_semihosting(struct target *target, int *retval)
struct arm *armv4_5 = target_to_armv4_5(target);
uint32_t lr, spsr;

if (!semihosting_active ||
if (!armv4_5->is_semihosting ||
armv4_5->core_mode != ARMV4_5_MODE_SVC ||
buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) != 0x08)
return 0;


+ 0
- 2
src/target/arm_semihosting.h View File

@@ -21,8 +21,6 @@
#ifndef ARM_SEMIHOSTING_H
#define ARM_SEMIHOSTING_H

extern int semihosting_active;

int arm_semihosting(struct target *target, int *retval);

#endif

+ 8
- 4
src/target/armv4_5.c View File

@@ -587,16 +587,20 @@ int armv4_5_arch_state(struct target *target)

if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
{
LOG_ERROR("BUG: called for a non-ARMv4/5 target");
LOG_ERROR("BUG: called for a non-ARM target");
return ERROR_FAIL;
}

LOG_USER("target halted in %s state due to %s, current mode: %s\ncpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "",
LOG_USER("target halted in %s state due to %s, current mode: %s\n"
"cpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "%s",
armv4_5_state_strings[armv4_5->core_state],
Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name,
Jim_Nvp_value2name_simple(nvp_target_debug_reason,
target->debug_reason)->name,
arm_mode_name(armv4_5->core_mode),
buf_get_u32(armv4_5->cpsr->value, 0, 32),
buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
buf_get_u32(armv4_5->core_cache->reg_list[15].value,
0, 32),
armv4_5->is_semihosting ? ", semihosting" : "");

return ERROR_OK;
}


+ 6
- 0
src/target/armv4_5.h View File

@@ -103,6 +103,12 @@ struct arm
/** Flag reporting unavailability of the BKPT instruction. */
bool is_armv4;

/** Flag reporting whether semihosting is active. */
bool is_semihosting;

/** Value to be returned by semihosting SYS_ERRNO request. */
int semihosting_errno;

/** Backpointer to the target. */
struct target *target;



Loading…
Cancel
Save