* 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.
*/
#include <errno.h>
#include <sys/ioctl.h>
#include "ummu_log.h"
#include "ummu_queue.h"
#include "ummu_resource.h"
void *ummu_get_core_buf(unsigned int tid, enum ummu_buf_mode mode, size_t size, int fd, unsigned long idx)
{
int prot = PROT_WRITE | PROT_READ;
int flags = MAP_SHARED;
void *addr = NULL;
if (size == 0) {
return addr;
}
switch (mode) {
case BASE_MODE_ENTRY_BLOCK:
addr = mmap(NULL, size, prot, flags, fd, UMMU_OFFSET_BLK(0UL, tid));
break;
case BASE_MODE_TABLE_BLOCK:
if (size < BLOCK_SIZE_16K || size > BLOCK_SIZE_2M) {
return addr;
}
addr = mmap(NULL, size, prot, flags, fd, UMMU_OFFSET_BLK(idx, tid));
break;
case BASE_MODE_QUEUE:
addr = mmap(NULL, size, prot, flags, fd, UMMU_OFFSET_QUE(tid));
break;
default:
break;
}
return addr;
}
void ummu_free_core_buf(enum ummu_buf_mode mode, void *buf, size_t size)
{
switch (mode) {
case BASE_MODE_ENTRY_BLOCK:
munmap(buf, BLOCK_SIZE_4K);
break;
case BASE_MODE_TABLE_BLOCK:
case BASE_MODE_QUEUE:
munmap(buf, size);
break;
default:
break;
}
return;
}
int ummu_get_tid(int fd, struct ummu_tid_info *info)
{
if (fd < 0) {
UMMU_MAPT_ERROR_LOG("Shared fd is invalid.\n");
return -ENOENT;
}
info->dev = (~0UL);
return ioctl(fd, UMMU_IOCALLOC_TID, info);
}
void ummu_put_tid(int fd, unsigned int tid)
{
struct ummu_tid_info info = {
.tid = tid,
};
int ret;
if (fd < 0) {
UMMU_MAPT_ERROR_LOG("Shared fd is invalid.\n");
return;
}
ret = ioctl(fd, UMMU_IOCFREE_TID, &info);
if (ret != 0) {
UMMU_MAPT_ERROR_LOG("Failed to put tid, ret = %d.\n", ret);
}
}
void ummu_kcmd_plbi(int fd, struct ummu_tid_info *info, uint32_t opcode)
{
int ret = 0;
if (fd < 0) {
UMMU_MAPT_ERROR_LOG("Shared fd is invalid.\n");
return;
}
if (opcode == PLBI_VA_OP) {
ret = ioctl(fd, UMMU_IOCPLBI_VA, info);
} else if (opcode == PLBI_ALL_OP) {
ret = ioctl(fd, UMMU_IOCPLBI_ALL, info);
} else {
UMMU_MAPT_WARN_LOG("Invalid plbi opcode.\n");
}
if (ret != 0) {
UMMU_MAPT_ERROR_LOG("Issue opcode = %u plbi failed, ret = %d.\n", opcode, ret);
}
}