2024-01-08 17:17:59 +01:00
|
|
|
#include "semihosting.h"
|
2024-01-10 10:15:05 +01:00
|
|
|
#include <cstdint>
|
2024-01-08 17:17:59 +01:00
|
|
|
#include <iss/vm_types.h>
|
|
|
|
#include <stdexcept>
|
2024-01-10 10:15:05 +01:00
|
|
|
// explanation of syscalls can be found at https://github.com/SpinalHDL/openocd_riscv/blob/riscv_spinal/src/target/semihosting_common.h
|
2024-01-09 12:50:41 +01:00
|
|
|
template <typename T> void semihosting_callback(iss::arch_if* arch_if_ptr, T call_number, T parameter) {
|
2024-01-10 10:15:05 +01:00
|
|
|
switch(static_cast<semihosting_syscalls>(call_number)) {
|
|
|
|
case semihosting_syscalls::SYS_CLOCK: {
|
2024-01-09 12:50:41 +01:00
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_CLOSE: {
|
2024-01-09 12:50:41 +01:00
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_ELAPSED: {
|
2024-01-09 12:50:41 +01:00
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_ERRNO: {
|
2024-01-09 12:50:41 +01:00
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_EXIT: {
|
|
|
|
|
|
|
|
throw std::runtime_error("ISS terminated by Semihost: SYS_EXIT");
|
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_EXIT_EXTENDED: {
|
|
|
|
throw std::runtime_error("ISS terminated by Semihost: SYS_EXIT_EXTENDED");
|
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_FLEN: {
|
2024-01-09 12:50:41 +01:00
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_GET_CMDLINE: {
|
2024-01-09 12:50:41 +01:00
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_HEAPINFO: {
|
2024-01-09 12:50:41 +01:00
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_ISERROR: {
|
2024-01-09 12:50:41 +01:00
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_ISTTY: {
|
2024-01-09 12:50:41 +01:00
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_OPEN: {
|
2024-01-09 12:50:41 +01:00
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_READ: {
|
2024-01-09 12:50:41 +01:00
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_READC: {
|
2024-01-09 12:50:41 +01:00
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_REMOVE: {
|
2024-01-09 12:50:41 +01:00
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_RENAME: {
|
2024-01-09 12:50:41 +01:00
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_SEEK: {
|
2024-01-09 12:50:41 +01:00
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_SYSTEM: {
|
2024-01-09 12:50:41 +01:00
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_TICKFREQ: {
|
2024-01-09 12:50:41 +01:00
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_TIME: {
|
2024-01-09 12:50:41 +01:00
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_TMPNAM: {
|
2024-01-09 12:50:41 +01:00
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_WRITE: {
|
2024-01-09 12:50:41 +01:00
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_WRITEC: {
|
|
|
|
uint8_t character;
|
|
|
|
auto res = arch_if_ptr->read(iss::address_type::PHYSICAL, iss::access_type::DEBUG_READ, 0, parameter, 1, &character);
|
|
|
|
if(res != iss::Ok)
|
|
|
|
return;
|
|
|
|
putchar(character);
|
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::SYS_WRITE0: {
|
2024-01-08 17:17:59 +01:00
|
|
|
uint8_t character;
|
|
|
|
while(1) {
|
2024-01-09 12:50:41 +01:00
|
|
|
auto res = arch_if_ptr->read(iss::address_type::PHYSICAL, iss::access_type::DEBUG_READ, 0, parameter, 1, &character);
|
2024-01-08 17:17:59 +01:00
|
|
|
if(res != iss::Ok)
|
|
|
|
return;
|
|
|
|
if(character == 0)
|
|
|
|
break;
|
|
|
|
putchar(character);
|
2024-01-09 12:50:41 +01:00
|
|
|
parameter++;
|
2024-01-08 17:17:59 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
2024-01-09 12:50:41 +01:00
|
|
|
}
|
2024-01-10 10:15:05 +01:00
|
|
|
case semihosting_syscalls::USER_CMD_0x100: {
|
2024-01-09 12:50:41 +01:00
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case semihosting_syscalls::USER_CMD_0x1FF: {
|
2024-01-09 12:50:41 +01:00
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
|
|
|
}
|
2024-01-09 12:50:41 +01:00
|
|
|
default:
|
|
|
|
throw std::runtime_error("Semihosting Call not Implemented");
|
2024-01-10 10:15:05 +01:00
|
|
|
break;
|
2024-01-08 17:17:59 +01:00
|
|
|
}
|
|
|
|
}
|
2024-01-09 12:50:41 +01:00
|
|
|
template void semihosting_callback<uint32_t>(iss::arch_if* arch_if_ptr, uint32_t call_number, uint32_t parameter);
|
|
|
|
template void semihosting_callback<uint64_t>(iss::arch_if* arch_if_ptr, uint64_t call_number, uint64_t parameter);
|