265 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			265 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
 | 
						|
#include "sys_usrmem.h"
 | 
						|
#include "rtosfdt.h"
 | 
						|
#include "libfdt.h"
 | 
						|
#include "compiler.h"
 | 
						|
#include <kwrap/error_no.h>
 | 
						|
#include <kwrap/debug.h>
 | 
						|
#include "MemCheck.h"
 | 
						|
#include "hdal.h"
 | 
						|
 | 
						|
#if !defined(__FREERTOS)
 | 
						|
#include <fcntl.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <sys/mman.h>
 | 
						|
#include <sys/types.h>
 | 
						|
#include <sys/stat.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <unistd.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#if defined(__FREERTOS)
 | 
						|
 | 
						|
INT32 sys_usrmem_init(SYS_USRMEM* usrmem)
 | 
						|
{
 | 
						|
	const void* fdt = fdt_get_base();
 | 
						|
	int nodeoffset = fdt_path_offset((const void*)fdt, SYS_USRMEM_NODE);
 | 
						|
 | 
						|
	int len;
 | 
						|
 | 
						|
	if(usrmem == NULL){
 | 
						|
		DBG_ERR("usrmem can't be null!\n");
 | 
						|
		return E_SYS;
 | 
						|
	}
 | 
						|
 | 
						|
	usrmem->is_init = FALSE;
 | 
						|
 | 
						|
	if(nodeoffset >= 0){
 | 
						|
		const unsigned long *nodep;
 | 
						|
		nodep = (const unsigned long *)fdt_getprop(fdt, nodeoffset, "reg", &len);
 | 
						|
 | 
						|
		usrmem->used_size = 0;
 | 
						|
		usrmem->addr = be32_to_cpu(nodep[0]);
 | 
						|
		usrmem->size = be32_to_cpu(nodep[1]);
 | 
						|
 | 
						|
		usrmem->hdr = (SYS_USRMEM_HDR*) usrmem->addr;
 | 
						|
		usrmem->hdr->photo_ofs = 0;
 | 
						|
		usrmem->hdr->photo_size = 0;
 | 
						|
		usrmem->hdr->photo_sum = 0;
 | 
						|
		usrmem->hdr->tag = SYS_USRMEM_TAG;
 | 
						|
		usrmem->used_size += sizeof(SYS_USRMEM_HDR);
 | 
						|
		usrmem->addr_photo = usrmem->addr + usrmem->used_size;
 | 
						|
 | 
						|
		DBG_DUMP("usrmem addr = %lx, size = %lx, addr_hdr = %lx, addr_photo = %lx\n",
 | 
						|
				usrmem->addr,
 | 
						|
				usrmem->size,
 | 
						|
				usrmem->hdr ,
 | 
						|
				usrmem->addr_photo);
 | 
						|
 | 
						|
		usrmem->is_init = TRUE;
 | 
						|
		return E_OK;
 | 
						|
	}
 | 
						|
 | 
						|
	DBG_ERR("fdt node %s not found!\n", SYS_USRMEM_NODE);
 | 
						|
 | 
						|
	return E_SYS;
 | 
						|
}
 | 
						|
 | 
						|
INT32 sys_usrmem_write_photo(SYS_USRMEM* usrmem, UINT32 buf, UINT32 size)
 | 
						|
{
 | 
						|
	if(usrmem == NULL){
 | 
						|
		DBG_ERR("usrmem can't be null!\n");
 | 
						|
		return E_SYS;
 | 
						|
	}
 | 
						|
 | 
						|
	if(usrmem->addr_photo == 0){
 | 
						|
		DBG_ERR("address photo can't be null!\n");
 | 
						|
		return E_SYS;
 | 
						|
	}
 | 
						|
 | 
						|
	if(buf == 0){
 | 
						|
		DBG_ERR("buf can't be null!\n");
 | 
						|
		return E_SYS;
 | 
						|
	}
 | 
						|
 | 
						|
	if(size == 0){
 | 
						|
		DBG_ERR("size can't be zero!\n");
 | 
						|
		return E_SYS;
 | 
						|
	}
 | 
						|
 | 
						|
	if(usrmem->is_init == FALSE){
 | 
						|
		DBG_ERR("usrmem is not init yet!\n");
 | 
						|
		return E_SYS;
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	memcpy((void*)usrmem->addr_photo, (void*)buf, size);
 | 
						|
	usrmem->hdr->photo_ofs = usrmem->used_size;
 | 
						|
	usrmem->hdr->photo_size = size;
 | 
						|
	usrmem->hdr->photo_sum = MemCheck_CalcCheckSum16Bit(usrmem->addr_photo, size);
 | 
						|
	usrmem->used_size += size;
 | 
						|
 | 
						|
	hd_common_mem_flush_cache((void*)usrmem->addr, usrmem->used_size);
 | 
						|
 | 
						|
	DBG_DUMP("photo addr:%lx, size:%lx, sum:%lx\n", usrmem->addr_photo, usrmem->hdr->photo_size, usrmem->hdr->photo_sum);
 | 
						|
 | 
						|
	return E_OK;
 | 
						|
 | 
						|
}
 | 
						|
#else
 | 
						|
 | 
						|
static void* usrmem_mmap(int fd, unsigned int mapped_size, off_t phy_addr)
 | 
						|
{
 | 
						|
	void *map_base = NULL;
 | 
						|
	unsigned page_size = 0;
 | 
						|
 | 
						|
	page_size = getpagesize();
 | 
						|
	map_base = mmap(NULL,
 | 
						|
			mapped_size,
 | 
						|
			PROT_READ | PROT_WRITE,
 | 
						|
			MAP_SHARED,
 | 
						|
			fd,
 | 
						|
			(phy_addr) & ~(off_t)(page_size - 1));
 | 
						|
 | 
						|
	if (map_base == MAP_FAILED)
 | 
						|
		return NULL;
 | 
						|
 | 
						|
	return map_base;
 | 
						|
}
 | 
						|
 | 
						|
static int usrmem_munmap(void* map_base, unsigned int mapped_size)
 | 
						|
{
 | 
						|
	if (munmap(map_base, mapped_size) == -1)
 | 
						|
		return -1;
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int usrmem_init_dev(char* dev)
 | 
						|
{
 | 
						|
	int fd = 0;
 | 
						|
 | 
						|
	DBG_DUMP("open %s\n", dev);
 | 
						|
 | 
						|
	fd = open(dev, O_RDWR | O_SYNC);
 | 
						|
	return fd;
 | 
						|
}
 | 
						|
 | 
						|
INT32 sys_usrmem_init(SYS_USRMEM* usrmem)
 | 
						|
{
 | 
						|
    const void* fdt = fdt_get_base();
 | 
						|
    int nodeoffset = fdt_path_offset((const void*)fdt, SYS_USRMEM_NODE);
 | 
						|
 | 
						|
    int len;
 | 
						|
 | 
						|
	if(usrmem == NULL){
 | 
						|
		DBG_ERR("usrmem can't be null!\n");
 | 
						|
		return E_SYS;
 | 
						|
	}
 | 
						|
 | 
						|
    usrmem->is_init = FALSE;
 | 
						|
 | 
						|
    if(nodeoffset >= 0){
 | 
						|
        const unsigned long *nodep;
 | 
						|
        nodep = (const unsigned long *)fdt_getprop(fdt, nodeoffset, "reg", &len);
 | 
						|
 | 
						|
        usrmem->addr = be32_to_cpu(nodep[0]);
 | 
						|
        usrmem->size = be32_to_cpu(nodep[1]);
 | 
						|
 | 
						|
        int fd = usrmem_init_dev("/dev/mem");
 | 
						|
        if(fd < 0){
 | 
						|
        	DBG_ERR("open %s failed\n", "/dev/mem");
 | 
						|
        	return E_SYS;
 | 
						|
        }
 | 
						|
 | 
						|
        DBG_DUMP("usrmem addr:%lx size:%lx\n", usrmem->addr, usrmem->size);
 | 
						|
 | 
						|
        void* va = usrmem_mmap(fd, usrmem->size ,usrmem->addr);
 | 
						|
        if(va){
 | 
						|
 | 
						|
        	usrmem->hdr = va;
 | 
						|
        	usrmem->used_size = sizeof(SYS_USRMEM_HDR);
 | 
						|
 | 
						|
        	if(usrmem->hdr->tag == SYS_USRMEM_TAG){
 | 
						|
 | 
						|
        		DBG_DUMP("check tag ok, hdr ofs:%lx, size:%lx, sum:%lx\n",
 | 
						|
        				usrmem->hdr->photo_ofs,
 | 
						|
						usrmem->hdr->photo_size,
 | 
						|
						usrmem->hdr->photo_sum);
 | 
						|
 | 
						|
        		usrmem->addr_photo = (UINT32)va + usrmem->hdr->photo_ofs;
 | 
						|
 | 
						|
        		DBG_DUMP("photo data = %lx\n", *((UINT32*)usrmem->addr_photo));
 | 
						|
 | 
						|
        		UINT32 sum = MemCheck_CalcCheckSum16Bit(usrmem->addr_photo, usrmem->hdr->photo_size);
 | 
						|
 | 
						|
        		usrmem->used_size += usrmem->hdr->photo_size;
 | 
						|
 | 
						|
        		if(sum == usrmem->hdr->photo_sum){
 | 
						|
        			DBG_DUMP("checksum ok(%lx)\n", sum);
 | 
						|
        			usrmem->is_init = TRUE;
 | 
						|
                    return E_OK;
 | 
						|
        		}
 | 
						|
        		else{
 | 
						|
        			DBG_ERR("checksum err(%lx)\n", sum);
 | 
						|
        		}
 | 
						|
        	}
 | 
						|
        	else{
 | 
						|
        		DBG_WRN("invalid usrmem hdr tag(%lx)!\n", usrmem->hdr->tag);
 | 
						|
        	}
 | 
						|
        }
 | 
						|
        else{
 | 
						|
        	DBG_ERR("mmap failed(addr:%lx size:%lx)\n", usrmem->addr, usrmem->size);
 | 
						|
        }
 | 
						|
 | 
						|
        close(fd);
 | 
						|
    }
 | 
						|
 | 
						|
    return E_SYS;
 | 
						|
}
 | 
						|
 | 
						|
INT32 sys_usrmem_read_photo(SYS_USRMEM* usrmem, UINT32* addr, UINT32* size)
 | 
						|
{
 | 
						|
	if(usrmem == NULL){
 | 
						|
		DBG_ERR("usrmem can't be null!\n");
 | 
						|
		return E_SYS;
 | 
						|
	}
 | 
						|
 | 
						|
	if(usrmem->is_init == FALSE){
 | 
						|
		DBG_ERR("usrmem not init yet!\n");
 | 
						|
		return E_SYS;
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	if(addr == NULL || size == NULL){
 | 
						|
		DBG_ERR("addr & size can't be null!\n");
 | 
						|
		return E_SYS;
 | 
						|
	}
 | 
						|
 | 
						|
	*addr = usrmem->addr_photo;
 | 
						|
	*size = usrmem->hdr->photo_size;
 | 
						|
 | 
						|
	return E_OK;
 | 
						|
}
 | 
						|
 | 
						|
INT32 sys_usrmem_hdr_uninit(SYS_USRMEM* usrmem)
 | 
						|
{
 | 
						|
	if(usrmem == NULL ){
 | 
						|
		DBG_ERR("usrmem can't be null!\n");
 | 
						|
		return E_SYS;
 | 
						|
	}
 | 
						|
 | 
						|
	if(!usrmem->addr && !usrmem->size){
 | 
						|
		DBG_ERR("addr & size can't be zero!\n");
 | 
						|
		return E_SYS;
 | 
						|
	}
 | 
						|
 | 
						|
	return usrmem_munmap((void* )usrmem->addr, usrmem->size);;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
 |