コード例 #1
0
ファイル: shm_api_linux.c プロジェクト: dejin/mymisc
static HRESULT MV_SHM_Unmap_Base(shm_dev_t *shm_dev, size_t Offset)
{
	shm_address_t *address_node;
	int res = 0;

	if (SHM_DEVICE_LOAD_COUNT <= 0) {
		MV_SHM_Print("MV_SHM_Unmap_Base shm device"
			" not be open\n");
		return E_NOTREADY;
	}

	pthread_rwlock_wrlock(&shm_dev->addr.m_rb_rwlock);
	address_node =
		MV_SHM_lookup_phyaddress_node(&shm_dev->addr.m_phyaddr_root,
			(shm_dev->base.m_base_physaddr + Offset));
	if (address_node == NULL) {
		pthread_rwlock_unlock(&shm_dev->addr.m_rb_rwlock);
		return S_OK;
	}
	res = MV_SHM_Munmap_Base(address_node->m_virtaddress,
			address_node->m_size, shm_dev->mem_type);
	if (res == 0) {
		MV_SHM_delete_phyaddress_node(
			&shm_dev->addr.m_phyaddr_root,address_node);
		MV_SHM_delete_virtaddress_node(
			&shm_dev->addr.m_virtaddr_root,address_node);
		free(address_node);
	}
	pthread_rwlock_unlock(&shm_dev->addr.m_rb_rwlock);
	return S_OK;
}
コード例 #2
0
int MV_SHM_iounmap_and_free_rbtree(shm_device_t *device, size_t Offset)
{
	shm_address_t *address_node;

	if (device == NULL) {
		shm_error("kernel MV_SHM_iounmap_and_free_rbtree error\n");
		return -ENODEV;
	}

	down_read(&device->m_rwsem);
	address_node = MV_SHM_lookup_phyaddress_node(
		&device->m_phyaddr_root, (Offset + device->m_base));
	up_read(&device->m_rwsem);

	if (address_node ==NULL) {
		return 0;
	}

	down_write(&device->m_rwsem);
	MV_SHM_delete_phyaddress_node(&device->m_phyaddr_root, address_node);
	MV_SHM_delete_virtaddress_node(&device->m_virtaddr_root,address_node);
	up_write(&device->m_rwsem);

	iounmap((void *)(address_node->m_virtaddress));
	kfree(address_node);

	return 0;
}
コード例 #3
0
ファイル: shm_api_linux.c プロジェクト: dejin/mymisc
static HRESULT MV_SHM_UnmapVirt_Base(shm_dev_t *shm_dev, void* virtaddress)
{
	shm_address_t *address_node;
	shm_driver_operation_t op;
	int res = 0;

	if (SHM_DEVICE_LOAD_COUNT <= 0) {
		MV_SHM_Print("MV_SHM_UnmapVirt_Base shm device"
			" not be open\n");
		return E_NOTREADY;
	}

	pthread_rwlock_wrlock(&shm_dev->addr.m_rb_rwlock);
	address_node = MV_SHM_lookup_virtaddress_node(
		&shm_dev->addr.m_virtaddr_root,(size_t)virtaddress);
	if (address_node == NULL) {
		pthread_rwlock_unlock(&shm_dev->addr.m_rb_rwlock);
		MV_SHM_Print("MV_SHM_UnmapVirt_Base shm device"
			" not found virtaddress[%08x]\n",virtaddress);
		return S_OK;
	}
	op.m_param1 = address_node->m_phyaddress
			- shm_dev->base.m_base_physaddr;
	res = MV_SHM_Munmap_Base(address_node->m_virtaddress,
			address_node->m_size, shm_dev->mem_type);
	if (res == 0) {
		MV_SHM_delete_phyaddress_node(
			&shm_dev->addr.m_phyaddr_root,address_node);
		MV_SHM_delete_virtaddress_node(
			&shm_dev->addr.m_virtaddr_root,address_node);
		free(address_node);
	}
	pthread_rwlock_unlock(&shm_dev->addr.m_rb_rwlock);
	MV_SHM_Print("MV_SHM_UnmapVirt_Base shm device"
			" free offset[%08x]\n", op.m_param1);
	res = ioctl(shm_dev->base.m_fd, SHM_DEVICE_CMD_FREE, &op);
	CHECK_NOTERROR("ioctl", res, -1);

	return S_OK;
}
コード例 #4
0
ファイル: shm_api_linux.c プロジェクト: dejin/mymisc
static PVOID MV_SHM_GetVirtAddr_Base(shm_dev_t *shm_dev, size_t Offset)
{
	shm_address_t *address_node;
	shm_driver_operation_t op;
	shm_free_t shm_free;
    ldns_rbnode_t *node;

	if ((SHM_DEVICE_LOAD_COUNT <= 0) ||
		((Offset >= shm_dev->base.m_size) &&((shm_dev->mem_type == SHM_CACHE)
			|| (shm_dev->mem_type == SHM_NONCACHE)))) {
		MV_SHM_Print("user space MV_SHM_GetVirtAddr_Base shm device not"
			" open or parameter fail. open[%d] offset[%08x] >= "
			"shm_size[%08x] mem_type[%d]\n", SHM_DEVICE_LOAD_COUNT,
			Offset, shm_dev->base.m_size, shm_dev->mem_type);
		return NULL;
	}

	pthread_rwlock_wrlock(&shm_dev->addr.m_rb_rwlock);
	address_node = MV_SHM_lookup_phyaddress_node(
			&(shm_dev->addr.m_phyaddr_root),
			(shm_dev->base.m_base_physaddr + Offset));

	if (address_node == NULL) {
		address_node = malloc_shm_node();
		if(address_node == NULL) {
			MV_SHM_Print("user space MV_SHM_GetVirtAddr_Base"
				" malloc fail\n");
			pthread_rwlock_unlock(&shm_dev->addr.m_rb_rwlock);
			return NULL;
		}

		op.m_param1 = shm_dev->base.m_base_physaddr + Offset;
		if (MV_SHM_mmap_preparation(shm_dev->base.m_fd, &op) != 0) {
			MV_SHM_Print("user space MV_SHM_GetVirtAddr_Base "
				"MV_SHM_mmap_preparation fail\n");
			free(address_node);
			pthread_rwlock_unlock(&shm_dev->addr.m_rb_rwlock);
			return NULL;
		}

		address_node->m_phyaddress = op.m_param1;
		address_node->m_size = op.m_param2;
		address_node->m_virtaddress = MV_SHM_Mmap_Base(shm_dev,
			address_node->m_phyaddress, address_node->m_size);

		if (address_node->m_virtaddress == (size_t)MAP_FAILED) {
			MV_SHM_Print("user space MV_SHM_GetVirtAddr_Base "
				"MV_SHM_Mmap_Base fail\n");
			free(address_node);
			pthread_rwlock_unlock(&shm_dev->addr.m_rb_rwlock);
			MV_SHM_DumpProcessMemoryMap();
			return NULL;
		}

		if (MV_SHM_insert_phyaddress_node(
			&(shm_dev->addr.m_phyaddr_root), address_node) == NULL) {
            MV_SHM_Print("SHM:GETV:PHY:0x%x,%d\n", Offset, __LINE__);
			MV_SHM_Dump_Node(&(shm_dev->addr.m_phyaddr_root));
            node = MV_SHM_delete_phyaddress_node(&(shm_dev->addr.m_phyaddr_root), \
                address_node);
            MV_SHM_delete_virtaddress_node(&(shm_dev->addr.m_virtaddr_root), \
                node->key);
            MV_SHM_insert_phyaddress_node(
			&(shm_dev->addr.m_phyaddr_root), address_node);
        }
	    if (MV_SHM_insert_virtaddress_node(
			&(shm_dev->addr.m_virtaddr_root), address_node) == NULL) {
			MV_SHM_Print("SHM:GETV:VIRT:0x%x,%d\n", Offset, __LINE__);
			MV_SHM_Dump_Node(&(shm_dev->addr.m_virtaddr_root));
            node = MV_SHM_delete_virtaddress_node(&(shm_dev->addr.m_virtaddr_root), \
                address_node);
            MV_SHM_delete_phyaddress_node(&(shm_dev->addr.m_phyaddr_root), \
                node->key);
            MV_SHM_insert_virtaddress_node(&(shm_dev->addr.m_virtaddr_root),
                address_node);
        }
		pthread_rwlock_unlock(&shm_dev->addr.m_rb_rwlock);
		return (PVOID)(address_node->m_virtaddress+
				((Offset + shm_dev->base.m_base_physaddr)
				- address_node->m_phyaddress));;
	} else {
		op.m_param1 = shm_dev->base.m_base_physaddr + Offset;
		if (MV_SHM_mmap_preparation(shm_dev->base.m_fd, &op) != 0) {
			MV_SHM_Print("user space MV_SHM_GetVirtAddr_Base 2 "
				"MV_SHM_mmap_preparation fail\n");
			pthread_rwlock_unlock(&shm_dev->addr.m_rb_rwlock);
			return NULL;
		}

		if ((address_node->m_size == op.m_param2) &&
			(address_node->m_phyaddress == op.m_param1)) {
			pthread_rwlock_unlock(&shm_dev->addr.m_rb_rwlock);
			return (PVOID)(address_node->m_virtaddress+
				((Offset + shm_dev->base.m_base_physaddr)
				- address_node->m_phyaddress));
		} else {
			shm_free.address = op.m_param1;
			shm_free.size = op.m_param2;
			shm_free.shm_root = &shm_dev->addr;
			shm_free.mem_type = shm_dev->mem_type;
			MV_SHM_free_all_node(&shm_free);

			address_node = shm_free.node;
			if (shm_free.flag == 0) {
				address_node->m_phyaddress = op.m_param1;
				address_node->m_size = op.m_param2;
				address_node->m_virtaddress = MV_SHM_Mmap_Base(shm_dev,
					address_node->m_phyaddress, address_node->m_size);

				if (address_node->m_virtaddress == (size_t)MAP_FAILED) {
					MV_SHM_Print("user space MV_SHM_GetVirtAddr_Base 4 "
						"MV_SHM_Mmap_Base fail\n");
					free(address_node);
					pthread_rwlock_unlock(&shm_dev->addr.m_rb_rwlock);
					MV_SHM_DumpProcessMemoryMap();
					return NULL;
				}

                if (MV_SHM_insert_phyaddress_node(
                    &(shm_dev->addr.m_phyaddr_root), address_node) == NULL) {
                    MV_SHM_Print("SHM:GETV:PHY:0x%x,%d\n", Offset, __LINE__);
                    MV_SHM_Dump_Node(&(shm_dev->addr.m_phyaddr_root));
                    node = MV_SHM_delete_phyaddress_node(&(shm_dev->addr.m_phyaddr_root), \
                        address_node);
                    MV_SHM_delete_virtaddress_node(&(shm_dev->addr.m_virtaddr_root), \
                        node->key);
                    MV_SHM_insert_phyaddress_node(
                    &(shm_dev->addr.m_phyaddr_root), address_node);
                }
                if (MV_SHM_insert_virtaddress_node(
                    &(shm_dev->addr.m_virtaddr_root), address_node) == NULL) {
                    MV_SHM_Print("SHM:GETV:VIRT:0x%x,%d\n", Offset, __LINE__);
                    MV_SHM_Dump_Node(&(shm_dev->addr.m_virtaddr_root));
                    node = MV_SHM_delete_virtaddress_node(&(shm_dev->addr.m_virtaddr_root), \
                        address_node);
                    MV_SHM_delete_phyaddress_node(&(shm_dev->addr.m_phyaddr_root), \
                        node->key);
                    MV_SHM_insert_virtaddress_node(&(shm_dev->addr.m_virtaddr_root),
                        address_node);
                }
			}
			pthread_rwlock_unlock(&shm_dev->addr.m_rb_rwlock);
			return (PVOID)(address_node->m_virtaddress+
				((Offset + shm_dev->base.m_base_physaddr)
					- address_node->m_phyaddress));;
		}
	}
}
コード例 #5
0
ファイル: shm_api_linux.c プロジェクト: dejin/mymisc
static int MV_SHM_free_all_node(shm_free_t *shm)
{
	int i = 0;
	int frist = 0;
	ldns_rbnode_t *node;
	shm_address_t *tmp;
	uint middle1, middle2, middle_size;

	shm->flag = 0;
	shm->node = NULL;

    MV_SHM_Print("SHM:FREE:START:%d\n", __LINE__);
    MV_SHM_Dump_Node(&shm->shm_root->m_phyaddr_root);
    MV_SHM_Dump_Node(&shm->shm_root->m_virtaddr_root);
	node = ldns_rbtree_first(&shm->shm_root->m_phyaddr_root);
	while (node != LDNS_RBTREE_NULL) {
		tmp = (shm_address_t *)(node->key);
		node = ldns_rbtree_next(node);

		middle1 = tmp->m_phyaddress + tmp->m_size/2;
		middle2 = shm->address + shm->size/2;
		middle_size = (tmp->m_size + shm->size)/2;
		if (middle1 > middle2)
			middle1 = middle1 - middle2;
		else
			middle1 = middle2 - middle1;

		if (middle1 < middle_size) {
			MV_SHM_Print("MV_SHM_free_all_node No.[%d], root[%p]"
				" Node_phys[%08x] Node_virt[%08x] Node_size[%08x]"
				" address[%08x] size[%08x]\n",
				i, tmp, tmp->m_phyaddress, tmp->m_virtaddress,
				tmp->m_size, shm->address, shm->size);
			i++;
			if ((tmp->m_phyaddress == shm->address)
				&& (tmp->m_size == shm->size)
				&& (shm->flag == 0)) {
				shm->flag = 1;
				if ((shm->node != NULL) && (frist == 1))
					free(shm->node);
				shm->node = tmp;
			} else {
				if (MV_SHM_Munmap_Base(tmp->m_virtaddress,
					tmp->m_size, shm->mem_type) == 0) {
					MV_SHM_delete_phyaddress_node(
                                            &shm->shm_root->m_phyaddr_root, tmp);
					MV_SHM_delete_virtaddress_node(
                                            &shm->shm_root->m_virtaddr_root, tmp);

					if ((frist == 0) && (shm->flag == 0)) {
						frist = 1;
						shm->node = tmp;
					} else {
						free(tmp);
					}
				}
			}
		}
	}
    MV_SHM_Print("SHM:FREE:END:%d\n", __LINE__);
    MV_SHM_Dump_Node(&shm->shm_root->m_phyaddr_root);
    MV_SHM_Dump_Node(&shm->shm_root->m_virtaddr_root);
	return 0;
}
コード例 #6
0
static void *MV_SHM_Base_GetVirtAddr(shm_device_t *shm_dev,
					size_t Offset, int mem_type)
{
	shm_address_t *address_node;
	memory_node_t *tmp;
	size_t physaddress = 0;

	if (shm_dev == NULL) {
		shm_error("kernel MV_SHM_Base_GetVirtAddr parameters"
			" error shm_dev is NULL");
		return NULL;
	}

	if (Offset >= shm_dev->m_size) {
		shm_error("kernel MV_SHM_Base_GetVirtAddr parameters error"
			" shm_dev[%p] Offset[%08x] > shm_size[%08x] mem_type[%d]"
			"\n", shm_dev, Offset, shm_dev->m_size, mem_type);
		return NULL;
	}

	physaddress = Offset + shm_dev->m_base;

	mutex_lock(&(shm_dev->m_engine->m_mutex));
	tmp = memory_engine_lookup_shm_node_for_size(
		&(shm_dev->m_engine->m_shm_root), physaddress);
	mutex_unlock(&(shm_dev->m_engine->m_mutex));
	if (tmp == NULL) {
		shm_error("kernel MV_SHM_Base_GetVirtAddr"
			" memory_engine_lookup_shm_node_for_size"
			" offset[%08x] physaddress[%08x] mem_type[%d]\n",
			Offset, (physaddress), mem_type);
		return NULL;
	}

	down_write(&shm_dev->m_rwsem);
	address_node =
	MV_SHM_lookup_phyaddress_node(
		&(shm_dev->m_phyaddr_root), physaddress);

	if (address_node == NULL) {
		address_node = kmalloc(sizeof(shm_address_t), GFP_KERNEL);
		if(address_node == NULL) {
			up_write(&shm_dev->m_rwsem);
			shm_error("kernel MV_SHM_Base_GetVirtAddr"
				" kmalloc fail offset[%08x] mem_type[%d]\n",
				Offset, mem_type);
			return NULL;
		}
		address_node->m_phyaddress = tmp->m_phyaddress;
		address_node->m_size = MEMNODE_ALIGN_SIZE(tmp);
		address_node->m_virtaddress = (size_t)MV_SHM_Base_ioremap(
					address_node->m_phyaddress,
					address_node->m_size, mem_type);
		if (address_node->m_virtaddress == (size_t)NULL) {
			kfree(address_node);
			up_write(&shm_dev->m_rwsem);
			shm_error("kernel MV_SHM_Base_GetVirtAddr"
				" MV_SHM_ioremap fail offset[%08x]"
				" mem_type[%d]\n",Offset, mem_type);
			return NULL;
		}

		MV_SHM_insert_phyaddress_node(
			&(shm_dev->m_phyaddr_root), address_node);
		MV_SHM_insert_virtaddress_node(
			&(shm_dev->m_virtaddr_root), address_node);
		up_write(&shm_dev->m_rwsem);

		return (void *)(address_node->m_virtaddress +
				((Offset + shm_dev->m_base)
				- address_node->m_phyaddress));
	} else {
		if((address_node->m_phyaddress == tmp->m_phyaddress)
			&& (address_node->m_size == MEMNODE_ALIGN_SIZE(tmp))) {
			up_write(&shm_dev->m_rwsem);
			return (void *)(address_node->m_virtaddress +
				((Offset + shm_dev->m_base)
				- address_node->m_phyaddress));
		} else {
			MV_SHM_delete_phyaddress_node(
				&(shm_dev->m_phyaddr_root), address_node);
			MV_SHM_delete_virtaddress_node(
				&(shm_dev->m_virtaddr_root),address_node);

			iounmap((void *)(address_node->m_virtaddress));

			address_node->m_phyaddress = tmp->m_phyaddress;
			address_node->m_size = MEMNODE_ALIGN_SIZE(tmp);
			address_node->m_virtaddress = (size_t)MV_SHM_Base_ioremap(
						address_node->m_phyaddress,
						address_node->m_size, mem_type);
			if (address_node->m_virtaddress == (size_t)NULL) {
				kfree(address_node);
				up_write(&shm_dev->m_rwsem);
				shm_error("kernel MV_SHM_Base_GetVirtAddr"
					" MV_SHM_ioremap fail offset[%08x]"
					" mem_type[%d]\n", Offset, mem_type);
				return NULL;
			}

			MV_SHM_insert_phyaddress_node(
				&(shm_dev->m_phyaddr_root), address_node);
			MV_SHM_insert_virtaddress_node(
				&(shm_dev->m_virtaddr_root), address_node);
			up_write(&shm_dev->m_rwsem);
			return (void *)(address_node->m_virtaddress +
				((Offset + shm_dev->m_base)
				- address_node->m_phyaddress));
		}
	}
}