/* * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved. * Description: spi-nor and nand universal module * Author: Hisilicon * Create: 2020-10-15 */ #include "nand.h" #include "uapi_flash.h" #include "flash_ext.h" #include "securec.h" static uapi_flash_partinfo g_part_info[MAX_PARTS]; static td_void nand_clear_part_info(td_void) { td_s32 i; for (i = 0; i < MAX_PARTS; i++) { memset_s(&g_part_info[i], sizeof(uapi_flash_partinfo), 0x0, sizeof(uapi_flash_partinfo)); g_part_info[i].perm = ACCESS_BUTT; } } static td_s32 nand_set_part_info(td_void) { td_s32 i; td_char line[BUF_LINE_SIZE]; td_u64 start_addr[UAPI_FLASH_TYPE_MAX] = {0}; uapi_flash_type flash_type; uapi_flash_partinfo *part_info = NULL; FILE *fp = NULL; fp = fopen("/proc/mtd", "r"); if (fp == NULL) { return -1; } if (fgets(line, sizeof(line), fp) == NULL) { /* skip first line */ (td_void)fclose(fp); return -1; } for (i = 0; i < MAX_PARTS; i++) { td_char argv[4][32]; /* 4 - Get the number of vars, 32 - The size of each var buffer */ td_char *p = NULL; if (!fgets(line, sizeof(line), fp)) { break; } p = &line[0]; p = get_word(p, argv[0]); p = get_word(p, argv[1]); /* 1 - partition size */ p = get_word(p, argv[2]); /* 2 - block size */ p = get_word(p, argv[3]); /* 3 - partition name */ part_info = &g_part_info[i]; part_info->part_size = (td_u64)strtoull(argv[1], NULL, HEX); /* 1 - partition size */ if (strncpy_s(part_info->dev_name, FLASH_NAME_LEN, argv[0], (strlen(argv[0]) - 1)) != 0) { break; } if (strncpy_s(part_info->part_name, FLASH_NAME_LEN, (argv[3] + 1), (strlen(argv[3]) - 2)) != 0) { /* 3 - partition name, 2 - */ break; } flash_type = get_flashtype_by_bootargs(part_info->part_name); if (flash_type >= UAPI_FLASH_TYPE_MAX) { continue; } part_info->start_addr = start_addr[flash_type]; start_addr[flash_type] += part_info->part_size; } (td_void)fclose(fp); return 0; } td_s32 flash_partition_info_init(td_void) { static td_s32 init_flag = -1; if (init_flag >= 0) { return 0; } nand_clear_part_info(); if (nand_set_part_info() < 0) { return -1; } init_flag = 0; return 0; } uapi_flash_partinfo *get_flash_partition_info(uapi_flash_type flash_type, const td_char *devname, td_u32 dev_len) { td_s32 i; uapi_flash_partinfo *part_info = NULL; if (flash_type >= UAPI_FLASH_TYPE_MAX || dev_len == 0) { return NULL; } if (devname == NULL) { return NULL; } for (i = 0; i < MAX_PARTS; i++) { part_info = &g_part_info[i]; if (strncmp(part_info->dev_name, devname, strlen(part_info->dev_name) > (td_u32)dev_len ? strlen(part_info->dev_name) : dev_len) == 0) { return (part_info); } } return NULL; }