-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #454 from Fabien-Chouteau/semihosting
Prototype of ARM semihosting support
- Loading branch information
Showing
4 changed files
with
255 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
#include <stdio.h> | ||
#include <string.h> | ||
|
||
#include "semihosting.h" | ||
|
||
#include <stlink.h> | ||
#include <stlink/logging.h> | ||
|
||
static int mem_read_u8(stlink_t *sl, uint32_t addr, uint8_t *data) | ||
{ | ||
int offset = addr % 4; | ||
int len = 4; | ||
|
||
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; | ||
} | ||
|
||
*data = sl->q_buf[offset]; | ||
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); | ||
|
||
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; | ||
} | ||
|
||
memcpy(data, &sl->q_buf[offset], sizeof(*data)); | ||
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); | ||
|
||
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; | ||
} | ||
|
||
memcpy(data, &sl->q_buf[offset], sizeof(*data)); | ||
return 0; | ||
} | ||
#endif | ||
|
||
static int mem_read(stlink_t *sl, uint32_t addr, uint8_t *data, uint16_t len) | ||
{ | ||
int offset = addr % 4; | ||
int read_len = len + offset; | ||
|
||
if (sl == NULL || data == NULL) { | ||
return -1; | ||
} | ||
|
||
/* Align read size */ | ||
if ((read_len % 4) != 0) { | ||
read_len += 4 - (read_len % 4); | ||
} | ||
|
||
/* Read address and length must be aligned */ | ||
if (stlink_read_mem32(sl, addr - offset, read_len) != 0) { | ||
return -1; | ||
} | ||
|
||
memcpy(data, &sl->q_buf[offset], len); | ||
return 0; | ||
} | ||
|
||
#define WRITE0_BUFFER_SIZE 64 | ||
|
||
int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret) { | ||
|
||
if (sl == NULL || ret == NULL) { | ||
return -1; | ||
} | ||
|
||
switch (r0) { | ||
case SYS_WRITEC: | ||
{ | ||
uint8_t c; | ||
if (mem_read_u8(sl, r1, &c) == 0) { | ||
fprintf(stderr, "%c", c); | ||
} | ||
break; | ||
} | ||
case SYS_WRITE0: | ||
{ | ||
uint8_t buf[WRITE0_BUFFER_SIZE]; | ||
|
||
while (true) { | ||
if (mem_read(sl, r1, buf, WRITE0_BUFFER_SIZE) != 0 ) { | ||
return -1; | ||
} | ||
for (int i = 0; i < WRITE0_BUFFER_SIZE; i++) { | ||
if (buf[i] == 0) { | ||
return 0; | ||
} | ||
fprintf(stderr, "%c", buf[i]); | ||
} | ||
r1 += WRITE0_BUFFER_SIZE; | ||
} | ||
break; | ||
} | ||
default: | ||
fprintf(stderr, "semihosting: unsupported call 0x%#x\n", r0); | ||
return -1; | ||
} | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#ifndef _SEMIHOSTING_H_ | ||
#define _SEMIHOSTING_H_ | ||
|
||
#include <stlink.h> | ||
|
||
#define SYS_OPEN 0x01 | ||
#define SYS_CLOSE 0x02 | ||
#define SYS_WRITEC 0x03 | ||
#define SYS_WRITE0 0x04 | ||
#define SYS_WRITE 0x05 | ||
#define SYS_READ 0x06 | ||
#define SYS_READC 0x07 | ||
#define SYS_ISERROR 0x08 | ||
#define SYS_ISTTY 0x09 | ||
#define SYS_SEEK 0x0A | ||
|
||
#define SYS_FLEN 0x0C | ||
#define SYS_TMPNAM 0x0D | ||
#define SYS_REMOVE 0x0E | ||
#define SYS_RENAME 0x0E | ||
#define SYS_CLOCK 0x10 | ||
#define SYS_TIME 0x11 | ||
|
||
#define SYS_ERRNO 0x13 | ||
|
||
#define SYS_GET_CMD 0x15 | ||
#define SYS_HEAPINFO 0x16 | ||
|
||
#define SYS_ELAPSED 0x30 | ||
#define SYS_TICKFREQ 0x31 | ||
|
||
int do_semihosting (stlink_t *sl, uint32_t r0, uint32_t r1, uint32_t *ret); | ||
|
||
#endif /* ! _SEMIHOSTING_H_ */ |