* Copyright (c) 2025 HiSilicon Technologies Co., Ltd. All rights reserved.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*/
#ifndef _UMMU_MAPT_H_
#define _UMMU_MAPT_H_
#include <stdint.h>
#include <pthread.h>
#include "ummu_api.h"
struct ummu_mapt_entry_node {
uint32_t valid : 1;
uint32_t reserved_0 : 2;
uint32_t e_bit : 1;
uint32_t permission : 6;
uint32_t reserved_1 : 22;
uint32_t reserved_2;
uint32_t base_low;
uint32_t base_high : 16;
uint32_t reserved_3 : 12;
uint32_t reserved_4 : 3;
uint32_t token_check : 1;
uint32_t limit_low;
uint32_t limit_high : 16;
uint32_t reserved_5 : 12;
uint32_t reserved_6 : 2;
uint32_t nonce : 2;
uint32_t token_val_0;
uint32_t token_val_1;
};
#define MAX_LEVEL_INDEX 3U
#define INDEX_MAX_SIZE 512UL
#define MAX_MAPT_ENTRY_INDEX 512U
#define INVALID_ADDR 0xFFF
#define MAX_ADDRESS_BITS 48U
#define UMMU_MAX_TOKEN_NUM 2
struct ummu_mapt_block {
void *block_addr;
size_t blk_size;
uint32_t block_id;
uint16_t level_cnt;
uint16_t *level_entry_cnt;
uint16_t lvl_block_cnt;
};
struct ummu_mapt_table_ctx {
int expan;
uint16_t block_cnt;
uint16_t lvl_block_cnt;
size_t blk_exp_size;
uint64_t granted_addr_mng;
uint32_t level_block_bitmap_size;
unsigned long *level_block_bitmap;
struct ummu_mapt_block *mapt_block_base;
void *mapt_block_array[INDEX_MAX_SIZE];
};
struct ummu_mapt_queue_ctx {
uint32_t ummu_cnt;
size_t queue_size;
uint16_t cmd_que_pi_size;
uint16_t cpl_que_size;
struct ummu_mapt_queue_args *queue;
};
struct ummu_seg_info {
uint64_t start_addr;
uint64_t grant_size;
enum ummu_mapt_perm permission;
enum ummu_ebit_state e_bit;
uint8_t token_check;
uint8_t token_count;
uint32_t token_val[UMMU_MAX_TOKEN_NUM];
};
struct ummu_mapt_info {
union {
struct ummu_mapt_entry_node *entry_block;
struct ummu_mapt_table_ctx *table_ctx;
} block_base;
unsigned int tid;
uint16_t valid;
uint8_t double_plbi;
uint8_t kcmd_plbi;
uint8_t positive_plbi;
uint8_t free_bit;
enum ummu_mapt_mode mode;
pthread_mutex_t mapt_mutex;
struct ummu_mapt_queue_ctx queue_ctx;
};
struct ummu_ctx_info {
pthread_mutex_t ctx_mutex;
void *mapt_map;
int shared_fd;
};
enum ummu_buf_mode {
BASE_MODE_ENTRY_BLOCK,
BASE_MODE_TABLE_BLOCK,
BASE_MODE_QUEUE
};
enum ummu_grant_op_type {
UMMU_GRANT = 0,
UMMU_ADD_TOKEN = 1,
UMMU_REMOVE_TOKEN = 2,
UMMU_UNGRANT = 3,
UMMU_OP_END
};
struct ummu_mapt_table_node {
uint32_t valid : 1;
uint32_t type : 1;
uint32_t next_block : 1;
uint32_t e_bit : 1;
uint32_t permission : 6;
uint32_t f_bit : 1;
uint32_t reserved_0 : 1;
uint32_t next_lv_offset_low : 20;
uint32_t next_lv_offset_high : 10;
uint32_t reserved_1 : 6;
uint32_t next_lv_index : 16;
uint32_t base_low;
uint32_t base_high : 7;
uint32_t reserved_2 : 21;
uint32_t reserved_3 : 3;
uint32_t token_check : 1;
uint32_t limit_low;
uint32_t limit_high : 7;
uint32_t reserved_4 : 21;
uint32_t flag : 2;
uint32_t nonce : 2;
uint32_t token_val_0;
uint32_t token_val_1;
};
struct ummu_data_info {
void *data;
size_t data_size;
enum ummu_mapt_perm perm;
struct ummu_token_info *token;
uint32_t tokenval;
uint64_t data_base;
uint64_t data_limit;
uint32_t token_check;
int bytoken;
enum ummu_ebit_state e_bit;
enum ummu_grant_op_type op;
struct ummu_mapt_info *mapt_info;
uint8_t lvl;
uint8_t head_flag;
};
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#define MAPT_VPAGE_SHIFT 12U
static const uint32_t g_mapt_range_bits[MAX_LEVEL_INDEX + 1U][2] = {{47, 39}, {38, 30}, {29, 21}, {20, 12}};
#define GET_BITS_MASK(bits) (((uint64_t)1 << (bits)) - 1)
#define GET_LEVEL_RANGE_MASK(level) (GET_BITS_MASK(g_mapt_range_bits[(level)][1]))
#define GET_LEVEL_BLOCK_INDEX(addr, level) (((uint64_t)(addr) >> g_mapt_range_bits[(level)][1]) & \
(GET_BITS_MASK(g_mapt_range_bits[(level)][0] - g_mapt_range_bits[(level)][1] + 1)))
#define MAX_CMD_QUE_INDEX(size) (((uint64_t)1 << (size)) - (uint64_t)1)
#define ALIGN_MAPT_MASK(x, mask) ((x) & ~(mask))
#define ALIGN_MAPT(x, a) ALIGN_MAPT_MASK(x, (typeof(x))(a) - 1UL)
#define ALIGN_CHECK(x, a) ((ALIGN_MAPT((x), (a))) == (x) ? true : false)
#define ALIGN_VPAGE_SHIFT_CHECK(val) ALIGN_CHECK(val, 1UL << MAPT_VPAGE_SHIFT)
#define ENTRY_ADDR_LOW(addr) ((uint32_t)((addr) & GENMASK_ULL(31, 0)))
#define ENTRY_ADDR_HIGH(addr) ((uint32_t)(((addr) & GENMASK_ULL(47, 32)) >> 32UL))
#define TABLE_ADDR_LOW(addr) ((uint32_t)((addr) & GENMASK_ULL(31, 0)))
#define TABLE_ADDR_HIGH(addr) ((uint32_t)(((addr) & GENMASK_ULL(38, 32)) >> 32UL))
#define LVL_OFFSET_LOW(offset) ((uint32_t)((offset) & GENMASK_ULL(19, 0)))
#define LVL_OFFSET_HIGH(offset) ((uint32_t)(((offset) & GENMASK_ULL(29, 20)) >> 20UL))
#define ADDR_FULL(low, high) (((uint64_t)(high) << 32UL) | (uint64_t)(low))
#define TABLE_LVL_OFFSET(low, high) (((uint32_t)(high) << 20UL) | (uint32_t)(low))
#define IS_RTE_IN_USE(addr) (((((uint64_t)(addr)) & INVALID_ADDR) == INVALID_ADDR) ? false : true)
extern struct ummu_ctx_info *get_ummu_ctx(void);
void ummu_mapt_destroy(struct ummu_mapt_info *info);
#endif