summaryrefslogtreecommitdiff
path: root/src/st-util/semihosting.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/st-util/semihosting.c')
-rw-r--r--src/st-util/semihosting.c149
1 files changed, 76 insertions, 73 deletions
diff --git a/src/st-util/semihosting.c b/src/st-util/semihosting.c
index 32169c8..8e9828c 100644
--- a/src/st-util/semihosting.c
+++ b/src/st-util/semihosting.c
@@ -1,72 +1,76 @@
#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
#include <string.h>
+
+#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
-#include <stdlib.h>
-#include <errno.h>
#include <stlink.h>
-#include <logging.h>
#include "semihosting.h"
-static int mem_read_u8(stlink_t *sl, uint32_t addr, uint8_t *data) {
- int offset = addr % 4;
- int len = 4;
+#include <logging.h>
+#include <read_write.h>
+
+static int32_t mem_read_u8(stlink_t *sl, uint32_t addr, uint8_t *data) {
+ int32_t offset = addr % 4;
+ int32_t len = 4;
- if (sl == NULL || data == NULL) { return(-1); }
+ if (sl == NULL || data == NULL) { return (-1); }
// read address and length must be aligned
- if (stlink_read_mem32(sl, addr - offset, len) != 0) { return(-1); }
+ if (stlink_read_mem32(sl, addr - offset, len) != 0) { return (-1); }
*data = sl->q_buf[offset];
- return(0);
+ return (0);
}
#ifdef UNUSED
-static int mem_read_u16(stlink_t *sl, uint32_t addr, uint16_t *data) {
- int offset = addr % 4;
- int len = (offset > 2 ? 8 : 4);
+static int32_t mem_read_u16(stlink_t *sl, uint32_t addr, uint16_t *data) {
+ int32_t offset = addr % 4;
+ int32_t len = (offset > 2 ? 8 : 4);
- if (sl == NULL || data == NULL) { return(-1); }
+ if (sl == NULL || data == NULL) { return (-1); }
// read address and length must be aligned
- if (stlink_read_mem32(sl, addr - offset, len) != 0) { return(-1); }
+ if (stlink_read_mem32(sl, addr - offset, len) != 0) { return (-1); }
memcpy(data, &sl->q_buf[offset], sizeof(*data));
- return(0);
+ return (0);
}
-static int mem_read_u32(stlink_t *sl, uint32_t addr, uint32_t *data) {
- int offset = addr % 4;
- int len = (offset > 0 ? 8 : 4);
+static int32_t mem_read_u32(stlink_t *sl, uint32_t addr, uint32_t *data) {
+ int32_t offset = addr % 4;
+ int32_t len = (offset > 0 ? 8 : 4);
- if (sl == NULL || data == NULL) { return(-1); }
+ if (sl == NULL || data == NULL) { return (-1); }
// read address and length must be aligned
- if (stlink_read_mem32(sl, addr - offset, len) != 0) { return(-1); }
+ if (stlink_read_mem32(sl, addr - offset, len) != 0) { return (-1); }
memcpy(data, &sl->q_buf[offset], sizeof(*data));
- return(0);
+ return (0);
}
#endif
-static int mem_read(stlink_t *sl, uint32_t addr, void *data, uint16_t len) {
- int offset = addr % 4;
- int read_len = len + offset;
+static int32_t mem_read(stlink_t *sl, uint32_t addr, void *data, uint16_t len) {
+ int32_t offset = addr % 4;
+ int32_t read_len = len + offset;
- if (sl == NULL || data == NULL) { return(-1); }
+ if (sl == NULL || data == NULL) { return (-1); }
// align read size
if ((read_len % 4) != 0) { read_len += 4 - (read_len % 4); }
// address and length must be aligned
- if (stlink_read_mem32(sl, addr - offset, read_len) != 0) { return(-1); }
+ if (stlink_read_mem32(sl, addr - offset, read_len) != 0) { return (-1); }
memcpy(data, &sl->q_buf[offset], len);
- return(0);
+ return (0);
}
-static int mem_write(stlink_t *sl, uint32_t addr, void *data, uint16_t len) {
+static int32_t mem_write(stlink_t *sl, uint32_t addr, void *data, uint16_t len) {
/* Note: this function can write more than it is asked to!
* If addr is not an even 32 bit boundary, or len is not a multiple of 4.
* If only 32 bit values can be written to the target, then this function should read
@@ -74,12 +78,12 @@ static int mem_write(stlink_t *sl, uint32_t addr, void *data, uint16_t len) {
* the requested bytes. (perhaps reading the whole area is faster??).
* If 16 and 8 bit writes are available, then they could be used instead.
* Just return when the length is zero avoiding unneeded work. */
- if (len == 0) { return(0); }
+ if (len == 0) { return (0); }
- int offset = addr % 4;
- int write_len = len + offset;
+ int32_t offset = addr % 4;
+ int32_t write_len = len + offset;
- if (sl == NULL || data == NULL) { return(-1); }
+ if (sl == NULL || data == NULL) { return (-1); }
// align read size
if ((write_len % 4) != 0) { write_len += 4 - (write_len % 4); }
@@ -87,9 +91,9 @@ static int mem_write(stlink_t *sl, uint32_t addr, void *data, uint16_t len) {
memcpy(&sl->q_buf[offset], data, len);
// address and length must be aligned
- if (stlink_write_mem32(sl, addr - offset, write_len) != 0) { return(-1); }
+ if (stlink_write_mem32(sl, addr - offset, write_len) != 0) { return (-1); }
- return(0);
+ return (0);
}
/* For the SYS_WRITE0 call, we don't know the size of the null-terminated buffer
@@ -110,7 +114,7 @@ static int mem_write(stlink_t *sl, uint32_t addr, void *data, uint16_t len) {
#define O_BINARY 0
#endif
-static int open_mode_flags[12] = {
+static int32_t open_mode_flags[12] = {
O_RDONLY,
O_RDONLY | O_BINARY,
O_RDWR,
@@ -125,11 +129,11 @@ static int open_mode_flags[12] = {
O_RDWR | O_CREAT | O_APPEND | O_BINARY
};
-static int saved_errno = 0;
+static int32_t saved_errno = 0;
-int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
+int32_t do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
- if (sl == NULL || ret == NULL) { return(-1); }
+ if (sl == NULL || ret == NULL) { return (-1); }
DLOG("Do semihosting R0=0x%08x R1=0x%08x\n", r0, r1);
@@ -145,7 +149,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
if (mem_read(sl, r1, args, sizeof(args)) != 0) {
DLOG("Semihosting SYS_OPEN error: cannot read args from target memory\n");
*ret = -1;
- return(-1);
+ return (-1);
}
name_address = args[0];
@@ -156,7 +160,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
/* Invalid mode */
DLOG("Semihosting SYS_OPEN error: invalid mode %d\n", mode);
*ret = -1;
- return(-1);
+ return (-1);
}
/* Add the trailing zero that is not counted in the length argument (see
@@ -167,7 +171,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
if (name_len > MAX_BUFFER_SIZE) {
DLOG("Semihosting SYS_OPEN error: name buffer size is too big %d\n", name_len);
*ret = -1;
- return(-1);
+ return (-1);
}
name = malloc(name_len);
@@ -175,14 +179,14 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
if (name == NULL) {
DLOG("Semihosting SYS_OPEN error: cannot allocate name buffer\n");
*ret = -1;
- return(-1);
+ return (-1);
}
if (mem_read(sl, name_address, name, name_len) != 0) {
free(name);
*ret = -1;
DLOG("Semihosting SYS_OPEN error: cannot read name from target memory\n");
- return(-1);
+ return (-1);
}
DLOG("Semihosting: open('%s', (SH open mode)%d, 0644)\n", name, mode);
@@ -198,15 +202,15 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
case SEMIHOST_SYS_CLOSE:
{
uint32_t args[1];
- int fd;
+ int32_t fd;
if (mem_read(sl, r1, args, sizeof(args)) != 0) {
DLOG("Semihosting SYS_CLOSE error: cannot read args from target memory\n");
*ret = -1;
- return(-1);
+ return (-1);
}
- fd = (int)args[0];
+ fd = (int32_t)args[0];
DLOG("Semihosting: close(%d)\n", fd);
@@ -220,17 +224,17 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
{
uint32_t args[3];
uint32_t buffer_address;
- int fd;
+ int32_t fd;
uint32_t buffer_len;
void *buffer;
if (mem_read(sl, r1, args, sizeof(args)) != 0) {
DLOG("Semihosting SYS_WRITE error: cannot read args from target memory\n");
*ret = -1;
- return(-1);
+ return (-1);
}
- fd = (int)args[0];
+ fd = (int32_t)args[0];
buffer_address = args[1];
buffer_len = args[2];
@@ -238,7 +242,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
DLOG("Semihosting SYS_WRITE error: buffer size is too big %d\n",
buffer_len);
*ret = buffer_len;
- return(-1);
+ return (-1);
}
buffer = malloc(buffer_len);
@@ -246,18 +250,17 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
if (buffer == NULL) {
DLOG("Semihosting SYS_WRITE error: cannot allocate buffer\n");
*ret = buffer_len;
- return(-1);
+ return (-1);
}
if (mem_read(sl, buffer_address, buffer, buffer_len) != 0) {
DLOG("Semihosting SYS_WRITE error: cannot read buffer from target memory\n");
free(buffer);
*ret = buffer_len;
- return(-1);
+ return (-1);
}
- DLOG("Semihosting: write(%d, target_addr:0x%08x, %u)\n", fd, buffer_address,
- buffer_len);
+ DLOG("Semihosting: write(%d, target_addr:0x%08x, %u)\n", fd, buffer_address, buffer_len);
*ret = (uint32_t)write(fd, buffer, buffer_len);
saved_errno = errno;
@@ -276,7 +279,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
{
uint32_t args[3];
uint32_t buffer_address;
- int fd;
+ int32_t fd;
uint32_t buffer_len;
void *buffer;
ssize_t read_result;
@@ -284,17 +287,17 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
if (mem_read(sl, r1, args, sizeof(args)) != 0) {
DLOG("Semihosting SYS_READ error: cannot read args from target memory\n");
*ret = -1;
- return(-1);
+ return (-1);
}
- fd = (int)args[0];
+ fd = (int32_t)args[0];
buffer_address = args[1];
buffer_len = args[2];
if (buffer_len > MAX_BUFFER_SIZE) {
DLOG("Semihosting SYS_READ error: buffer size is too big %d\n", buffer_len);
*ret = buffer_len;
- return(-1);
+ return (-1);
}
buffer = malloc(buffer_len);
@@ -302,7 +305,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
if (buffer == NULL) {
DLOG("Semihosting SYS_READ error: cannot allocatebuffer\n");
*ret = buffer_len;
- return(-1);
+ return (-1);
}
DLOG("Semihosting: read(%d, target_addr:0x%08x, %u)\n", fd, buffer_address,
@@ -318,7 +321,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
DLOG("Semihosting SYS_READ error: cannot write buffer to target memory\n");
free(buffer);
*ret = buffer_len;
- return(-1);
+ return (-1);
} else {
*ret = buffer_len - (uint32_t)read_result;
}
@@ -344,7 +347,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
if (mem_read(sl, r1, args, sizeof(args)) != 0) {
DLOG("Semihosting SYS_REMOVE error: cannot read args from target memory\n");
*ret = -1;
- return(-1);
+ return (-1);
}
name_address = args[0];
@@ -359,7 +362,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
DLOG("Semihosting SYS_REMOVE error: name buffer size is too big %d\n",
name_len);
*ret = -1;
- return(-1);
+ return (-1);
}
name = malloc(name_len);
@@ -367,14 +370,14 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
if (name == NULL) {
DLOG("Semihosting SYS_REMOVE error: cannot allocate name buffer\n");
*ret = -1;
- return(-1);
+ return (-1);
}
if (mem_read(sl, name_address, name, name_len) != 0) {
free(name);
*ret = -1;
DLOG("Semihosting SYS_REMOVE error: cannot read name from target memory\n");
- return(-1);
+ return (-1);
}
DLOG("Semihosting: unlink('%s')\n", name);
@@ -387,19 +390,19 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
case SEMIHOST_SYS_SEEK:
{
uint32_t args[2];
- int fd;
+ int32_t fd;
off_t offset;
if (mem_read(sl, r1, args, sizeof(args)) != 0) {
DLOG("Semihosting SYS_SEEK error: cannot read args from target memory\n");
*ret = -1;
- return(-1);
+ return (-1);
}
- fd = (int)args[0];
+ fd = (int32_t)args[0];
offset = (off_t)args[1];
- DLOG("Semihosting: lseek(%d, %d, SEEK_SET)\n", fd, (int)offset);
+ DLOG("Semihosting: lseek(%d, %d, SEEK_SET)\n", fd, (int32_t)offset);
*ret = (uint32_t)lseek(fd, offset, SEEK_SET);
saved_errno = errno;
@@ -433,11 +436,11 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
while (true) {
if (mem_read(sl, r1, buf, WRITE0_BUFFER_SIZE) != 0) {
DLOG("Semihosting WRITE0: cannot read target memory at 0x%08x\n", r1);
- return(-1);
+ return (-1);
}
- for (int i = 0; i < WRITE0_BUFFER_SIZE; i++) {
- if (buf[i] == 0) { return(0); }
+ for (int32_t i = 0; i < WRITE0_BUFFER_SIZE; i++) {
+ if (buf[i] == 0) { return (0); }
fprintf(stderr, "%c", buf[i]);
}
@@ -449,7 +452,7 @@ int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) {
}
default:
fprintf(stderr, "semihosting: unsupported call %#x\n", r0);
- return(-1);
+ return (-1);
}
- return(0);
+ return (0);
}