* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef DEVMM_CHANNEL_H
#define DEVMM_CHANNEL_H
#include "svm_ioctl.h"
#include "drv_type.h"
#define DEVMM_CHANNEL_MASK 0x00000FFF
#define DEVMM_MAX_BLOCK_NUM 16
enum {
DEVMM_CHAN_EX_PGINFO_H2D_ID = 0,
DEVMM_CHAN_SETUP_DEVICE_H2D = 1,
DEVMM_CHAN_CLOSE_DEVICE_H2D = 2,
DEVMM_CHAN_PAGE_QUERY_H2D_ID = 3,
DEVMM_CHAN_PAGE_CREATE_H2D_ID = 4,
DEVMM_CHAN_PAGE_CREATE_QUERY_H2D_ID = 5,
DEVMM_CHAN_PAGE_P2P_CREATE_H2D_ID = 6,
DEVMM_CHAN_PAGE_FAULT_P2P_ID = 7,
DEVMM_CHAN_FREE_PAGES_H2D_ID = 8,
DEVMM_CHAN_MEMSET8_H2D_ID = 9,
DEVMM_CHAN_ADVISE_CACHE_PERSIST_H2D_ID = 10,
DEVMM_CHAN_MEM_DFX_QUERY_H2D_ID = 11,
DEVMM_CHAN_PAGE_FAULT_H2D_ID = 12,
DEVMM_CHAN_MAP_DEV_RESERVE_H2D_ID = 13,
DEVMM_CHAN_PAGE_FAULT_D2H_ID = 14,
DEVMM_CHAN_QUERY_VAFLGS_D2H_ID = 15,
DEVMM_CHAN_UPDATE_HEAP_H2D_ID = 16,
DEVMM_CHAN_QUERY_MEMINFO_H2D_ID = 17,
DEVMM_CHAN_MEMCPY_D2D_ID = 18,
DEVMM_CHAN_REMOTE_MAP_ID = 19,
DEVMM_CHAN_REMOTE_UNMAP_ID = 20,
DEVMM_CHAN_SHM_GET_PAGES_D2H_ID = 21,
DEVMM_CHAN_SHM_PUT_PAGES_D2H_ID = 22,
DEVMM_CHAN_CHECK_VA_D2H_ID = 23,
DEVMM_CHAN_PROCESS_STATUS_REPORT_D2H_ID = 24,
DEVMM_CHAN_QUERY_PROCESS_STATUS_H2D_ID = 25,
DEVMM_CHAN_MEM_CREATE_H2D_ID = 26,
DEVMM_CHAN_MEM_RELEASE_H2D_ID = 27,
DEVMM_CHAN_MEM_MAP_H2D_ID = 28,
DEVMM_CHAN_MEM_UNMAP_H2D_ID = 29,
DEVMM_CHAN_MEM_EXPORT_H2D_ID = 30,
DEVMM_CHAN_MEM_IMPORT_H2D_ID = 31,
DEVMM_CHAN_SHARE_MEM_RELEASE_H2D_ID = 32,
DEVMM_CHAN_SHARE_MEM_MEMSET_H2D_ID = 33,
DEVMM_CHAN_TARGET_ADDR_P2P_ID = 34,
DEVMM_CHAN_SVM_MEM_REPAIR_H2D_ID = 35,
DEVMM_CHAN_NO_SVM_MEM_REPAIR_H2D_ID = 36,
DEVMM_CHAN_GET_BLK_INFO_H2D_ID = 37,
DEVMM_CHAN_SOMA_CREATE_POOL_H2D_ID = 38,
DEVMM_CHAN_SOMA_DESTROY_POOL_H2D_ID = 39,
DEVMM_CHAN_SOMA_TRIM_POOL_H2D_ID = 40,
DEVMM_CHAN_MAX_ID
};
enum {
DEVMM_DMA,
DEVMM_NON_DMA
};
struct devmm_chan_msg_head {
struct devmm_svm_process_id process_id;
u16 msg_id;
u16 logical_devid;
* agent to master: src agent id;
* agent to agent: dst agent id;
*/
u16 dev_id;
u16 vfid;
short result;
u16 extend_num;
u32 res;
};
struct devmm_chan_addr_head {
struct devmm_chan_msg_head head;
u64 va;
};
enum {
DEVMM_EXCHANGE_DDR_SIZE,
DEVMM_EXCHANGE_HBM_SIZE,
DEVMM_EXCHANGE_MAX_MEM_TYPE
};
struct devmm_device_capability {
u64 dvpp_memsize;
u32 svm_offset_num;
u32 feature_phycial_address;
u32 feature_bar_mem;
u32 feature_pcie_th;
u32 feature_dev_read_only;
u32 feature_pcie_dma_support_sva;
u32 feature_dev_mem_map_host;
u32 feature_bar_huge_mem;
u64 double_pgtable_offset;
u32 feature_giant_page;
u32 feature_aic_reg_map;
u32 feature_remote_mmap;
u32 feature_shmem_repair;
u32 feature_host_mem_map_cap;
u32 feature_mem_host_uva;
};
struct devmm_chan_exchange_pginfo {
struct devmm_chan_msg_head head;
u32 host_page_shift;
u32 host_hpage_shift;
u32 device_page_shift;
u32 device_hpage_shift;
u32 cluster_id;
u32 ts_shm_block_num;
u32 ts_shm_data_num;
u32 ts_shm_support_bar_write;
u32 ts_shm_block_id[DEVMM_MAX_BLOCK_NUM];
u64 ts_shm_dma_addr[DEVMM_MAX_BLOCK_NUM];
u64 ts_shm_addr[DEVMM_MAX_BLOCK_NUM];
u64 dev_mem[DEVMM_EXCHANGE_MAX_MEM_TYPE];
u64 dev_mem_p2p[DEVMM_EXCHANGE_MAX_MEM_TYPE];
struct devmm_device_capability device_capability;
u64 host_uva_start;
};
struct devmm_chan_phy_block {
unsigned long pa;
unsigned int sz;
};
#define DEVMM_PAGE_NUM_PER_FAULT 514
struct devmm_chan_page_fault {
struct devmm_chan_msg_head head;
u64 va;
u32 num;
struct devmm_chan_phy_block blks[DEVMM_PAGE_NUM_PER_FAULT];
};
#define DEVMM_BLKNUM_ADD_NUM 2
#define DEVMM_CHUNK_PAGE_SHIFT 12
#define DEVMM_HUGE_PAGE_SHIFT 21
#define DEVMM_SIZE_TO_PAGE_NUM(size, page_size) (((size) / (page_size)) + DEVMM_BLKNUM_ADD_NUM)
#define DEVMM_SIZE_TO_PAGE_MAX_NUM(size, page_size) (((size) / (page_size)) + DEVMM_BLKNUM_ADD_NUM)
#define DEVMM_SIZE_TO_HUGEPAGE_MAX_NUM(size) (((size) >> DEVMM_HUGE_PAGE_SHIFT) + DEVMM_BLKNUM_ADD_NUM)
#define DEVMM_BLKNUM_TO_DMANODE_MAX_NUM(blk_num) ((blk_num) * 2 + DEVMM_BLKNUM_ADD_NUM)
#define DEVMM_VA_SIZE_TO_PAGE_NUM(va, sz, pgsz) ((ka_base_round_up((va) + (sz), pgsz) - ka_base_round_down(va, pgsz)) / (pgsz))
#ifdef CFG_SOC_PLATFORM_ESL_FPGA
#define DEVMM_PAGE_NUM_PER_MSG 32ULL
#else
#define DEVMM_PAGE_NUM_PER_MSG 3072ULL
#endif
#define DEVMM_MEMSET_SIZE_PER_MSG (1ULL << 24)
#ifdef CFG_SOC_PLATFORM_ESL_FPGA
#define DEVMM_MEMSET8D_SIZE_PER_MSG (1ULL << 24)
#else
#define DEVMM_MEMSET8D_SIZE_PER_MSG (1ULL << 29)
#endif
#ifdef CFG_SOC_PLATFORM_ESL_FPGA
#define DEVMM_FREE_SECTION_NUM 128
#else
#define DEVMM_FREE_SECTION_NUM 8192
#endif
#define DEVMM_PA_VALID 0x1ul
#define DEVMM_PA_FIRST 0x2ul
#ifndef EMU_ST
#define DEVMM_PA_MASK 0xfful
#else
#define DEVMM_PA_MASK 0xful
#endif
#define DEVMM_ADDR_TYPE_PHY 0
#define DEVMM_ADDR_TYPE_DMA 1
* one msg has a byte to maintain msg status
* bit4~bit31: reserve
* bit3: msg write lock
* bit2: first data is va, like struct devmm_chan_addr_head
* bit1: svm_process exit return ok
* bit0: don't need svm_process, msg proc fun pass null
*/
#define DEVMM_MSG_NOT_NEED_SVM_PROC_BIT 0
#define DEVMM_MSG_RETURN_OK_BIT 1
#define DEVMM_MSG_GET_HEAP_BIT 2
#define DEVMM_MSG_WRITE_LOCK_BIT 3
#define DEVMM_MSG_ADD_CGROUP_BIT 4
#define DEVMM_MSG_NOT_NEED_PROC_MASK (1UL << DEVMM_MSG_NOT_NEED_SVM_PROC_BIT)
#define DEVMM_MSG_RETURN_OK_MASK (1UL << DEVMM_MSG_RETURN_OK_BIT)
#define DEVMM_MSG_GET_HEAP_MASK (1UL << DEVMM_MSG_GET_HEAP_BIT)
#define DEVMM_MSG_WRITE_LOCK_MASK (1UL << DEVMM_MSG_WRITE_LOCK_BIT)
#define DEVMM_MSG_ADD_CGROUP_MASK (1UL << DEVMM_MSG_ADD_CGROUP_BIT)
struct devmm_chan_page_query {
struct devmm_chan_msg_head head;
u64 va;
u64 size;
u32 bitmap;
u32 shr_page_num;
};
struct devmm_chan_query_phy_blk {
u64 dma_addr;
u64 phy_addr;
};
struct devmm_chan_page_query_ack {
struct devmm_chan_msg_head head;
u64 va;
u64 size;
u32 addr_type;
u32 bitmap;
u32 num;
u32 page_size;
u32 is_giant_page;
u32 p2p_owner_sdid;
u64 p2p_owner_va;
u64 mem_map_route;
struct devmm_svm_process_id p2p_owner_process_id;
struct devmm_chan_query_phy_blk blks[];
};
struct devmm_node_info {
u64 total_normal_size;
u64 free_normal_size;
u64 total_huge_size;
u64 free_huge_size;
};
struct devmm_chan_query_mem_dfx {
struct devmm_chan_msg_head head;
struct devmm_node_info node_info[DEVMM_MAX_NUMA_NUM_OF_PER_DEV];
u32 node_index[DEVMM_MAX_NUMA_NUM_OF_PER_DEV];
u32 node_num;
u32 mem_type;
u64 used_page_cnt;
u64 used_hpage_cnt;
};
struct devmm_chan_advise_cache_persist {
struct devmm_chan_msg_head head;
u64 va;
u64 count;
};
struct devmm_chan_target_blk {
u64 target_addr;
};
struct devmm_chan_target_query_ack {
struct devmm_chan_msg_head head;
u64 va;
u64 size;
u32 num;
int addr_type;
struct devmm_chan_target_blk blks[];
};
struct devmm_dma_blk {
u64 dma_addr;
u64 size;
};
struct devmm_target_blk {
u64 target_addr;
struct devmm_dma_blk dma_blk;
};
struct devmm_chan_target_blk_query_msg) / sizeof(struct devmm_target_blk) */
#define SVM_CS_HOST_BLK_MAX_NUM 16
struct devmm_chan_target_blk_query_msg {
int share_sdid;
int share_devid;
int share_id;
int addr_type;
u32 dma_saved;
u32 num;
u32 offset;
struct devmm_target_blk blk[];
};
struct devmm_chan_target_blk_query {
struct devmm_chan_msg_head head;
struct devmm_chan_target_blk_query_msg msg;
};
struct devmm_chan_free_pages {
struct devmm_chan_msg_head head;
u64 va;
u64 real_size;
};
struct devmm_chan_memset {
struct devmm_chan_msg_head head;
u64 dst;
u64 value;
u32 count;
};
#define DEVMM_CHAN_MAX_HEAP_INFO_NUM 128
struct devmm_chan_heap_info {
u32 heap_idx;
u32 heap_type;
u32 heap_sub_type;
u64 heap_size;
};
#define DEVMM_POLLING_CMD_CREATE 0xEFEF0001
#define DEVMM_POLLING_CMD_UPDATE_HEAP 0xEFEF0004
struct devmm_chan_setup_device {
struct devmm_chan_msg_head head;
u32 cmd;
pid_t devpid;
int ssid;
u32 logic_devid;
u32 heap_cnt;
struct devmm_chan_heap_info heap_info[];
};
struct devmm_chan_device_meminfo {
struct devmm_chan_msg_head head;
u32 mem_type;
u64 normal_free_size;
u64 normal_total_size;
u64 huge_free_size;
u64 huge_total_size;
u64 giant_free_size;
u64 giant_total_size;
};
struct devmm_chan_close_device {
struct devmm_chan_msg_head head;
u32 cmd;
pid_t devpid;
};
struct devmm_chan_update_heap {
struct devmm_chan_msg_head head;
struct devmm_update_heap_para cmd;
};
struct devmm_chan_check_va {
struct devmm_chan_msg_head head;
u64 check_va;
u64 pre_start_va;
u64 pre_end_va;
u64 post_start_va;
u64 post_end_va;
u64 bitmap;
};
struct devmm_chan_proc_abort {
struct devmm_chan_msg_head head;
u32 status;
u32 dma_status;
};
struct devmm_chan_memcpy_d2d {
struct devmm_chan_msg_head head;
u64 dst;
u64 src;
u64 size;
};
struct devmm_chan_remote_map {
struct devmm_chan_msg_head head;
u64 src_va;
u32 access;
u64 size;
u64 dst_va;
u32 page_size;
u32 map_type;
u32 proc_type;
u64 src_pa[];
};
struct devmm_chan_remote_unmap {
struct devmm_chan_msg_head head;
u64 src_va;
u64 dst_va;
u64 size;
u32 map_type;
u32 proc_type;
};
struct devmm_chan_shm_getput_pages_d2h {
struct devmm_chan_msg_head head;
u64 dev_va;
u64 size;
};
struct devmm_chan_agent_proc_exiting_d2h {
struct devmm_chan_msg_head head;
};
struct devmm_chan_map_dev_reserve {
struct devmm_chan_msg_head head;
u32 addr_type;
u64 va;
u64 len;
};
struct devmm_chan_process_status {
struct devmm_chan_msg_head head;
processStatus_t pid_status;
bool status_occur;
u32 pid;
u32 tid;
};
struct devmm_chan_mem_create {
struct devmm_chan_msg_head head;
u32 is_create_to_new_blk;
int id;
u32 module_id;
u32 pg_type;
u32 mem_type;
u32 total_pg_num;
u32 to_create_pg_num;
};
struct devmm_chan_mem_release {
struct devmm_chan_msg_head head;
int id;
u32 free_type;
u64 to_free_pg_num;
};
struct devmm_chan_mem_map {
struct devmm_chan_msg_head head;
u64 va;
u64 size;
int phy_addr_blk_id;
u32 pg_type;
u64 offset_pg_num;
u64 dma_blk_id;
u64 dma_blk_pg_id;
u32 get_next_dma_blk_pg_id;
u32 module_id;
u64 phy_addr_blk_pg_num;
struct devmm_chan_query_phy_blk blks[];
};
struct devmm_chan_mem_unmap {
struct devmm_chan_msg_head head;
u64 va;
};
struct devmm_chan_mem_export {
struct devmm_chan_msg_head head;
int id;
int share_id;
u64 pg_num;
u32 module_id;
u32 side;
u32 pg_type;
u32 mem_type;
};
struct devmm_chan_mem_import {
struct devmm_chan_msg_head head;
int side;
int share_id;
u32 share_sdid;
u32 host_did;
u32 module_id;
u32 pg_type;
u32 mem_type;
u32 total_pg_num;
u32 to_create_pg_num;
u32 is_create_to_new_blk;
int id;
};
struct devmm_chan_share_mem_memset {
struct devmm_chan_msg_head head;
u64 va_offset;
u64 value;
u32 count;
int share_id;
};
struct devmm_chan_mem_repair {
struct devmm_chan_msg_head head;
u64 addr;
u64 len;
u8 need_cache_update;
u8 is_giant_page;
u32 bitmap;
struct devmm_chan_query_phy_blk blk;
};
#define DEVMM_P2P_PAGE_MAX_NUM_QUERY_MSG 32
int devmm_host_dev_init(u32 dev_id, u32 vfid);
void devmm_host_dev_uninit(u32 dev_id);
void devmm_chan_set_host_device_page_size(void);
void devmm_merg_pa_by_num(u64 *pas, u32 num, u32 pgsz, u32 *merg_szlist, u32 *merg_num);
void devmm_merg_phy_blk(struct devmm_chan_phy_block *blks, u32 blks_idx, u32 *merg_idx);
int devmm_chan_page_fault_d2h_process_dma_copy(struct devmm_chan_page_fault *fault_msg, u64 *pas,
u32 *szs, u32 num);
int devmm_init_convert_addr_mng(u32 dev_id, struct devmm_chan_exchange_pginfo *info);
void devmm_uninit_convert_addr_mng(u32 dev_id);
typedef int (*svm_host_agent_msg_send_handle)(int agent_id, void *msg, unsigned int len, unsigned int out_len);
void devmm_register_host_agent_msg_send_handle(svm_host_agent_msg_send_handle func);
int devmm_host_chan_msg_recv(void *msg, unsigned int len, unsigned int out_len);
struct devmm_ipc_pod_msg_head {
u32 devid;
u32 cmdtype;
u16 valid;
s16 result;
u32 rsv;
};
#define DEVMM_IPC_POD_MSG_TOTAL_LEN 512
#define DEVMM_IPC_POD_MSG_DATA_LEN (DEVMM_IPC_POD_MSG_TOTAL_LEN - sizeof(struct devmm_ipc_pod_msg_head))
#define DEVMM_IPC_POD_MSG_SEND_MAGIC 0x5A5A
#define DEVMM_IPC_POD_MSG_RCV_MAGIC 0xA5A5
struct devmm_ipc_pod_msg_data {
struct devmm_ipc_pod_msg_head header;
char payload[DEVMM_IPC_POD_MSG_DATA_LEN];
};
enum devmm_ipc_pod_msg_cmd {
DEVMM_IPC_POD_MSG_SET_PID,
DEVMM_IPC_POD_MSG_DESTROY,
DEVMM_IPC_POD_MSG_MEM_REPAIR,
DEVMM_GET_SHARE_INFO,
DEVMM_PUT_SHARE_INFO,
DEVMM_GET_BLK_INFO,
DEVMM_IPC_POD_MSG_MAX
};
#endif