Files
6CAR/middleware/dloader/dloader.h
2026-04-18 09:16:58 +08:00

239 lines
6.8 KiB
C

/*
* dloader.h
*
* Copyright (c) 2020 SemiDrive Semiconductor.
* All rights reserved.
*
* Description:
*
* Revision History:
* -----------------
*/
#ifndef _DLOADER_H_
#define _DLOADER_H_
#include <debug.h>
#include <disk/disk.h>
#define MAX_DEV_INST_OF_DISK 3
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef MD5_LEN
#define MD5_LEN 16
#endif
#ifndef MAX_GPT_NAME_SIZE
#define MAX_GPT_NAME_SIZE 72
#endif
#define DL_DEBUG_ON 1
#if DL_DEBUG_ON
#define ERROR(format, args...) \
ssdk_printf(SSDK_CRIT, "[ERROR]DLOADER:%s %d " format "", __func__, \
__LINE__, ##args);
#define DBG(format, args...) \
ssdk_printf(SSDK_CRIT, "[DEBUG]DLOADER:%s %d " format "", __func__, \
__LINE__, ##args);
#else
#define ERROR(format, args...)
#define DBG(format, args...)
#endif
#define SPARSE_HEADER_MAGIC 0xed26ff3a
#define CHUNK_TYPE_RAW 0xCAC1
#define CHUNK_TYPE_FILL 0xCAC2
#define CHUNK_TYPE_DONT_CARE 0xCAC3
#define CHUNK_TYPE_CRC 0xCAC4
typedef enum dl_err_code {
ERR_NONE = 0,
ERR_UNKNOWN = 0x1,
ERR_FLASH1_INIT_FAIL,
ERR_EMMC1_INIT_FAIL,
ERR_SD1_INIT_FAIL,
ERR_PRI_PTB_NOT_MATCH,
ERR_SUB_PTB_NOT_MATCH,
ERR_PT_NOT_FOUND,
ERR_IMAGE_TOO_LARGE,
ERR_IMAGE_FORMAT_ERR,
ERR_PRI_PTB_NOT_FLASH,
ERR_SUB_PTB_NOT_FLASH,
ERR_PT_READ_FAIL,
ERR_PT_FLASH_FAIL,
ERR_PT_ERASE_FAIL,
ERR_PT_OVERLAP,
ERR_PT_FULL_NAME_FORMAT,
ERR_INVALID_BLOCK_SIZE,
ERR_SPARSE_IMAGE_SIZE_TOO_LOW,
ERR_SPARSE_IMAGE_HEADER,
ERR_SPARSE_IMAGE_BUFFERED,
ERR_SPARSE_IMAGE_CHUNK_HEADER,
ERR_SPARSE_IMAGE_CHUNK_TOO_LARGE,
ERR_SPARSE_IMAGE_CHUNK_NOT_MATCH,
ERR_SPARSE_IMAGE_CHUNK_UNKNOWN,
ERR_SPARSE_IMAGE_MALLOC,
ERR_SPARSE_IMAGE_DO_NOT_SUPPORT,
ERR_HASH_FAIL,
ERR_EFUSE_INDEX,
ERR_EFUSE_BURN,
ERR_EFUSE_READ,
ERR_SWITCH_PART,
ERR_CMD_ERROR,
ERR_PT_BASE_ERROR,
ERR_PT_SIZE_ERROR,
ERR_PTNAME_NOT_EXIST,
ERR_DISK_NOT_EXIST,
ERR_DISK_OPEN_ERROR,
ERR_PARTITION_READ_ERROR,
HYPER_FLASH_FUSE_READ_ERROR,
HYPER_FLASH_FUSE_WRITE_ERROR,
HYPER_FLASH_FUSE_VAL_ERROR,
VERIFY_SIZE_ERROR,
CAN_NOT_FIND_A_DOWNLOAD_FUNCTION,
CAN_NOT_FIND_A_ERASE_FUNCTION,
CAN_NOT_FIND_A_VERIFY_FUNCTION,
ERR_HASH_FAIL_FROM_PC,
ERR_DL_FUSE_SIZE_CHECK_FAIL,
ERR_DL_FUSE_LENGTH_CHECK_FAIL,
ERR_DL_FUSE_ACTION_TYPE_NOT_FIND,
ERR_DL_FUSE_CRC_CHECK_FAIL,
ERR_DL_FUSE_ENC_INIT_FAIL,
ERR_DL_FUSE_ENC_FAIL,
ERR_DL_FUSE_MALLOC_FAIL,
ERR_DL_FUSE_GEN_DATA_FAIL,
ERR_DL_FUSE_READBACK_VERIFY_FAIL,
ERR_GET_SFS_FORM_MSFS_FAIL,
ERR_MAX,
} DL_ERR_CODE_E;
typedef enum partition_type_enum {
TYPE_PT_UNKNOWN = 0,
TYPE_PRI_PTB,
TYPE_PRI_PT,
TYPE_SUB_PTB,
TYPE_SUB_PT,
TYPE_SUB_PT_WHOLE,
TYPE_ALL_PT, /* only for erase all partitions in the gpt */
TYPE_NOT_IN_GPT = 0x100,
TYPE_BOOT_PACK0,
TYPE_BOOT_PACK1,
TYPE_BOOT_PACK2,
TYPE_SAFETY_SFS_PT,
TYPE_SAFETY_RFD_PT,
TYPE_ADD_DIRECT,
} PARTITION_TYPE_E;
typedef enum dev_inst_enum {
FLASH_DEV_INST = 0,
EMMC_USER_SPACE_DEV_INST = 0,
EMMC_BOOT1_DEV_INST = 1,
EMMC_BOOT2_DEV_INST = 2,
EMMC_DEV_INST_MAX,
} DEV_INST_E;
typedef enum disk_type_enum {
MMC,
NORFLASH,
RAMDISK,
USBDISK,
ALLDISK,
STORAGE_TYPE_NM,
} DISK_TYPE_E;
struct ptb_dl_name {
struct list_node node;
char *name;
};
/* record downloaded state */
typedef struct dl_state {
const char download_name[MAX_GPT_NAME_SIZE + 1];
const char disk_name[MAX_GPT_NAME_SIZE + 1];
const char disk_boot1_name[MAX_GPT_NAME_SIZE + 1];
const char disk_boot2_name[MAX_GPT_NAME_SIZE + 1];
DISK_TYPE_E disk_type;
struct disk_dev *disk_inst[MAX_DEV_INST_OF_DISK];
uint32_t block_size;
uint32_t erase_size;
uint64_t capacity;
struct partition_device *ptdev;
uint64_t ptb_offset;
PARTITION_TYPE_E partiton_type;
char ptname[MAX_GPT_NAME_SIZE + 1];
char sub_ptbname[MAX_GPT_NAME_SIZE + 1];
const uint64_t boot_offset;
} DL_STATE_T;
typedef struct command_table {
PARTITION_TYPE_E partiton_type;
DISK_TYPE_E disk_type;
DL_ERR_CODE_E(*flash_callback)
(DL_STATE_T *ds, void *data, unsigned sz, uint8_t sparse_data);
DL_ERR_CODE_E (*erase_cmd_callback)(DL_STATE_T *ds);
DL_ERR_CODE_E (*verify_cmd_callback)(DL_STATE_T *ds);
char *download_cmd_name;
char *erase_cmd_name;
} COMMAND_TABLE_T;
typedef struct download_type_table {
char *ptname;
uint8_t is_sub_pt;
char *type_name;
PARTITION_TYPE_E partiton_type;
} DOWNLOAD_TYPE_TABLE_T;
typedef struct sparse_header {
uint32_t magic; /* 0xed26ff3a */
uint16_t
major_version; /* (0x1) - reject images with higher major versions */
uint16_t minor_version; /* (0x0) - allow images with higer minor versions */
uint16_t file_hdr_sz; /* 28 bytes for first revision of the file format */
uint16_t chunk_hdr_sz; /* 12 bytes for first revision of the file format */
uint32_t blk_sz; /* block size in bytes, must be a multiple of 4 (4096) */
uint32_t total_blks; /* total blocks in the non-sparse output image */
uint32_t total_chunks; /* total chunks in the sparse input image */
uint32_t image_checksum; /* CRC32 checksum of the original data, counting
"don't care" */
/* as 0. Standard 802.3 polynomial, use a Public Domain */
/* table implementation */
} sparse_header_t;
typedef struct chunk_header {
uint16_t
chunk_type; /* 0xCAC1 -> raw; 0xCAC2 -> fill; 0xCAC3 -> don't care */
uint16_t reserved1;
uint32_t chunk_sz; /* in blocks in output image */
uint32_t total_sz; /* in bytes of chunk input file including chunk header
and data */
} chunk_header_t;
extern void *dl_scratch_base;
extern uint32_t dl_scratch_sz;
extern void *dl_data_base;
extern uint32_t dl_data_sz;
extern DL_STATE_T *parse_partition_name(const char *full_ptname,
DL_ERR_CODE_E *err);
extern int dloader_init(void);
extern void read_sfs(DL_STATE_T *ds);
extern void read_rfd(DL_STATE_T *ds);
extern uint8_t md5_received[MD5_LEN];
extern DL_ERR_CODE_E dl_cmd_flash(const char *arg, void *data, unsigned sz);
extern DL_ERR_CODE_E dl_cmd_erase(const char *arg, void *data, unsigned sz);
int dl_disk_read(struct disk_dev *dev, disk_addr_t addr, uint8_t *dst,
disk_size_t size);
int dl_disk_write(struct disk_dev *dev, disk_addr_t addr, uint8_t *src,
disk_size_t size);
int dl_disk_erase(struct disk_dev *dev, disk_addr_t addr, disk_size_t size);
char *response_error(enum dl_err_code err, const char *pname);
#endif