Files

177 lines
4.8 KiB
C

#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include "xmedia_mmz.h"
#include "pm_aux.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include "pm_flash.h"
/* note: size must be 2k alignment */
#define AUX_TOTAL_MEM_SIZE (UBOOT_HEADER_PARAM_LEN + AUX_AREA_SIZE)
#define AUX_TOTAL_MEM_NAME "AUX_MEM"
static xmedia_u64 aux_mem_addr = XMEDIA_NULL;
const char nand_uboot_part[] = "/dev/mtd0";
const char spi_uboot_part[] = "/dev/mtd0";
const char emmc_uboot_part[] = "/dev/mmcblk0p0";
const char *uboot_name[PM_FLASH_TYPE_MAX] = {spi_uboot_part, nand_uboot_part, emmc_uboot_part};
static struct flash_part_dev *flash_uboot_init(void)
{
struct flash_part_dev *uboot_part_dev;
xmedia_s32 ret = XMEDIA_SUCCESS;
uboot_part_dev = alloc_flash_part();
if (uboot_part_dev == XMEDIA_NULL)
return XMEDIA_NULL;
memcpy(uboot_part_dev->part.devname, uboot_name[uboot_part_dev->part.flash_type], strlen(uboot_name[uboot_part_dev->part.flash_type]));
ret = flash_open(uboot_part_dev, ACCESS_RD);
if (ret != XMEDIA_SUCCESS) {
PM_USR_TRACE(MODULE_DBG_ERR, "open error\n");
free_flash_part(uboot_part_dev);
return XMEDIA_NULL;
}
ret = flash_get_info(uboot_part_dev);
if (ret != XMEDIA_SUCCESS) {
PM_USR_TRACE(MODULE_DBG_ERR, "get info err\n");
uboot_part_dev->part_opt->close(uboot_part_dev);
free_flash_part(uboot_part_dev);
return XMEDIA_NULL;
}
ret = flash_init(uboot_part_dev);
if (ret != XMEDIA_SUCCESS) {
PM_USR_TRACE(MODULE_DBG_ERR, "flash init err\n");
uboot_part_dev->part_opt->close(uboot_part_dev);
free_flash_part(uboot_part_dev);
return XMEDIA_NULL;
}
return uboot_part_dev;
}
static xmedia_s32 flash_uboot_read(struct flash_part_dev *part_dev, xmedia_u32 addr, xmedia_u32 size, xmedia_char *buf)
{
return flash_read(part_dev, addr, size, buf);
}
static xmedia_s32 flash_uboot_deinit(struct flash_part_dev *part_dev)
{
flash_close(part_dev);
free_flash_part(part_dev);
return XMEDIA_SUCCESS;
}
xmedia_s32 aux_free_mem(void)
{
if (aux_mem_addr != XMEDIA_NULL) {
xmedia_mmz_free(aux_mem_addr);
aux_mem_addr = XMEDIA_NULL;
}
return XMEDIA_SUCCESS;
}
xmedia_s32 aux_read(xmedia_char *buf, xmedia_u32 size)
{
struct flash_part_dev *uboot_part_dev;
xmedia_u32 aux_len;
xmedia_s32 ret = XMEDIA_SUCCESS;
uboot_part_dev = flash_uboot_init();
if (uboot_part_dev == XMEDIA_NULL) {
PM_USR_TRACE(MODULE_DBG_ERR, "uboot init error\n");
return XMEDIA_ERRCODE_OPEN_FAILED;
}
if (size < UBOOT_HEADER_PARAM_LEN) {
PM_USR_TRACE(MODULE_DBG_ERR, "%s bufsize(0x%x) < headersize(0x%x)\n", __func__, size, UBOOT_HEADER_PARAM_LEN);
flash_uboot_deinit(uboot_part_dev);
return XMEDIA_ERRCODE_INVALID_PARAM;
}
ret = flash_uboot_read(uboot_part_dev, 0, UBOOT_HEADER_PARAM_LEN, buf);
if (ret != UBOOT_HEADER_PARAM_LEN) {
PM_USR_TRACE(MODULE_DBG_ERR, "%s read header error ret:%d\n", __func__, ret);
flash_uboot_deinit(uboot_part_dev);
return ret;
}
aux_len = *(xmedia_u32 *)(buf + AUX_LEN_POS);
if (aux_len > size - UBOOT_HEADER_PARAM_LEN) {
PM_USR_TRACE(MODULE_DBG_ERR, "%s aux len(0x%x) > bufsize(0x%x) - headersize(0x%x)\n", __func__, aux_len, size, UBOOT_HEADER_PARAM_LEN);
flash_uboot_deinit(uboot_part_dev);
return XMEDIA_ERRCODE_INVALID_PARAM;
}
ret = flash_uboot_read(uboot_part_dev, UBOOT_HEADER_PARAM_LEN, aux_len, buf + UBOOT_HEADER_PARAM_LEN);
if (ret != aux_len) {
PM_USR_TRACE(MODULE_DBG_ERR, "%s read aux len(0x%x) error ret:%d\n", __func__, aux_len, ret);
flash_uboot_deinit(uboot_part_dev);
return ret;
}
flash_uboot_deinit(uboot_part_dev);
return XMEDIA_SUCCESS;
}
xmedia_s32 read_aux_to_ddr(struct aux_mem *paux)
{
xmedia_void *pbuf = NULL;
if (aux_mem_addr != XMEDIA_NULL) {
PM_USR_TRACE(MODULE_DBG_ERR, "aux exist in ddr now\n");
paux->phy_addr = aux_mem_addr;
paux->size = AUX_TOTAL_MEM_SIZE;
return XMEDIA_SUCCESS;
}
aux_mem_addr = xmedia_mmz_alloc(NULL, AUX_TOTAL_MEM_NAME, AUX_TOTAL_MEM_SIZE);
if (aux_mem_addr == XMEDIA_NULL)
return XMEDIA_ERRCODE_NOT_ENOUGH_MEMORY;
pbuf = xmedia_mmz_map(aux_mem_addr, AUX_TOTAL_MEM_SIZE, XMEDIA_TRUE);
if (pbuf == XMEDIA_NULL) {
aux_free_mem();
return XMEDIA_ERRCODE_NOT_ENOUGH_MEMORY;
}
PM_USR_TRACE(MODULE_DBG_INFO, "aux_mem phy addr:0x%llx vir addr: 0x%x\n", aux_mem_addr, (xmedia_u32)paux);
if (aux_read(pbuf, AUX_TOTAL_MEM_SIZE) != XMEDIA_SUCCESS) {
PM_USR_TRACE(MODULE_DBG_ERR, "read aux error\n");
xmedia_mmz_unmap(pbuf);
aux_free_mem();
return XMEDIA_ERRCODE_COPY_DATA_ERROR;
}
xmedia_mmz_flush_cache(aux_mem_addr, pbuf, AUX_TOTAL_MEM_SIZE);
xmedia_mmz_unmap(pbuf);
paux->phy_addr = aux_mem_addr;
paux->size = AUX_TOTAL_MEM_SIZE;
return XMEDIA_SUCCESS;
}
#ifdef __cplusplus
}
#endif /* __cplusplus */