From: Sonal Santan <sonal.santan@xxxxxxxxxx> Add XRT UAPI header files which describe flash layout, XRT mailbox protocol, xclBin/axlf FPGA image container format and XRT management physical function driver ioctl interfaces. flash_xrt_data.h: Layout used by XRT to store private data on flash. mailbox_proto.h: Mailbox opcodes and high level data structures representing various kinds of information like sensors, clock, etc. mailbox_transport.h: Transport protocol used by mailbox. xclbin.h: Container format used to store compiled FPGA image which includes bitstream and metadata. xmgmt-ioctl.h: Ioctls defined by management physical function driver: * XMGMT_IOCICAPDOWNLOAD_AXLF xclbin download which programs the user partition * XMGMT_IOCFREQSCALE Program the clocks driving user partition Signed-off-by: Sonal Santan <sonal.santan@xxxxxxxxxx> --- include/uapi/linux/xrt/flash_xrt_data.h | 67 ++++ include/uapi/linux/xrt/mailbox_proto.h | 394 +++++++++++++++++++ include/uapi/linux/xrt/mailbox_transport.h | 74 ++++ include/uapi/linux/xrt/xclbin.h | 418 +++++++++++++++++++++ include/uapi/linux/xrt/xmgmt-ioctl.h | 72 ++++ 5 files changed, 1025 insertions(+) create mode 100644 include/uapi/linux/xrt/flash_xrt_data.h create mode 100644 include/uapi/linux/xrt/mailbox_proto.h create mode 100644 include/uapi/linux/xrt/mailbox_transport.h create mode 100644 include/uapi/linux/xrt/xclbin.h create mode 100644 include/uapi/linux/xrt/xmgmt-ioctl.h diff --git a/include/uapi/linux/xrt/flash_xrt_data.h b/include/uapi/linux/xrt/flash_xrt_data.h new file mode 100644 index 000000000000..0cafc2f38fbe --- /dev/null +++ b/include/uapi/linux/xrt/flash_xrt_data.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Xilinx, Inc. + * + * Authors: + * Cheng Zhen <maxz@xxxxxxxxxx> + */ + +#ifndef _FLASH_XRT_DATA_H_ +#define _FLASH_XRT_DATA_H_ + +#define XRT_DATA_MAGIC "XRTDATA" + +/* + * This header file contains data structure for xrt meta data on flash. This + * file is included in user space utilities and kernel drivers. The data + * structure is used to describe on-flash xrt data which is written by utility + * and read by driver. Any change of the data structure should either be + * backward compatible or cause version to be bumped up. + */ + +struct flash_data_ident { + char fdi_magic[7]; + char fdi_version; +}; + +/* + * On-flash meta data describing XRT data on flash. Either fdh_id_begin or + * fdh_id_end should be at well-known location on flash so that the reader + * can easily pick up fdi_version from flash before it tries to interpret + * the whole data structure. + * E.g., you align header in the end of the flash so that fdh_id_end is at well + * known location or align header at the beginning of the flash so that + * fdh_id_begin is at well known location. + */ +struct flash_data_header { + struct flash_data_ident fdh_id_begin; + uint32_t fdh_data_offset; + uint32_t fdh_data_len; + uint32_t fdh_data_parity; + uint8_t fdh_reserved[16]; + struct flash_data_ident fdh_id_end; +}; + +static inline uint32_t flash_xrt_data_get_parity32(unsigned char *buf, size_t n) +{ + char *p; + size_t i; + size_t len; + uint32_t parity = 0; + + for (len = 0; len < n; len += 4) { + uint32_t tmp = 0; + size_t thislen = n - len; + + /* One word at a time. */ + if (thislen > 4) + thislen = 4; + + for (i = 0, p = (char *)&tmp; i < thislen; i++) + p[i] = buf[len + i]; + parity ^= tmp; + } + return parity; +} + +#endif diff --git a/include/uapi/linux/xrt/mailbox_proto.h b/include/uapi/linux/xrt/mailbox_proto.h new file mode 100644 index 000000000000..2aa782d86792 --- /dev/null +++ b/include/uapi/linux/xrt/mailbox_proto.h @@ -0,0 +1,394 @@ +/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0 */ +/* + * Copyright (C) 2019-2020, Xilinx Inc + */ + +#ifndef _XCL_MB_PROTOCOL_H_ +#define _XCL_MB_PROTOCOL_H_ + +#ifndef __KERNEL__ +#include <stdint.h> +#else +#include <linux/types.h> +#endif + +/* + * This header file contains mailbox protocol b/w mgmt and user pfs. + * - Any changes made here should maintain backward compatibility. + * - If it's not possible, new OP code should be added and version number should + * be bumped up. + * - Support for old OP code should never be removed. + */ +#define XCL_MB_PROTOCOL_VER 0U + +/* + * UUID_SZ should ALWAYS have the same number + * as the MACRO UUID_SIZE defined in linux/uuid.h + */ +#define XCL_UUID_SZ 16 + +/** + * enum mailbox_request - List of all mailbox request OPCODE. Some OP code + * requires arguments, which is defined as corresponding + * data structures below. Response to the request usually + * is a int32_t containing the error code. Some responses + * are more complicated and require a data structure, + * which is also defined below in this file. + * @XCL_MAILBOX_REQ_UNKNOWN: invalid OP code + * @XCL_MAILBOX_REQ_TEST_READY: test msg is ready (post only, internal test only) + * @XCL_MAILBOX_REQ_TEST_READ: fetch test msg from peer (internal test only) + * @XCL_MAILBOX_REQ_LOCK_BITSTREAM: lock down xclbin on mgmt pf (not implemented) + * @XCL_MAILBOX_REQ_UNLOCK_BITSTREAM: unlock xclbin on mgmt pf (not implemented) + * @XCL_MAILBOX_REQ_HOT_RESET: request mgmt pf driver to reset the board + * @XCL_MAILBOX_REQ_FIREWALL: firewall trip detected on mgmt pf (post only) + * @XCL_MAILBOX_REQ_LOAD_XCLBIN_KADDR: download xclbin (pointed to by a pointer) + * @XCL_MAILBOX_REQ_LOAD_XCLBIN: download xclbin (bitstream is in payload) + * @XCL_MAILBOX_REQ_RECLOCK: set clock frequency + * @XCL_MAILBOX_REQ_PEER_DATA: read specified data from peer + * @XCL_MAILBOX_REQ_USER_PROBE: for user pf to probe the peer mgmt pf + * @XCL_MAILBOX_REQ_MGMT_STATE: for mgmt pf to notify user pf of its state change + * (post only) + * @XCL_MAILBOX_REQ_CHG_SHELL: shell change is required on mgmt pf (post only) + * @XCL_MAILBOX_REQ_PROGRAM_SHELL: request mgmt pf driver to reprogram shell + */ +enum xcl_mailbox_request { + XCL_MAILBOX_REQ_UNKNOWN = 0, + XCL_MAILBOX_REQ_TEST_READY = 1, + XCL_MAILBOX_REQ_TEST_READ = 2, + XCL_MAILBOX_REQ_LOCK_BITSTREAM = 3, + XCL_MAILBOX_REQ_UNLOCK_BITSTREAM = 4, + XCL_MAILBOX_REQ_HOT_RESET = 5, + XCL_MAILBOX_REQ_FIREWALL = 6, + XCL_MAILBOX_REQ_LOAD_XCLBIN_KADDR = 7, + XCL_MAILBOX_REQ_LOAD_XCLBIN = 8, + XCL_MAILBOX_REQ_RECLOCK = 9, + XCL_MAILBOX_REQ_PEER_DATA = 10, + XCL_MAILBOX_REQ_USER_PROBE = 11, + XCL_MAILBOX_REQ_MGMT_STATE = 12, + XCL_MAILBOX_REQ_CHG_SHELL = 13, + XCL_MAILBOX_REQ_PROGRAM_SHELL = 14, + XCL_MAILBOX_REQ_READ_P2P_BAR_ADDR = 15, + /* Version 0 OP code ends */ +}; + +static inline const char *mailbox_req2name(enum xcl_mailbox_request req) +{ + switch (req) { + case XCL_MAILBOX_REQ_TEST_READY: return "XCL_MAILBOX_REQ_TEST_READY"; + case XCL_MAILBOX_REQ_TEST_READ: return "XCL_MAILBOX_REQ_TEST_READ"; + case XCL_MAILBOX_REQ_LOCK_BITSTREAM: return "XCL_MAILBOX_REQ_LOCK_BITSTREAM"; + case XCL_MAILBOX_REQ_UNLOCK_BITSTREAM: return "XCL_MAILBOX_REQ_UNLOCK_BITSTREAM"; + case XCL_MAILBOX_REQ_HOT_RESET: return "XCL_MAILBOX_REQ_HOT_RESET"; + case XCL_MAILBOX_REQ_FIREWALL: return "XCL_MAILBOX_REQ_FIREWALL"; + case XCL_MAILBOX_REQ_LOAD_XCLBIN_KADDR: return "XCL_MAILBOX_REQ_LOAD_XCLBIN_KADDR"; + case XCL_MAILBOX_REQ_LOAD_XCLBIN: return "XCL_MAILBOX_REQ_LOAD_XCLBIN"; + case XCL_MAILBOX_REQ_RECLOCK: return "XCL_MAILBOX_REQ_RECLOCK"; + case XCL_MAILBOX_REQ_PEER_DATA: return "XCL_MAILBOX_REQ_PEER_DATA"; + case XCL_MAILBOX_REQ_USER_PROBE: return "XCL_MAILBOX_REQ_USER_PROBE"; + case XCL_MAILBOX_REQ_MGMT_STATE: return "XCL_MAILBOX_REQ_MGMT_STATE"; + case XCL_MAILBOX_REQ_CHG_SHELL: return "XCL_MAILBOX_REQ_CHG_SHELL"; + case XCL_MAILBOX_REQ_PROGRAM_SHELL: return "XCL_MAILBOX_REQ_PROGRAM_SHELL"; + case XCL_MAILBOX_REQ_READ_P2P_BAR_ADDR: return "XCL_MAILBOX_REQ_READ_P2P_BAR_ADDR"; + default: return "UNKNOWN"; + } +} + +/** + * struct mailbox_req_bitstream_lock - MAILBOX_REQ_LOCK_BITSTREAM and + * MAILBOX_REQ_UNLOCK_BITSTREAM payload type + * @uuid: uuid of the xclbin + */ +struct xcl_mailbox_req_bitstream_lock { + uint64_t reserved; + uint8_t uuid[XCL_UUID_SZ]; +}; + +/** + * enum group_kind - Groups of data that can be fetched from mgmt side + * @SENSOR: all kinds of sensor readings + * @ICAP: ICAP IP related information + * @BDINFO: Board Info, serial_num, mac_address + * @MIG_ECC: ECC statistics + * @FIREWALL: AF detected time, status + */ +enum xcl_group_kind { + XCL_SENSOR = 0, + XCL_ICAP, + XCL_BDINFO, + XCL_MIG_ECC, + XCL_FIREWALL, + XCL_DNA, + XCL_SUBDEV, +}; + +static inline const char *mailbox_group_kind2name(enum xcl_group_kind kind) +{ + switch (kind) { + case XCL_SENSOR: return "XCL_SENSOR"; + case XCL_ICAP: return "XCL_ICAP"; + case XCL_BDINFO: return "XCL_BDINFO"; + case XCL_MIG_ECC: return "XCL_MIG_ECC"; + case XCL_FIREWALL: return "XCL_FIREWALL"; + case XCL_DNA: return "XCL_DNA"; + case XCL_SUBDEV: return "XCL_SUBDEV"; + default: return "UNKNOWN"; + } +} + +/** + * struct xcl_board_info - Data structure used to fetch BDINFO group + */ +#define BOARD_INFO_STR_LEN 256 +#define BOARD_INFO_MAC_LEN 6 +#define BOARD_INFO_PAD_LEN 26 +struct xcl_board_info { + char serial_num[BOARD_INFO_STR_LEN]; + char mac_addr0[BOARD_INFO_MAC_LEN]; + char padding0[BOARD_INFO_PAD_LEN]; + char mac_addr1[BOARD_INFO_MAC_LEN]; + char padding1[BOARD_INFO_PAD_LEN]; + char mac_addr2[BOARD_INFO_MAC_LEN]; + char padding2[BOARD_INFO_PAD_LEN]; + char mac_addr3[BOARD_INFO_MAC_LEN]; + char padding3[BOARD_INFO_PAD_LEN]; + char revision[BOARD_INFO_STR_LEN]; + char bd_name[BOARD_INFO_STR_LEN]; + char bmc_ver[BOARD_INFO_STR_LEN]; + uint32_t max_power; + uint32_t fan_presence; + uint32_t config_mode; + char exp_bmc_ver[BOARD_INFO_STR_LEN]; + uint32_t mac_contiguous_num; + char mac_addr_first[BOARD_INFO_MAC_LEN]; +}; + +/** + * struct xcl_sensor - Data structure used to fetch SENSOR group + */ +struct xcl_sensor { + uint32_t vol_12v_pex; + uint32_t vol_12v_aux; + uint32_t cur_12v_pex; + uint32_t cur_12v_aux; + uint32_t vol_3v3_pex; + uint32_t vol_3v3_aux; + uint32_t cur_3v3_aux; + uint32_t ddr_vpp_btm; + uint32_t sys_5v5; + uint32_t top_1v2; + uint32_t vol_1v8; + uint32_t vol_0v85; + uint32_t ddr_vpp_top; + uint32_t mgt0v9avcc; + uint32_t vol_12v_sw; + uint32_t mgtavtt; + uint32_t vcc1v2_btm; + uint32_t fpga_temp; + uint32_t fan_temp; + uint32_t fan_rpm; + uint32_t dimm_temp0; + uint32_t dimm_temp1; + uint32_t dimm_temp2; + uint32_t dimm_temp3; + uint32_t vccint_vol; + uint32_t vccint_curr; + uint32_t se98_temp0; + uint32_t se98_temp1; + uint32_t se98_temp2; + uint32_t cage_temp0; + uint32_t cage_temp1; + uint32_t cage_temp2; + uint32_t cage_temp3; + uint32_t hbm_temp0; + uint32_t cur_3v3_pex; + uint32_t cur_0v85; + uint32_t vol_3v3_vcc; + uint32_t vol_1v2_hbm; + uint32_t vol_2v5_vpp; + uint32_t vccint_bram; + uint32_t version; + uint32_t oem_id; + uint32_t vccint_temp; + uint32_t vol_12v_aux1; + uint32_t vol_vcc1v2_i; + uint32_t vol_v12_in_i; + uint32_t vol_v12_in_aux0_i; + uint32_t vol_v12_in_aux1_i; + uint32_t vol_vccaux; + uint32_t vol_vccaux_pmc; + uint32_t vol_vccram; +}; + +/** + * struct xcl_hwicap - Data structure used to fetch ICAP group + */ +struct xcl_pr_region { + uint64_t freq_data; + uint64_t freq_kernel; + uint64_t freq_system; + uint64_t freq_unused; + uint64_t freq_cntr_data; + uint64_t freq_cntr_kernel; + uint64_t freq_cntr_system; + uint64_t freq_cntr_unused; + uint64_t idcode; + uint8_t uuid[XCL_UUID_SZ]; + uint64_t mig_calib; + uint64_t data_retention; +}; + +/** + * struct xcl_mig_ecc - Data structure used to fetch MIG_ECC group + */ +struct xcl_mig_ecc { + uint64_t mem_type; + uint64_t mem_idx; + uint64_t ecc_enabled; + uint64_t ecc_status; + uint64_t ecc_ce_cnt; + uint64_t ecc_ue_cnt; + uint64_t ecc_ce_ffa; + uint64_t ecc_ue_ffa; +}; + +/** + * struct xcl_firewall - Data structure used to fetch FIREWALL group + */ +struct xcl_firewall { + uint64_t max_level; + uint64_t curr_status; + uint64_t curr_level; + uint64_t err_detected_status; + uint64_t err_detected_level; + uint64_t err_detected_time; +}; + + +/** + * struct xcl_dna - Data structure used to fetch DNA group + */ +struct xcl_dna { + uint64_t status; + uint32_t dna[4]; + uint64_t capability; + uint64_t dna_version; + uint64_t revision; +}; +/** + * Data structure used to fetch SUBDEV group + */ +enum xcl_subdev_return_code { + XRT_MSG_SUBDEV_RTN_UNCHANGED = 1, + XRT_MSG_SUBDEV_RTN_PARTIAL, + XRT_MSG_SUBDEV_RTN_COMPLETE, + XRT_MSG_SUBDEV_RTN_PENDINGPLP, +}; +struct xcl_subdev { + uint32_t ver; + enum xcl_subdev_return_code rtncode; + uint64_t checksum; + uint64_t size; + uint64_t offset; + uint64_t data[1]; +}; +/** + * struct mailbox_subdev_peer - MAILBOX_REQ_PEER_DATA payload type + * @kind: data group + * @size: buffer size for receiving response + */ +struct xcl_mailbox_peer_data { + enum xcl_group_kind kind; + uint32_t padding; + uint64_t size; + uint64_t entries; + uint64_t offset; +}; + +/** + * struct mailbox_conn - MAILBOX_REQ_USER_PROBE payload type + * @kaddr: KVA of the verification data buffer + * @paddr: physical addresss of the verification data buffer + * @crc32: CRC value of the verification data buffer + * @version: protocol version supported by peer + */ +struct xcl_mailbox_conn { + uint64_t kaddr; + uint64_t paddr; + uint32_t crc32; + uint32_t version; +}; + +#define XCL_COMM_ID_SIZE 2048 +#define XCL_MB_PEER_READY (1UL << 0) +#define XCL_MB_PEER_SAME_DOMAIN (1UL << 1) +/** + * struct mailbox_conn_resp - MAILBOX_REQ_USER_PROBE response payload type + * @version: protocol version should be used + * @conn_flags: connection status + * @chan_switch: bitmap to indicate SW / HW channel for each OP code msg + * @comm_id: user defined cookie + */ +struct xcl_mailbox_conn_resp { + uint32_t version; + uint32_t reserved; + uint64_t conn_flags; + uint64_t chan_switch; + char comm_id[XCL_COMM_ID_SIZE]; +}; + +#define XCL_MB_STATE_ONLINE (1UL << 0) +#define XCL_MB_STATE_OFFLINE (1UL << 1) +/** + * struct mailbox_peer_state - MAILBOX_REQ_MGMT_STATE payload type + * @state_flags: peer state flags + */ +struct xcl_mailbox_peer_state { + uint64_t state_flags; +}; + +/** + * struct mailbox_bitstream_kaddr - MAILBOX_REQ_LOAD_XCLBIN_KADDR payload type + * @addr: pointer to xclbin body + */ +struct xcl_mailbox_bitstream_kaddr { + uint64_t addr; +}; + +/** + * struct mailbox_clock_freqscaling - MAILBOX_REQ_RECLOCK payload type + * @region: region of clock + * @target_freqs: array of target clock frequencies (max clocks: 16) + */ +struct xcl_mailbox_clock_freqscaling { + unsigned int region; + unsigned short target_freqs[16]; +}; + +/** + * struct mailbox_req - mailbox request message header + * @req: opcode + * @flags: flags of this message + * @data: payload of variable length + */ +struct xcl_mailbox_req { + uint64_t flags; + enum xcl_mailbox_request req; + char data[1]; /* variable length of payload */ +}; + +/** + * struct mailbox_p2p_bar_addr + * @bar_addr: p2p bar address + * @bar_len: p2p bar length + */ +struct xcl_mailbox_p2p_bar_addr { + uint64_t p2p_bar_addr; + uint64_t p2p_bar_len; +}; + +static inline const char *mailbox_chan2name(bool sw_ch) +{ + return sw_ch ? "SW-CHANNEL" : "HW-CHANNEL"; +} + +#endif /* _XCL_MB_PROTOCOL_H_ */ diff --git a/include/uapi/linux/xrt/mailbox_transport.h b/include/uapi/linux/xrt/mailbox_transport.h new file mode 100644 index 000000000000..4823446797a6 --- /dev/null +++ b/include/uapi/linux/xrt/mailbox_transport.h @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0 */ +/* + * Copyright (C) 2020 Xilinx, Inc. + * + * Authors: + * Cheng Zhen <maxz@xxxxxxxxxx> + */ + +#ifndef _XCL_MB_TRANSPORT_H_ +#define _XCL_MB_TRANSPORT_H_ + +/* + * This header file contains data structures used in mailbox transport layer + * b/w mgmt and user pfs. Any changes made here should maintain backward + * compatibility. + */ + +/** + * struct sw_chan - mailbox software channel message metadata. This defines the + * interface between daemons (MPD and MSD) and mailbox's + * read or write callbacks. A mailbox message (either a request + * or response) is wrapped by this data structure as payload. + * A sw_chan is passed between mailbox driver and daemon via + * read / write driver callbacks. And it is also passed between + * MPD and MSD via vendor defined interface (TCP socket, etc). + * @sz: payload size + * @flags: flags of this message as in struct mailbox_req + * @id: message ID + * @data: payload (struct mailbox_req or response data matching the request) + */ +struct xcl_sw_chan { + uint64_t sz; + uint64_t flags; + uint64_t id; + char data[1]; /* variable length of payload */ +}; + +/** + * A packet transport by mailbox hardware channel. + * When extending, only add new data structure to body. Choose to add new flag + * if new feature can be safely ignored by peer, other wise, add new type. + */ +enum packet_type { + PKT_INVALID = 0, + PKT_TEST, + PKT_MSG_START, + PKT_MSG_BODY +}; + +#define PACKET_SIZE 16 /* Number of DWORD. */ + +/* Lower 8 bits for type, the rest for flags. Total packet size is 64 bytes */ +#define PKT_TYPE_MASK 0xff +#define PKT_TYPE_MSG_END (1 << 31) +struct mailbox_pkt { + struct { + u32 type; + u32 payload_size; + } hdr; + union { + u32 data[PACKET_SIZE - 2]; + struct { + u64 msg_req_id; + u32 msg_flags; + u32 msg_size; + u32 payload[0]; + } msg_start; + struct { + u32 payload[0]; + } msg_body; + } body; +} __packed; + +#endif /* _XCL_MB_TRANSPORT_H_ */ diff --git a/include/uapi/linux/xrt/xclbin.h b/include/uapi/linux/xrt/xclbin.h new file mode 100644 index 000000000000..885cae1700f9 --- /dev/null +++ b/include/uapi/linux/xrt/xclbin.h @@ -0,0 +1,418 @@ +/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0 */ +/* + * Xilinx FPGA compiled binary container format + * + * Copyright (C) 2015-2020, Xilinx Inc + */ + + +#ifndef _XCLBIN_H_ +#define _XCLBIN_H_ + +#ifdef _WIN32 + #include <cstdint> + #include <algorithm> + #include "windows/uuid.h" +#else + #if defined(__KERNEL__) + #include <linux/types.h> + #include <linux/uuid.h> + #include <linux/version.h> + #elif defined(__cplusplus) + #include <cstdlib> + #include <cstdint> + #include <algorithm> + #include <uuid/uuid.h> + #else + #include <stdlib.h> + #include <stdint.h> + #include <uuid/uuid.h> + #endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * Container format for Xilinx bitstreams, metadata and other + * binary blobs. + * Every segment must be aligned at 8 byte boundary with null byte padding + * between adjacent segments if required. + * For segements which are not present both offset and length must be 0 in + * the header. + * Currently only xclbin0\0 is recognized as file magic. In future if/when file + * format is updated the magic string will be changed to xclbin1\0 and so on. + */ + enum XCLBIN_MODE { + XCLBIN_FLAT, + XCLBIN_PR, + XCLBIN_TANDEM_STAGE2, + XCLBIN_TANDEM_STAGE2_WITH_PR, + XCLBIN_HW_EMU, + XCLBIN_SW_EMU, + XCLBIN_MODE_MAX + }; + + /* + * AXLF LAYOUT + * ----------- + * + * ----------------------------------------- + * | Magic | + * ----------------------------------------- + * | Header | + * ----------------------------------------- + * | One or more section headers | + * ----------------------------------------- + * | Matching number of sections with data | + * ----------------------------------------- + * + */ + + enum axlf_section_kind { + BITSTREAM = 0, + CLEARING_BITSTREAM, + EMBEDDED_METADATA, + FIRMWARE, + DEBUG_DATA, + SCHED_FIRMWARE, + MEM_TOPOLOGY, + CONNECTIVITY, + IP_LAYOUT, + DEBUG_IP_LAYOUT, + DESIGN_CHECK_POINT, + CLOCK_FREQ_TOPOLOGY, + MCS, + BMC, + BUILD_METADATA, + KEYVALUE_METADATA, + USER_METADATA, + DNA_CERTIFICATE, + PDI, + BITSTREAM_PARTIAL_PDI, + PARTITION_METADATA, + EMULATION_DATA, + SYSTEM_METADATA, + SOFT_KERNEL, + ASK_FLASH, + AIE_METADATA, + ASK_GROUP_TOPOLOGY, + ASK_GROUP_CONNECTIVITY + }; + + enum MEM_TYPE { + MEM_DDR3, + MEM_DDR4, + MEM_DRAM, + MEM_STREAMING, + MEM_PREALLOCATED_GLOB, + MEM_ARE, //Aurora + MEM_HBM, + MEM_BRAM, + MEM_URAM, + MEM_STREAMING_CONNECTION + }; + + enum IP_TYPE { + IP_MB = 0, + IP_KERNEL, //kernel instance + IP_DNASC, + IP_DDR4_CONTROLLER, + IP_MEM_DDR4, + IP_MEM_HBM + }; + + struct axlf_section_header { + uint32_t m_sectionKind; /* Section type */ + char m_sectionName[16]; /* Examples: "stage2", "clear1", "clear2", "ocl1", "ocl2, "ublaze", "sched" */ + uint64_t m_sectionOffset; /* File offset of section data */ + uint64_t m_sectionSize; /* Size of section data */ + }; + + struct axlf_header { + uint64_t m_length; /* Total size of the xclbin file */ + uint64_t m_timeStamp; /* Number of seconds since epoch when xclbin was created */ + uint64_t m_featureRomTimeStamp; /* TimeSinceEpoch of the featureRom */ + uint16_t m_versionPatch; /* Patch Version */ + uint8_t m_versionMajor; /* Major Version - Version: 2.1.0*/ + uint8_t m_versionMinor; /* Minor Version */ + uint32_t m_mode; /* XCLBIN_MODE */ + union { + struct { + uint64_t m_platformId; /* 64 bit platform ID: vendor-device-subvendor-subdev */ + uint64_t m_featureId; /* 64 bit feature id */ + } rom; + unsigned char rom_uuid[16]; /* feature ROM UUID for which this xclbin was generated */ + }; + unsigned char m_platformVBNV[64]; /* e.g. xilinx:xil-accel-rd-ku115:4ddr-xpr:3.4: null terminated */ + union { + char m_next_axlf[16]; /* Name of next xclbin file in the daisy chain */ + uuid_t uuid; /* uuid of this xclbin*/ + }; + char m_debug_bin[16]; /* Name of binary with debug information */ + uint32_t m_numSections; /* Number of section headers */ + }; + + struct axlf { + char m_magic[8]; /* Should be "xclbin2\0" */ + int32_t m_signature_length; /* Length of the signature. -1 indicates no signature */ + unsigned char reserved[28]; /* Note: Initialized to 0xFFs */ + + unsigned char m_keyBlock[256]; /* Signature for validation of binary */ + uint64_t m_uniqueId; /* axlf's uniqueId, use it to skip redownload etc */ + struct axlf_header m_header; /* Inline header */ + struct axlf_section_header m_sections[1]; /* One or more section headers follow */ + }; + + typedef struct axlf xclBin; + + /**** BEGIN : Xilinx internal section *****/ + + /* bitstream information */ + struct xlnx_bitstream { + uint8_t m_freq[8]; + char bits[1]; + }; + + /**** MEMORY TOPOLOGY SECTION ****/ + struct mem_data { + uint8_t m_type; //enum corresponding to mem_type. + uint8_t m_used; //if 0 this bank is not present + union { + uint64_t m_size; //if mem_type DDR, then size in KB; + uint64_t route_id; //if streaming then "route_id" + }; + union { + uint64_t m_base_address;//if DDR then the base address; + uint64_t flow_id; //if streaming then "flow id" + }; + unsigned char m_tag[16]; //DDR: BANK0,1,2,3, has to be null terminated; if streaming then stream0, 1 etc + }; + + struct mem_topology { + int32_t m_count; //Number of mem_data + struct mem_data m_mem_data[1]; //Should be sorted on mem_type + }; + + /**** CONNECTIVITY SECTION ****/ + /* Connectivity of each argument of Kernel. It will be in terms of argument + * index associated. For associating kernel instances with arguments and + * banks, start at the connectivity section. Using the m_ip_layout_index + * access the ip_data.m_name. Now we can associate this kernel instance + * with its original kernel name and get the connectivity as well. This + * enables us to form related groups of kernel instances. + */ + + struct connection { + int32_t arg_index; //From 0 to n, may not be contiguous as scalars skipped + int32_t m_ip_layout_index; //index into the ip_layout section. ip_layout.m_ip_data[index].m_type == IP_KERNEL + int32_t mem_data_index; //index of the m_mem_data . Flag error is m_used false. + }; + + struct connectivity { + int32_t m_count; + struct connection m_connection[1]; + }; + + + /**** IP_LAYOUT SECTION ****/ + + // IP Kernel + #define IP_INT_ENABLE_MASK 0x0001 + #define IP_INTERRUPT_ID_MASK 0x00FE + #define IP_INTERRUPT_ID_SHIFT 0x1 + + enum IP_CONTROL { + AP_CTRL_HS = 0, + AP_CTRL_CHAIN = 1, + AP_CTRL_NONE = 2, + AP_CTRL_ME = 3, + ACCEL_ADAPTER = 4 + }; + + #define IP_CONTROL_MASK 0xFF00 + #define IP_CONTROL_SHIFT 0x8 + + /* IPs on AXI lite - their types, names, and base addresses.*/ + struct ip_data { + uint32_t m_type; //map to IP_TYPE enum + union { + uint32_t properties; // Default: 32-bits to indicate ip specific property. + // m_type: IP_KERNEL + // m_int_enable : Bit - 0x0000_0001; + // m_interrupt_id : Bits - 0x0000_00FE; + // m_ip_control : Bits = 0x0000_FF00; + struct { // m_type: IP_MEM_* + uint16_t m_index; + uint8_t m_pc_index; + uint8_t unused; + } indices; + }; + uint64_t m_base_address; + uint8_t m_name[64]; //eg Kernel name corresponding to KERNEL instance, can embed CU name in future. + }; + + struct ip_layout { + int32_t m_count; + struct ip_data m_ip_data[1]; //All the ip_data needs to be sorted by m_base_address. + }; + + /*** Debug IP section layout ****/ + enum DEBUG_IP_TYPE { + UNDEFINED = 0, + LAPC, + ILA, + AXI_MM_MONITOR, + AXI_TRACE_FUNNEL, + AXI_MONITOR_FIFO_LITE, + AXI_MONITOR_FIFO_FULL, + ACCEL_MONITOR, + AXI_STREAM_MONITOR, + AXI_STREAM_PROTOCOL_CHECKER, + TRACE_S2MM, + AXI_DMA, + TRACE_S2MM_FULL + }; + + struct debug_ip_data { + uint8_t m_type; // type of enum DEBUG_IP_TYPE + uint8_t m_index_lowbyte; + uint8_t m_properties; + uint8_t m_major; + uint8_t m_minor; + uint8_t m_index_highbyte; + uint8_t m_reserved[2]; + uint64_t m_base_address; + char m_name[128]; + }; + + struct debug_ip_layout { + uint16_t m_count; + struct debug_ip_data m_debug_ip_data[1]; + }; + + enum CLOCK_TYPE { /* Supported clock frequency types */ + CT_UNUSED = 0, /* Initialized value */ + CT_DATA = 1, /* Data clock */ + CT_KERNEL = 2, /* Kernel clock */ + CT_SYSTEM = 3 /* System Clock */ + }; + + struct clock_freq { /* Clock Frequency Entry */ + uint16_t m_freq_Mhz; /* Frequency in MHz */ + uint8_t m_type; /* Clock type (enum CLOCK_TYPE) */ + uint8_t m_unused[5]; /* Not used - padding */ + char m_name[128]; /* Clock Name */ + }; + + struct clock_freq_topology { /* Clock frequency section */ + int16_t m_count; /* Number of entries */ + struct clock_freq m_clock_freq[1]; /* Clock array */ + }; + + enum MCS_TYPE { /* Supported MCS file types */ + MCS_UNKNOWN = 0, /* Initialized value */ + MCS_PRIMARY = 1, /* The primary mcs file data */ + MCS_SECONDARY = 2, /* The secondary mcs file data */ + }; + + struct mcs_chunk { /* One chunk of MCS data */ + uint8_t m_type; /* MCS data type */ + uint8_t m_unused[7]; /* padding */ + uint64_t m_offset; /* data offset from the start of the section */ + uint64_t m_size; /* data size */ + }; + + struct mcs { /* MCS data section */ + int8_t m_count; /* Number of chunks */ + int8_t m_unused[7]; /* padding */ + struct mcs_chunk m_chunk[1]; /* MCS chunks followed by data */ + }; + + struct bmc { /* bmc data section */ + uint64_t m_offset; /* data offset from the start of the section */ + uint64_t m_size; /* data size (bytes)*/ + char m_image_name[64]; /* Name of the image (e.g., MSP432P401R) */ + char m_device_name[64]; /* Device ID (e.g., VCU1525) */ + char m_version[64]; + char m_md5value[33]; /* MD5 Expected Value(e.g., 56027182079c0bd621761b7dab5a27ca)*/ + char m_padding[7]; /* Padding */ + }; + + struct soft_kernel { /* soft kernel data section */ + // Prefix Syntax: + // mpo - member, pointer, offset + // This variable represents a zero terminated string + // that is offseted from the beginning of the section. + // + // The pointer to access the string is initialized as follows: + // char * pCharString = (address_of_section) + (mpo value) + uint32_t mpo_name; // Name of the soft kernel + uint32_t m_image_offset; // Image offset + uint32_t m_image_size; // Image size + uint32_t mpo_version; // Version + uint32_t mpo_md5_value; // MD5 checksum + uint32_t mpo_symbol_name; // Symbol name + uint32_t m_num_instances; // Number of instances + uint8_t padding[36]; // Reserved for future use + uint8_t reservedExt[16]; // Reserved for future extended data + }; + + enum CHECKSUM_TYPE + { + CST_UNKNOWN = 0, + CST_SDBM = 1, + CST_LAST + }; + + /**** END : Xilinx internal section *****/ + +# ifdef __cplusplus + namespace xclbin { + inline const axlf_section_header* + get_axlf_section(const axlf* top, axlf_section_kind kind) + { + auto begin = top->m_sections; + auto end = begin + top->m_header.m_numSections; + auto itr = std::find_if(begin,end,[kind](const axlf_section_header& sec) { return sec.m_sectionKind==(const uint32_t) kind; }); + return (itr!=end) ? &(*itr) : nullptr; + } + + // Helper C++ section iteration + // To keep with with the current "coding" them, the function get_axlf_section_next() was + // introduced find 'next' common section names. + // + // Future TODO: Create a custom iterator and refactor the code base to use it. + // + // Example on how this function may be used: + // + // const axlf_section_header * pSection; + // const axlf* top = <xclbin image in memory>; + // for (pSection = xclbin::get_axlf_section( top, SOFT_KERNEL); + // pSection != nullptr; + // pSection = xclbin::get_axlf_section_next( top, pSection, SOFT_KERNEL)) { + // <code to do work> + // } + inline const axlf_section_header* + get_axlf_section_next(const axlf* top, const axlf_section_header* current_section, axlf_section_kind kind) + { + if (top == nullptr) { return nullptr; } + if (current_section == nullptr) { return nullptr; } + + auto end = top->m_sections + top->m_header.m_numSections; + + auto begin = current_section + 1; // Point to the next section + if (begin == end) { return nullptr; } + + auto itr = std::find_if(begin, end, [kind](const axlf_section_header &sec) {return sec.m_sectionKind == (const uint32_t)kind;}); + return (itr!=end) ? &(*itr) : nullptr; + } + } +# endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/uapi/linux/xrt/xmgmt-ioctl.h b/include/uapi/linux/xrt/xmgmt-ioctl.h new file mode 100644 index 000000000000..f949a7c21560 --- /dev/null +++ b/include/uapi/linux/xrt/xmgmt-ioctl.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0 */ +/* + * Copyright (C) 2015-2020, Xilinx Inc + * + */ + +/** + * DOC: PCIe Kernel Driver for Managament Physical Function + * Interfaces exposed by *xclmgmt* driver are defined in file, *mgmt-ioctl.h*. + * Core functionality provided by *xmgmt* driver is described in the following table: + * + * ==== ====================================== ============================== ================================== + * # Functionality ioctl request code data format + * ==== ====================================== ============================== ================================== + * 1 FPGA image download XCLMGMT_IOCICAPDOWNLOAD_AXLF xmgmt_ioc_bitstream_axlf + * 2 CL frequency scaling XCLMGMT_IOCFREQSCALE xmgmt_ioc_freqscaling + * ==== ====================================== ============================== ================================== + * + */ + +#ifndef _XMGMT_IOCALLS_POSIX_H_ +#define _XMGMT_IOCALLS_POSIX_H_ + +#include <linux/ioctl.h> + +#define XMGMT_IOC_MAGIC 'X' +#define XMGMT_NUM_SUPPORTED_CLOCKS 4 + +#define XMGMT_IOC_FREQ_SCALE 0x2 +#define XMGMT_IOC_ICAP_DOWNLOAD_AXLF 0x6 + + +/** + * struct xmgmt_ioc_bitstream_axlf - load xclbin (AXLF) device image + * used with XMGMT_IOCICAPDOWNLOAD_AXLF ioctl + * + * @xclbin: Pointer to user's xclbin structure in memory + */ +struct xmgmt_ioc_bitstream_axlf { + struct axlf *xclbin; +}; + +/** + * struct xmgmt_ioc_freqscaling - scale frequencies on the board using Xilinx clock wizard + * used with XMGMT_IOCFREQSCALE ioctl + * + * @ocl_region: PR region (currently only 0 is supported) + * @ocl_target_freq: Array of requested frequencies, a value o zero in the array indicates leave untouched + */ +struct xmgmt_ioc_freqscaling { + unsigned int ocl_region; + unsigned short ocl_target_freq[XMGMT_NUM_SUPPORTED_CLOCKS]; +}; + +#define DATA_CLK 0 +#define KERNEL_CLK 1 +#define SYSTEM_CLK 2 + +#define XMGMT_IOCICAPDOWNLOAD_AXLF _IOW(XMGMT_IOC_MAGIC, XMGMT_IOC_ICAP_DOWNLOAD_AXLF, struct xmgmt_ioc_bitstream_axlf) +#define XMGMT_IOCFREQSCALE _IOW(XMGMT_IOC_MAGIC, XMGMT_IOC_FREQ_SCALE, struct xmgmt_ioc_freqscaling) + +/* + * The following definitions are for binary compatibility with classic XRT management driver + */ + +#define XCLMGMT_IOCICAPDOWNLOAD_AXLF XMGMT_IOCICAPDOWNLOAD_AXLF +#define XCLMGMT_IOCFREQSCALE XMGMT_IOCFREQSCALE + +#define xclmgmt_ioc_bitstream_axlf xmgmt_ioc_bitstream_axlf +#define xclmgmt_ioc_freqscaling xmgmt_ioc_freqscaling + +#endif -- 2.17.1