修改上传所有文件

This commit is contained in:
2025-10-21 19:40:27 +08:00
parent 5a84d13ae4
commit 391f81f8fc
8417 changed files with 2995282 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,106 @@
/**
* @file ab_partition_parse.h
*
* Copyright (c) 2021 Semidrive Semiconductor.
* All rights reserved.
*
* Description:
*
* Revision History:
* -----------------
*/
#ifndef __AB_PART_H__
#define __AB_PART_H__
#include <partition_parser.h>
#include <stdio.h>
extern const char *suffix_slot[];
extern const char *suffix_delimiter;
#define SUFFIX_SLOT(part_slot) suffix_slot[(part_slot)]
#define MAX_SLOT_SUFFIX_SZ 3
#define BOOT_DEV_NAME_SIZE_MAX 10
#define MAX_RSP_SIZE 64
#define MAX_GET_VAR_NAME_SIZE 256
#define MAX_NR_SCAN_FOR_SLOT 16
typedef struct {
char Suffix[MAX_SLOT_SUFFIX_SZ];
} Slot;
#define SET_BIT(p, n) ((p) |= ((uint64_t)0x1 << (n)))
#define CLR_BIT(p, n) ((p) &= (~(((uint64_t)0x1) << (n))))
enum { SLOT_A = 0, SLOT_B = 1, AB_SUPPORTED_SLOTS = 2, INVALID = -1 };
typedef enum part_attr {
ATTR_UNBOOTABLE,
ATTR_ACTIVE,
ATTR_SUCCESSFUL,
ATTR_RETRY,
ATTR_NUM
} part_attr_t;
/* Structure to print get var info */
struct ab_slot_info {
char slot_is_unbootable[MAX_GET_VAR_NAME_SIZE];
char slot_is_unbootable_rsp[MAX_RSP_SIZE];
char slot_is_active[MAX_GET_VAR_NAME_SIZE];
char slot_is_active_rsp[MAX_RSP_SIZE];
char slot_is_succesful[MAX_GET_VAR_NAME_SIZE];
char slot_is_succesful_rsp[MAX_RSP_SIZE];
char slot_retry_count[MAX_GET_VAR_NAME_SIZE];
char slot_retry_count_rsp[MAX_RSP_SIZE];
};
/* A/B support API(s) */
/* Check Multislot is supported */
bool ptdev_multislot_is_supported(partition_device_t *part_dev);
/* Calling to scan part. table. */
bool ptdev_scan_for_multislot(partition_device_t *part_dev);
/* Marking slot active */
void ptdev_mark_active_slot(partition_device_t *part_dev, int slot);
void ptdev_mark_slot_attr(partition_device_t *part_dev, int slot,
int attr); /* Marking slot active */
void ptdev_clean_slot_attr(partition_device_t *part_dev, int slot, int attr);
/* Resetting slot attr. */
void ptdev_reset_attributes(partition_device_t *part_dev, unsigned index);
/* Fill slot meta infomation */
void ptdev_fill_slot_meta(partition_device_t *part_dev,
struct ab_slot_info *slot_info);
/* Switching slots */
void ptdev_switch_slots(partition_device_t *part_dev, int old_slot,
int new_slot);
/* Mark slot unbootable and reset other attributes*/
void ptdev_deactivate_slot(partition_device_t *part_dev, int slot);
/* Mark slot bootable and set other attributes*/
void ptdev_activate_slot(partition_device_t *part_dev, int slot);
/* Find bootable partition */
int ptdev_find_boot_slot(partition_device_t *part_dev);
/* Find current active partition*/
int ptdev_find_active_slot(partition_device_t *part_dev);
int get_inverse_slot(partition_device_t *part_dev, int slot);
/* Fill partition slot info meta*/
int ptdev_find_successfull_slot(partition_device_t *part_dev);
int ptdev_fill_partition_meta(partition_device_t *part_dev,
char has_slot_pname[][MAX_GET_VAR_NAME_SIZE],
char has_slot_reply[][MAX_RSP_SIZE],
int array_size);
/* partition ota roll back check*/
void ptdev_roll_back_check(partition_device_t *part_dev);
void ptdev_mark_slot_attr_noupdate(partition_device_t *part_dev, unsigned slot,
int attr);
void ptdev_clean_slot_attr_noupdate(partition_device_t *part_dev, unsigned slot,
int attr);
void ptdev_mark_slot_temp(partition_device_t *part_dev, unsigned slot,
int attr);
int ptdev_attributes_update(partition_device_t *part_dev);
void ptdev_reset_all_attributes(partition_device_t *part_dev);
#endif /* __AB_PART_H__ */

View File

@@ -0,0 +1,208 @@
/**
* @file partition_disk_io.c
*
* Copyright (c) 2021 Semidrive Semiconductor.
* All rights reserved.
*
* Description:
*
* Revision History:
* -----------------
*/
#include <ab_partition_parser.h>
#include <assert.h>
#include <compiler.h>
#include <debug.h>
#include <disk.h>
#include <param.h>
#include <partition_parser.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <types.h>
/**
* @brief pt_disk_read
*
* @param dev disk device
* @param addr read addr
* @param dst data destination
* @param size read size
* @return int 0 success other if failed
*/
int pt_disk_read(struct disk_dev *dev, disk_addr_t addr, uint8_t *dst,
disk_size_t size)
{
struct disk_info *info = dev->info;
#if CONFIG_PARTITION_BLOCK_IO_MODE
if (NULL == dev || NULL == dev->info) {
PT_ERROR("no disk device node\n");
return -1;
}
if (!dev->block_size || !IS_ALIGNED(addr, dev->block_size) ||
!IS_ALIGNED(size, dev->block_size)) {
PT_ERROR("addr 0x%llx or size 0x%llx not aligned to block_size = %d\n",
addr, size, dev->block_size);
return -1;
}
if (!IS_ALIGNED(dst, dev->info->mem_align_size)) {
PT_ERROR("mem addresses 0x%p not aligned to 0x%x\n", dst,
dev->info->mem_align_size);
return -1;
}
if (info->disk_ops->disk_read_block)
return info->disk_ops->disk_read_block(
info, dst, addr / (dev->block_size), size / (dev->block_size),
dev->block_size);
else
return -DISK_ERROR_NO_FUN;
#else
if (info->disk_ops->disk_read)
return info->disk_ops->disk_read(info, dst, addr, size);
else
return -DISK_ERROR_NO_FUN;
#endif
}
/**
* @brief dl_disk_write
*
* @param dev disk device
* @param addr write addr
* @param src data source
* @param size write size
* @return int 0 success other if failed
*/
int pt_disk_write(struct disk_dev *dev, disk_addr_t addr, uint8_t *src,
disk_size_t size)
{
struct disk_info *info = dev->info;
#if CONFIG_PARTITION_BLOCK_IO_MODE
if (NULL == dev || NULL == dev->info) {
PT_ERROR("no disk device node\n");
return -1;
}
if (!dev->block_size || !IS_ALIGNED(addr, dev->block_size) ||
!IS_ALIGNED(size, dev->block_size)) {
PT_ERROR("addr 0x%llx or size 0x%llx not aligned to block_size = %d\n",
addr, size, dev->block_size);
return -1;
}
if (!IS_ALIGNED(src, dev->info->mem_align_size)) {
PT_ERROR("mem addresses 0x%p not aligned to 0x%x\n", src,
dev->info->mem_align_size);
return -1;
}
if (info->disk_ops->disk_write_block)
return info->disk_ops->disk_write_block(
info, src, addr / (dev->block_size), size / (dev->block_size),
dev->block_size);
else
return -DISK_ERROR_NO_FUN;
#else
if (info->disk_ops->disk_write)
return info->disk_ops->disk_write(info, src, addr, size);
else
return -DISK_ERROR_NO_FUN;
#endif
}
/**
* @brief dloader disk erase
*
* @param dev disk device
* @param addr erase addr
* @param size erase size
* @return int 0 success
*/
int pt_disk_erase(struct disk_dev *dev, disk_addr_t addr, disk_size_t size)
{
struct disk_info *info = dev->info;
#if CONFIG_PARTITION_BLOCK_IO_MODE
if (NULL == dev || NULL == dev->info) {
PT_ERROR("no disk device node\n");
return -1;
}
if (strstr(dev->info->disk_name, "flash")) {
if (!dev->info->erase_size ||
!IS_ALIGNED(addr, dev->info->erase_size) ||
!IS_ALIGNED(size, dev->info->erase_size)) {
PT_ERROR(
"addr 0x%llx or size 0x%llx not aligned to erase_size = %d\n",
addr, size, dev->info->erase_size);
return -1;
}
if (info->disk_ops->disk_erase_group)
return info->disk_ops->disk_erase_group(
info, addr / (dev->info->erase_size),
size / (dev->info->erase_size), info->erase_size,
DISK_ERASE_DEFAULT);
else
return -DISK_ERROR_NO_FUN;
} else {
if (info->disk_ops->disk_erase)
return info->disk_ops->disk_erase(info, addr, size,
DISK_ERASE_DEFAULT);
else
return -DISK_ERROR_NO_FUN;
}
#else
if (info->disk_ops->disk_erase)
return info->disk_ops->disk_erase(info, addr, size, DISK_ERASE_DEFAULT);
else
return -DISK_ERROR_NO_FUN;
#endif
}
/**
* @brief pt_disk_get_blocksize
*
* @param dev disk device
* @return uint32_t block size
*/
uint32_t pt_disk_get_blocksize(struct disk_dev *dev) { return dev->block_size; }
/**
* @brief pt_disk_get_erasesize
*
* @param dev disk device
* @return uint32_t ersase size
*/
uint32_t pt_disk_get_erasesize(struct disk_dev *dev)
{
return dev->info->erase_size;
}
/**
* @brief pt_disk_get_capacity
*
* @param dev disk device
* @return uint32_t disk capacity size
*/
uint64_t pt_disk_get_capacity(struct disk_dev *dev)
{
return dev->info->disk_size;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,353 @@
/**
* @file partition_parse.h
*
* Copyright (c) 2021 Semidrive Semiconductor.
* All rights reserved.
*
* Description:
*
* Revision History:
* -----------------
*/
#ifndef __PARTITION_PARSER_H
#define __PARTITION_PARSER_H
#include <disk.h>
#define INVALID_PTN -1
#define PARTITION_TYPE_MBR 0
#define PARTITION_TYPE_GPT 1
#define PARTITION_TYPE_GPT_BACKUP 2
#define GPT_HEADER_SIZE 92
#define GPT_HEADER_BLOCKS 1
#define MBR_BLOCKS 1
#define GPT_LBA 1
#define PARTITION_ENTRY_SIZE 128
/* GPT Signature should be 0x5452415020494645 */
#define GPT_SIGNATURE_1 0x54524150
#define GPT_SIGNATURE_2 0x20494645
#define MMC_MBR_SIGNATURE_BYTE_0 0x55
#define MMC_MBR_SIGNATURE_BYTE_1 0xAA
/* GPT Offsets */
#define PROTECTIVE_MBR_SIZE BLOCK_SIZE
#define HEADER_SIZE_OFFSET 12
#define HEADER_CRC_OFFSET 16
#define PRIMARY_HEADER_OFFSET 24
#define BACKUP_HEADER_OFFSET 32
#define FIRST_USABLE_LBA_OFFSET 40
#define LAST_USABLE_LBA_OFFSET 48
#define PARTITION_ENTRIES_OFFSET 72
#define PARTITION_COUNT_OFFSET 80
#define PENTRY_SIZE_OFFSET 84
#define PARTITION_CRC_OFFSET 88
#define MIN_PARTITION_ARRAY_SIZE 0x4000
#define PARTITION_ENTRY_LAST_LBA 40
#define UNIQUE_GUID_OFFSET 16
#define FIRST_LBA_OFFSET 32
#define LAST_LBA_OFFSET 40
#define ATTRIBUTE_FLAG_OFFSET 48
#define PARTITION_NAME_OFFSET 56
#define MAX_GPT_NAME_SIZE 72
#define PARTITION_TYPE_GUID_SIZE 16
#define UNIQUE_PARTITION_GUID_SIZE 16
#define NUM_PARTITIONS 128
#define PART_ATT_READONLY_OFFSET 60
#define MAX_PRIORITY 4
#define MAX_RETRY_COUNT 4
#define PART_ATT_PRIORITY_BIT 48
#define PART_ATT_ACTIVE_BIT 50
#define PART_ATT_MAX_RETRY_CNT_BIT 51
#define PART_ATT_SUB_PARTITION_BIT 53
#define PART_ATT_SUCCESS_BIT 54
#define PART_ATT_UNBOOTABLE_BIT 55
#define PART_ATT_PRIORITY_VAL \
((uint64_t)(MAX_PRIORITY - 1) << PART_ATT_PRIORITY_BIT)
#define PART_ATT_ACTIVE_VAL ((uint64_t)0x1 << PART_ATT_ACTIVE_BIT)
#define PART_ATT_MAX_RETRY_COUNT_VAL \
((uint64_t)(MAX_RETRY_COUNT - 1) << PART_ATT_MAX_RETRY_CNT_BIT)
#define PART_ATT_SUB_PARTITION_VAL ((uint64_t)0x1 << PART_ATT_SUB_PARTITION_BIT)
#define PART_ATT_SUCCESSFUL_VAL ((uint64_t)0x1 << PART_ATT_SUCCESS_BIT)
#define PART_ATT_UNBOOTABLE_VAL ((uint64_t)0x1 << PART_ATT_UNBOOTABLE_BIT)
#define PART_ATT_READONLY_VAL ((uint64_t)0x1 << PART_ATT_READONLY_OFFSET)
/* Some useful define used to access the MBR/EBR table */
#define BLOCK_SIZE 0x200
#define TABLE_ENTRY_0 0x1BE
#define TABLE_ENTRY_1 0x1CE
#define TABLE_ENTRY_2 0x1DE
#define TABLE_ENTRY_3 0x1EE
#define TABLE_SIGNATURE 0x1FE
#define TABLE_ENTRY_SIZE 0x010
#define OFFSET_STATUS 0x00
#define OFFSET_TYPE 0x04
#define OFFSET_FIRST_SEC 0x08
#define OFFSET_SIZE 0x0C
#define COPYBUFF_SIZE (1024 * 16)
#define BINARY_IN_TABLE_SIZE (16 * 512)
#define MAX_FILE_ENTRIES 20
#define MBR_EBR_TYPE 0x05
#define MBR_MODEM_TYPE 0x06
#define MBR_MODEM_TYPE2 0x0C
#define MBR_SBL1_TYPE 0x4D
#define MBR_SBL2_TYPE 0x51
#define MBR_SBL3_TYPE 0x45
#define MBR_RPM_TYPE 0x47
#define MBR_TZ_TYPE 0x46
#define MBR_MODEM_ST1_TYPE 0x4A
#define MBR_MODEM_ST2_TYPE 0x4B
#define MBR_EFS2_TYPE 0x4E
#define MBR_ABOOT_TYPE 0x4C
#define MBR_BOOT_TYPE 0x48
#define MBR_SYSTEM_TYPE 0x82
#define MBR_USERDATA_TYPE 0x83
#define MBR_RECOVERY_TYPE 0x60
#define MBR_MISC_TYPE 0x63
#define MBR_PROTECTED_TYPE 0xEE
#define MBR_SSD_TYPE 0x5D
#define GET_PRI_GPT_SIZE(block_size) \
((GPT_HEADER_BLOCKS + 1) * block_size + \
NUM_PARTITIONS * PARTITION_ENTRY_SIZE)
#define GET_SEC_GPT_SIZE(block_size) \
(GPT_HEADER_BLOCKS * block_size + NUM_PARTITIONS * PARTITION_ENTRY_SIZE)
#define GET_LWORD_FROM_BYTE(x) \
((unsigned)*(x) | ((unsigned)*(x + 1) << 8) | ((unsigned)*(x + 2) << 16) | \
((unsigned)*(x + 3) << 24))
#define GET_LLWORD_FROM_BYTE(x) \
((unsigned long long)*(x) | ((unsigned long long)*(x + 1) << 8) | \
((unsigned long long)*(x + 2) << 16) | \
((unsigned long long)*(x + 3) << 24) | \
((unsigned long long)*(x + 4) << 32) | \
((unsigned long long)*(x + 5) << 40) | \
((unsigned long long)*(x + 6) << 48) | \
((unsigned long long)*(x + 7) << 56))
#define GET_LONG(x) \
((uint32_t) * (x) | ((uint32_t) * (x + 1) << 8) | \
((uint32_t) * (x + 2) << 16) | ((uint32_t) * (x + 3) << 24))
#define PUT_LONG(x, y) \
*(x) = y & 0xff; \
*(x + 1) = (y >> 8) & 0xff; \
*(x + 2) = (y >> 16) & 0xff; \
*(x + 3) = (y >> 24) & 0xff;
#define PUT_LONG_LONG(x, y) \
*(x) = (y)&0xff; \
*((x) + 1) = (((y) >> 8) & 0xff); \
*((x) + 2) = (((y) >> 16) & 0xff); \
*((x) + 3) = (((y) >> 24) & 0xff); \
*((x) + 4) = (((y) >> 32) & 0xff); \
*((x) + 5) = (((y) >> 40) & 0xff); \
*((x) + 6) = (((y) >> 48) & 0xff); \
*((x) + 7) = (((y) >> 56) & 0xff);
#define PT_ALWAYS(format, args...) \
ssdk_printf(SSDK_CRIT, "[INFO]GPT: %s %d " format "", __func__, __LINE__, \
##args);
#define PT_ERROR(format, args...) \
ssdk_printf(SSDK_CRIT, "[ERROR]GPT: %s %d " format "", __func__, __LINE__, \
##args);
#define PT_DBG(format, args...) \
ssdk_printf(SSDK_INFO, "[DEBUG]GPT: %s %d " format "", __func__, __LINE__, \
##args);
#ifndef ROUNDUP
#define ROUNDUP(a, b) (((a) + ((b)-1)) & ~((b)-1))
#endif
#ifndef ROUNDDOWN
#define ROUNDDOWN(a, b) ((a) & ~((b)-1))
#endif
#ifndef MIN
#define MIN(a, b) ((a) > (b) ? (b) : (a))
#endif
struct partition_entry {
unsigned char type_guid[PARTITION_TYPE_GUID_SIZE];
unsigned char unique_partition_guid[UNIQUE_PARTITION_GUID_SIZE];
unsigned long long first_lba;
unsigned long long last_lba;
unsigned long long attribute_flag;
unsigned char name[MAX_GPT_NAME_SIZE];
// TMP no need
unsigned dtype;
unsigned long long size;
};
/* Partition info requested by app layer */
struct partition_info {
uint64_t offset;
uint64_t size;
};
typedef struct partition_device {
struct disk_dev *diskdev;
uint64_t gpt_offset;
struct partition_entry *partition_entries;
unsigned count;
signed active_slot; /* to store current active slot */
bool attributes_updated; /* to store if we need to update partition table */
bool multislot_support; /* to store if multislot support is present */
bool gpt_partitions_exist;
} partition_device_t;
typedef struct {
uint8_t sign[8];
uint8_t version[4];
uint32_t header_sz;
uint32_t header_crc32;
uint8_t reserve[4];
uint64_t current_lba;
uint64_t backup_lba;
uint64_t first_usable_lba;
uint64_t last_usable_lba;
uint8_t guid[16];
uint64_t partition_entry_lba;
uint32_t partition_entry_count;
uint32_t partition_entry_sz;
uint32_t entry_array_crc32;
struct partition_entry *partition_entries;
uint32_t actual_entries_count;
} GPT_header;
typedef enum restore_direction { PRI2SEC = 0, SEC2PRI } restore_direction;
/*
* Name is for querying avaliable storage devices, which shall be implemented by
* platform. gpt_start is for GPT table offset, some devices like OSPI, the GPT
* head is not located at the second block.
*
* Return initialized partition_device
*/
partition_device_t *ptdev_setup(struct disk_dev *diskdev, uint64_t gpt_offset);
/*
* Release partition entries and ptdev
*/
unsigned int ptdev_destroy(partition_device_t *ptdev);
/*
* Query the index by partition name, the index is to indicate partition entries
* array
*/
unsigned int ptdev_get_index(partition_device_t *part_dev, const char *name);
/*
* Get size of the partition
* Return 0 if the name is invalid
*/
unsigned long long ptdev_get_size(partition_device_t *part_dev,
const char *name);
/*
* Get offset of the partition
* Return 0 if the name is invalid
*/
unsigned long long ptdev_get_offset(partition_device_t *part_dev,
const char *name);
/*
* Read the storage device, fill the partition entries array, scan and find
* active slot Invoke after ptdev_set_abslot_decider, or else take for no a/b
* slot support
*/
int ptdev_read_table(partition_device_t *part_dev);
/*
* Overwrite the partition table, if name is NULL, overwrite the globe partition
* table, or else overwrite the sub-partition table.
*/
int ptdev_write_table(partition_device_t *part_dev, const char *name,
unsigned size, unsigned char *ptable,
bool last_part_extend);
/* Return the partition offset & size to app layer
* Size and offset is zero if the name is invalid
*/
struct partition_info ptdev_get_info(partition_device_t *part_dev,
const char *name);
/* For Debugging
* Print all parsed partitions
*/
void ptdev_dump(partition_device_t *part_dev);
/* For Debugging
* Print all parsed partitions attributes
*/
void ptdev_attr_dump(partition_device_t *ptdev);
/* Read only attribute for partition */
bool partition_is_readonly(partition_device_t *part_dev, const char *name);
/* Get Partition Count */
unsigned ptdev_get_partition_count(partition_device_t *part_dev);
/* Read Partition entried list pointer, indicate the entry by index from
* ptdev_get_index */
struct partition_entry *
ptdev_get_partition_entries(partition_device_t *part_dev);
/* check the attribute of part entry */
bool part_is_active(const struct partition_entry *entry);
/* Parse a buffer, check if it has a primary or secondary parition table or
* inside */
unsigned int parse_gpt_table_from_buffer(uint8_t *buf, uint32_t buf_len,
GPT_header *gpt_header,
uint32_t block_size,
bool is_secondary_gpt);
/* Get the partition index from header object */
int get_partition_index_from_header(const char *name, GPT_header *gpt_header);
/* Get the partition size from header object buffer */
unsigned long long get_partition_size_from_header(int index,
GPT_header *gpt_header,
uint32_t block_size);
/* Get the partition offset from header object buffer */
unsigned long long get_partition_offset_from_header(int index,
GPT_header *gpt_header,
uint32_t block_size);
/* Get the partition size and offset from header object buffer */
struct partition_info get_partition_info_from_header(const char *name,
GPT_header *gpt_header,
uint32_t block_size);
/* Making every parition is aligned to the sector size */
uint32_t gpt_partition_round(uint8_t *buffer, uint32_t buf_len,
uint32_t block_size, uint32_t sector_sz,
uint64_t cap);
int pt_disk_read(struct disk_dev *dev, disk_addr_t addr, uint8_t *dst,
disk_size_t size);
int pt_disk_write(struct disk_dev *dev, disk_addr_t addr, uint8_t *src,
disk_size_t size);
int pt_disk_erase(struct disk_dev *dev, disk_addr_t addr, disk_size_t size);
uint32_t pt_disk_get_blocksize(struct disk_dev *dev);
uint32_t pt_disk_get_erasesize(struct disk_dev *dev);
uint64_t pt_disk_get_capacity(struct disk_dev *dev);
#endif