Skip to content

File casvp-driver.cc

File List > casvp > casvp-driver.cc

Go to the documentation of this file

#include "casvp-driver.h"

#include <formosa-driver.h>
#include <libcomm/comm.h>
#include <libcomm/msg.h>
#include <signal.h>
#include <unistd.h>

#include <cstddef>
#include <cstdint>
#include <cstring>

#include "casvp-config.h"
#include "falloc.h"

Device device;

int fsa_copy_to_dev(uintptr_t dev_addr, const void *host_ptr, size_t size) {
  if (host_ptr == nullptr) return -1;
  msg_t *msg = msg_create(device.msg_id++, WRITE, size, dev_addr);
  if (msg == nullptr) return -1;
  msg = msg_set_payload(msg, static_cast<const uint8_t *>(host_ptr));
  if (msg == nullptr) return -1;
  int err = ipc_send_write_msg(device.fd, msg);
  msg_destroy(msg);
  return err;
}

int fsa_copy_from_dev(uintptr_t dev_addr, void *host_ptr, size_t size) {
  if (host_ptr == nullptr) return -1;
  msg_t *msg = msg_create(device.msg_id++, READ, size, dev_addr);
  if (msg == nullptr) return -1;
  int err = ipc_send_read_msg(device.fd, msg);
  if (err == 0) {
    memcpy(host_ptr, msg->payload, size);
  }
  msg_destroy(msg);
  return err;
}

int fsa_addr_malloc(uintptr_t dev_addr, size_t size) {
  return falloc_addr_malloc(dev_addr, size);
}

int fsa_malloc(void **dev_addr, size_t size) {
  return falloc_malloc(dev_addr, size);
}

int fsa_free(void *dev_addr) { return falloc_free(dev_addr); }

int fsa_start_kernel() {
  int err = 0;
  uint64_t start_status = 0;
  do {
    err = fsa_mmio(CASVP_FORMOSA_CSR_START, 0, &start_status);
  } while (start_status != 0);

  err = fsa_mmio(CASVP_FORMOSA_CSR_START, 1, nullptr);
  return err;
}

int fsa_cache_flush() {
  // TODO: Implement this
  return -1;
}

int fsa_cache_invalidate() {
  // TODO: Implement this
  return -1;
}

int fsa_cmd_barrier() {
  // TODO: Implement this
  return -1;
}

int fsa_probe() {
  struct timeval timeout;
  timeout.tv_sec = 0;
  timeout.tv_usec = 100000;  // 100ms
  int client_socket = client_connect(getenv("AGENT_SOCKET_PATH"), &timeout);
  if (client_socket == -1) {
    return -1;
  }
  int err = ipc_send_probe(client_socket);
  if (err == -1) {
    return -1;
  }
  close(client_socket);
  return 0;
}

int fsa_driver_init(void *args) {
  if (args == nullptr) {
    return -1;
  }
  InitArgs *init_args = static_cast<InitArgs *>(args);
  falloc_init(init_args->global_mem_base, CASVP_FORMOSA_GLOBAL_MEM_SIZE, 0);
  device.fd = client_connect(getenv("AGENT_SOCKET_PATH"), NULL);
  if (device.fd == -1) {
    return -1;
  }
  // Register interrupt signal
  signal(SIGUSR1, init_args->interrupt_handler);
  if (ipc_register_signal(device.fd, SIGUSR1) == -1) {
    return -1;
  }
  device.csr_base = init_args->csr_base;
  return 0;
}

int fsa_driver_uninit() {
  if (device.fd != -1) {
    close(device.fd);
  }
  return 0;
}

int fsa_mmio(int id, uint64_t wr_val, uint64_t *rd_ptr) {
  msg_t *msg = nullptr;
  int err = 0;
  if (rd_ptr == nullptr) {
    // Write request
    msg = msg_create(device.msg_id++, WRITE, 8, device.csr_base + id);
    if (msg == nullptr) {
      return -1;
    }
    msg = msg_set_payload(msg, reinterpret_cast<uint8_t *>(&wr_val));
    if (msg == nullptr) {
      return -1;
    }
    err = ipc_send_write_msg(device.fd, msg);
  } else {
    // Read request
    msg = msg_create(device.msg_id++, READ, 8, device.csr_base + id);
    if (msg == nullptr) {
      return -1;
    }
    err = ipc_send_read_msg(device.fd, msg);
    if (err == 0) {
      *rd_ptr = *reinterpret_cast<uint64_t *>(msg->payload);
    }
  }
  msg_destroy(msg);
  return err;
}