Blame opae-libs/pyopae/pyhandle.cpp

Packit 534379
// Copyright(c) 2018, Intel Corporation
Packit 534379
//
Packit 534379
// Redistribution  and  use  in source  and  binary  forms,  with  or  without
Packit 534379
// modification, are permitted provided that the following conditions are met:
Packit 534379
//
Packit 534379
// * Redistributions of  source code  must retain the  above copyright notice,
Packit 534379
//   this list of conditions and the following disclaimer.
Packit 534379
// * Redistributions in binary form must reproduce the above copyright notice,
Packit 534379
//   this list of conditions and the following disclaimer in the documentation
Packit 534379
//   and/or other materials provided with the distribution.
Packit 534379
// * Neither the name  of Intel Corporation  nor the names of its contributors
Packit 534379
//   may be used to  endorse or promote  products derived  from this  software
Packit 534379
//   without specific prior written permission.
Packit 534379
//
Packit 534379
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTOR."AS ."
Packit 534379
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,  BUT NOT LIMITED TO,  THE
Packit 534379
// IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit 534379
// ARE DISCLAIMED.  IN NO EVENT  SHALL THE COPYRIGHT OWNER  OR CONTRIBUTORS BE
Packit 534379
// LIABLE  FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR
Packit 534379
// CONSEQUENTIAL  DAMAGES  (INCLUDING,  BUT  NOT LIMITED  TO,  PROCUREMENT  OF
Packit 534379
// SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE,  DATA, OR PROFITS;  OR BUSINESS
Packit 534379
// INTERRUPTION)  HOWEVER CAUSED  AND ON ANY THEORY  OF LIABILITY,  WHETHER IN
Packit 534379
// CONTRACT,  STRICT LIABILITY,  OR TORT  (INCLUDING NEGLIGENCE  OR OTHERWISE)
Packit 534379
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  EVEN IF ADVISED OF THE
Packit 534379
// POSSIBILITY OF SUCH DAMAGE.
Packit 534379
#include <Python.h>
Packit 534379
#include "pyhandle.h"
Packit 534379
#include "pycontext.h"
Packit 534379
#include <sstream>
Packit 534379
Packit 534379
namespace py = pybind11;
Packit 534379
using opae::fpga::types::handle;
Packit 534379
using opae::fpga::types::token;
Packit 534379
Packit 534379
const char *handle_doc_open() {
Packit 534379
  return R"opaedoc(
Packit 534379
    Create a new handle object from a token.
Packit 534379
  )opaedoc";
Packit 534379
}
Packit 534379
Packit 534379
handle::ptr_t handle_open(token::ptr_t tok, int flags) {
Packit 534379
  return handle::open(tok, flags);
Packit 534379
}
Packit 534379
Packit 534379
const char *handle_doc_reconfigure() {
Packit 534379
  return R"opaedoc(
Packit 534379
    Reconfigure an accelerator resource. By default, an attempt will be
Packit 534379
    made to open the accelerator in exclusive mode which will result in
Packit 534379
    an exception being thrown if that accelerator is currently in use.
Packit 534379
    Use FPGA_RECONF_FORCE to bypass this behavior and program the GBS.
Packit 534379
    Args:
Packit 534379
      slot: The slot number to program.
Packit 534379
      fd(file): The file object obtained by openeing the GBS file.
Packit 534379
      flags: Flags that control behavior of reconfiguration.
Packit 534379
             Value of 0 indicates no flags. FPGA_RECONF_FORCE indicates
Packit 534379
             that the bitstream be programmed into the slot without
Packit 534379
             checking if the resource is currently in use.
Packit 534379
Packit 534379
  )opaedoc";
Packit 534379
}
Packit 534379
Packit 534379
void handle_reconfigure(handle::ptr_t handle, uint32_t slot, py::object file,
Packit 534379
                        int flags) {
Packit 534379
  PyObject *obj = file.ptr();
Packit 534379
#if PY_MAJOR_VERSION == 3
Packit 534379
  int fd = PyObject_AsFileDescriptor(obj);
Packit 534379
  FILE *fp = fdopen(fd, "r");
Packit 534379
#else
Packit 534379
  if (!PyFile_Check(obj)) {
Packit 534379
    throw std::invalid_argument("fd argument is not a file object");
Packit 534379
  }
Packit 534379
  FILE *fp = PyFile_AsFile(obj);
Packit 534379
#endif
Packit 534379
  if (!fp) {
Packit 534379
    throw std::runtime_error("could not convert fd to FILE*");
Packit 534379
  }
Packit 534379
  // PyFile_IncUseCount(obj);
Packit 534379
  // is fd object already holding a reference count while in this function?
Packit 534379
  fseek(fp, 0L, SEEK_END);
Packit 534379
  size_t size = ftell(fp);
Packit 534379
  fseek(fp, 0L, SEEK_SET);
Packit 534379
  std::vector<char> buffer(size);
Packit 534379
  if (!fread(buffer.data(), size, 1, fp)) {
Packit 534379
    fclose(fp);
Packit 534379
    throw std::runtime_error("error reading from file object");
Packit 534379
  }
Packit 534379
  fclose(fp);
Packit 534379
  handle->reconfigure(slot, reinterpret_cast<const uint8_t *>(buffer.data()),
Packit 534379
                      size, flags);
Packit 534379
}
Packit 534379
Packit 534379
const char *handle_doc_valid() {
Packit 534379
  return R"opaedoc(
Packit 534379
    "Boolean protocol to test if a handle is open or not."
Packit 534379
  )opaedoc";
Packit 534379
}
Packit 534379
Packit 534379
bool handle_valid(opae::fpga::types::handle::ptr_t handle) {
Packit 534379
  return *handle != nullptr;
Packit 534379
}
Packit 534379
Packit 534379
const char *handle_doc_context_enter() {
Packit 534379
  return R"opaedoc(
Packit 534379
    Context manager protocol enter function.
Packit 534379
    Simply returns the handle object.
Packit 534379
  )opaedoc";
Packit 534379
}
Packit 534379
Packit 534379
handle::ptr_t handle_context_enter(handle::ptr_t hnd) {
Packit 534379
  buffer_registry::instance().register_handle(hnd);
Packit 534379
  return hnd;
Packit 534379
}
Packit 534379
Packit 534379
const char *handle_doc_context_exit() {
Packit 534379
  return R"opaedoc(
Packit 534379
    Context manager protocol exit function.
Packit 534379
    Closes the resource identified by this handle and currently does nothing with the exit arguments.
Packit 534379
  )opaedoc";
Packit 534379
}
Packit 534379
Packit 534379
void handle_context_exit(opae::fpga::types::handle::ptr_t hnd, py::args args) {
Packit 534379
  // TODO: Use args for logging exceptions
Packit 534379
  (void)args;
Packit 534379
  buffer_registry::instance().unregister_handle(hnd);
Packit 534379
  hnd->close();
Packit 534379
}
Packit 534379
Packit 534379
const char *handle_doc_close() {
Packit 534379
  return R"opaedoc(
Packit 534379
    "Close an accelerator associated with handle."
Packit 534379
  )opaedoc";
Packit 534379
}
Packit 534379
Packit 534379
const char *handle_doc_reset() {
Packit 534379
  return R"opaedoc(
Packit 534379
    Reset the accelerator associated with this handle.
Packit 534379
    The accelerator must be opened.
Packit 534379
  )opaedoc";
Packit 534379
}
Packit 534379
Packit 534379
const char *handle_doc_read_csr32() {
Packit 534379
  return R"opaedoc(
Packit 534379
    Read 32 bits from a CSR belonging to a resource associated with a handle.
Packit 534379
    Args:
Packit 534379
      offset: The register offset.
Packit 534379
      csr_space: The CSR space to read from. Default is 0.
Packit 534379
  )opaedoc";
Packit 534379
}
Packit 534379
Packit 534379
const char *handle_doc_read_csr64() {
Packit 534379
  return R"opaedoc(
Packit 534379
    Read 64 bits from a CSR belonging to a resource associated with a handle.
Packit 534379
    Args:
Packit 534379
      offset: The register offset.
Packit 534379
      csr_space: The CSR space to read from. Default is 0.
Packit 534379
  )opaedoc";
Packit 534379
}
Packit 534379
Packit 534379
const char *handle_doc_write_csr32() {
Packit 534379
  return R"opaedoc(
Packit 534379
    Write 32 bits to a CSR belonging to a resource associated with a handle.
Packit 534379
    Args:
Packit 534379
      offset: The register offset.
Packit 534379
      value: The 32-bit value to write to the register.
Packit 534379
      csr_space: The CSR space to write from. Default is 0.
Packit 534379
  )opaedoc";
Packit 534379
}
Packit 534379
Packit 534379
const char *handle_doc_write_csr64() {
Packit 534379
  return R"opaedoc(
Packit 534379
    Write 64 bits to a CSR belonging to a resource associated with a handle.
Packit 534379
    Args:
Packit 534379
      offset: The register offset.
Packit 534379
      value: The 64-bit value to write to the register.
Packit 534379
      csr_space: The CSR space to write from. Default is 0.
Packit 534379
  )opaedoc";
Packit 534379
}