// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "riscv/riscv_arm_semihost.h"

#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>

#include <cerrno>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <limits>
#include <string>
#include <utility>

#include "absl/functional/bind_front.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "mpact/sim/generic/register.h"
#include "mpact/sim/util/memory/memory_interface.h"

namespace mpact {
namespace sim {
namespace riscv {

RiscVArmSemihost::RiscVArmSemihost(BitWidth bit_width,
                                   util::MemoryInterface *i_memory_if,
                                   util::MemoryInterface *d_memory_if)
    : i_memory_if_(i_memory_if),
      d_memory_if_(d_memory_if),
      // Put the functions that implement the different semihosting operations
      // into a map according to their function code.
      semihost_operations_(
          {{kSysClose, absl::bind_front(&RiscVArmSemihost::SysClose, this)},
           {kSysClock, absl::bind_front(&RiscVArmSemihost::SysClock, this)},
           {kSysElapsed, absl::bind_front(&RiscVArmSemihost::SysElapsed, this)},
           {kSysErrno, absl::bind_front(&RiscVArmSemihost::SysErrno, this)},
           {kSysException,
            absl::bind_front(&RiscVArmSemihost::SysException, this)},
           {kSysFlen, absl::bind_front(&RiscVArmSemihost::SysFlen, this)},
           {kSysGetCmdline,
            absl::bind_front(&RiscVArmSemihost::SysGetCmdline, this)},
           {kSysHeapInfo,
            absl::bind_front(&RiscVArmSemihost::SysHeapInfo, this)},
           {kSysIsError, absl::bind_front(&RiscVArmSemihost::SysIsError, this)},
           {kSysIsTty, absl::bind_front(&RiscVArmSemihost::SysIsTty, this)},
           {kSysOpen, absl::bind_front(&RiscVArmSemihost::SysOpen, this)},
           {kSysRead, absl::bind_front(&RiscVArmSemihost::SysRead, this)},
           {kSysReadc, absl::bind_front(&RiscVArmSemihost::SysReadc, this)},
           {kSysRemove, absl::bind_front(&RiscVArmSemihost::SysRemove, this)},
           {kSysRename, absl::bind_front(&RiscVArmSemihost::SysRename, this)},
           {kSysSeek, absl::bind_front(&RiscVArmSemihost::SysSeek, this)},
           {kSysSystem, absl::bind_front(&RiscVArmSemihost::SysSystem, this)},
           {kSysTickFreq,
            absl::bind_front(&RiscVArmSemihost::SysTickFreq, this)},
           {kSysTime, absl::bind_front(&RiscVArmSemihost::SysTime, this)},
           {kSysTmpnam, absl::bind_front(&RiscVArmSemihost::SysTmpnam, this)},
           {kSysWrite, absl::bind_front(&RiscVArmSemihost::SysWrite, this)},
           {kSysWritec, absl::bind_front(&RiscVArmSemihost::SysWritec, this)},
           {kSysWrite0,
            absl::bind_front(&RiscVArmSemihost::SysWrite0, this)}}) {
  is_32_bit_ = bit_width == BitWidth::kWord32;
  // Pre-allocate some fixed length data buffers that are used across semihost
  // calls. Set the length according to the register width for those used to
  // fetch parameters from data memory.
  db_inst_ = db_factory_.Allocate<uint32_t>(3);
  db1_ = is_32_bit_ ? db_factory_.Allocate<uint32_t>(1)
                    : db_factory_.Allocate<uint64_t>(1);
  db2_ = is_32_bit_ ? db_factory_.Allocate<uint32_t>(2)
                    : db_factory_.Allocate<uint64_t>(2);
  db3_ = is_32_bit_ ? db_factory_.Allocate<uint32_t>(3)
                    : db_factory_.Allocate<uint64_t>(3);
  db4_ = is_32_bit_ ? db_factory_.Allocate<uint32_t>(4)
                    : db_factory_.Allocate<uint64_t>(4);
  // stdin
  fd_map_.insert(std::make_pair(0, 0));
  // stdout
  fd_map_.insert(std::make_pair(1, 1));
  // stderr
  fd_map_.insert(std::make_pair(2, 2));
}

RiscVArmSemihost::~RiscVArmSemihost() {
  db_inst_->DecRef();
  db1_->DecRef();
  db2_->DecRef();
  db3_->DecRef();
  db4_->DecRef();
}

bool RiscVArmSemihost::IsSemihostingCall(const Instruction *inst) {
  if (inst == nullptr) return false;
  // Load the instruction words on either side of the ebreak instruction.
  uint64_t address = inst->address() - 4;
  i_memory_if_->Load(address, db_inst_, nullptr, nullptr);
  // Check to see if this is a semihosting call, if not, return.
  if ((db_inst_->Get<uint32_t>(0) != kSlliNop1f) ||
      (db_inst_->Get<uint32_t>(1) != kEBreak) ||
      (db_inst_->Get<uint32_t>(2) != kSraiNop7)) {
    return false;
  }
  return true;
}

void RiscVArmSemihost::OnEBreak(const Instruction *inst) {
  if (!IsSemihostingCall(inst)) return;

  // Handle the semihosting call.
  auto registers = inst->state()->registers();
  auto iter = registers->find(kA0Name);
  auto *a0 = iter == registers->end() ? nullptr : iter->second;
  iter = registers->find(kA1Name);
  auto *a1 = iter == registers->end() ? nullptr : iter->second;
  if ((a0 == nullptr) || (a1 == nullptr)) {
    LOG(ERROR) << "Failed to fetch semihost argument registers";
  }

  // Read the op number and the address of the parameter block from the
  // registers.
  uint64_t op_num = 0;
  uint64_t parameter = 0;
  if (is_32_bit_) {
    op_num = a0->data_buffer()->Get<uint32_t>(0);
    parameter = a1->data_buffer()->Get<uint32_t>(0);
  } else {
    op_num = a0->data_buffer()->Get<uint64_t>(0);
    parameter = a1->data_buffer()->Get<uint64_t>(0);
  }

  // Make sure the op number is valid.
  auto op = semihost_operations_.find(op_num);
  if (op == semihost_operations_.end()) {
    LOG(ERROR) << absl::StrCat("Illegal semihost operation (",
                               absl::Hex(op_num), ")");
    return;
  }

  // Call the semihosting op.
  uint64_t ret_val = 0;
  auto status = op->second(parameter, &ret_val);

  // In case of error, set an error code and log the error message.
  if (!status.ok()) {
    LOG(ERROR) << absl::StrCat("Semihost error: ", status.message());
    if (is_32_bit_) {
      a0->data_buffer()->Set<uint32_t>(0, std::numeric_limits<uint32_t>::max());
    } else {
      a0->data_buffer()->Set<uint64_t>(0, std::numeric_limits<uint64_t>::max());
    }
  } else {
    if (is_32_bit_) {
      a0->data_buffer()->Set<uint32_t>(0, static_cast<uint32_t>(ret_val));
    } else {
      a0->data_buffer()->Set<uint64_t>(0, ret_val);
    }
  }
}

absl::Status RiscVArmSemihost::SysClose(uint64_t parameter, uint64_t *ret_val) {
  // Load the file descriptor from the parameter block.
  d_memory_if_->Load(parameter, db1_, nullptr, nullptr);
  int target_fd = is_32_bit_ ? static_cast<int>(db1_->Get<uint32_t>(0))
                             : static_cast<int>(db1_->Get<uint64_t>(0));
  // Check to see that the target file descriptor is in the map, if not,
  // the fd is not for an opened file.
  auto iter = fd_map_.find(target_fd);
  if (iter == fd_map_.end()) {
    *ret_val = -1ULL;
    return absl::OkStatus();
  }
  // Get the host fd and close the file.
  int host_fd = iter->second;
  // If it's stdin, stdout, or stderr, ignore, just return ok.
  if (host_fd <= 2) {
    *ret_val = 0;
    return absl::OkStatus();
  }
  int ret = close(host_fd);
  if (!ret) {
    sys_errno_ = errno;
  } else {
    // Remove the file descriptor from the map.
    fd_map_.erase(iter);
  }
  *ret_val = static_cast<uint64_t>(ret);
  return absl::OkStatus();
}

// Currently not implemented, will implement once there is need for it.
absl::Status RiscVArmSemihost::SysClock(uint64_t parameter, uint64_t *ret_val) {
  return absl::UnimplementedError("SysClock not implemented");
  // TODO: Complete implementation.
}

// Currently not implemented, will implement once there is need for it.
absl::Status RiscVArmSemihost::SysElapsed(uint64_t parameter,
                                          uint64_t *ret_val) {
  return absl::UnimplementedError("SysElapsed not implemented");
  // TODO: Complete implementation.
}

// Return the value of the simulated errno.
absl::Status RiscVArmSemihost::SysErrno(uint64_t parameter, uint64_t *ret_val) {
  *ret_val = sys_errno_;
  return absl::OkStatus();
}

// Exception notification. The program should be terminated.
absl::Status RiscVArmSemihost::SysException(uint64_t parameter, uint64_t *) {
  // In gcc it seems like the parameter value is passed in the parameter
  // register for RV32, but stored in memory, and then a pointer passed in the
  // parameter register for RV64. A bit odd...
  uint32_t param_value;
  if (is_32_bit_) {
    param_value = static_cast<uint32_t>(parameter);
  } else {
    d_memory_if_->Load(parameter, db1_, nullptr, nullptr);
    param_value = static_cast<uint32_t>(db1_->Get<uint64_t>(0));
  }
  if (param_value == kAdpStoppedApplicationExit) {
    if (exit_callback_ != nullptr) {
      exit_callback_();
      return absl::OkStatus();
    }
    LOG(ERROR) << "Program exit not caught in ARM semihosting - no callback";
    return absl::NotFoundError("Exit callback not valid in ARM semihosting");
  }
  LOG(ERROR) << absl::StrCat(
      "Exception ", absl::Hex(param_value), " other than ApplicationExit (",
      absl::Hex(kAdpStoppedApplicationExit), ") are not implemented");
  return absl::UnimplementedError(
      "Exceptions other than ApplicationExit are not implemented");
}

// Return the length of a file given by the file descriptor.
absl::Status RiscVArmSemihost::SysFlen(uint64_t parameter, uint64_t *ret_val) {
  // Load the targeted file descriptor.
  d_memory_if_->Load(parameter, db1_, nullptr, nullptr);
  int target_fd = is_32_bit_ ? static_cast<int>(db1_->Get<uint32_t>(0))
                             : static_cast<int>(db1_->Get<uint64_t>(0));
  // Verify that the file descriptor is valid.
  auto iter = fd_map_.find(target_fd);
  if (iter == fd_map_.end()) {
    *ret_val = -1ULL;
    return absl::OkStatus();
  }
  auto host_fd = iter->second;
  // Get the file info, and get the file length.
  struct stat statbuf;
  int res = fstat(host_fd, &statbuf);
  if (res < 0) {
    sys_errno_ = errno;
    *ret_val = -1ULL;
    return absl::OkStatus();
  }
  *ret_val = static_cast<uint64_t>(statbuf.st_size);
  return absl::OkStatus();
}

// Currently unimplemented. Will implement if there is a demand.
absl::Status RiscVArmSemihost::SysGetCmdline(uint64_t parameter,
                                             uint64_t *ret_val) {
  d_memory_if_->Load(parameter, db2_, nullptr, nullptr);
  uint64_t buffer_address = is_32_bit_
                                ? static_cast<uint64_t>(db2_->Get<uint32_t>(0))
                                : static_cast<uint64_t>(db2_->Get<uint64_t>(0));
  size_t buffer_len = is_32_bit_ ? static_cast<size_t>(db2_->Get<uint32_t>(1))
                                 : static_cast<size_t>(db2_->Get<uint64_t>(1));
  if (buffer_len <= cmd_line_.size()) {
    *ret_val = -1ULL;
    return absl::OkStatus();
  }
  auto *db = db_factory_.Allocate<uint8_t>(cmd_line_.size() + 1);
  std::memcpy(db->raw_ptr(), cmd_line_.c_str(), cmd_line_.size());
  db->Set<uint8_t>(cmd_line_.size(), 0);
  d_memory_if_->Store(buffer_address, db);
  db->DecRef();
  if (is_32_bit_) {
    db2_->Set<uint32_t>(1, static_cast<uint32_t>(cmd_line_.size()));
  } else {
    db2_->Set<uint64_t>(1, cmd_line_.size());
  }
  d_memory_if_->Store(parameter, db2_);
  *ret_val = cmd_line_.size();
  return absl::OkStatus();
}

// Returns 0 information indicating that the call doesn't provide this info.
absl::Status RiscVArmSemihost::SysHeapInfo(uint64_t parameter,
                                           uint64_t *ret_val) {
  d_memory_if_->Load(parameter, db1_, nullptr, nullptr);
  uint64_t block_address = is_32_bit_
                               ? static_cast<int>(db1_->Get<uint32_t>(0))
                               : static_cast<int>(db1_->Get<uint64_t>(0));
  // Return all zeros.
  auto *db = db_factory_.Allocate<uint32_t>(4);
  d_memory_if_->Load(block_address, db, nullptr, nullptr);
  db->Set<uint32_t>(0, 0);
  db->Set<uint32_t>(1, 0);
  db->Set<uint32_t>(2, 0);
  db->Set<uint32_t>(3, 0);
  d_memory_if_->Store(block_address, db);
  db->DecRef();
  return absl::OkStatus();
}

// This function is not implemented for now. Will look into it if there is
// demand.
absl::Status RiscVArmSemihost::SysIsError(uint64_t parameter,
                                          uint64_t *ret_val) {
  return absl::UnimplementedError("SysGetCmdline not implemented");
  // TODO: Complete implementation.
}

// Check if the fd is a tty.
absl::Status RiscVArmSemihost::SysIsTty(uint64_t parameter, uint64_t *ret_val) {
  // Load the target file descriptor.
  d_memory_if_->Load(parameter, db1_, nullptr, nullptr);
  int target_fd = is_32_bit_ ? static_cast<int>(db1_->Get<uint32_t>(0))
                             : static_cast<int>(db1_->Get<uint64_t>(0));
  // Check if the fd is valid.
  auto iter = fd_map_.find(target_fd);
  if (iter == fd_map_.end()) {
    *ret_val = -1ULL;
    return absl::OkStatus();
  }
  auto host_fd = iter->second;
  // Return the value of the isatty call.
  int ret = isatty(host_fd);
  if (!ret) {
    sys_errno_ = errno;
  }
  *ret_val = static_cast<uint64_t>(ret);
  return absl::OkStatus();
}

// Open a file, return the file descriptor if successful.
absl::Status RiscVArmSemihost::SysOpen(uint64_t parameter, uint64_t *ret_val) {
  // Load the parameter block consisiting of pointer to a string, the file open
  // mode, and the length of the string.
  d_memory_if_->Load(parameter, db3_, nullptr, nullptr);
  uint64_t string_address = is_32_bit_
                                ? static_cast<uint64_t>(db3_->Get<uint32_t>(0))
                                : static_cast<uint64_t>(db3_->Get<uint64_t>(0));
  int mode = is_32_bit_ ? static_cast<int>(db3_->Get<int32_t>(1))
                        : static_cast<int>(db3_->Get<int64_t>(1));
  uint64_t file_name_len = is_32_bit_
                               ? static_cast<int>(db3_->Get<uint32_t>(2))
                               : static_cast<int>(db3_->Get<uint64_t>(2));
  // Allocate a data buffer for the file name string, load it, and initialize
  // a string variable with it.
  std::string file_name;
  if (file_name_len > 0) {
    auto *db_c = db_factory_.Allocate<uint8_t>(file_name_len);
    d_memory_if_->Load(string_address, db_c, nullptr, nullptr);
    file_name =
        std::string(static_cast<char *>(db_c->raw_ptr()), file_name_len);
    db_c->DecRef();
  }
  // If the name is ":tt" then it's either cin or cout depending on the mode.
  // In this case just dup the corresponding host fd's.
  int host_fd;
  int target_fd;
  if (file_name == ":tt") {
    if (mode == O_RDONLY) {
      host_fd = 0;
      target_fd = dup(0);
    } else {
      host_fd = 1;
      target_fd = dup(1);
    }
  } else {
    // Open the file, create if needed for write/update modes.
    if (mode == O_RDONLY) {
      host_fd = open(file_name.c_str(), 0, mode);
    } else {
      host_fd = open(file_name.c_str(), O_CREAT, mode);
    }
    target_fd = dup(host_fd);
  }
  *ret_val = static_cast<uint64_t>(target_fd);
  if (target_fd < 0) {
    sys_errno_ = errno;
    return absl::OkStatus();
  }

  fd_map_.insert(std::make_pair(target_fd, host_fd));
  return absl::OkStatus();
}

absl::Status RiscVArmSemihost::SysRead(uint64_t parameter, uint64_t *ret_val) {
  // Load the parameter block, consisting of the target file descriptor, the
  // target buffer address, and buffer length.
  d_memory_if_->Load(parameter, db3_, nullptr, nullptr);
  int target_fd = is_32_bit_ ? static_cast<int>(db3_->Get<uint32_t>(0))
                             : static_cast<int>(db3_->Get<uint64_t>(0));
  uint64_t buffer_address = is_32_bit_
                                ? static_cast<uint64_t>(db3_->Get<uint32_t>(1))
                                : static_cast<uint64_t>(db3_->Get<uint64_t>(1));
  int length = is_32_bit_ ? static_cast<int>(db3_->Get<int32_t>(2))
                          : static_cast<int>(db3_->Get<int64_t>(2));
  // Check that the file descriptor is valid.
  auto iter = fd_map_.find(target_fd);
  if (iter == fd_map_.end()) {
    *ret_val = -1ULL;
    return absl::OkStatus();
  }
  auto host_fd = iter->second;
  // Allocate a data buffer sufficient for the target buffer length.
  auto *db = db_factory_.Allocate<uint8_t>(length);
  // Read from the file/
  int res = read(host_fd, db->raw_ptr(), length);
  *ret_val = static_cast<uint64_t>(res);
  if (res < 0) {
    sys_errno_ = errno;
    return absl::OkStatus();
  }
  // Write to the buffer.
  d_memory_if_->Store(buffer_address, db);
  db->DecRef();
  return absl::OkStatus();
}

// Read a byte from the debug console. This is not implemented for now.
absl::Status RiscVArmSemihost::SysReadc(uint64_t parameter, uint64_t *ret_val) {
  return absl::UnimplementedError("SysReadc not implemented");
  // TODO: Complete implementation.
}

// Remove a file from the host file system. This will not be implemented.
absl::Status RiscVArmSemihost::SysRemove(uint64_t parameter,
                                         uint64_t *ret_val) {
  return absl::UnimplementedError("SysRemove not implemented");
}

// Rename a file in the host file system. This will not be implemented.
absl::Status RiscVArmSemihost::SysRename(uint64_t parameter,
                                         uint64_t *ret_val) {
  return absl::UnimplementedError("SysRename not implemented");
}

// Seek in the file specified by the target file descriptor.
absl::Status RiscVArmSemihost::SysSeek(uint64_t parameter, uint64_t *ret_val) {
  // Load the parameters consisting of the target fd and the desired seek
  // offset.
  d_memory_if_->Load(parameter, db2_, nullptr, nullptr);
  int target_fd = is_32_bit_ ? static_cast<int>(db2_->Get<uint32_t>(0))
                             : static_cast<int>(db2_->Get<uint64_t>(0));
  uint64_t offset = is_32_bit_ ? static_cast<int>(db2_->Get<uint32_t>(1))
                               : static_cast<int>(db2_->Get<uint64_t>(1));
  // Verify that the target fd is valid.
  auto iter = fd_map_.find(target_fd);
  if (iter == fd_map_.end()) {
    *ret_val = -1ULL;
    return absl::OkStatus();
  }
  auto host_fd = iter->second;
  // Perform the seek relative to the beginning of the file.
  auto res = lseek(host_fd, offset, SEEK_SET);
  if (res < 0) {
    sys_errno_ = errno;
    res = -1;
  } else {
    res = 0;
  }
  *ret_val = static_cast<uint64_t>(res);
  return absl::OkStatus();
}

// Execute a command in the shell of the host. This will not be implemented.
absl::Status RiscVArmSemihost::SysSystem(uint64_t parameter,
                                         uint64_t *ret_val) {
  return absl::UnimplementedError("SysSystem not implemented");
}

// Return the system tick frequency. For now just return -1 to indicate that
// this call is not fully supported.
absl::Status RiscVArmSemihost::SysTickFreq(uint64_t parameter,
                                           uint64_t *ret_val) {
  *ret_val = -1ULL;
  return absl::OkStatus();
}

// Return unix time in seconds.
absl::Status RiscVArmSemihost::SysTime(uint64_t parameter, uint64_t *ret_val) {
  *ret_val = time(nullptr);
  return absl::OkStatus();
}

// Return a temporary file name.
absl::Status RiscVArmSemihost::SysTmpnam(uint64_t parameter,
                                         uint64_t *ret_val) {
  // Load parameters consisting of a pointer to a buffer, an int (0-255) that
  // is a target identifier for this filename, and the length of the buffer.
  d_memory_if_->Load(parameter, db3_, nullptr, nullptr);
  uint64_t buffer_address = is_32_bit_
                                ? static_cast<int>(db3_->Get<uint32_t>(0))
                                : static_cast<int>(db3_->Get<uint64_t>(0));
  int target_id = is_32_bit_ ? static_cast<uint64_t>(db3_->Get<uint32_t>(1))
                             : static_cast<uint64_t>(db3_->Get<uint64_t>(1));
  int length = is_32_bit_ ? static_cast<int>(db3_->Get<int32_t>(2))
                          : static_cast<int>(db3_->Get<int64_t>(2));
  // Validate the target_id.
  if (target_id < 0 || target_id > 255) {
    *ret_val = -1ULL;
    return absl::OkStatus();
  }
  // The length of the buffer has to be at least L_tmpnam
  if (length < L_tmpnam) {
    *ret_val = -1ULL;
    return absl::OkStatus();
  }
  // Allocate a data buffer and call tmpnam, then write the name to the buffer.
  auto tmpnam_db = db_factory_.Allocate<uint8_t>(length);
  tmpnam(static_cast<char *>(tmpnam_db->raw_ptr()));
  d_memory_if_->Store(buffer_address, tmpnam_db);
  tmpnam_db->DecRef();
  return absl::OkStatus();
}

// Write data to a file.
absl::Status RiscVArmSemihost::SysWrite(uint64_t parameter, uint64_t *ret_val) {
  // Load parameters consisting of target fd, target buffer address, and
  // length.
  d_memory_if_->Load(parameter, db3_, nullptr, nullptr);
  int target_fd = is_32_bit_ ? static_cast<int>(db3_->Get<uint32_t>(0))
                             : static_cast<int>(db3_->Get<uint64_t>(0));
  uint64_t buffer_address = is_32_bit_
                                ? static_cast<uint64_t>(db3_->Get<uint32_t>(1))
                                : static_cast<uint64_t>(db3_->Get<uint64_t>(1));
  int length = is_32_bit_ ? static_cast<int>(db3_->Get<int32_t>(2))
                          : static_cast<int>(db3_->Get<int64_t>(2));
  // Verify that the target fd is valid.
  auto iter = fd_map_.find(target_fd);
  if (iter == fd_map_.end()) {
    *ret_val = -1ULL;
    return absl::OkStatus();
  }
  auto host_fd = iter->second;
  // Allocate the data buffer necessary to read the data to be written to the
  // file.
  auto *db = db_factory_.Allocate<uint8_t>(length);
  d_memory_if_->Load(buffer_address, db, nullptr, nullptr);
  // Write the data to the file.
  int res = write(host_fd, db->raw_ptr(), length);
  *ret_val = static_cast<uint64_t>(res);
  if (res < 0) {
    sys_errno_ = errno;
  }
  *ret_val = static_cast<uint64_t>(res);
  db->DecRef();
  return absl::OkStatus();
}

// Write a byte to the degbug console. This is not implemented for now.
absl::Status RiscVArmSemihost::SysWritec(uint64_t parameter,
                                         uint64_t *ret_val) {
  return absl::UnimplementedError("SysWritec not implemented");
}

// Write a null terminated string to the debug console. This is not implemented
// for now.
absl::Status RiscVArmSemihost::SysWrite0(uint64_t parameter,
                                         uint64_t *ret_val) {
  return absl::UnimplementedError("SysWrite0 not implemented");
}

}  // namespace riscv
}  // namespace sim
}  // namespace mpact
