|
|
|
@ -5,12 +5,14 @@ |
|
|
|
#include "elfloader.h" |
|
|
|
#include "platform.h" |
|
|
|
#include "byteorder.h" |
|
|
|
#include "trap.h" |
|
|
|
#include <algorithm> |
|
|
|
#include <assert.h> |
|
|
|
#include <vector> |
|
|
|
#include <queue> |
|
|
|
#include <iostream> |
|
|
|
#include <fstream> |
|
|
|
#include <sstream> |
|
|
|
#include <iomanip> |
|
|
|
#include <stdio.h> |
|
|
|
#include <unistd.h> |
|
|
|
@ -86,6 +88,13 @@ void htif_t::start() |
|
|
|
reset(); |
|
|
|
} |
|
|
|
|
|
|
|
static void bad_address(const std::string& situation, reg_t addr) |
|
|
|
{ |
|
|
|
std::cerr << "Access exception occurred while " << situation << ":\n"; |
|
|
|
std::cerr << "Memory address 0x" << std::hex << addr << " is invalid\n"; |
|
|
|
exit(-1); |
|
|
|
} |
|
|
|
|
|
|
|
std::map<std::string, uint64_t> htif_t::load_payload(const std::string& payload, reg_t* entry) |
|
|
|
{ |
|
|
|
std::string path; |
|
|
|
@ -119,7 +128,12 @@ std::map<std::string, uint64_t> htif_t::load_payload(const std::string& payload, |
|
|
|
htif_t* htif; |
|
|
|
} preload_aware_memif(this); |
|
|
|
|
|
|
|
return load_elf(path.c_str(), &preload_aware_memif, entry); |
|
|
|
try { |
|
|
|
return load_elf(path.c_str(), &preload_aware_memif, entry); |
|
|
|
} catch (mem_trap_t& t) { |
|
|
|
bad_address("loading payload " + payload, t.get_tval()); |
|
|
|
abort(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void htif_t::load_program() |
|
|
|
@ -218,19 +232,36 @@ int htif_t::run() |
|
|
|
|
|
|
|
while (!signal_exit && exitcode == 0) |
|
|
|
{ |
|
|
|
if (auto tohost = from_target(mem.read_uint64(tohost_addr))) { |
|
|
|
mem.write_uint64(tohost_addr, target_endian<uint64_t>::zero); |
|
|
|
command_t cmd(mem, tohost, fromhost_callback); |
|
|
|
device_list.handle_command(cmd); |
|
|
|
uint64_t tohost; |
|
|
|
|
|
|
|
try { |
|
|
|
if ((tohost = from_target(mem.read_uint64(tohost_addr))) != 0) |
|
|
|
mem.write_uint64(tohost_addr, target_endian<uint64_t>::zero); |
|
|
|
} catch (mem_trap_t& t) { |
|
|
|
bad_address("accessing tohost", t.get_tval()); |
|
|
|
} |
|
|
|
|
|
|
|
if (tohost != 0) { |
|
|
|
try { |
|
|
|
command_t cmd(mem, tohost, fromhost_callback); |
|
|
|
device_list.handle_command(cmd); |
|
|
|
device_list.tick(); |
|
|
|
} catch (mem_trap_t& t) { |
|
|
|
std::stringstream tohost_hex; |
|
|
|
tohost_hex << std::hex << tohost; |
|
|
|
bad_address("host was accessing memory on behalf of target (tohost = 0x" + tohost_hex.str() + ")", t.get_tval()); |
|
|
|
} |
|
|
|
} else { |
|
|
|
idle(); |
|
|
|
} |
|
|
|
|
|
|
|
device_list.tick(); |
|
|
|
|
|
|
|
if (!fromhost_queue.empty() && !mem.read_uint64(fromhost_addr)) { |
|
|
|
mem.write_uint64(fromhost_addr, to_target(fromhost_queue.front())); |
|
|
|
fromhost_queue.pop(); |
|
|
|
try { |
|
|
|
if (!fromhost_queue.empty() && !mem.read_uint64(fromhost_addr)) { |
|
|
|
mem.write_uint64(fromhost_addr, to_target(fromhost_queue.front())); |
|
|
|
fromhost_queue.pop(); |
|
|
|
} |
|
|
|
} catch (mem_trap_t& t) { |
|
|
|
bad_address("accessing fromhost", t.get_tval()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|