2023-08-30 16:21:18 +08:00
|
|
|
/*
|
2025-01-08 19:12:06 +08:00
|
|
|
* Copyright (c) 2023-2024, Artinchip Technology Co., Ltd
|
2023-08-30 16:21:18 +08:00
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
*
|
|
|
|
|
* Xiong Hao <hao.xiong@artinchip.com>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <aic_common.h>
|
|
|
|
|
#include <aic_core.h>
|
|
|
|
|
#include <aic_soc.h>
|
|
|
|
|
#include <aic_hal.h>
|
|
|
|
|
#include <mmc.h>
|
2025-01-08 19:12:06 +08:00
|
|
|
#include <private_param.h>
|
2023-08-30 16:21:18 +08:00
|
|
|
#include <partition_table.h>
|
2025-01-08 19:12:06 +08:00
|
|
|
#include <boot_param.h>
|
|
|
|
|
#include <aic_image.h>
|
|
|
|
|
#include <aic_partition.h>
|
2023-08-30 16:21:18 +08:00
|
|
|
#include "sdmc.h"
|
|
|
|
|
|
|
|
|
|
#define MAX_PART_NAME 32
|
|
|
|
|
#define GPT_HEADER_SIZE (34 * 512)
|
|
|
|
|
|
|
|
|
|
#ifdef IMAGE_CFG_JSON_PARTS_GPT
|
|
|
|
|
#define MMC_GPT_PARTS IMAGE_CFG_JSON_PARTS_GPT
|
|
|
|
|
#else
|
|
|
|
|
#define MMC_GPT_PARTS ""
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
struct aic_partition *mmc_new_partition(char *s, u64 start)
|
|
|
|
|
{
|
2025-01-08 19:12:06 +08:00
|
|
|
return aic_part_gpt_parse(s);
|
2023-08-30 16:21:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mmc_free_partition(struct aic_partition *part)
|
|
|
|
|
{
|
2025-01-08 19:12:06 +08:00
|
|
|
aic_part_free(part);
|
|
|
|
|
}
|
2023-08-30 16:21:18 +08:00
|
|
|
|
2025-01-08 19:12:06 +08:00
|
|
|
char *aic_mmc_get_partition_string(int mmc_id)
|
|
|
|
|
{
|
|
|
|
|
char *parts = NULL;
|
|
|
|
|
|
|
|
|
|
#ifdef AIC_BOOTLOADER
|
|
|
|
|
void *res_addr;
|
|
|
|
|
res_addr = aic_get_boot_resource();
|
|
|
|
|
parts = private_get_partition_string(res_addr);
|
|
|
|
|
if (parts == NULL)
|
|
|
|
|
parts = MMC_GPT_PARTS;
|
|
|
|
|
if (parts)
|
|
|
|
|
parts = strdup(parts);
|
|
|
|
|
#else
|
|
|
|
|
uint8_t head_buf[512], *res;
|
|
|
|
|
struct aic_image_header head;
|
|
|
|
|
struct aic_sdmc *sdmc = NULL;
|
|
|
|
|
u64 blkstart, blkcnt;
|
|
|
|
|
u32 ret;
|
|
|
|
|
|
|
|
|
|
sdmc = find_mmc_dev_by_index(mmc_id);
|
|
|
|
|
if (!sdmc) {
|
|
|
|
|
parts = MMC_GPT_PARTS;
|
|
|
|
|
return parts;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* First partition start from blk#34 */
|
|
|
|
|
blkstart = GPT_HEADER_SIZE / 512;
|
|
|
|
|
ret = mmc_bread(sdmc, blkstart, 1, (void *)head_buf);
|
|
|
|
|
if (ret <= 0) {
|
|
|
|
|
pr_err("Failed to read aic image head.\n");
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2023-08-30 16:21:18 +08:00
|
|
|
|
2025-01-08 19:12:06 +08:00
|
|
|
memcpy(&head, head_buf, sizeof(head));
|
|
|
|
|
if (head.magic != AIC_IMAGE_MAGIC) {
|
|
|
|
|
pr_err("aic image head verify failure.");
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
if (head.private_data_offset) {
|
|
|
|
|
blkstart += (head.private_data_offset + 511) / 512;
|
|
|
|
|
blkcnt = (head.private_data_len + 511) / 512;
|
|
|
|
|
res = malloc(blkcnt * 512);
|
|
|
|
|
if (res == NULL) {
|
|
|
|
|
pr_err("Failed to malloc resource buffer.\n");
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
ret = mmc_bread(sdmc, blkstart, blkcnt, (void *)res);
|
|
|
|
|
if (ret <= 0) {
|
|
|
|
|
pr_err("Failed to read aic image head.");
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
parts = private_get_partition_string(res);
|
|
|
|
|
if (parts == NULL)
|
|
|
|
|
parts = MMC_GPT_PARTS;
|
|
|
|
|
if (parts)
|
|
|
|
|
parts = strdup(parts);
|
|
|
|
|
free(res);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
return parts;
|
2023-08-30 16:21:18 +08:00
|
|
|
}
|
|
|
|
|
|
2025-01-08 19:12:06 +08:00
|
|
|
struct aic_partition *mmc_create_gpt_part2(int mmc_id)
|
2023-08-30 16:21:18 +08:00
|
|
|
{
|
|
|
|
|
struct aic_partition *parts = NULL;
|
2025-01-08 19:12:06 +08:00
|
|
|
char *partstr;
|
2023-08-30 16:21:18 +08:00
|
|
|
|
2025-01-08 19:12:06 +08:00
|
|
|
partstr = aic_mmc_get_partition_string(mmc_id);
|
|
|
|
|
parts = aic_part_gpt_parse(partstr);
|
2023-08-30 16:21:18 +08:00
|
|
|
if (!parts)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
if (parts->start != GPT_HEADER_SIZE) {
|
|
|
|
|
pr_err("First partition start offset is not correct\n");
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return parts;
|
|
|
|
|
|
|
|
|
|
out:
|
|
|
|
|
if (parts)
|
2025-01-08 19:12:06 +08:00
|
|
|
aic_part_free(parts);
|
2023-08-30 16:21:18 +08:00
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-08 19:12:06 +08:00
|
|
|
/* Legacy API, only for eMMC */
|
|
|
|
|
struct aic_partition *mmc_create_gpt_part(void)
|
|
|
|
|
{
|
|
|
|
|
return mmc_create_gpt_part2(0);
|
|
|
|
|
}
|