177 lines
4.8 KiB
C
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 */
|