text: /*
   * Copyright (C) 2021, Xilinx Inc - All rights reserved
   * Xilinx Runtime (XRT) Experimental APIs
   *
   * Licensed under the Apache License, Version 2.0 (the "License"). You may
   * not use this file except in compliance with the License. A copy of the
   * License is located at
   *
   *     http://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.
   */
  #ifndef _XRT_IP_H_
  #define _XRT_IP_H_
  
  #include "xrt.h"
  #include "xrt/xrt_uuid.h"
  #include "xrt/xrt_device.h"
  #include "xrt/detail/pimpl.h"
  
  #ifdef __cplusplus
  # include <cstdint>
  # include <string>
  #endif
  
  #ifdef __cplusplus
  
  namespace xrt {
  
  /*!  
   * @class ip
   *
   * @brief
   * xrt::ip represent the custom IP
   *
   * @details The ip can be controlled through read- and write register
   * only.  If the IP supports interrupt notification, then xrt::ip
   * objects supports enabling and control of underlying IP interrupt.
   *
   * In order to construct an ip object, the following requirements must be met:
   *
   *   - The custom IP must appear in IP_LAYOUT section of xclbin.
   *   - The custom IP must have a base address such that it can be controlled
   *     through register access at offsets from base address.
   *   - The custom IP must have an address range so that write and read access 
   *     to base address offset can be validated.
   *   - XRT supports exclusive access only for the custom IP, this is to other 
   *     processes from accessing the same IP at the same time.
   */
  class ip_impl;
  class ip : public detail::pimpl<ip_impl>
  {
  public:
    /*!
     * @class interrupt
     *
     * @brief
     * xrt::ip::interrupt represents an IP interrupt event.
     *
     * This class represents an IP interrupt event.  The interrupt
     * object is contructed via `xrt::ip::create_interrupt_notify()`.
     * The object can be used to enable and disable IP interrupts
     * and to wait for an interrupt to occur.
     *
     * Upon construction, the IP interrupt is automatically enabled.
     */
    class interrupt_impl;
    class interrupt : public detail::pimpl<interrupt_impl>
    {
    public:
      /// @cond
      explicit
      interrupt(std::shared_ptr<interrupt_impl> handle)
        : detail::pimpl<interrupt_impl>(std::move(handle))
      {}
      /// @endcond
  
      /**
       * enable() - Enable interrupt
       *
       * Enables the IP interrupt if not already enabled.  The
       * IP interrupt is automatically enabled when the interrupt
       * object is created.
       */
      XCL_DRIVER_DLLESPEC
      void
      enable();
   
      /**
       * disable() - Disable interrupt
       *
       * Disables the IP interrupt notification from IP.
       */
      XCL_DRIVER_DLLESPEC
      void
      disable();
   
      /**
       * wait() - Wait for interrupt
       *
       * Wait for interrupt from IP. Upon return, interrupt is 
       * re-enabled.
       */
      XCL_DRIVER_DLLESPEC
      void
      wait();
    };
   
  public:
    /**
     * ip() - Construct empty ip object
     */
    ip()
    {}
  
    /**
     * ip() - Constructor from a device and xclbin
     *
     * @param device
     *  Device programmed with the IP
     * @param xclbin_id
     *  UUID of the xclbin with the IP
     * @param name
     *  Name of IP to construct
     *
     * The IP is opened with exclusive access meaning that no other
     * xrt::ip objects can use the same IP, nor will another process be
     * able to use the IP while one process has been granted access.
     *
     * Constructor throws on error.
     */
    XCL_DRIVER_DLLESPEC
    ip(const xrt::device& device, const xrt::uuid& xclbin_id, const std::string& name);
   
    /**
     * write_register() - Write to the address range of an ip
     *
     * @param offset
     *  Offset in register space to write to
     * @param data    
     *  Data to write
     *
     * Throws std::out_or_range if offset is outside the
     * ip address space
     */
    XCL_DRIVER_DLLESPEC
    void
    write_register(uint32_t offset, uint32_t data);
   
    /**
     * read_register() - Read data from ip address range
     *
     * @param offset 
     *  Offset in register space to read from
     * @return
     *  Value read from offset
     *
     * Throws std::out_or_range if offset is outside the
     * ip address space
     */
    XCL_DRIVER_DLLESPEC
    uint32_t
    read_register(uint32_t offset) const;
   
    /**
     * create_interrupt_notify() - Create xrt::ip::interrupt object
     *
     * @return
     *  xrt::ip::interrupt object can be used to control IP interrupt.
     *
     * This function creates an xrt::ip::interrupt object that can be
     * used to control and wait for IP interrupt.   On successful
     * return the IP has interrupt enabled.
     *
     * Throws if the custom IP doesn't support interrupts.
     */
    XCL_DRIVER_DLLESPEC
    interrupt
    create_interrupt_notify();  
  };
  
  } // xrt
  #endif
  
  #endif
  
  