aboutsummaryrefslogtreecommitdiff
path: root/src/cortexm.c
diff options
context:
space:
mode:
authorPaul Fertser2013-04-15 21:42:46 +0400
committerGareth McMullin2013-05-18 15:33:58 +1200
commitdf32aad757935c8953c844ffaa455fa940b4b405 (patch)
treeb1e201e8a2b979c98c127f2a51f87932dc817c35 /src/cortexm.c
parent5020d1f05db920cd0633982016c0b1978a310d20 (diff)
semihosting: improve handling of console I/O
This implements special handling for SYS_OPEN to catch requests for ":tt" which is reserved by ARM for console input/output. They're mapped to the appropriate GDB file descriptors automatically. An additional file handle offset is introduced because ARM doesn't consider zero handle to be valid. Signed-off-by: Paul Fertser <fercerpav@gmail.com>
Diffstat (limited to 'src/cortexm.c')
-rw-r--r--src/cortexm.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/src/cortexm.c b/src/cortexm.c
index 179fb36..130f683 100644
--- a/src/cortexm.c
+++ b/src/cortexm.c
@@ -28,6 +28,7 @@
* Issues:
* There are way too many magic numbers used here.
*/
+#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -949,41 +950,60 @@ static int cortexm_hostio_request(target *t)
FILEIO_O_WRONLY | FILEIO_O_CREAT | FILEIO_O_APPEND,/*a*/
FILEIO_O_RDWR | FILEIO_O_CREAT | FILEIO_O_APPEND,/*a+*/
};
+ uint32_t pflag = flags[params[1] >> 1];
+ char filename[4];
+
+ target_mem_read_bytes(t, filename, params[0], sizeof(filename));
+ /* handle requests for console i/o */
+ if (!strcmp(filename, ":tt")) {
+ if (pflag == FILEIO_O_RDONLY)
+ arm_regs[0] = STDIN_FILENO;
+ else if (pflag & FILEIO_O_TRUNC)
+ arm_regs[0] = STDOUT_FILENO;
+ else
+ arm_regs[0] = STDERR_FILENO;
+ arm_regs[0]++;
+ target_regs_write(t, arm_regs);
+ return 1;
+ }
+
gdb_putpacket_f("Fopen,%08X/%X,%08X,%08X",
params[0], params[2] + 1,
- flags[params[1] >> 1], 0644);
+ pflag, 0644);
break;
}
case SYS_CLOSE: /* close */
- gdb_putpacket_f("Fclose,%08X", params[0]);
+ gdb_putpacket_f("Fclose,%08X", params[0] - 1);
break;
case SYS_READ: /* read */
priv->byte_count = params[2];
gdb_putpacket_f("Fread,%08X,%08X,%08X",
- params[0], params[1], params[2]);
+ params[0] - 1, params[1], params[2]);
break;
case SYS_WRITE: /* write */
priv->byte_count = params[2];
gdb_putpacket_f("Fwrite,%08X,%08X,%08X",
- params[0], params[1], params[2]);
+ params[0] - 1, params[1], params[2]);
break;
case SYS_ISTTY: /* isatty */
- gdb_putpacket_f("Fisatty,%08X", params[0]);
+ gdb_putpacket_f("Fisatty,%08X", params[0] - 1);
break;
case SYS_SEEK: /* lseek */
gdb_putpacket_f("Flseek,%08X,%08X,%08X",
- params[0], params[1], FILEIO_SEEK_SET);
+ params[0] - 1, params[1], FILEIO_SEEK_SET);
break;
case SYS_RENAME:/* rename */
gdb_putpacket_f("Frename,%08X/%X,%08X/%X",
- params[0], params[1] + 1,
+ params[0] - 1, params[1] + 1,
params[2], params[3] + 1);
break;
case SYS_REMOVE:/* unlink */
- gdb_putpacket_f("Funlink,%08X/%X", params[0], params[1] + 1);
+ gdb_putpacket_f("Funlink,%08X/%X", params[0] - 1,
+ params[1] + 1);
break;
case SYS_SYSTEM:/* system */
- gdb_putpacket_f("Fsystem,%08X/%X", params[0], params[1] + 1);
+ gdb_putpacket_f("Fsystem,%08X/%X", params[0] - 1,
+ params[1] + 1);
break;
case SYS_FLEN: /* Not supported, fake success */
@@ -1015,6 +1035,8 @@ static void cortexm_hostio_reply(target *t, int32_t retcode, uint32_t errcode)
if (((priv->syscall == SYS_READ) || (priv->syscall == SYS_WRITE)) &&
(retcode > 0))
retcode = priv->byte_count - retcode;
+ if ((priv->syscall == SYS_OPEN) && (retcode != -1))
+ retcode++;
arm_regs[0] = retcode;
target_regs_write(t, arm_regs);
priv->errno = errcode;