applies clang-format
This commit is contained in:
parent
37db31fb4b
commit
551822916c
|
@ -380,7 +380,7 @@ protected:
|
||||||
bool tohost_lower_written = false;
|
bool tohost_lower_written = false;
|
||||||
riscv_instrumentation_if instr_if;
|
riscv_instrumentation_if instr_if;
|
||||||
|
|
||||||
semihosting_cb_t<reg_t> semihosting_cb;
|
semihosting_cb_t<reg_t> semihosting_cb;
|
||||||
|
|
||||||
using mem_type = util::sparse_array<uint8_t, 1ULL << 32>;
|
using mem_type = util::sparse_array<uint8_t, 1ULL << 32>;
|
||||||
using csr_type = util::sparse_array<typename traits<BASE>::reg_t, 1ULL << 12, 12>;
|
using csr_type = util::sparse_array<typename traits<BASE>::reg_t, 1ULL << 12, 12>;
|
||||||
|
|
|
@ -1,35 +1,36 @@
|
||||||
#include "semihosting.h"
|
#include "semihosting.h"
|
||||||
#include <cstdint>
|
|
||||||
#include <map>
|
|
||||||
#include <iss/vm_types.h>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <iss/vm_types.h>
|
||||||
|
#include <map>
|
||||||
|
#include <stdexcept>
|
||||||
// explanation of syscalls can be found at https://github.com/SpinalHDL/openocd_riscv/blob/riscv_spinal/src/target/semihosting_common.h
|
// explanation of syscalls can be found at https://github.com/SpinalHDL/openocd_riscv/blob/riscv_spinal/src/target/semihosting_common.h
|
||||||
|
|
||||||
const char *SYS_OPEN_MODES_STRS[] = { "r", "rb", "r+", "r+b", "w", "wb", "w+", "w+b", "a", "ab", "a+", "a+b" };
|
const char* SYS_OPEN_MODES_STRS[] = {"r", "rb", "r+", "r+b", "w", "wb", "w+", "w+b", "a", "ab", "a+", "a+b"};
|
||||||
|
|
||||||
template <typename T> T sh_read_field(iss::arch_if* arch_if_ptr, T addr, int len=4) {
|
template <typename T> T sh_read_field(iss::arch_if* arch_if_ptr, T addr, int len = 4) {
|
||||||
uint8_t bytes[4];
|
uint8_t bytes[4];
|
||||||
auto res = arch_if_ptr->read(iss::address_type::PHYSICAL, iss::access_type::DEBUG_READ, 0, addr, 4, &bytes[0]);
|
auto res = arch_if_ptr->read(iss::address_type::PHYSICAL, iss::access_type::DEBUG_READ, 0, addr, 4, &bytes[0]);
|
||||||
//auto res = arch_if_ptr->read(iss::address_type::PHYSICAL, iss::access_type::DEBUG_READ, 0, *parameter, 1, &character);
|
// auto res = arch_if_ptr->read(iss::address_type::PHYSICAL, iss::access_type::DEBUG_READ, 0, *parameter, 1, &character);
|
||||||
|
|
||||||
if(res != iss::Ok){
|
if(res != iss::Ok) {
|
||||||
return 0; //TODO THROW ERROR
|
return 0; // TODO THROW ERROR
|
||||||
} else return static_cast<T>(bytes[0]) | (static_cast<T>(bytes[1]) << 8) | (static_cast<T>(bytes[2]) << 16) | (static_cast<T>(bytes[3]) << 24);
|
} else
|
||||||
|
return static_cast<T>(bytes[0]) | (static_cast<T>(bytes[1]) << 8) | (static_cast<T>(bytes[2]) << 16) |
|
||||||
|
(static_cast<T>(bytes[3]) << 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> std::string sh_read_string(iss::arch_if* arch_if_ptr, T addr, T str_len){
|
template <typename T> std::string sh_read_string(iss::arch_if* arch_if_ptr, T addr, T str_len) {
|
||||||
std::vector<uint8_t> buffer(str_len);
|
std::vector<uint8_t> buffer(str_len);
|
||||||
for (int i = 0; i < str_len; i++ ) {
|
for(int i = 0; i < str_len; i++) {
|
||||||
buffer[i] = sh_read_field(arch_if_ptr, addr + i, 1);
|
buffer[i] = sh_read_field(arch_if_ptr, addr + i, 1);
|
||||||
}
|
}
|
||||||
std::string str(buffer.begin(), buffer.end());
|
std::string str(buffer.begin(), buffer.end());
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arch_if_ptr, T* call_number, T* parameter) {
|
template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arch_if_ptr, T* call_number, T* parameter) {
|
||||||
static std::map<T, FILE *> openFiles;
|
static std::map<T, FILE*> openFiles;
|
||||||
static T file_count = 3;
|
static T file_count = 3;
|
||||||
static T semihostingErrno;
|
static T semihostingErrno;
|
||||||
|
|
||||||
|
@ -38,18 +39,18 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc
|
||||||
auto end = std::chrono::high_resolution_clock::now(); // end measurement
|
auto end = std::chrono::high_resolution_clock::now(); // end measurement
|
||||||
auto elapsed = end - timeVar;
|
auto elapsed = end - timeVar;
|
||||||
auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count();
|
auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count();
|
||||||
*call_number = millis; //TODO get time now
|
*call_number = millis; // TODO get time now
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case semihosting_syscalls::SYS_CLOSE: {
|
case semihosting_syscalls::SYS_CLOSE: {
|
||||||
T file_handle = *parameter;
|
T file_handle = *parameter;
|
||||||
if (openFiles.size() <= file_handle && file_handle < 0) {
|
if(openFiles.size() <= file_handle && file_handle < 0) {
|
||||||
semihostingErrno = EBADF;
|
semihostingErrno = EBADF;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto file = openFiles[file_handle];
|
auto file = openFiles[file_handle];
|
||||||
openFiles.erase(file_handle);
|
openFiles.erase(file_handle);
|
||||||
if (!(file == stdin || file == stdout || file == stderr)) {
|
if(!(file == stdin || file == stdout || file == stderr)) {
|
||||||
int i = fclose(file);
|
int i = fclose(file);
|
||||||
*call_number = i;
|
*call_number = i;
|
||||||
} else {
|
} else {
|
||||||
|
@ -80,7 +81,8 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc
|
||||||
auto file = openFiles[file_handle];
|
auto file = openFiles[file_handle];
|
||||||
|
|
||||||
size_t currentPos = ftell(file);
|
size_t currentPos = ftell(file);
|
||||||
if (currentPos < 0) throw std::runtime_error("SYS_FLEN negative value");
|
if(currentPos < 0)
|
||||||
|
throw std::runtime_error("SYS_FLEN negative value");
|
||||||
fseek(file, 0, SEEK_END);
|
fseek(file, 0, SEEK_END);
|
||||||
size_t length = ftell(file);
|
size_t length = ftell(file);
|
||||||
fseek(file, currentPos, SEEK_SET);
|
fseek(file, currentPos, SEEK_SET);
|
||||||
|
@ -107,30 +109,30 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc
|
||||||
}
|
}
|
||||||
case semihosting_syscalls::SYS_OPEN: {
|
case semihosting_syscalls::SYS_OPEN: {
|
||||||
T path_str_addr = sh_read_field<T>(arch_if_ptr, *parameter);
|
T path_str_addr = sh_read_field<T>(arch_if_ptr, *parameter);
|
||||||
T mode = sh_read_field<T>(arch_if_ptr, 4+(*parameter));
|
T mode = sh_read_field<T>(arch_if_ptr, 4 + (*parameter));
|
||||||
T path_len = sh_read_field<T>(arch_if_ptr, 8+(*parameter));
|
T path_len = sh_read_field<T>(arch_if_ptr, 8 + (*parameter));
|
||||||
|
|
||||||
std::string path_str = sh_read_string<T>(arch_if_ptr, path_str_addr, path_len);
|
std::string path_str = sh_read_string<T>(arch_if_ptr, path_str_addr, path_len);
|
||||||
|
|
||||||
//TODO LOG INFO
|
// TODO LOG INFO
|
||||||
|
|
||||||
if (mode >= 12) {
|
if(mode >= 12) {
|
||||||
//TODO throw ERROR
|
// TODO throw ERROR
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *file = nullptr;
|
FILE* file = nullptr;
|
||||||
if(path_str == ":tt") {
|
if(path_str == ":tt") {
|
||||||
if (mode < 4)
|
if(mode < 4)
|
||||||
file = stdin;
|
file = stdin;
|
||||||
else if (mode < 8)
|
else if(mode < 8)
|
||||||
file = stdout;
|
file = stdout;
|
||||||
else
|
else
|
||||||
file = stderr;
|
file = stderr;
|
||||||
} else {
|
} else {
|
||||||
file = fopen(path_str.c_str(), SYS_OPEN_MODES_STRS[mode]);
|
file = fopen(path_str.c_str(), SYS_OPEN_MODES_STRS[mode]);
|
||||||
if (file == nullptr) {
|
if(file == nullptr) {
|
||||||
//TODO throw error
|
// TODO throw error
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,45 +140,41 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc
|
||||||
openFiles[file_handle] = file;
|
openFiles[file_handle] = file;
|
||||||
*call_number = file_handle;
|
*call_number = file_handle;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
case semihosting_syscalls::SYS_READ: {
|
case semihosting_syscalls::SYS_READ: {
|
||||||
T file_handle = sh_read_field<T>(arch_if_ptr, (*parameter)+4);
|
T file_handle = sh_read_field<T>(arch_if_ptr, (*parameter) + 4);
|
||||||
T addr = sh_read_field<T>(arch_if_ptr, *parameter);
|
T addr = sh_read_field<T>(arch_if_ptr, *parameter);
|
||||||
T count = sh_read_field<T>(arch_if_ptr, (*parameter)+8);
|
T count = sh_read_field<T>(arch_if_ptr, (*parameter) + 8);
|
||||||
|
|
||||||
auto file = openFiles[file_handle];
|
auto file = openFiles[file_handle];
|
||||||
|
|
||||||
std::vector<uint8_t> buffer(count);
|
std::vector<uint8_t> buffer(count);
|
||||||
size_t num_read = 0;
|
size_t num_read = 0;
|
||||||
if (file == stdin)
|
if(file == stdin) {
|
||||||
{
|
|
||||||
// when reading from stdin: mimic behaviour from read syscall
|
// when reading from stdin: mimic behaviour from read syscall
|
||||||
// and return on newline.
|
// and return on newline.
|
||||||
while (num_read < count)
|
while(num_read < count) {
|
||||||
{
|
|
||||||
char c = fgetc(file);
|
char c = fgetc(file);
|
||||||
buffer[num_read] = c;
|
buffer[num_read] = c;
|
||||||
num_read++;
|
num_read++;
|
||||||
if (c == '\n')
|
if(c == '\n')
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
num_read = fread(buffer.data(), 1, count, file);
|
num_read = fread(buffer.data(), 1, count, file);
|
||||||
}
|
}
|
||||||
buffer.resize(num_read);
|
buffer.resize(num_read);
|
||||||
for(int i = 0; i<num_read; i++) {
|
for(int i = 0; i < num_read; i++) {
|
||||||
auto res = arch_if_ptr->write(iss::address_type::PHYSICAL, iss::access_type::DEBUG_READ, 0, addr+i, 1, &buffer[i]);
|
auto res = arch_if_ptr->write(iss::address_type::PHYSICAL, iss::access_type::DEBUG_READ, 0, addr + i, 1, &buffer[i]);
|
||||||
if(res != iss::Ok)
|
if(res != iss::Ok)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*call_number = count - num_read;
|
*call_number = count - num_read;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
case semihosting_syscalls::SYS_READC: {
|
case semihosting_syscalls::SYS_READC: {
|
||||||
uint8_t character = getchar();
|
uint8_t character = getchar();
|
||||||
//character = getchar();
|
// character = getchar();
|
||||||
/*if(character != iss::Ok)
|
/*if(character != iss::Ok)
|
||||||
std::cout << "Not OK";
|
std::cout << "Not OK";
|
||||||
return;*/
|
return;*/
|
||||||
|
@ -185,17 +183,18 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc
|
||||||
}
|
}
|
||||||
case semihosting_syscalls::SYS_REMOVE: {
|
case semihosting_syscalls::SYS_REMOVE: {
|
||||||
T path_str_addr = sh_read_field<T>(arch_if_ptr, *parameter);
|
T path_str_addr = sh_read_field<T>(arch_if_ptr, *parameter);
|
||||||
T path_len = sh_read_field<T>(arch_if_ptr, (*parameter)+4);
|
T path_len = sh_read_field<T>(arch_if_ptr, (*parameter) + 4);
|
||||||
std::string path_str = sh_read_string<T>(arch_if_ptr, path_str_addr, path_len);
|
std::string path_str = sh_read_string<T>(arch_if_ptr, path_str_addr, path_len);
|
||||||
|
|
||||||
if(remove(path_str.c_str())<0) *call_number = -1;
|
if(remove(path_str.c_str()) < 0)
|
||||||
|
*call_number = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case semihosting_syscalls::SYS_RENAME: {
|
case semihosting_syscalls::SYS_RENAME: {
|
||||||
T path_str_addr_old = sh_read_field<T>(arch_if_ptr, *parameter);
|
T path_str_addr_old = sh_read_field<T>(arch_if_ptr, *parameter);
|
||||||
T path_len_old = sh_read_field<T>(arch_if_ptr, (*parameter)+4);
|
T path_len_old = sh_read_field<T>(arch_if_ptr, (*parameter) + 4);
|
||||||
T path_str_addr_new = sh_read_field<T>(arch_if_ptr, (*parameter)+8);
|
T path_str_addr_new = sh_read_field<T>(arch_if_ptr, (*parameter) + 8);
|
||||||
T path_len_new = sh_read_field<T>(arch_if_ptr, (*parameter)+12);
|
T path_len_new = sh_read_field<T>(arch_if_ptr, (*parameter) + 12);
|
||||||
|
|
||||||
std::string path_str_old = sh_read_string<T>(arch_if_ptr, path_str_addr_old, path_len_old);
|
std::string path_str_old = sh_read_string<T>(arch_if_ptr, path_str_addr_old, path_len_old);
|
||||||
std::string path_str_new = sh_read_string<T>(arch_if_ptr, path_str_addr_new, path_len_new);
|
std::string path_str_new = sh_read_string<T>(arch_if_ptr, path_str_addr_new, path_len_new);
|
||||||
|
@ -204,17 +203,18 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc
|
||||||
}
|
}
|
||||||
case semihosting_syscalls::SYS_SEEK: {
|
case semihosting_syscalls::SYS_SEEK: {
|
||||||
T file_handle = sh_read_field<T>(arch_if_ptr, *parameter);
|
T file_handle = sh_read_field<T>(arch_if_ptr, *parameter);
|
||||||
T pos = sh_read_field<T>(arch_if_ptr, (*parameter)+1);
|
T pos = sh_read_field<T>(arch_if_ptr, (*parameter) + 1);
|
||||||
auto file = openFiles[file_handle];
|
auto file = openFiles[file_handle];
|
||||||
|
|
||||||
int retval = fseek(file, pos, SEEK_SET);
|
int retval = fseek(file, pos, SEEK_SET);
|
||||||
if(retval<0) throw std::runtime_error("SYS_SEEK negative return value");
|
if(retval < 0)
|
||||||
|
throw std::runtime_error("SYS_SEEK negative return value");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case semihosting_syscalls::SYS_SYSTEM: {
|
case semihosting_syscalls::SYS_SYSTEM: {
|
||||||
T cmd_addr = sh_read_field<T>(arch_if_ptr, *parameter);
|
T cmd_addr = sh_read_field<T>(arch_if_ptr, *parameter);
|
||||||
T cmd_len = sh_read_field<T>(arch_if_ptr, (*parameter)+1);
|
T cmd_len = sh_read_field<T>(arch_if_ptr, (*parameter) + 1);
|
||||||
std::string cmd = sh_read_string<T>(arch_if_ptr, cmd_addr, cmd_len);
|
std::string cmd = sh_read_string<T>(arch_if_ptr, cmd_addr, cmd_len);
|
||||||
system(cmd.c_str());
|
system(cmd.c_str());
|
||||||
break;
|
break;
|
||||||
|
@ -224,16 +224,16 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case semihosting_syscalls::SYS_TIME: {
|
case semihosting_syscalls::SYS_TIME: {
|
||||||
//returns time in seconds scince 01.01.1970 00:00
|
// returns time in seconds scince 01.01.1970 00:00
|
||||||
*call_number = time(NULL);
|
*call_number = time(NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case semihosting_syscalls::SYS_TMPNAM: {
|
case semihosting_syscalls::SYS_TMPNAM: {
|
||||||
T buffer_addr = sh_read_field<T>(arch_if_ptr, *parameter);
|
T buffer_addr = sh_read_field<T>(arch_if_ptr, *parameter);
|
||||||
T identifier = sh_read_field<T>(arch_if_ptr, (*parameter)+1);
|
T identifier = sh_read_field<T>(arch_if_ptr, (*parameter) + 1);
|
||||||
T buffer_len = sh_read_field<T>(arch_if_ptr, (*parameter)+2);
|
T buffer_len = sh_read_field<T>(arch_if_ptr, (*parameter) + 2);
|
||||||
|
|
||||||
if (identifier > 255) {
|
if(identifier > 255) {
|
||||||
*call_number = -1;
|
*call_number = -1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -243,15 +243,16 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc
|
||||||
|
|
||||||
for(int i = 0; i < buffer_len; i++) {
|
for(int i = 0; i < buffer_len; i++) {
|
||||||
uint8_t character = filename[i];
|
uint8_t character = filename[i];
|
||||||
auto res = arch_if_ptr->write(iss::address_type::PHYSICAL, iss::access_type::DEBUG_READ, 0, (*parameter)+i, 1, &character);
|
auto res = arch_if_ptr->write(iss::address_type::PHYSICAL, iss::access_type::DEBUG_READ, 0, (*parameter) + i, 1, &character);
|
||||||
if(res != iss::Ok) return;
|
if(res != iss::Ok)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case semihosting_syscalls::SYS_WRITE: {
|
case semihosting_syscalls::SYS_WRITE: {
|
||||||
T file_handle = sh_read_field<T>(arch_if_ptr, (*parameter)+4);
|
T file_handle = sh_read_field<T>(arch_if_ptr, (*parameter) + 4);
|
||||||
T addr = sh_read_field<T>(arch_if_ptr, *parameter);
|
T addr = sh_read_field<T>(arch_if_ptr, *parameter);
|
||||||
T count = sh_read_field<T>(arch_if_ptr, (*parameter)+8);
|
T count = sh_read_field<T>(arch_if_ptr, (*parameter) + 8);
|
||||||
|
|
||||||
auto file = openFiles[file_handle];
|
auto file = openFiles[file_handle];
|
||||||
std::string str = sh_read_string<T>(arch_if_ptr, addr, count);
|
std::string str = sh_read_string<T>(arch_if_ptr, addr, count);
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#ifndef _SEMIHOSTING_H_
|
#ifndef _SEMIHOSTING_H_
|
||||||
#define _SEMIHOSTING_H_
|
#define _SEMIHOSTING_H_
|
||||||
#include <iss/arch_if.h>
|
|
||||||
#include <functional>
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <functional>
|
||||||
|
#include <iss/arch_if.h>
|
||||||
/*
|
/*
|
||||||
* According to:
|
* According to:
|
||||||
* "Semihosting for AArch32 and AArch64, Release 2.0"
|
* "Semihosting for AArch32 and AArch64, Release 2.0"
|
||||||
|
@ -50,9 +50,10 @@ enum class semihosting_syscalls {
|
||||||
USER_CMD_0x1FF = 0x1FF,
|
USER_CMD_0x1FF = 0x1FF,
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T> struct semihosting_callback{
|
template <typename T> struct semihosting_callback {
|
||||||
std::chrono::high_resolution_clock::time_point timeVar;
|
std::chrono::high_resolution_clock::time_point timeVar;
|
||||||
semihosting_callback(): timeVar(std::chrono::high_resolution_clock::now()) {}
|
semihosting_callback()
|
||||||
|
: timeVar(std::chrono::high_resolution_clock::now()) {}
|
||||||
void operator()(iss::arch_if* arch_if_ptr, T* call_number, T* parameter);
|
void operator()(iss::arch_if* arch_if_ptr, T* call_number, T* parameter);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,7 @@ int main(int argc, char* argv[]) {
|
||||||
iss::vm_ptr vm{nullptr};
|
iss::vm_ptr vm{nullptr};
|
||||||
iss::cpu_ptr cpu{nullptr};
|
iss::cpu_ptr cpu{nullptr};
|
||||||
semihosting_callback<uint32_t> cb{};
|
semihosting_callback<uint32_t> cb{};
|
||||||
semihosting_cb_t<uint32_t> semihosting_cb = [&cb](iss::arch_if* i, uint32_t* a0, uint32_t* a1) {cb(i,a0,a1);};
|
semihosting_cb_t<uint32_t> semihosting_cb = [&cb](iss::arch_if* i, uint32_t* a0, uint32_t* a1) { cb(i, a0, a1); };
|
||||||
std::string isa_opt(clim["isa"].as<std::string>());
|
std::string isa_opt(clim["isa"].as<std::string>());
|
||||||
if(isa_opt.size() == 0 || isa_opt == "?") {
|
if(isa_opt.size() == 0 || isa_opt == "?") {
|
||||||
auto list = f.get_names();
|
auto list = f.get_names();
|
||||||
|
|
Loading…
Reference in New Issue