diff --git a/drivers/Kconfig b/drivers/Kconfig index 4f5b62381941..c7a3c412bce1 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -202,6 +202,8 @@ source "drivers/fpga/Kconfig" source "drivers/tee/Kconfig" +source "drivers/rkflash/Kconfig" + source "drivers/rk_nand/Kconfig" source "drivers/headset_observe/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index 02834d4b8d43..e0bbaa27570e 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -178,3 +178,5 @@ obj-$(CONFIG_FPGA) += fpga/ obj-$(CONFIG_TEE) += tee/ obj-$(CONFIG_RK_NAND) += rk_nand/ obj-$(CONFIG_RK_HEADSET) += headset_observe/ +obj-$(CONFIG_RK_FLASH) += rkflash/ +obj-y += rk_nand/ diff --git a/drivers/rkflash/Kconfig b/drivers/rkflash/Kconfig new file mode 100644 index 000000000000..79a1a7ba9b5c --- /dev/null +++ b/drivers/rkflash/Kconfig @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: GPL-2.0 + +if ARCH_ROCKCHIP + +menuconfig RK_FLASH + tristate "Rockchip Flash Devices Support" + default n + help + Enable rockchip flash devices support. + + rkflash driver support 3-type flash devices: NANDC NAND, SFC_NOR + and SFC_NAND. + + Say Y when you have a board with one of them. + +if RK_FLASH + +comment "Rockchip Flash Devices" + +config RK_NANDC_NAND + tristate "RK NANDC NAND Device Support" + default n + help + Enable NANDC_NAND device support. + It's block interface. + Say Y when you have a board with nand flash supported by rockchip + nandc controller. + +config RK_SFC_NOR + tristate "RK SFC NOR Device Support" + default n + help + Enable SFC_NOR device support. + It's block interface. + Say Y when you have a board with nor flash supported by rockchip + sfc controller. + +config RK_SFC_NAND + tristate "RK SFC NAND Device Support" + default n + help + Enable SFC_NAND device support. + It's block interface + Say Y when you have a board with nand flash supported by rockchip + sfc controller. + +config RK_SFC_NOR_MTD + bool "RK SFC NOR mtd Interface Support" + depends on RK_SFC_NOR + default n + help + Enable mtd interface for SFC_NOR device. + It's mtd block interface. + Say Y when you have a board with mtd interface nor flash supported + by rockchip sfc controller. + +endif # RK_FLASH + +endif # ARCH_ROCKCHIP diff --git a/drivers/rkflash/Makefile b/drivers/rkflash/Makefile new file mode 100644 index 000000000000..bfde79399609 --- /dev/null +++ b/drivers/rkflash/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_RK_NANDC_NAND) += rkflash_blk.o rkflash_debug.o rknandc_base.o nand_boot.o flash.o nandc.o ftl_flash_plat.o rk_sftl.o +obj-$(CONFIG_RK_SFC_NOR) += rkflash_blk.o rkflash_debug.o rksfc_base.o sfc_nor_boot.o sfc_nor.o sfc.o +obj-$(CONFIG_RK_SFC_NOR_MTD) += sfc_nor_mtd.o +obj-$(CONFIG_RK_SFC_NAND) += rkflash_blk.o rkflash_debug.o rksfc_base.o sfc_nand_boot.o sfc_nand.o sfc.o ftl_flash_plat.o rk_sftl.o diff --git a/drivers/rkflash/flash.c b/drivers/rkflash/flash.c new file mode 100644 index 000000000000..d96e1af09e5b --- /dev/null +++ b/drivers/rkflash/flash.c @@ -0,0 +1,500 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#include +#include + +#include "flash.h" +#include "flash_com.h" +#include "nandc.h" + +#define FLASH_STRESS_TEST_EN 0 + +static u8 id_byte[MAX_FLASH_NUM][8]; +static u8 die_cs_index[MAX_FLASH_NUM]; +static u8 g_nand_max_die; +static u16 g_totle_block; +static u8 g_nand_flash_ecc_bits; +static u8 g_nand_idb_res_blk_num; + +static struct NAND_PARA_INFO_T nand_para = { + 2, + {0x98, 0xF1, 0, 0, 0, 0}, + TOSHIBA, + 1, + 4, + 64, + 1, + 1, + 1024, + 0x100, + LSB_0, + RR_NONE, + 16, + 40, + 1, + 0, + BBF_1, + MPM_0, + {0} +}; /* TC58NVG0S3HTA00 */ + +void nandc_flash_reset(u8 cs) +{ + nandc_flash_cs(cs); + nandc_writel(RESET_CMD, NANDC_CHIP_CMD(cs)); + nandc_wait_flash_ready(cs); + nandc_flash_de_cs(cs); +} + +static void flash_read_id_raw(u8 cs, u8 *buf) +{ + u8 *ptr = (u8 *)buf; + + nandc_flash_reset(cs); + nandc_flash_cs(cs); + nandc_writel(READ_ID_CMD, NANDC_CHIP_CMD(cs)); + nandc_writel(0x00, NANDC_CHIP_ADDR(cs)); + nandc_delayns(200); + + ptr[0] = nandc_readl(NANDC_CHIP_DATA(cs)); + ptr[1] = nandc_readl(NANDC_CHIP_DATA(cs)); + ptr[2] = nandc_readl(NANDC_CHIP_DATA(cs)); + ptr[3] = nandc_readl(NANDC_CHIP_DATA(cs)); + ptr[4] = nandc_readl(NANDC_CHIP_DATA(cs)); + ptr[5] = nandc_readl(NANDC_CHIP_DATA(cs)); + ptr[6] = nandc_readl(NANDC_CHIP_DATA(cs)); + ptr[7] = nandc_readl(NANDC_CHIP_DATA(cs)); + + nandc_flash_de_cs(cs); + if (ptr[0] != 0xFF && ptr[0] && ptr[1] != 0xFF) + PRINT_E("No.%d FLASH ID:%x %x %x %x %x %x\n", + cs + 1, ptr[0], ptr[1], ptr[2], + ptr[3], ptr[4], ptr[5]); +} + +static void flash_bch_sel(u8 bits) +{ + g_nand_flash_ecc_bits = bits; + nandc_bch_sel(bits); +} + +static __maybe_unused void flash_timing_cfg(u32 ahb_khz) +{ + nandc_time_cfg(nand_para.access_freq); +} + +static void flash_read_cmd(u8 cs, u32 page_addr) +{ + nandc_writel(READ_CMD >> 8, NANDC_CHIP_CMD(cs)); + nandc_writel(0x00, NANDC_CHIP_ADDR(cs)); + nandc_writel(0x00, NANDC_CHIP_ADDR(cs)); + nandc_writel(page_addr & 0x00ff, NANDC_CHIP_ADDR(cs)); + nandc_writel(page_addr >> 8, NANDC_CHIP_ADDR(cs)); + nandc_writel(page_addr >> 16, NANDC_CHIP_ADDR(cs)); + nandc_writel(READ_CMD & 0x00ff, NANDC_CHIP_CMD(cs)); +} + +static void flash_prog_first_cmd(u8 cs, u32 page_addr) +{ + nandc_writel(PAGE_PROG_CMD >> 8, NANDC_CHIP_CMD(cs)); + nandc_writel(0x00, NANDC_CHIP_ADDR(cs)); + nandc_writel(0x00, NANDC_CHIP_ADDR(cs)); + nandc_writel(page_addr & 0x00ff, NANDC_CHIP_ADDR(cs)); + nandc_writel(page_addr >> 8, NANDC_CHIP_ADDR(cs)); + nandc_writel(page_addr >> 16, NANDC_CHIP_ADDR(cs)); +} + +static void flash_erase_cmd(u8 cs, u32 page_addr) +{ + nandc_writel(BLOCK_ERASE_CMD >> 8, NANDC_CHIP_CMD(cs)); + nandc_writel(page_addr & 0x00ff, NANDC_CHIP_ADDR(cs)); + nandc_writel(page_addr >> 8, NANDC_CHIP_ADDR(cs)); + nandc_writel(page_addr >> 16, NANDC_CHIP_ADDR(cs)); + nandc_writel(BLOCK_ERASE_CMD & 0x00ff, NANDC_CHIP_CMD(cs)); +} + +static void flash_prog_second_cmd(u8 cs, u32 page_addr) +{ + nandc_writel(PAGE_PROG_CMD & 0x00ff, NANDC_CHIP_CMD(cs)); +} + +static u32 flash_read_status(u8 cs, u32 page_addr) +{ + nandc_writel(READ_STATUS_CMD, NANDC_CHIP_CMD(cs)); + nandc_delayns(80); + + return nandc_readl(NANDC_CHIP_DATA(cs)); +} + +static void flash_read_random_dataout_cmd(u8 cs, u32 col_addr) +{ + nandc_writel(READ_DP_OUT_CMD >> 8, NANDC_CHIP_CMD(cs)); + nandc_writel(col_addr & 0x00ff, NANDC_CHIP_ADDR(cs)); + nandc_writel(col_addr >> 8, NANDC_CHIP_ADDR(cs)); + nandc_writel(READ_DP_OUT_CMD & 0x00ff, NANDC_CHIP_CMD(cs)); +} + +static u32 flash_read_page_raw(u8 cs, u32 page_addr, u32 *p_data, u32 *p_spare) +{ + u32 ret = 0; + u32 error_ecc_bits; + u32 sec_per_page = nand_para.sec_per_page; + + nandc_wait_flash_ready(cs); + nandc_flash_cs(cs); + flash_read_cmd(cs, page_addr); + nandc_wait_flash_ready(cs); + flash_read_random_dataout_cmd(cs, 0); + nandc_wait_flash_ready(cs); + + error_ecc_bits = nandc_xfer_data(cs, NANDC_READ, sec_per_page, + p_data, p_spare); + if (error_ecc_bits > 2) { + PRINT_E("FlashReadRawPage %x %x error_ecc_bits %d\n", + cs, page_addr, error_ecc_bits); + if (p_data) + rknand_print_hex("data:", p_data, 4, 8); + if (p_spare) + rknand_print_hex("spare:", p_spare, 4, 2); + } + nandc_flash_de_cs(cs); + + if (error_ecc_bits != NAND_STS_ECC_ERR) { + if (error_ecc_bits >= (u32)nand_para.ecc_bits - 3) + ret = NAND_STS_REFRESH; + else + ret = NAND_STS_OK; + } + + return ret; +} + +static u32 flash_read_page(u8 cs, u32 page_addr, u32 *p_data, u32 *p_spare) +{ + u32 ret; + + ret = flash_read_page_raw(cs, page_addr, p_data, p_spare); + if (ret == NAND_STS_ECC_ERR) + ret = flash_read_page_raw(cs, page_addr, p_data, p_spare); + + return ret; +} + +static u32 flash_prog_page(u8 cs, u32 page_addr, u32 *p_data, u32 *p_spare) +{ + u32 status; + u32 sec_per_page = nand_para.sec_per_page; + + nandc_wait_flash_ready(cs); + nandc_flash_cs(cs); + flash_prog_first_cmd(cs, page_addr); + nandc_xfer_data(cs, NANDC_WRITE, sec_per_page, p_data, p_spare); + flash_prog_second_cmd(cs, page_addr); + nandc_wait_flash_ready(cs); + status = flash_read_status(cs, page_addr); + nandc_flash_de_cs(cs); + status &= 0x01; + if (status) + PRINT_I("%s addr=%x status=%x\n", __func__, + page_addr, status); + + return status; +} + +static u32 flash_erase_block(u8 cs, u32 page_addr) +{ + u32 status; + + nandc_wait_flash_ready(cs); + nandc_flash_cs(cs); + flash_erase_cmd(cs, page_addr); + nandc_wait_flash_ready(cs); + status = flash_read_status(cs, page_addr); + nandc_flash_de_cs(cs); + status &= 0x01; + if (status) + PRINT_I("%s addr=%x status=%x\n", __func__, + page_addr, status); + + return status; +} + +static void flash_read_spare(u8 cs, u32 page_addr, u8 *spare) +{ + u32 col = nand_para.sec_per_page << 9; + + nandc_writel(READ_CMD >> 8, NANDC_CHIP_CMD(cs)); + nandc_writel(col, NANDC_CHIP_ADDR(cs)); + nandc_writel(col >> 8, NANDC_CHIP_ADDR(cs)); + nandc_writel(page_addr & 0x00ff, NANDC_CHIP_ADDR(cs)); + nandc_writel(page_addr >> 8, NANDC_CHIP_ADDR(cs)); + nandc_writel(page_addr >> 16, NANDC_CHIP_ADDR(cs)); + nandc_writel(READ_CMD & 0x00ff, NANDC_CHIP_CMD(cs)); + + nandc_wait_flash_ready(cs); + + *spare = nandc_readl(NANDC_CHIP_DATA(cs)); +} + +/* + * Read the 1st page's 1st spare byte of a phy_blk + * If not FF, it's bad blk + */ +static s32 get_bad_blk_list(u16 *table, u32 die) +{ + u16 blk; + u32 bad_cnt, page_addr0, page_addr1, page_addr2; + u32 blk_per_die; + u8 bad_flag0, bad_flag1, bad_flag2; + + bad_cnt = 0; + blk_per_die = nand_para.plane_per_die * nand_para.blk_per_plane; + for (blk = 0; blk < blk_per_die; blk++) { + bad_flag0 = 0xFF; + bad_flag1 = 0xFF; + bad_flag2 = 0xFF; + page_addr0 = (blk + blk_per_die * die) * + nand_para.page_per_blk + 0; + page_addr1 = page_addr0 + 1; + page_addr2 = page_addr0 + nand_para.page_per_blk - 1; + flash_read_spare(die, page_addr0, &bad_flag0); + flash_read_spare(die, page_addr1, &bad_flag1); + flash_read_spare(die, page_addr2, &bad_flag2); + if (bad_flag0 != 0xFF || + bad_flag1 != 0xFF || + bad_flag2 != 0xFF) { + table[bad_cnt++] = blk; + PRINT_E("die[%d], bad_blk[%d]\n", die, blk); + } + } + return bad_cnt; +} + +#if FLASH_STRESS_TEST_EN + +#define FLASH_PAGE_SIZE 2048 +#define FLASH_SPARE_SIZE 8 + +static u16 bad_blk_list[1024]; +static u32 pwrite[FLASH_PAGE_SIZE / 4]; +static u32 pread[FLASH_PAGE_SIZE / 4]; +static u32 pspare_write[FLASH_SPARE_SIZE / 4]; +static u32 pspare_read[FLASH_SPARE_SIZE / 4]; +static u32 bad_blk_num; +static u32 bad_page_num; + +static void flash_test(void) +{ + u32 i, blk, page, bad_cnt, page_addr; + int ret; + u32 pages_num = 64; + u32 blk_addr = 64; + u32 is_bad_blk = 0; + + PRINT_E("%s\n", __func__); + + bad_blk_num = 0; + bad_page_num = 0; + bad_cnt = get_bad_blk_list(bad_blk_list, 0); + + for (blk = 0; blk < 1024; blk++) { + for (i = 0; i < bad_cnt; i++) { + if (bad_blk_list[i] == blk) + break; + } + if (i < bad_cnt) + continue; + is_bad_blk = 0; + PRINT_E("Flash prog block: %x\n", blk); + flash_erase_block(0, blk * blk_addr); + for (page = 0; page < pages_num; page++) { + page_addr = blk * blk_addr + page; + for (i = 0; i < 512; i++) + pwrite[i] = (page_addr << 16) + i; + pspare_write[0] = pwrite[0] + 0x5AF0; + pspare_write[1] = pspare_write[0] + 1; + flash_prog_page(0, page_addr, pwrite, pspare_write); + memset(pread, 0, 2048); + memset(pspare_read, 0, 8); + ret = flash_read_page(0, page_addr, pread, + pspare_read); + if (ret != NAND_STS_OK) + is_bad_blk = 1; + for (i = 0; i < 512; i++) { + if (pwrite[i] != pread[i]) { + is_bad_blk = 1; + break; + } + } + for (i = 0; i < 2; i++) { + if (pspare_write[i] != pspare_read[i]) { + is_bad_blk = 1; + break; + } + } + if (is_bad_blk) { + bad_page_num++; + PRINT_E("ERR:page%x, ret=%x\n", page_addr, ret); + rknand_print_hex("data:", pread, 4, 8); + rknand_print_hex("spare:", pspare_read, 4, 2); + } + } + flash_erase_block(0, blk * blk_addr); + if (is_bad_blk) + bad_blk_num++; + } + PRINT_E("bad_blk_num = %d, bad_page_num = %d\n", + bad_blk_num, bad_page_num); + + PRINT_E("Flash Test Finish!!!\n"); + while (1) + ; +} +#endif + +static void flash_die_info_init(void) +{ + u32 cs; + + g_nand_max_die = 0; + for (cs = 0; cs < MAX_FLASH_NUM; cs++) { + if (nand_para.nand_id[1] == id_byte[cs][1]) { + die_cs_index[g_nand_max_die] = cs; + g_nand_max_die++; + } + } + g_totle_block = g_nand_max_die * nand_para.plane_per_die * + nand_para.blk_per_plane; +} + +static void flash_print_info(void) +{ + PRINT_I("No.0 FLASH ID: %x %x %x %x %x %x\n", + nand_para.nand_id[0], + nand_para.nand_id[1], + nand_para.nand_id[2], + nand_para.nand_id[3], + nand_para.nand_id[4], + nand_para.nand_id[5]); + PRINT_I("die_per_chip: %x\n", nand_para.die_per_chip); + PRINT_I("sec_per_page: %x\n", nand_para.sec_per_page); + PRINT_I("page_per_blk: %x\n", nand_para.page_per_blk); + PRINT_I("cell: %x\n", nand_para.cell); + PRINT_I("plane_per_die: %x\n", nand_para.plane_per_die); + PRINT_I("blk_per_plane: %x\n", nand_para.blk_per_plane); + PRINT_I("TotleBlock: %x\n", g_totle_block); + PRINT_I("die gap: %x\n", nand_para.die_gap); + PRINT_I("lsb_mode: %x\n", nand_para.lsb_mode); + PRINT_I("read_retry_mode: %x\n", nand_para.read_retry_mode); + PRINT_I("ecc_bits: %x\n", nand_para.ecc_bits); + PRINT_I("Use ecc_bits: %x\n", g_nand_flash_ecc_bits); + PRINT_I("access_freq: %x\n", nand_para.access_freq); + PRINT_I("opt_mode: %x\n", nand_para.opt_mode); + + PRINT_I("Cache read enable: %x\n", + nand_para.operation_opt & NAND_CACHE_READ_EN ? 1 : 0); + PRINT_I("Cache random read enable: %x\n", + nand_para.operation_opt & NAND_CACHE_RANDOM_READ_EN ? 1 : 0); + PRINT_I("Cache prog enable: %x\n", + nand_para.operation_opt & NAND_CACHE_PROG_EN ? 1 : 0); + PRINT_I("multi read enable: %x\n", + nand_para.operation_opt & NAND_MULTI_READ_EN ? 1 : 0); + + PRINT_I("multi prog enable: %x\n", + nand_para.operation_opt & NAND_MULTI_PROG_EN ? 1 : 0); + PRINT_I("interleave enable: %x\n", + nand_para.operation_opt & NAND_INTERLEAVE_EN ? 1 : 0); + + PRINT_I("read retry enable: %x\n", + nand_para.operation_opt & NAND_READ_RETRY_EN ? 1 : 0); + PRINT_I("randomizer enable: %x\n", + nand_para.operation_opt & NAND_RANDOMIZER_EN ? 1 : 0); + + PRINT_I("SDR enable: %x\n", + nand_para.operation_opt & NAND_SDR_EN ? 1 : 0); + PRINT_I("ONFI enable: %x\n", + nand_para.operation_opt & NAND_ONFI_EN ? 1 : 0); + PRINT_I("TOGGLE enable: %x\n", + nand_para.operation_opt & NAND_TOGGLE_EN ? 1 : 0); + + PRINT_I("g_nand_idb_res_blk_num: %x\n", g_nand_idb_res_blk_num); +} + +static void ftl_flash_init(void) +{ + /* para init */ + g_nand_phy_info.nand_type = nand_para.cell; + g_nand_phy_info.die_num = nand_para.die_per_chip; + g_nand_phy_info.plane_per_die = nand_para.plane_per_die; + g_nand_phy_info.blk_per_plane = nand_para.blk_per_plane; + g_nand_phy_info.page_per_blk = nand_para.page_per_blk; + g_nand_phy_info.page_per_slc_blk = nand_para.page_per_blk / + nand_para.cell; + g_nand_phy_info.byte_per_sec = 512; + g_nand_phy_info.sec_per_page = nand_para.sec_per_page; + g_nand_phy_info.sec_per_blk = nand_para.sec_per_page * + nand_para.page_per_blk; + g_nand_phy_info.reserved_blk = 8; + g_nand_phy_info.blk_per_die = nand_para.plane_per_die * + nand_para.blk_per_plane; + g_nand_phy_info.ecc_bits = nand_para.ecc_bits; + + /* driver register */ + g_nand_ops.get_bad_blk_list = get_bad_blk_list; + g_nand_ops.erase_blk = flash_erase_block; + g_nand_ops.prog_page = flash_prog_page; + g_nand_ops.read_page = flash_read_page; +} + +u32 nandc_flash_init(void __iomem *nandc_addr) +{ + u32 cs; + + /* PRINT_I("...%s enter...\n", __func__); */ + g_nand_idb_res_blk_num = MAX_IDB_RESERVED_BLOCK; + + nandc_init(nandc_addr); + + for (cs = 0; cs < MAX_FLASH_NUM; cs++) { + flash_read_id_raw(cs, id_byte[cs]); + if (cs == 0) { + if (id_byte[0][0] == 0xFF || + id_byte[0][0] == 0 || + id_byte[0][1] == 0xFF) + return FTL_NO_FLASH; + if (id_byte[0][1] != 0xF1 && + id_byte[0][1] != 0xDA && + id_byte[0][1] != 0xD1 && + id_byte[0][1] != 0x95) + return FTL_UNSUPPORTED_FLASH; + } + } + nand_para.nand_id[1] = id_byte[0][1]; + if (id_byte[0][1] == 0xDA) { + nand_para.plane_per_die = 2; + nand_para.nand_id[1] = 0xDA; + } + flash_die_info_init(); + flash_bch_sel(nand_para.ecc_bits); + flash_print_info(); + /* flash_print_info(); */ + ftl_flash_init(); + + #if FLASH_STRESS_TEST_EN + flash_test(); + #endif + + return 0; +} + +void nandc_flash_get_id(u8 cs, void *buf) +{ + memcpy(buf, id_byte[cs], 5); +} + +u32 nandc_flash_deinit(void) +{ + return 0; +} diff --git a/drivers/rkflash/flash.h b/drivers/rkflash/flash.h new file mode 100644 index 000000000000..ce8145794586 --- /dev/null +++ b/drivers/rkflash/flash.h @@ -0,0 +1,143 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#ifndef __FLASH_H +#define __FLASH_H + +#include "typedef.h" + +#ifndef BIT +#define BIT(nr) (1 << (nr)) +#endif + +#define MAX_FLASH_NUM 2 +#define MAX_IDB_RESERVED_BLOCK 12 + +#define NAND_CACHE_READ_EN BIT(0) +#define NAND_CACHE_RANDOM_READ_EN BIT(1) +#define NAND_CACHE_PROG_EN BIT(2) +#define NAND_MULTI_READ_EN BIT(3) + +#define NAND_MULTI_PROG_EN BIT(4) +#define NAND_INTERLEAVE_EN BIT(5) +#define NAND_READ_RETRY_EN BIT(6) +#define NAND_RANDOMIZER_EN BIT(7) + +#define NAND_INTER_MODE_OFFSET (0x8) +#define NAND_INTER_MODE_MARK (0x07) +#define NAND_INTER_SDR_EN BIT(0) +#define NAND_INTER_ONFI_EN BIT(1) +#define NAND_INTER_TOGGLE_EN BIT(2) + +#define NAND_SDR_EN BIT(8) +#define NAND_ONFI_EN BIT(9) +#define NAND_TOGGLE_EN BIT(10) +#define NAND_UNIQUE_ID_EN BIT(11) + +#define RESET_CMD 0xff +#define READ_ID_CMD 0x90 +#define READ_STATUS_CMD 0x70 +#define PAGE_PROG_CMD 0x8010 +#define BLOCK_ERASE_CMD 0x60d0 +#define READ_CMD 0x0030 +#define READ_DP_OUT_CMD 0x05E0 + +#define SAMSUNG 0x00 /* SAMSUNG */ +#define TOSHIBA 0x01 /* TOSHIBA */ +#define HYNIX 0x02 /* HYNIX */ +#define INFINEON 0x03 /* INFINEON */ +#define MICRON 0x04 /* MICRON */ +#define RENESAS 0x05 /* RENESAS */ +#define ST 0x06 /* ST */ +#define INTEL 0x07 /* intel */ +#define Sandisk 0x08 /* Sandisk */ + +#define RR_NONE 0x00 +#define RR_HY_1 0x01 /* hynix H27UCG8T2M */ +#define RR_HY_2 0x02 /* hynix H27UBG08U0B */ +#define RR_HY_3 0x03 /* hynix H27UCG08U0B H27UBG08U0C */ +#define RR_HY_4 0x04 /* hynix H27UCG8T2A */ +#define RR_HY_5 0x05 /* hynix H27UCG8T2E */ +#define RR_HY_6 0x06 /* hynix H27QCG8T2F5R-BCG */ +#define RR_MT_1 0x11 /* micron */ +#define RR_MT_2 0x12 /* micron L94C L95B */ +#define RR_TH_1 0x21 /* toshiba */ +#define RR_TH_2 0x22 /* toshiba */ +#define RR_TH_3 0x23 /* toshiba */ +#define RR_SS_1 0x31 /* samsung */ +#define RR_SD_1 0x41 /* Sandisk */ +#define RR_SD_2 0x42 /* Sandisk */ +#define RR_SD_3 0x43 /* Sandisk */ +#define RR_SD_4 0x44 /* Sandisk */ + +/* 0 1 2 3 4 5 6 7 8 9 slc */ +#define LSB_0 0 +/* 0 1 2 3 6 7 A B E F hynix, micron 74A */ +#define LSB_1 1 +/* 0 1 3 5 7 9 B D toshiba samsung sandisk */ +#define LSB_2 2 +/* 0 1 2 3 4 5 8 9 C D 10 11 micron 84A */ +#define LSB_3 3 +/* 0 1 2 3 4 5 7 8 A B E F micron L95B */ +#define LSB_4 4 +/* 0 1 2 3 4 5 8 9 14 15 20 21 26 27 micron B74A TLC */ +#define LSB_6 6 +/* 0 3 6 9 C F 12 15 18 15 1B 1E 21 24 K9ABGD8U0C TLC */ +#define LSB_7 7 + +/* BadBlockFlagMode */ +/* first spare @ first page of each blocks */ +#define BBF_1 1 +/* first spare @ last page of each blocks */ +#define BBF_2 2 +/* first spare @ first and last page of each blocks */ +#define BBF_11 3 +/* sandisk 15nm flash prog first page without data and check status */ +#define BBF_3 4 + +#define MPM_0 0 /* block 0 ~ 1 */ +#define MPM_1 1 /* block 0 ~ 2048... */ + +struct NAND_PARA_INFO_T { + u8 id_bytes; + u8 nand_id[6]; + u8 vendor; + u8 die_per_chip; + u8 sec_per_page; + u16 page_per_blk; + u8 cell; /* 1 slc , 2 mlc , 3 tlc */ + u8 plane_per_die; + u16 blk_per_plane; + u16 operation_opt; + u8 lsb_mode; + u8 read_retry_mode; + u8 ecc_bits; + u8 access_freq; + u8 opt_mode; + u8 die_gap; + u8 bad_block_mode; + u8 multi_plane_mode; + u8 reversd2[6]; /* 32 bytes */ +}; + +struct FLASH_INFO_T { + u16 block_size; + u8 ecc_bits; + u32 flash_size; + u16 page_size; + u8 access_time; + u8 manufacturer_name; + u8 flash_mask; +}; + +extern struct nand_phy_info g_nand_phy_info; +extern struct nand_ops g_nand_ops; +extern void __iomem *nandc_base; + +void nandc_flash_get_id(u8 cs, void *buf); +void nandc_flash_reset(u8 chip_sel); +u32 nandc_flash_init(void __iomem *nandc_addr); +u32 nandc_flash_deinit(void); + +#endif diff --git a/drivers/rkflash/flash_com.h b/drivers/rkflash/flash_com.h new file mode 100644 index 000000000000..8e2cbce9bbb5 --- /dev/null +++ b/drivers/rkflash/flash_com.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#ifndef __FLASH_COM_H +#define __FLASH_COM_H + +#include "typedef.h" + +#define NAND_ERROR INVALID_UINT32 +#define NAND_OK 0 + +#define NAND_STS_OK 0 /* bit 0 ecc error or ok */ +#define NAND_STS_REFRESH 256 /* need refresh */ +#define NAND_STS_EMPTY 512 /* page is not proged */ +#define NAND_STS_ECC_ERR NAND_ERROR + +#define FULL_SLC 0 +#define SLC 1 + +#define NAND_FLASH_MLC_PAGE_TAG 0xFFFF +#define MAX_FLASH_PAGE_SIZE 0x1000 /* 4KB */ + +#define PAGE_ADDR_BITS 0 +#define PAGE_ADDR_MASK ((1u << 11) - 1) +#define BLOCK_ADDR_BITS 11 +#define BLOCK_ADDR_MASK ((1u << 14) - 1) +#define DIE_ADDR_BITS 25 +#define DIE_ADDR_MASK ((1u << 3) - 1) +#define FLAG_ADDR_BITS 28 +#define FLAG_ADDR_MASK ((1u << 4) - 1) +#define PHY_BLK_DIE_ADDR_BITS 14 + +struct nand_req { + u32 status; + u32 page_addr; /* 31:28 flag, 27:25: die, 24:11 block, 10:0 page */ + u32 *p_data; + u32 *p_spare; + u32 lpa; +}; + +struct nand_phy_info { + u16 nand_type; /* SLC,MLC,TLC */ + u16 die_num; /* number of LUNs */ + u16 plane_per_die; + u16 blk_per_plane; + u16 blk_per_die; + u16 page_per_blk; /* in MLC mode */ + u16 page_per_slc_blk; /* in SLC mode */ + u16 sec_per_page; /* physical page data size */ + u16 sec_per_blk; /* physical page data size */ + u16 byte_per_sec; /* size of logical sectors */ + u16 reserved_blk; /* reserved for boot loader in die 0*/ + u8 ecc_bits; +}; + +struct nand_ops { + s32 (*get_bad_blk_list)(u16 *table, u32 die); + u32 (*erase_blk)(u8 cs, u32 page_addr); + u32 (*prog_page)(u8 cs, u32 page_addr, u32 *data, u32 *spare); + u32 (*read_page)(u8 cs, u32 page_addr, u32 *data, u32 *spare); +}; + +s32 ftl_flash_prog_pages(void *req, u32 num_req, u32 flash_type, u32 check); +s32 ftl_flash_read_pages(void *req, u32 num_req, u32 flash_type); +s32 ftl_flash_erase_blocks(void *req, u32 num_req); +s32 ftl_flash_test_blk(u16 phy_block); +s32 ftl_flash_get_bad_blk_list(u16 *table, u32 die); + +#endif diff --git a/drivers/rkflash/ftl_flash_plat.c b/drivers/rkflash/ftl_flash_plat.c new file mode 100644 index 000000000000..497c29aa72ac --- /dev/null +++ b/drivers/rkflash/ftl_flash_plat.c @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#include +#include "flash_com.h" + +struct nand_phy_info g_nand_phy_info; +struct nand_ops g_nand_ops; + +static u32 check_buf[MAX_FLASH_PAGE_SIZE / 4]; +static u32 check_spare_buf[MAX_FLASH_PAGE_SIZE / 8 / 4]; +static u32 pg_buf0[MAX_FLASH_PAGE_SIZE / 4]; + +static u32 l2p_addr_tran(struct nand_req *req, u32 *addr, u32 *p_die) +{ + u16 block_index, page_index; + u16 blk_per_die = g_nand_phy_info.blk_per_die; + u32 die_index; + + block_index = (u16)((req[0].page_addr >> BLOCK_ADDR_BITS) & + BLOCK_ADDR_MASK); + page_index = (u16)(req[0].page_addr & PAGE_ADDR_MASK); + die_index = (u16)((req[0].page_addr >> DIE_ADDR_BITS) & + DIE_ADDR_MASK); + *p_die = die_index; + *addr = (block_index + blk_per_die * die_index) * + g_nand_phy_info.page_per_blk + page_index; + return 0; +} + +s32 ftl_flash_prog_pages(void *request, u32 num_req, u32 flash_type, u32 check) +{ + u32 i, cs, status, addr; + struct nand_req *req = (struct nand_req *)request; + + for (i = 0; i < num_req; i++) { + l2p_addr_tran(&req[i], &addr, &cs); + status = g_nand_ops.prog_page(cs, + addr, + req[i].p_data, + req[i].p_spare); + req[i].status = status; + if (status != NAND_STS_OK) + req[i].status = NAND_STS_ECC_ERR; + } + + if (check == 0) + return 0; + for (i = 0; i < num_req; i++) { + l2p_addr_tran(&req[i], &addr, &cs); + status = g_nand_ops.read_page(cs, + addr, + check_buf, + check_spare_buf); + if (status != NAND_STS_ECC_ERR) + req[i].status = NAND_STS_OK; + if (check_buf[0] != req[i].p_data[0]) + req[i].status = NAND_STS_ECC_ERR; + } + return 0; +} + +s32 ftl_flash_read_pages(void *request, u32 num_req, u32 flash_type) +{ + u32 i, cs, status, addr; + struct nand_req *req = (struct nand_req *)request; + + for (i = 0; i < num_req; i++) { + l2p_addr_tran(&req[i], &addr, &cs); + status = g_nand_ops.read_page(cs, + addr, + req[i].p_data, + req[i].p_spare); + req[i].status = status; + } + return OK; +} + +s32 ftl_flash_erase_blocks(void *request, u32 num_req) +{ + u32 i, cs, status, addr; + struct nand_req *req = (struct nand_req *)request; + + for (i = 0; i < num_req; i++) { + l2p_addr_tran(&req[i], &addr, &cs); + status = g_nand_ops.erase_blk(cs, addr); + req[i].status = status; + if (status != NAND_STS_OK) + req[i].status = NAND_STS_ECC_ERR; + } + return OK; +} + +s32 ftl_flash_get_bad_blk_list(u16 *table, u32 die) +{ + return g_nand_ops.get_bad_blk_list(table, die); +} + +s32 ftl_flash_test_blk(u16 phy_block) +{ + s32 sts = 0; + u32 spare[16]; + struct nand_req req; + + req.p_data = pg_buf0; + req.p_spare = spare; + memset(spare, 0xA5, 32); + memset(pg_buf0, 0x5A, 8); + req.page_addr = phy_block << BLOCK_ADDR_BITS; + ftl_flash_erase_blocks((void *)&req, 1); + ftl_flash_prog_pages((void *)&req, 1, SLC, 1); + if (req.status == NAND_STS_ECC_ERR) { + PRINT_E("%s %x is bad block\n", __func__, phy_block); + sts = -1; + } + ftl_flash_erase_blocks((void *)&req, 1); + + return sts; +} diff --git a/drivers/rkflash/ftl_include.h b/drivers/rkflash/ftl_include.h new file mode 100644 index 000000000000..f9967e323f6d --- /dev/null +++ b/drivers/rkflash/ftl_include.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#ifndef _FTL_INCLUDE_ +#define _FTL_INCLUDE_ + +#include + +#include "flash_com.h" +#include "typedef.h" + +#define ENABLE_LOW_FORMAT +#define SYS_FTL_VERSION "ftl_ver 1.2.2" + +/* + * debug + */ +#define FTL_DEBUG_LEVEL D_INF +#define FTL_DEBUG(level, format, arg...) \ + do {\ + if ((level) <= FTL_DEBUG_LEVEL) {\ + pr_info(format, ##arg);\ + } \ + } while (0) + +#define D_ERR 0 +#define D_WAN 1 +#define D_INF 2 +#define D_DBG 3 + +/* For init, load, recovery, flush_all */ +#define FTL_DBG_GLB D_DBG +/* For open_blk, erase_blk, write_trace_page, get_trace_list */ +#define FTL_DBG_BLK (FTL_DBG_GLB + 1) +/* For flush 1 cache, write page */ +#define FTL_DBG_PAGE (FTL_DBG_GLB + 2) +/* For lookup/update l2p */ +#define FTL_DBG_MAP (FTL_DBG_GLB + 3) + +#define FTL_DEBUG_BREAK(exp) \ + do { \ + if (exp) { \ + FTL_DEBUG(0, "FILE: %s:%d:\n", __FILE__, __LINE__);\ + dump_ftl_info();\ + while (1)\ + ;\ + } \ + } while (0) + +#endif diff --git a/drivers/rkflash/nand_boot.c b/drivers/rkflash/nand_boot.c new file mode 100644 index 000000000000..c170650e5166 --- /dev/null +++ b/drivers/rkflash/nand_boot.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#include +#include + +#include "flash.h" +#include "nand_boot.h" +#include "rk_sftl.h" +#include "typedef.h" + +int sftl_flash_init(void __iomem *reg_addr) +{ + int ret; + + ret = nandc_flash_init(reg_addr); + if (ret == 0) + ret = sftl_init(); + + return ret; +} +EXPORT_SYMBOL_GPL(sftl_flash_init); + +void sftl_flash_read_id(u8 chip_sel, void *buf) +{ + nandc_flash_get_id(chip_sel, buf); +} +EXPORT_SYMBOL_GPL(sftl_flash_read_id); + +unsigned int sftl_flash_get_capacity(void) +{ + return sftl_get_density(); +} + +int sftl_flash_write(u32 sec, u32 n_sec, void *p_data) +{ + sftl_write(sec, n_sec, p_data); + return 0; +} + +int sftl_flash_read(u32 sec, u32 n_sec, void *p_data) +{ + sftl_read(sec, n_sec, p_data); + return 0; +} + +void sftl_flash_deinit(void) +{ + u8 chip_sel = 0; + + sftl_deinit(); + nandc_flash_reset(chip_sel); +} + +int sftl_flash_resume(void __iomem *reg_addr) +{ + return nandc_flash_init(reg_addr); +} + +void sftl_flash_clean_irq(void) +{ +} diff --git a/drivers/rkflash/nand_boot.h b/drivers/rkflash/nand_boot.h new file mode 100644 index 000000000000..d82145948126 --- /dev/null +++ b/drivers/rkflash/nand_boot.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#ifndef _SFC_H +#define _SFC_H + +int sftl_flash_init(void __iomem *reg_addr); +void sftl_flash_read_id(u8 chip_sel, void *buf); +int sftl_flash_read(unsigned int sec, unsigned int n_sec, void *p_data); +int sftl_flash_write(unsigned int sec, unsigned int n_sec, void *p_data); +unsigned int sftl_flash_get_capacity(void); +void sftl_flash_deinit(void); +int sftl_flash_resume(void __iomem *reg_addr); +void sftl_flash_clean_irq(void); + +#endif diff --git a/drivers/rkflash/nandc.c b/drivers/rkflash/nandc.c new file mode 100644 index 000000000000..78a286e63829 --- /dev/null +++ b/drivers/rkflash/nandc.c @@ -0,0 +1,294 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#include +#include + +#include "flash.h" +#include "flash_com.h" +#include "nandc.h" +#include "typedef.h" + +#define CPU_DELAY_NS(n) ndelay(n) + +#define NANDC_MASTER_EN + +void __iomem *nandc_base; + +static u32 g_nandc_ecc_bits; +#ifdef NANDC_MASTER_EN +static struct MASTER_INFO_T master; +static u32 *g_master_temp_buf; +#endif + +void nandc_init(void __iomem *nandc_addr) +{ + union FM_CTL_T ctl_reg; + + nandc_base = nandc_addr; + + ctl_reg.d32 = 0; + ctl_reg.V6.wp = 1; + nandc_writel(ctl_reg.d32, NANDC_FMCTL); + nandc_writel(0, NANDC_RANDMZ_CFG); + nandc_time_cfg(40); + +#ifdef NANDC_MASTER_EN + if (!g_master_temp_buf) + g_master_temp_buf = (u32 *)ftl_malloc(MAX_FLASH_PAGE_SIZE + + MAX_FLASH_PAGE_SIZE / 8); + master.page_buf = &g_master_temp_buf[0]; + master.spare_buf = &g_master_temp_buf[MAX_FLASH_PAGE_SIZE / 4]; + master.mapped = 0; +#endif +} + +void nandc_flash_cs(u8 chip_sel) +{ + union FM_CTL_T tmp; + + tmp.d32 = nandc_readl(NANDC_FMCTL); + tmp.V6.cs = 0x01 << chip_sel; + nandc_writel(tmp.d32, NANDC_FMCTL); +} + +void nandc_flash_de_cs(u8 chip_sel) +{ + union FM_CTL_T tmp; + + tmp.d32 = nandc_readl(NANDC_FMCTL); + tmp.V6.cs = 0; + tmp.V6.flash_abort_clear = 0; + nandc_writel(tmp.d32, NANDC_FMCTL); +} + +u32 nandc_delayns(u32 count) +{ + CPU_DELAY_NS(count); + return 0; +} + +u32 nandc_wait_flash_ready(u8 chip_sel) +{ + union FM_CTL_T tmp; + u32 status; + u32 i; + + status = 0; + for (i = 0; i < 100000; i++) { + nandc_delayns(100); + tmp.d32 = nandc_readl(NANDC_FMCTL); + if (tmp.V6.rdy != 0) + break; + } + + if (i >= 100000) + status = -1; + return status; +} + +void nandc_randmz_sel(u8 chip_sel, u32 randmz_seed) +{ + nandc_writel(randmz_seed, NANDC_RANDMZ_CFG); +} + +void nandc_time_cfg(u32 ns) +{ + if (ns < 36) + nandc_writel(0x1061, NANDC_FMWAIT); + else if (ns >= 100) + nandc_writel(0x2082, NANDC_FMWAIT); + else + nandc_writel(0x1081, NANDC_FMWAIT); +} + +void nandc_bch_sel(u8 bits) +{ + union BCH_CTL_T tmp; + union FL_CTL_T fl_reg; + + fl_reg.d32 = 0; + fl_reg.V6.rst = 1; + nandc_writel(fl_reg.d32, NANDC_FLCTL); + g_nandc_ecc_bits = bits; + tmp.d32 = 0; + tmp.V6.addr = 0x10; + tmp.V6.bch_mode1 = 0; + if (bits == 16) { + tmp.V6.bch_mode = 0; + } else if (bits == 24) { + tmp.V6.bch_mode = 1; + } else { + tmp.V6.bch_mode1 = 1; + tmp.V6.bch_mode = 1; + if (bits == 40) + tmp.V6.bch_mode = 0; + } + tmp.V6.rst = 1; + nandc_writel(tmp.d32, NANDC_BCHCTL); +} + +static void nandc_xfer_start(u8 chip_sel, + u8 dir, + u8 sector_count, + u8 st_buf, + u32 *p_data, + u32 *p_spare) +{ + union BCH_CTL_T bch_reg; + union FL_CTL_T fl_reg; + u8 bus_mode = (p_spare || p_data); + u32 i; + union MTRANS_CFG_T master_reg; + u16 *p_spare_tmp = (u16 *)p_spare; + + fl_reg.d32 = 0; + bch_reg.d32 = nandc_readl(NANDC_BCHCTL); + bch_reg.V6.addr = 0x10; + bch_reg.V6.power_down = 0; + bch_reg.V6.region = chip_sel; + + fl_reg.V6.rdn = dir; + fl_reg.V6.dma = 1; + fl_reg.V6.tr_count = 1; + fl_reg.V6.async_tog_mix = 1; + fl_reg.V6.cor_en = 1; + fl_reg.V6.st_addr = st_buf / 2; + + master_reg.d32 = nandc_readl(NANDC_MTRANS_CFG); + master_reg.V6.bus_mode = 0; + #ifdef NANDC_MASTER_EN + if (bus_mode != 0 && dir != 0) { + u32 spare_sz = 64; + + for (i = 0; i < sector_count / 2; i++) { + if (p_spare) { + master.spare_buf[i * spare_sz / 4] = + (p_spare_tmp[0]) | ((u32)p_spare_tmp[1] << 16); + p_spare_tmp += 2; + } else{ + master.spare_buf[i * spare_sz / 4] = + 0xffffffff; + } + } + } + fl_reg.V6.page_num = (sector_count + 1) / 2; + master.page_vir = (u32 *)((p_data == (u32 *)NULL) ? + master.page_buf : + (u32 *)p_data); + master.spare_vir = (u32 *)master.spare_buf; + master.page_phy = + (u32)rknandc_dma_map_single((unsigned long)master.page_vir, + fl_reg.V6.page_num * 1024, + dir); + master.spare_phy = + (u32)rknandc_dma_map_single((unsigned long)master.spare_vir, + fl_reg.V6.page_num * 64, + dir); + master.mapped = 1; + nandc_writel(master.page_phy, NANDC_MTRANS_SADDR0); + nandc_writel(master.spare_phy, NANDC_MTRANS_SADDR1); + master_reg.d32 = 0; + master_reg.V6.incr_num = 16; + master_reg.V6.burst = 7; + if ((((unsigned long)p_data) & 0x03) == 0) + master_reg.V6.hsize = 2; + master_reg.V6.bus_mode = 1; + master_reg.V6.ahb_wr = !dir; + master_reg.V6.ahb_wr_st = 1; + #endif + + nandc_writel(master_reg.d32, NANDC_MTRANS_CFG); + nandc_writel(bch_reg.d32, NANDC_BCHCTL); + nandc_writel(fl_reg.d32, NANDC_FLCTL); + fl_reg.V6.start = 1; + nandc_writel(fl_reg.d32, NANDC_FLCTL); +} + +static void nandc_xfer_comp(u8 chip_sel) +{ + union FL_CTL_T fl_reg; + union MTRANS_CFG_T master_reg; + + master_reg.d32 = nandc_readl(NANDC_MTRANS_CFG); + if (master_reg.V6.bus_mode != 0) { + union MTRANS_STAT_T stat_reg; + + if (master_reg.V6.ahb_wr != 0) { + do { + fl_reg.d32 = nandc_readl(NANDC_FLCTL); + stat_reg.d32 = nandc_readl(NANDC_MTRANS_STAT); + } while (stat_reg.V6.mtrans_cnt < fl_reg.V6.page_num); + + if (master.mapped) { + rknandc_dma_unmap_single((u64)master.page_phy, + fl_reg.V6.page_num * 1024, + 0); + rknandc_dma_unmap_single((u64)master.spare_phy, + fl_reg.V6.page_num * 64, + 0); + } + } else { + do { + fl_reg.d32 = nandc_readl(NANDC_FLCTL); + } while (fl_reg.V6.tr_rdy == 0); + } + } else { + do { + fl_reg.d32 = nandc_readl(NANDC_FLCTL); + } while ((fl_reg.V6.tr_rdy == 0)); + } +} + +u32 nandc_xfer_data(u8 chip_sel, u8 dir, u8 sector_count, + u32 *p_data, u32 *p_spare) +{ + u32 status = NAND_STS_OK; + u32 i; + u32 spare[16]; + union BCH_ST_T bch_st_reg; + + if (dir == NANDC_WRITE && !p_spare) { + p_spare = (u32 *)spare; + memset(spare, 0xFF, sizeof(spare)); + } + nandc_xfer_start(chip_sel, dir, sector_count, 0, p_data, p_spare); + nandc_xfer_comp(chip_sel); + if (dir == NANDC_READ) { + if (p_spare) { + u32 spare_sz = 64; + u32 temp_data; + u8 *p_spare_temp = (u8 *)p_spare; + + for (i = 0; i < sector_count / 2; i++) { + temp_data = master.spare_buf[i * spare_sz / 4]; + *p_spare_temp++ = (u8)temp_data; + *p_spare_temp++ = (u8)(temp_data >> 8); + *p_spare_temp++ = (u8)(temp_data >> 16); + *p_spare_temp++ = (u8)(temp_data >> 24); + } + } + for (i = 0; i < sector_count / 4 ; i++) { + bch_st_reg.d32 = nandc_readl(NANDC_BCHST(i)); + if (bch_st_reg.V6.fail0 || bch_st_reg.V6.fail1) { + status = NAND_STS_ECC_ERR; + } else { + u32 tmp = 0; + + tmp = + max(bch_st_reg.V6.err_bits0 | + ((u32)bch_st_reg.V6.err_bits0_5 << 5), + bch_st_reg.V6.err_bits1 | + ((u32)bch_st_reg.V6.err_bits1_5 << 5)); + status = max(tmp, status); + } + } + } + nandc_writel(0, NANDC_MTRANS_CFG); + return status; +} + +void nandc_clean_irq(void) +{ +} diff --git a/drivers/rkflash/nandc.h b/drivers/rkflash/nandc.h new file mode 100644 index 000000000000..07f04bc6f5c7 --- /dev/null +++ b/drivers/rkflash/nandc.h @@ -0,0 +1,222 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#ifndef __NAND_H +#define __NAND_H + +#include + +#define nandc_writel(v, offs) writel((v), (offs) + nandc_base) +#define nandc_readl(offs) readl((offs) + nandc_base) + +#define NANDC_READ 0 +#define NANDC_WRITE 1 + +/* INT ID */ +enum NANDC_IRQ_NUM_T { + NC_IRQ_DMA = 0, + NC_IRQ_FRDY, + NC_IRQ_BCHERR, + NC_IRQ_BCHFAIL, + NC_IRQ_LLP +}; + +union FM_CTL_T { + u32 d32; + struct { + unsigned cs : 8; /* bits[0:7] */ + unsigned wp : 1; /* bits[8] */ + unsigned rdy : 1; /* bits[9] */ + unsigned fifo_empty : 1; /* bits[10] */ + unsigned reserved11 : 1; /* bits[11] */ + unsigned dwidth : 1; /* bits[12] */ + unsigned tm : 1; /* bits[13] */ + unsigned onficlk_en : 1; /* bits[14] */ + unsigned toggle_en : 1; /* bits[15] */ + unsigned flash_abort_en : 1; /* bits[16] */ + unsigned flash_abort_clear : 1; /* bits[17] */ + unsigned reserved18_23 : 6; /* bits[18:23] */ + unsigned read_delay : 3; /* bits[24:26] */ + unsigned reserved27_31 : 5; /* bits[27:31] */ + } V6; +}; + +union FM_WAIT_T { + u32 d32; + struct { + unsigned csrw : 5; + unsigned rwpw : 6; + unsigned rdy : 1; + unsigned rwcs : 6; + unsigned reserved18_23 : 6; + unsigned fmw_dly : 6; + unsigned fmw_dly_en : 1; + unsigned reserved31_31 : 1; + } V6; +}; + +union FL_CTL_T { + u32 d32; + struct { + unsigned rst : 1; + unsigned rdn : 1; + unsigned start : 1; + unsigned dma : 1; + unsigned st_addr : 1; + unsigned tr_count : 2; + unsigned rdy_ignore : 1; + /* unsigned int_clr : 1; */ + /* unsigned int_en : 1; */ + unsigned reserved8_9 : 2; + unsigned cor_en : 1; + unsigned lba_en : 1; + unsigned spare_size : 7; + unsigned reserved19 : 1; + unsigned tr_rdy : 1; + unsigned page_size : 1; + unsigned page_num : 6; + unsigned low_power : 1; + unsigned async_tog_mix : 1; + unsigned reserved30_31 : 2; + } V6; +}; + +union BCH_CTL_T { + u32 d32; + struct { + unsigned rst : 1; + unsigned reserved : 1; + unsigned addr_not_care : 1; + unsigned power_down : 1; + unsigned bch_mode : 1; /* 0-16bit/1KB, 1-24bit/1KB */ + unsigned region : 3; + unsigned addr : 8; + unsigned bchpage : 1; + unsigned reserved17 : 1; + unsigned bch_mode1 : 1; + unsigned thres : 8; + unsigned reserved27_31 : 5; + } V6; +}; + +union BCH_ST_T { + u32 d32; + struct { + unsigned errf0 : 1; + unsigned done0 : 1; + unsigned fail0 : 1; + unsigned err_bits0 : 5; + unsigned err_bits_low0 : 5; + unsigned errf1 : 1; + unsigned done1 : 1; + unsigned fail1 : 1; + unsigned err_bits1 : 5; + unsigned err_bits_low1 : 5; + unsigned rdy : 1; + /* unsigned cnt : 1; */ + unsigned err_bits0_5 : 1; + unsigned err_bits_low0_5 : 1; + unsigned err_bits1_5 : 1; + unsigned err_bits_low1_5 : 1; + unsigned reserved31_31 : 1; + } V6; +}; + +union MTRANS_CFG_T { + u32 d32; + struct { + unsigned ahb_wr_st : 1; + unsigned ahb_wr : 1; + unsigned bus_mode : 1; + unsigned hsize : 3; + unsigned burst : 3; + unsigned incr_num : 5; + unsigned fl_pwd : 1; + unsigned ahb_rst : 1; + unsigned reserved16_31 : 16; + } V6; +}; + +union MTRANS_STAT_T { + u32 d32; + struct { + unsigned bus_err : 16; + unsigned mtrans_cnt : 5; + unsigned reserved21_31 : 11; + } V6; +}; + +/* NANDC Registers */ +#define NANDC_FMCTL 0x0 +#define NANDC_FMWAIT 0x4 +#define NANDC_FLCTL 0x8 +#define NANDC_BCHCTL 0xc +#define NANDC_MTRANS_CFG 0x10 +#define NANDC_MTRANS_SADDR0 0x14 +#define NANDC_MTRANS_SADDR1 0x18 +#define NANDC_MTRANS_STAT 0x1c +#define NANDC_DLL_CTL_REG0 0x130 +#define NANDC_DLL_CTL_REG1 0x134 +#define NANDC_DLL_OBS_REG0 0x138 +#define NANDC_RANDMZ_CFG 0x150 +#define NANDC_EBI_EN 0x154 +#define NANDC_FMWAIT_SYN 0x158 +#define NANDC_MTRANS_STAT2 0x15c +#define NANDC_NANDC_VER 0x160 +#define NANDC_LLP_CTL 0x164 +#define NANDC_LLP_STAT 0x168 +#define NANDC_INTEN 0x16c +#define NANDC_INTCLR 0x170 +#define NANDC_INTST 0x174 +#define NANDC_SPARE0 0x200 +#define NANDC_SPARE1 0x230 + +#define NANDC_BCHST(i) ({ \ + u32 x = (i); \ + 4 * x + x < 8 ? 0x20 : 0x520; }) + +#define NANDC_CHIP_DATA(id) (0x800 + (id) * 0x100) +#define NANDC_CHIP_ADDR(id) (0x800 + (id) * 0x100 + 0x4) +#define NANDC_CHIP_CMD(id) (0x800 + (id) * 0x100 + 0x8) + +struct MASTER_INFO_T { + u32 *page_buf; /* [DATA_LEN]; */ + u32 *spare_buf; /* [DATA_LEN / (1024/128)]; */ + u32 *page_vir; /* page_buf_vir_addr */ + u32 *spare_vir; /* spare_buf_vir_addr */ + u32 page_phy; /* page_buf_phy_addr */ + u32 spare_phy; /* spare_buf_phy_addr*/ + u32 mapped; + u32 cnt; +}; + +struct CHIP_MAP_INFO_T { + u32 *nandc_addr; + u32 chip_num; +}; + +unsigned long rknandc_dma_map_single(unsigned long ptr, + int size, + int dir); +void rknandc_dma_unmap_single(unsigned long ptr, + int size, + int dir); + +void nandc_init(void __iomem *nandc_addr); +void nandc_flash_cs(u8 chip_sel); +void nandc_flash_de_cs(u8 chip_sel); +u32 nandc_wait_flash_ready(u8 chip_sel); +u32 nandc_delayns(u32 count); +u32 nandc_xfer_data(u8 chip_sel, + u8 dir, + u8 sector_count, + u32 *p_data, + u32 *p_spare); +void nandc_randmz_sel(u8 chip_sel, u32 randmz_seed); +void nandc_bch_sel(u8 bits); +void nandc_read_not_case_busy_en(u8 en); +void nandc_time_cfg(u32 ns); +void nandc_clean_irq(void); + +#endif diff --git a/drivers/rkflash/rk_sftl.S b/drivers/rkflash/rk_sftl.S new file mode 100644 index 000000000000..ccb0a016259a --- /dev/null +++ b/drivers/rkflash/rk_sftl.S @@ -0,0 +1,14046 @@ +/* + * New ftl for slc nand and spi nand + * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * date: 2017-9-28 + */ + .arch armv7-a + .fpu softvfp + .eabi_attribute 20, 1 + .eabi_attribute 21, 1 + .eabi_attribute 23, 3 + .eabi_attribute 24, 1 + .eabi_attribute 25, 1 + .eabi_attribute 26, 2 + .eabi_attribute 30, 4 + .eabi_attribute 18, 4 + .file "rk_sftl.c" + .text + .align 2 + .global Ftl_log2 + .type Ftl_log2, %function +Ftl_log2: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + mov r2, #1 + mov r3, #0 + b .L2 +.L3: + add r3, r3, #1 + mov r2, r2, asl #1 + uxth r3, r3 +.L2: + cmp r2, r0 + bls .L3 + sub r3, r3, #1 + uxth r0, r3 + bx lr + .fnend + .size Ftl_log2, .-Ftl_log2 + .align 2 + .global FtlPrintInfo + .type FtlPrintInfo, %function +FtlPrintInfo: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + bx lr + .fnend + .size FtlPrintInfo, .-FtlPrintInfo + .align 2 + .global FtlSysBlkNumInit + .type FtlSysBlkNumInit, %function +FtlSysBlkNumInit: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + ldr r3, .L8 + cmp r0, #23 + movls r0, #24 + ldrh r2, [r3, #4] + ldrh r1, [r3, #14] + str r0, [r3, #0] + mul r2, r2, r0 + rsb r0, r0, r1 + ldr r1, [r3, #20] + strh r0, [r3, #12] @ movhi + mov r0, #0 + str r2, [r3, #8] + rsb r2, r2, r1 + str r2, [r3, #16] + bx lr +.L9: + .align 2 +.L8: + .word .LANCHOR0 + .fnend + .size FtlSysBlkNumInit, .-FtlSysBlkNumInit + .global __aeabi_idiv + .global __aeabi_uidiv + .align 2 + .global FtlConstantsInit + .type FtlConstantsInit, %function +FtlConstantsInit: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r3, r4, r5, r6, r7, r8, r9, sl, fp, lr} + mov sl, r0 + ldrh r1, [r0, #0] + ldr r3, .L16 + ldrh r5, [r0, #2] + ldrh r6, [sl, #6] + ldrh r0, [r0, #4] + strh r1, [r3, #24] @ movhi + strh r5, [r3, #26] @ movhi + mov r6, r6, lsr #1 + strh r0, [r3, #28] @ movhi + strh r6, [r3, #14] @ movhi + mov r3, #0 +.L11: + ldr r2, .L16 + add ip, r2, #30 + strb r3, [r3, ip] + add r3, r3, #1 + cmp r3, #32 + bne .L11 + mul r5, r5, r0 + ldr r4, .L16 + mul r0, r0, r6 + cmp r1, #1 + mov r3, #5 + strh r3, [r2, #62] @ movhi + streqh r1, [r2, #62] @ movhi + mov r3, #0 + strh r3, [r2, #64] @ movhi + uxth r5, r5 + mov r8, #640 + strh r5, [r4, #4] @ movhi + uxth r0, r0 + strh r8, [r4, #66] @ movhi + strh r0, [r4, #68] @ movhi + bl Ftl_log2 + ldrh fp, [sl, #12] + ldrh r9, [sl, #14] + mul r3, fp, r5 + mov r9, r9, asl #1 + strh fp, [r4, #72] @ movhi + uxth r9, r9 + strh fp, [r4, #74] @ movhi + strh r9, [r4, #78] @ movhi + strh r3, [r4, #76] @ movhi + strh r0, [r4, #70] @ movhi + mov r0, r9 + bl Ftl_log2 + mov r3, r9, asl #9 + mul r1, fp, r9 + uxth r3, r3 + strh r3, [r4, #82] @ movhi + mov r3, r3, lsr #8 + strh r3, [r4, #84] @ movhi + ldrh r3, [sl, #20] + strh r3, [r4, #86] @ movhi + mul r3, r6, r5 + mov r6, r6, asl #6 + str r3, [r4, #20] + mul r3, r9, r3 + mul r3, fp, r3 + mov r3, r3, asr #11 + str r3, [r4, #88] + mov r7, r0 + strh r0, [r4, #80] @ movhi + mov r0, #5120 + mov r8, r8, asr r7 + bl __aeabi_idiv + add r7, r7, #9 + mov r6, r6, asr r7 + mov r1, r5 + add r8, r8, #2 + strh r8, [r4, #94] @ movhi + uxth r6, r6 + strh r6, [r4, #96] @ movhi + uxth r0, r0 + strh r0, [r4, #92] @ movhi + cmp r0, #4 + movls r3, #4 + strlsh r3, [r4, #92] @ movhi + mul r3, r5, r6 + ldrh r0, [r4, #92] + add r6, r6, #8 + str r3, [r4, #100] + bl __aeabi_uidiv + cmp r5, #1 + ldreq r3, .L16 + uxtah r6, r6, r0 + str r6, [r4, #0] + ldr r4, .L16 + addeq r6, r6, #4 + streq r6, [r3, #0] + ldrh r0, [r4, #0] + bl FtlSysBlkNumInit + ldr r3, [r4, #0] + ldrh r2, [r4, #72] + mov r0, #0 + str r0, [r4, #112] + str r3, [r4, #104] + ldr r3, [r4, #16] + mov r3, r3, asl #2 + mul r3, r2, r3 + ldrh r2, [r4, #80] + add r2, r2, #9 + mov r3, r3, lsr r2 + add r3, r3, #2 + strh r3, [r4, #108] @ movhi + mov r3, #32 + strh r3, [r4, #110] @ movhi + ldrh r3, [r4, #92] + add r3, r3, #3 + strh r3, [r4, #92] @ movhi + ldr r3, [r4, #100] + add r3, r3, #3 + str r3, [r4, #100] + ldmfd sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, pc} +.L17: + .align 2 +.L16: + .word .LANCHOR0 + .fnend + .size FtlConstantsInit, .-FtlConstantsInit + .align 2 + .global IsBlkInVendorPart + .type IsBlkInVendorPart, %function +IsBlkInVendorPart: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + ldr r3, .L26 + ldrh r2, [r3, #116] + cmp r2, #0 + ldrneh r1, [r3, #92] + ldrne r2, [r3, #120] + movne r3, #0 + bne .L20 + b .L25 +.L22: + ldrh ip, [r2], #2 + cmp ip, r0 + beq .L24 + add r3, r3, #1 + uxth r3, r3 +.L20: + cmp r3, r1 + bne .L22 + mov r0, #0 + bx lr +.L24: + mov r0, #1 + bx lr +.L25: + mov r0, r2 + bx lr +.L27: + .align 2 +.L26: + .word .LANCHOR0 + .fnend + .size IsBlkInVendorPart, .-IsBlkInVendorPart + .align 2 + .global sftl_get_density + .type sftl_get_density, %function +sftl_get_density: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + ldr r3, .L29 + ldr r0, [r3, #112] + bx lr +.L30: + .align 2 +.L29: + .word .LANCHOR0 + .fnend + .size sftl_get_density, .-sftl_get_density + .align 2 + .global FtlBbmMapBadBlock + .type FtlBbmMapBadBlock, %function +FtlBbmMapBadBlock: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r0, r1, r4, r5, r6, lr} + .save {r0, r1, r4, r5, r6, lr} + mov r5, r0 + ldr r4, .L32 + ldrh r6, [r4, #68] + mov r1, r6 + bl __aeabi_uidiv + uxth r2, r0 + mls r3, r6, r2, r5 + add r1, r4, r2, asl #2 + mov r6, #1 + ldr r0, [r1, #152] + uxth r3, r3 + and r1, r3, #31 + mov ip, r3, lsr #5 + ldr lr, [r0, ip, asl #2] + orr r1, lr, r6, asl r1 + str r1, [r0, ip, asl #2] + str r1, [sp, #0] + mov r1, r5 + ldr r0, .L32+4 + bl printk + ldrh r3, [r4, #130] + mov r0, #0 + add r3, r3, r6 + strh r3, [r4, #130] @ movhi + ldmfd sp!, {r2, r3, r4, r5, r6, pc} +.L33: + .align 2 +.L32: + .word .LANCHOR0 + .word .LC0 + .fnend + .size FtlBbmMapBadBlock, .-FtlBbmMapBadBlock + .global __aeabi_uidivmod + .align 2 + .global FtlBbmIsBadBlock + .type FtlBbmIsBadBlock, %function +FtlBbmIsBadBlock: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, r6, r7, lr} + .save {r3, r4, r5, r6, r7, lr} + mov r7, r0 + ldr r5, .L35 + ldrh r6, [r5, #68] + mov r1, r6 + bl __aeabi_uidivmod + mov r0, r7 + uxth r4, r1 + mov r1, r6 + bl __aeabi_uidiv + mov r2, r4, lsr #5 + and r4, r4, #31 + uxth r0, r0 + add r5, r5, r0, asl #2 + ldr r3, [r5, #152] + ldr r0, [r3, r2, asl #2] + mov r0, r0, lsr r4 + and r0, r0, #1 + ldmfd sp!, {r3, r4, r5, r6, r7, pc} +.L36: + .align 2 +.L35: + .word .LANCHOR0 + .fnend + .size FtlBbmIsBadBlock, .-FtlBbmIsBadBlock + .align 2 + .global FtlBbtInfoPrint + .type FtlBbtInfoPrint, %function +FtlBbtInfoPrint: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + bx lr + .fnend + .size FtlBbtInfoPrint, .-FtlBbtInfoPrint + .align 2 + .global FtlBbtCalcTotleCnt + .type FtlBbtCalcTotleCnt, %function +FtlBbtCalcTotleCnt: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, lr} + .save {r4, r5, r6, lr} + mov r4, #0 + mov r5, r4 + ldr r6, .L42 + b .L39 +.L41: + mov r0, r5 + add r5, r5, #1 + bl FtlBbmIsBadBlock + uxth r5, r5 + cmp r0, #0 + addne r4, r4, #1 + uxthne r4, r4 +.L39: + ldrh r3, [r6, #68] + ldrh r2, [r6, #26] + mul r3, r2, r3 + cmp r5, r3 + blt .L41 + mov r0, r4 + ldmfd sp!, {r4, r5, r6, pc} +.L43: + .align 2 +.L42: + .word .LANCHOR0 + .fnend + .size FtlBbtCalcTotleCnt, .-FtlBbtCalcTotleCnt + .align 2 + .global V2P_block + .type V2P_block, %function +V2P_block: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, r6, r7, lr} + .save {r3, r4, r5, r6, r7, lr} + mov r7, r1 + ldr r5, .L45 + mov r6, r0 + ldrh r4, [r5, #28] + mov r1, r4 + bl __aeabi_uidiv + ldrh r5, [r5, #68] + mul r7, r4, r7 + mov r1, r4 + mla r5, r5, r0, r7 + mov r0, r6 + bl __aeabi_uidivmod + add r1, r5, r1 + uxth r0, r1 + ldmfd sp!, {r3, r4, r5, r6, r7, pc} +.L46: + .align 2 +.L45: + .word .LANCHOR0 + .fnend + .size V2P_block, .-V2P_block + .align 2 + .global P2V_plane + .type P2V_plane, %function +P2V_plane: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + ldr r3, .L48 + stmfd sp!, {r4, r5, r6, lr} + .save {r4, r5, r6, lr} + mov r6, r0 + ldrh r1, [r3, #68] + ldrh r4, [r3, #28] + bl __aeabi_uidiv + mov r1, r4 + mul r5, r0, r4 + mov r0, r6 + bl __aeabi_uidivmod + add r1, r5, r1 + uxth r0, r1 + ldmfd sp!, {r4, r5, r6, pc} +.L49: + .align 2 +.L48: + .word .LANCHOR0 + .fnend + .size P2V_plane, .-P2V_plane + .align 2 + .global P2V_block_in_plane + .type P2V_block_in_plane, %function +P2V_block_in_plane: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, lr} + .save {r4, lr} + ldr r4, .L51 + ldrh r1, [r4, #68] + bl __aeabi_uidivmod + uxth r0, r1 + ldrh r1, [r4, #28] + bl __aeabi_uidiv + uxth r0, r0 + ldmfd sp!, {r4, pc} +.L52: + .align 2 +.L51: + .word .LANCHOR0 + .fnend + .size P2V_block_in_plane, .-P2V_block_in_plane + .align 2 + .global ftl_cmp_data_ver + .type ftl_cmp_data_ver, %function +ftl_cmp_data_ver: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + cmp r0, r1 + bls .L54 + rsb r0, r1, r0 + cmp r0, #-2147483648 + movhi r0, #0 + movls r0, #1 + bx lr +.L54: + rsb r0, r0, r1 + cmp r0, #-2147483648 + movls r0, #0 + movhi r0, #1 + bx lr + .fnend + .size ftl_cmp_data_ver, .-ftl_cmp_data_ver + .align 2 + .global FtlFreeSysBlkQueueEmpty + .type FtlFreeSysBlkQueueEmpty, %function +FtlFreeSysBlkQueueEmpty: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + ldr r3, .L57 + ldrh r0, [r3, #190] + rsbs r0, r0, #1 + movcc r0, #0 + bx lr +.L58: + .align 2 +.L57: + .word .LANCHOR0 + .fnend + .size FtlFreeSysBlkQueueEmpty, .-FtlFreeSysBlkQueueEmpty + .align 2 + .global FtlFreeSysBlkQueueFull + .type FtlFreeSysBlkQueueFull, %function +FtlFreeSysBlkQueueFull: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + ldr r3, .L60 + ldrh r0, [r3, #190] + sub r3, r0, #1024 + rsbs r0, r3, #0 + adc r0, r0, r3 + bx lr +.L61: + .align 2 +.L60: + .word .LANCHOR0 + .fnend + .size FtlFreeSysBlkQueueFull, .-FtlFreeSysBlkQueueFull + .align 2 + .global FtlFreeSysBLkSort + .type FtlFreeSysBLkSort, %function +FtlFreeSysBLkSort: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, r6, r7, lr} + .save {r3, r4, r5, r6, r7, lr} + mov r5, #0 + ldr r4, .L72 + b .L63 +.L64: + ldrh r3, [r4, #186] + add r3, r5, r3 + add r3, r4, r3, asl #1 + ldrh r0, [r3, #192] + bl P2V_block_in_plane + ldr r2, [r4, #2244] + ldr r3, [r4, #2240] + mov r0, r0, asl #1 + ldrh r2, [r2, r0] + str r2, [r3, r5, asl #2] + add r5, r5, #1 + uxth r5, r5 +.L63: + ldrh r3, [r4, #190] + cmp r3, r5 + bhi .L64 + mov r3, #0 + ldr r1, .L72 + b .L65 +.L70: + add r5, r3, #1 + ldr r0, [r1, #2240] + mov r2, r3 + uxth r5, r5 + mov ip, r5 + b .L66 +.L68: + ldr r7, [r0, r2, asl #2] + ldr r6, [r0, ip, asl #2] + cmp r7, r6 + movhi r2, ip + add ip, ip, #1 + uxth ip, ip +.L66: + cmp ip, r4 + bcc .L68 + cmp r3, r2 + beq .L69 + ldr r4, [r0, r3, asl #2] + ldr ip, [r0, r2, asl #2] + str r4, [r0, r2, asl #2] + ldr r0, [r1, #2240] + str ip, [r0, r3, asl #2] + ldrh r0, [r1, #186] + add r2, r0, r2 + add r3, r0, r3 + add r2, r2, #4 + add r3, r3, #4 + add r2, r1, r2, asl #1 + add r3, r1, r3, asl #1 + ldrh ip, [r2, #184] + ldrh r0, [r3, #184] + strh r0, [r2, #184] @ movhi + strh ip, [r3, #184] @ movhi +.L69: + mov r3, r5 +.L65: + ldrh r4, [r1, #190] + sub r2, r4, #1 + cmp r3, r2 + blt .L70 + ldmfd sp!, {r3, r4, r5, r6, r7, pc} +.L73: + .align 2 +.L72: + .word .LANCHOR0 + .fnend + .size FtlFreeSysBLkSort, .-FtlFreeSysBLkSort + .align 2 + .global IsInFreeQueue + .type IsInFreeQueue, %function +IsInFreeQueue: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + ldr r2, .L80 + stmfd sp!, {r4, lr} + .save {r4, lr} + ldrh r1, [r2, #190] + cmp r1, #1024 + ldrneh ip, [r2, #186] + movne r3, #0 + bne .L76 + b .L78 +.L77: + add r4, r3, ip + mov r4, r4, asl #22 + add r4, r2, r4, lsr #21 + ldrh r4, [r4, #192] + cmp r4, r0 + beq .L79 + add r3, r3, #1 +.L76: + cmp r3, r1 + bcc .L77 +.L78: + mov r0, #0 + ldmfd sp!, {r4, pc} +.L79: + mov r0, #1 + ldmfd sp!, {r4, pc} +.L81: + .align 2 +.L80: + .word .LANCHOR0 + .fnend + .size IsInFreeQueue, .-IsInFreeQueue + .align 2 + .global FtlFreeSysBlkQueueOut + .type FtlFreeSysBlkQueueOut, %function +FtlFreeSysBlkQueueOut: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + ldr r3, .L85 + ldrh r1, [r3, #190] + cmp r1, #0 + subne r1, r1, #1 + ldrneh r2, [r3, #186] + movweq r0, #65535 + addne r0, r3, r2, asl #1 + addne r2, r2, #1 + bicne r2, r2, #64512 + ldrneh r0, [r0, #192] + strneh r1, [r3, #190] @ movhi + strneh r2, [r3, #186] @ movhi + bx lr +.L86: + .align 2 +.L85: + .word .LANCHOR0 + .fnend + .size FtlFreeSysBlkQueueOut, .-FtlFreeSysBlkQueueOut + .align 2 + .global insert_data_list + .type insert_data_list, %function +insert_data_list: + .fnstart + @ args = 0, pretend = 0, frame = 8 + @ frame_needed = 0, uses_anonymous_args = 0 + movw r3, #65535 + cmp r0, r3 + stmfd sp!, {r0, r1, r2, r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r0, r1, r2, r4, r5, r6, r7, r8, r9, sl, fp, lr} + beq .L88 + ldr r1, .L102 + mov ip, #6 + mul ip, ip, r0 + mvn r6, #0 + ldr r4, [r1, #2248] + mov r8, r1 + add r2, r4, ip + strh r6, [r2, #2] @ movhi + strh r6, [r4, ip] @ movhi + ldr r3, [r1, #2252] + cmp r3, #0 + beq .L101 +.L89: + ldr r7, [r1, #2256] + mov sl, r0, asl #1 + ldrh r1, [r2, #4] + ldr r9, .L102+4 + ldrh r5, [r7, sl] + cmp r1, #0 + ldr fp, [r8, #2244] + mulne r6, r1, r5 + ldr r5, [r8, #2248] + add sl, fp, sl + str sl, [sp, #4] + rsb r1, r5, r3 + mov r1, r1, asr #1 + mul r1, r9, r1 + uxth r1, r1 +.L96: + mov r9, r1, asl #1 + ldrh r8, [r3, #4] + ldrh sl, [r7, r9] + cmp r8, #0 + mvneq r8, #0 + mulne r8, r8, sl + cmp r8, r6 + bne .L92 + ldrh sl, [fp, r9] + ldr r9, [sp, #4] + ldrh r8, [r9, #0] + cmp sl, r8 + bcc .L94 + b .L93 +.L92: + bhi .L93 +.L94: + ldrh r8, [r3, #0] + movw sl, #65535 + cmp r8, sl + streqh r1, [r2, #2] @ movhi + streqh r0, [r3, #0] @ movhi + ldreq r3, .L102 + streq r2, [r3, #2260] + beq .L88 +.L95: + mov r1, #6 + mla r3, r1, r8, r5 + mov r1, r8 + b .L96 +.L93: + strh r1, [r4, ip] @ movhi + ldrh r1, [r3, #2] + strh r1, [r2, #2] @ movhi + ldr r1, .L102 + ldr ip, [r1, #2252] + cmp r3, ip + bne .L97 + strh r0, [r3, #2] @ movhi +.L101: + str r2, [r1, #2252] + b .L88 +.L97: + ldrh r2, [r3, #2] + mov ip, #6 + ldr r1, [r1, #2248] + mul r2, ip, r2 + strh r0, [r1, r2] @ movhi + strh r0, [r3, #2] @ movhi +.L88: + mov r0, #0 + ldmfd sp!, {r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, pc} +.L103: + .align 2 +.L102: + .word .LANCHOR0 + .word -1431655765 + .fnend + .size insert_data_list, .-insert_data_list + .align 2 + .global INSERT_DATA_LIST + .type INSERT_DATA_LIST, %function +INSERT_DATA_LIST: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, lr} + .save {r3, lr} + bl insert_data_list + movw r1, #2264 + ldr r3, .L106 + ldrh r2, [r3, r1] + add r2, r2, #1 + uxth r2, r2 + strh r2, [r3, r1] @ movhi + ldrh r3, [r3, #12] + cmp r3, r2 + ldmcsfd sp!, {r3, pc} + ldr r0, .L106+4 + mov r2, #189 + ldr r1, .L106+8 + ldmfd sp!, {r3, lr} + b printk +.L107: + .align 2 +.L106: + .word .LANCHOR0 + .word .LC1 + .word .LANCHOR1 + .fnend + .size INSERT_DATA_LIST, .-INSERT_DATA_LIST + .align 2 + .global insert_free_list + .type insert_free_list, %function +insert_free_list: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + .save {r4, r5, r6, r7, r8, r9, sl, lr} + movw r6, #65535 + cmp r0, r6 + beq .L109 + ldr r1, .L116 + mov r5, #6 + mul ip, r5, r0 + mvn r3, #0 + ldr r4, [r1, #2248] + add r2, r4, ip + strh r3, [r2, #2] @ movhi + strh r3, [r4, ip] @ movhi + ldr r3, [r1, #2268] + cmp r3, #0 + beq .L115 +.L110: + ldr sl, [r1, #2248] + mov r8, r0, asl #1 + ldr r7, [r1, #2244] + rsb r1, sl, r3 + ldr r9, .L116+4 + mov r1, r1, asr #1 + ldrh r8, [r7, r8] + mul r1, r9, r1 + mov r9, r5 + uxth r1, r1 +.L113: + mov r5, r1, asl #1 + ldrh r5, [r7, r5] + cmp r5, r8 + bcs .L111 + ldrh r5, [r3, #0] + cmp r5, r6 + streqh r1, [r2, #2] @ movhi + streqh r0, [r3, #0] @ movhi + beq .L109 +.L112: + mla r3, r9, r5, sl + mov r1, r5 + b .L113 +.L111: + ldrh r5, [r3, #2] + strh r5, [r2, #2] @ movhi + strh r1, [r4, ip] @ movhi + ldr r1, .L116 + ldr ip, [r1, #2268] + cmp r3, ip + bne .L114 + strh r0, [r3, #2] @ movhi +.L115: + str r2, [r1, #2268] + b .L109 +.L114: + ldrh r2, [r3, #2] + mov ip, #6 + ldr r1, [r1, #2248] + mul r2, ip, r2 + strh r0, [r1, r2] @ movhi + strh r0, [r3, #2] @ movhi +.L109: + mov r0, #0 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, pc} +.L117: + .align 2 +.L116: + .word .LANCHOR0 + .word -1431655765 + .fnend + .size insert_free_list, .-insert_free_list + .align 2 + .global INSERT_FREE_LIST + .type INSERT_FREE_LIST, %function +INSERT_FREE_LIST: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, lr} + .save {r3, lr} + bl insert_free_list + mov r1, #2272 + ldr r3, .L120 + ldrh r2, [r3, r1] + add r2, r2, #1 + uxth r2, r2 + strh r2, [r3, r1] @ movhi + ldrh r3, [r3, #12] + cmp r3, r2 + ldmcsfd sp!, {r3, pc} + ldr r0, .L120+4 + mov r2, #182 + ldr r1, .L120+8 + ldmfd sp!, {r3, lr} + b printk +.L121: + .align 2 +.L120: + .word .LANCHOR0 + .word .LC1 + .word .LANCHOR1+17 + .fnend + .size INSERT_FREE_LIST, .-INSERT_FREE_LIST + .align 2 + .global List_remove_node + .type List_remove_node, %function +List_remove_node: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, r6, r7, lr} + .save {r3, r4, r5, r6, r7, lr} + mov r5, #6 + ldr r3, .L128 + mov r7, r0 + mul r5, r5, r1 + ldr r6, [r3, #2248] + movw r3, #65535 + add r4, r6, r5 + ldrh r2, [r4, #2] + cmp r2, r3 + bne .L123 + ldr r3, [r0, #0] + cmp r4, r3 + beq .L123 + ldr r0, .L128+4 + movw r2, #337 + ldr r1, .L128+8 + bl printk +.L123: + ldr r3, [r7, #0] + movw r2, #65535 + cmp r4, r3 + ldrh r3, [r6, r5] + bne .L124 + cmp r3, r2 + ldrne r2, .L128 + movne r1, #6 + moveq r3, #0 + streq r3, [r7, #0] + ldrne r2, [r2, #2248] + mlane r3, r1, r3, r2 + mvnne r2, #0 + strne r3, [r7, #0] + strneh r2, [r3, #2] @ movhi + b .L126 +.L124: + cmp r3, r2 + ldr r1, .L128 + mov r2, #6 + ldrh r0, [r4, #2] + muleq r2, r2, r0 + ldreq r3, [r1, #2248] + mvneq r1, #0 + streqh r1, [r3, r2] @ movhi + beq .L126 +.L127: + ldr ip, [r1, #2248] + mla r3, r2, r3, ip + strh r0, [r3, #2] @ movhi + ldrh ip, [r4, #2] + ldrh r0, [r6, r5] + ldr r3, [r1, #2248] + mul r2, r2, ip + strh r0, [r3, r2] @ movhi +.L126: + mvn r3, #0 + mov r0, #0 + strh r3, [r6, r5] @ movhi + strh r3, [r4, #2] @ movhi + ldmfd sp!, {r3, r4, r5, r6, r7, pc} +.L129: + .align 2 +.L128: + .word .LANCHOR0 + .word .LC1 + .word .LANCHOR1+34 + .fnend + .size List_remove_node, .-List_remove_node + .align 2 + .global List_pop_index_node + .type List_pop_index_node, %function +List_pop_index_node: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, lr} + .save {r4, lr} + ldr r3, [r0, #0] + cmp r3, #0 + beq .L135 + ldr r2, .L136 + movw lr, #65535 + mov ip, #6 + ldr r4, [r2, #2248] + b .L132 +.L134: + mla r3, ip, r2, r4 + sub r1, r1, #1 + uxth r1, r1 +.L132: + cmp r1, #0 + beq .L133 + ldrh r2, [r3, #0] + cmp r2, lr + bne .L134 +.L133: + rsb r4, r4, r3 + ldr r3, .L136+4 + mov r4, r4, asr #1 + mul r4, r3, r4 + uxth r4, r4 + mov r1, r4 + bl List_remove_node + mov r0, r4 + ldmfd sp!, {r4, pc} +.L135: + movw r0, #65535 + ldmfd sp!, {r4, pc} +.L137: + .align 2 +.L136: + .word .LANCHOR0 + .word -1431655765 + .fnend + .size List_pop_index_node, .-List_pop_index_node + .align 2 + .global List_pop_head_node + .type List_pop_head_node, %function +List_pop_head_node: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + mov r1, #0 + b List_pop_index_node + .fnend + .size List_pop_head_node, .-List_pop_head_node + .align 2 + .global List_get_gc_head_node + .type List_get_gc_head_node, %function +List_get_gc_head_node: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + ldr r2, .L145 + ldr r3, [r2, #2252] + cmp r3, #0 + beq .L144 + ldr r2, [r2, #2248] + movw r1, #65535 + mov ip, #6 + b .L141 +.L143: + mla r3, ip, r3, r2 + sub r0, r0, #1 + uxth r0, r0 +.L141: + cmp r0, #0 + beq .L142 + ldrh r3, [r3, #0] + cmp r3, r1 + bne .L143 + mov r0, r1 + bx lr +.L142: + rsb r3, r2, r3 + ldr r0, .L145+4 + mov r3, r3, asr #1 + mul r0, r0, r3 + uxth r0, r0 + bx lr +.L144: + movw r0, #65535 + bx lr +.L146: + .align 2 +.L145: + .word .LANCHOR0 + .word -1431655765 + .fnend + .size List_get_gc_head_node, .-List_get_gc_head_node + .align 2 + .global List_update_data_list + .type List_update_data_list, %function +List_update_data_list: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, r6, r7, lr} + .save {r3, r4, r5, r6, r7, lr} + movw r2, #2276 + ldr r3, .L155 + mov r4, r0 + ldrh r2, [r3, r2] + cmp r2, r0 + beq .L148 + movw r2, #2324 + ldrh r2, [r3, r2] + cmp r2, r0 + beq .L148 + movw r2, #2372 + ldrh r2, [r3, r2] + cmp r2, r0 + beq .L148 + mov r2, #6 + ldr r1, [r3, #2248] + mul r2, r2, r0 + ldr r0, [r3, #2252] + add r5, r1, r2 + cmp r5, r0 + beq .L148 + ldr r0, [r3, #2256] + mov r3, r4, asl #1 + ldrh r6, [r5, #4] + ldrh r3, [r0, r3] + muls r6, r6, r3 + ldrh r3, [r5, #2] + mvneq r6, #0 + movw r0, #65535 + cmp r3, r0 + bne .L150 + ldrh r2, [r1, r2] + cmp r2, r3 + bne .L150 + ldr r0, .L155+4 + movw r2, #426 + ldr r1, .L155+8 + bl printk +.L150: + ldr r7, .L155 + mov r1, #6 + ldrh r2, [r5, #2] + ldr r3, [r7, #2248] + mla r2, r1, r2, r3 + ldr r1, .L155+12 + rsb r3, r3, r2 + mov r3, r3, asr #1 + ldrh r2, [r2, #4] + mul r3, r1, r3 + ldr r1, [r7, #2256] + uxth r3, r3 + mov r3, r3, asl #1 + ldrh r3, [r1, r3] + muls r3, r2, r3 + mvneq r3, #0 + cmp r6, r3 + bcs .L148 + ldr r0, .L155+16 + mov r1, r4 + movw r5, #2264 + bl List_remove_node + ldrh r3, [r7, r5] + cmp r3, #0 + bne .L152 + ldr r0, .L155+4 + movw r2, #435 + ldr r1, .L155+8 + bl printk +.L152: + ldr r3, .L155 + mov r0, r4 + ldrh r2, [r3, r5] + sub r2, r2, #1 + strh r2, [r3, r5] @ movhi + bl INSERT_DATA_LIST +.L148: + mov r0, #0 + ldmfd sp!, {r3, r4, r5, r6, r7, pc} +.L156: + .align 2 +.L155: + .word .LANCHOR0 + .word .LC1 + .word .LANCHOR1+51 + .word -1431655765 + .word .LANCHOR0+2252 + .fnend + .size List_update_data_list, .-List_update_data_list + .align 2 + .global ftl_map_blk_alloc_new_blk + .type ftl_map_blk_alloc_new_blk, %function +ftl_map_blk_alloc_new_blk: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, r6, r7, lr} + .save {r3, r4, r5, r6, r7, lr} + mov r4, r0 + ldrh r2, [r0, #10] + mov r5, #0 + ldr r3, [r0, #12] + b .L158 +.L161: + mov r7, r3 + add r3, r3, #2 + ldrh r6, [r7, #0] + cmp r6, #0 + bne .L159 + bl FtlFreeSysBlkQueueOut + cmp r0, #0 + strh r0, [r7, #0] @ movhi + beq .L160 + ldr r3, [r4, #28] + strh r6, [r4, #2] @ movhi + add r3, r3, #1 + str r3, [r4, #28] + ldrh r3, [r4, #8] + strh r5, [r4, #0] @ movhi + add r3, r3, #1 + strh r3, [r4, #8] @ movhi + b .L160 +.L159: + add r5, r5, #1 + uxth r5, r5 +.L158: + cmp r5, r2 + bne .L161 +.L160: + ldrh r3, [r4, #10] + cmp r3, r5 + bhi .L162 + ldr r0, .L163 + mov r2, #532 + ldr r1, .L163+4 + bl printk +.L162: + mov r0, #0 + ldmfd sp!, {r3, r4, r5, r6, r7, pc} +.L164: + .align 2 +.L163: + .word .LC1 + .word .LANCHOR1+73 + .fnend + .size ftl_map_blk_alloc_new_blk, .-ftl_map_blk_alloc_new_blk + .align 2 + .global select_l2p_ram_region + .type select_l2p_ram_region, %function +select_l2p_ram_region: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + ldr r2, .L177 + movw r1, #65535 + stmfd sp!, {r3, r4, r5, r6, r7, lr} + .save {r3, r4, r5, r6, r7, lr} + ldrh r3, [r2, #110] + ldr r0, [r2, #2420] + mov r2, #0 + mov r4, r2 + b .L166 +.L168: + add r2, r2, #12 + add ip, r0, r2 + ldrh ip, [ip, #-12] + cmp ip, r1 + beq .L167 + add r4, r4, #1 + uxth r4, r4 +.L166: + cmp r4, r3 + bne .L168 + mov r1, #0 + mov r4, r3 + mov r5, #-2147483648 + mov r2, r1 + b .L169 +.L171: + add ip, r0, r1 + ldr ip, [ip, #4] + cmp ip, #0 + blt .L170 + cmp ip, r5 + movcc r5, ip + movcc r4, r2 +.L170: + add r2, r2, #1 + add r1, r1, #12 + uxth r2, r2 +.L169: + cmp r2, r3 + bne .L171 + cmp r4, r3 + bcc .L167 + ldr r1, .L177 + movw r2, #2424 + mov r4, r3 + mvn ip, #0 + ldrh r6, [r1, r2] + mov r1, #0 + mov r2, r1 + b .L172 +.L174: + add r5, r0, r1 + ldr r5, [r5, #4] + cmp r5, ip + bcs .L173 + ldrh r7, [r0, r1] + cmp r7, r6 + movne ip, r5 + movne r4, r2 +.L173: + add r2, r2, #1 + add r1, r1, #12 + uxth r2, r2 +.L172: + cmp r2, r3 + bne .L174 + cmp r4, r2 + bcc .L167 + ldr r0, .L177+4 + movw r2, #735 + ldr r1, .L177+8 + bl printk +.L167: + mov r0, r4 + ldmfd sp!, {r3, r4, r5, r6, r7, pc} +.L178: + .align 2 +.L177: + .word .LANCHOR0 + .word .LC1 + .word .LANCHOR1+99 + .fnend + .size select_l2p_ram_region, .-select_l2p_ram_region + .align 2 + .global FtlUpdateVaildLpn + .type FtlUpdateVaildLpn, %function +FtlUpdateVaildLpn: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + ldr r3, .L185 + movw r2, #2426 + stmfd sp!, {r4, r5, lr} + .save {r4, r5, lr} + ldrh r1, [r3, r2] + cmp r1, #4 + add ip, r1, #1 + mov r1, r2 + strh ip, [r3, r2] @ movhi + bhi .L180 + cmp r0, #0 + ldmeqfd sp!, {r4, r5, pc} +.L180: + mov r2, #0 + ldrh r4, [r3, #12] + strh r2, [r3, r1] @ movhi + movw ip, #65535 + str r2, [r3, #2428] + ldr r1, [r3, #2256] + mov r3, r2 + ldr r2, .L185 + b .L182 +.L184: + ldrh r0, [r1], #2 + add r3, r3, #1 + cmp r0, ip + uxth r3, r3 + ldrne r5, [r2, #2428] + addne r0, r0, r5 + strne r0, [r2, #2428] +.L182: + cmp r3, r4 + bne .L184 + ldmfd sp!, {r4, r5, pc} +.L186: + .align 2 +.L185: + .word .LANCHOR0 + .fnend + .size FtlUpdateVaildLpn, .-FtlUpdateVaildLpn + .align 2 + .global ftl_set_blk_mode + .type ftl_set_blk_mode, %function +ftl_set_blk_mode: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + ldr r3, .L191 + mov r2, r0, lsr #5 + cmp r1, #0 + and r0, r0, #31 + uxth r2, r2 + mov ip, #1 + ldr r3, [r3, #2432] + ldr r1, [r3, r2, asl #2] + orrne r0, r1, ip, asl r0 + biceq r0, r1, ip, asl r0 + str r0, [r3, r2, asl #2] + bx lr +.L192: + .align 2 +.L191: + .word .LANCHOR0 + .fnend + .size ftl_set_blk_mode, .-ftl_set_blk_mode + .align 2 + .global ftl_get_blk_mode + .type ftl_get_blk_mode, %function +ftl_get_blk_mode: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + ldr r3, .L194 + mov r2, r0, lsr #5 + and r0, r0, #31 + ldr r3, [r3, #2432] + ldr r3, [r3, r2, asl #2] + mov r0, r3, lsr r0 + and r0, r0, #1 + bx lr +.L195: + .align 2 +.L194: + .word .LANCHOR0 + .fnend + .size ftl_get_blk_mode, .-ftl_get_blk_mode + .align 2 + .global ftl_sb_update_avl_pages + .type ftl_sb_update_avl_pages, %function +ftl_sb_update_avl_pages: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + mov r3, #0 + strh r3, [r0, #4] @ movhi + ldr r3, .L203 + movw ip, #65535 + stmfd sp!, {r4, r5, r6, lr} + .save {r4, r5, r6, lr} + ldrh r3, [r3, #4] + b .L197 +.L199: + add r4, r0, r2, asl #1 + add r2, r2, #1 + ldrh r4, [r4, #16] + uxth r2, r2 + cmp r4, ip + ldrneh r4, [r0, #4] + addne r4, r4, #1 + strneh r4, [r0, #4] @ movhi +.L197: + cmp r2, r3 + bcc .L199 + ldr r2, .L203 + mov ip, r0 + movw r4, #65535 + mvn r1, r1 + ldrh r5, [r2, #72] + mov r2, #0 + b .L200 +.L202: + ldrh r6, [ip, #16] + add r2, r2, #1 + add ip, ip, #2 + cmp r6, r4 + uxth r2, r2 + ldrneh r6, [r0, #4] + addne r6, r5, r6 + addne r6, r6, r1 + strneh r6, [r0, #4] @ movhi +.L200: + cmp r2, r3 + bne .L202 + ldmfd sp!, {r4, r5, r6, pc} +.L204: + .align 2 +.L203: + .word .LANCHOR0 + .fnend + .size ftl_sb_update_avl_pages, .-ftl_sb_update_avl_pages + .align 2 + .global FtlSlcSuperblockCheck + .type FtlSlcSuperblockCheck, %function +FtlSlcSuperblockCheck: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + ldrh r3, [r0, #4] + cmp r3, #0 + bxeq lr + ldrh r2, [r0, #0] + movw r3, #65535 + cmp r2, r3 + bxeq lr + ldrb r2, [r0, #6] @ zero_extendqisi2 + ldr r1, .L210 + add r2, r0, r2, asl #1 + ldrh ip, [r1, #4] + mov r1, #0 + ldrh r2, [r2, #16] + b .L207 +.L209: + ldrb r2, [r0, #6] @ zero_extendqisi2 + add r2, r2, #1 + uxtb r2, r2 + strb r2, [r0, #6] + cmp r2, ip + streqb r1, [r0, #6] + ldreqh r2, [r0, #2] + addeq r2, r2, #1 + streqh r2, [r0, #2] @ movhi + ldrb r2, [r0, #6] @ zero_extendqisi2 + add r2, r0, r2, asl #1 + ldrh r2, [r2, #16] +.L207: + cmp r2, r3 + beq .L209 + bx lr +.L211: + .align 2 +.L210: + .word .LANCHOR0 + .fnend + .size FtlSlcSuperblockCheck, .-FtlSlcSuperblockCheck + .align 2 + .global make_superblock + .type make_superblock, %function +make_superblock: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, r6, r7, r8, sl, lr} + .save {r3, r4, r5, r6, r7, r8, sl, lr} + mov r4, r0 + ldr r3, .L218 + ldrh r2, [r0, #0] + ldrh r3, [r3, #12] + cmp r2, r3 + bcc .L213 + ldr r0, .L218+4 + movw r2, #2049 + ldr r1, .L218+8 + bl printk +.L213: + mov r5, #0 + ldr r6, .L218 + strh r5, [r4, #4] @ movhi + mvn r7, #0 + strb r5, [r4, #7] + b .L214 +.L216: + add r3, r6, r5 + ldrh r1, [r4, #0] + add r8, r5, #8 + add r5, r5, #1 + ldrb r0, [r3, #30] @ zero_extendqisi2 + bl V2P_block + mov r8, r8, asl #1 + uxth r5, r5 + strh r7, [r4, r8] @ movhi + mov sl, r0 + bl FtlBbmIsBadBlock + cmp r0, #0 + streqh sl, [r4, r8] @ movhi + ldreqb r3, [r4, #7] @ zero_extendqisi2 + addeq r3, r3, #1 + streqb r3, [r4, #7] +.L214: + ldrh r2, [r6, #4] + ldr r3, .L218 + cmp r2, r5 + bhi .L216 + ldrb r2, [r4, #7] @ zero_extendqisi2 + ldrh r1, [r3, #72] + mul r2, r1, r2 + strh r2, [r4, #4] @ movhi + mov r2, #0 + strb r2, [r4, #9] + ldr r2, [r3, #2436] + cmp r2, #0 + beq .L217 + ldrh r1, [r4, #0] + ldr r2, [r3, #2244] + mov r3, r1, asl #1 + ldrh r3, [r2, r3] + cmp r3, #59 + movls r3, #1 + strlsb r3, [r4, #9] +.L217: + mov r0, #0 + ldmfd sp!, {r3, r4, r5, r6, r7, r8, sl, pc} +.L219: + .align 2 +.L218: + .word .LANCHOR0 + .word .LC1 + .word .LANCHOR1+121 + .fnend + .size make_superblock, .-make_superblock + .align 2 + .global update_multiplier_value + .type update_multiplier_value, %function +update_multiplier_value: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, r6, r7, lr} + .save {r3, r4, r5, r6, r7, lr} + mov r4, #0 + mov r7, r0 + mov r5, r4 + ldr r6, .L225 + b .L221 +.L223: + add r3, r6, r5 + mov r1, r7 + add r5, r5, #1 + ldrb r0, [r3, #30] @ zero_extendqisi2 + bl V2P_block + uxth r5, r5 + bl FtlBbmIsBadBlock + cmp r0, #0 + ldreqh r3, [r6, #72] + addeq r4, r4, r3 + uxtheq r4, r4 +.L221: + ldrh r3, [r6, #4] + cmp r3, r5 + bhi .L223 + cmp r4, #0 + beq .L224 + mov r1, r4 + mov r0, #32768 + bl __aeabi_idiv + uxth r4, r0 +.L224: + ldr r3, .L225 + mov r2, #6 + mov r0, #0 + ldr r3, [r3, #2248] + mla r7, r2, r7, r3 + strh r4, [r7, #4] @ movhi + ldmfd sp!, {r3, r4, r5, r6, r7, pc} +.L226: + .align 2 +.L225: + .word .LANCHOR0 + .fnend + .size update_multiplier_value, .-update_multiplier_value + .align 2 + .global GetFreeBlockMinEraseCount + .type GetFreeBlockMinEraseCount, %function +GetFreeBlockMinEraseCount: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + ldr r3, .L230 + ldr r0, [r3, #2268] + cmp r0, #0 + bxeq lr + ldr r2, [r3, #2248] + rsb r0, r2, r0 + ldr r2, .L230+4 + mov r0, r0, asr #1 + mul r0, r2, r0 + ldr r2, [r3, #2244] + uxth r0, r0 + mov r3, r0, asl #1 + ldrh r0, [r2, r3] + bx lr +.L231: + .align 2 +.L230: + .word .LANCHOR0 + .word -1431655765 + .fnend + .size GetFreeBlockMinEraseCount, .-GetFreeBlockMinEraseCount + .align 2 + .global GetFreeBlockMaxEraseCount + .type GetFreeBlockMaxEraseCount, %function +GetFreeBlockMaxEraseCount: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + ldr r2, .L239 + stmfd sp!, {r4, r5, lr} + .save {r4, r5, lr} + ldr r3, [r2, #2268] + cmp r3, #0 + beq .L238 + mov r1, #2272 + mov ip, #7 + ldrh r1, [r2, r1] + mov r5, #6 + movw r4, #65535 + mul r1, ip, r1 + mov r1, r1, asr #3 + cmp r0, r1 + uxthgt r0, r1 + ldr r1, [r2, #2248] + ldr r2, .L239+4 + rsb r3, r1, r3 + mov r3, r3, asr #1 + mul r3, r2, r3 + mov r2, #0 + uxth r3, r3 + b .L235 +.L237: + mul ip, r5, r3 + ldrh ip, [r1, ip] + cmp ip, r4 + beq .L236 + add r2, r2, #1 + mov r3, ip + uxth r2, r2 +.L235: + cmp r2, r0 + bne .L237 +.L236: + ldr r2, .L239 + mov r3, r3, asl #1 + ldr r2, [r2, #2244] + ldrh r0, [r2, r3] + ldmfd sp!, {r4, r5, pc} +.L238: + mov r0, r3 + ldmfd sp!, {r4, r5, pc} +.L240: + .align 2 +.L239: + .word .LANCHOR0 + .word -1431655765 + .fnend + .size GetFreeBlockMaxEraseCount, .-GetFreeBlockMaxEraseCount + .align 2 + .global FtlPrintInfo2buf + .type FtlPrintInfo2buf, %function +FtlPrintInfo2buf: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, lr} + .save {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, lr} + mov r8, r0 + ldr r4, .L251 + add r5, r8, #12 + ldr r1, .L251+4 + mov r7, #2272 + bl strcpy + mov r0, r5 + ldr r2, [r4, #88] + movw r6, #2276 + ldr r1, .L251+8 + bl sprintf + ldr r1, .L251+12 + add r5, r5, r0 + mov r0, r5 + add r5, r5, #10 + bl strcpy + ldr r1, .L251+16 + mov r0, r5 + ldr r2, [r4, #2440] + bl sprintf + ldr r1, .L251+20 + ldr r2, [r4, #2428] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+24 + ldr r2, [r4, #2444] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+28 + ldr r2, [r4, #2448] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+32 + ldr r2, [r4, #2452] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+36 + ldr r2, [r4, #2456] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+40 + ldr r2, [r4, #2460] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+44 + ldr r2, [r4, #2464] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r2, [r4, #2468] + ldr r1, .L251+48 + mov r2, r2, lsr #11 + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r2, [r4, #2472] + ldr r1, .L251+52 + mov r2, r2, lsr #11 + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+56 + ldr r2, [r4, #2476] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+60 + ldr r2, [r4, #2480] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+64 + ldrh r2, [r4, #130] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+68 + ldrh r2, [r4, r7] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+72 + ldr r2, [r4, #2484] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+76 + ldr r2, [r4, #2488] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+80 + ldr r2, [r4, #2492] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+84 + ldr r2, [r4, #2496] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+88 + ldr r2, [r4, #2500] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+92 + ldr r2, [r4, #2504] + add r5, r5, r0 + mov r0, r5 + bl sprintf + movw r3, #2538 + ldrh r2, [r4, r3] + ldr r1, .L251+96 + add r5, r5, r0 + mov r0, r5 + bl sprintf + movw r3, #2536 + ldrh r2, [r4, r3] + ldr r1, .L251+100 + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+104 + ldr r2, [r4, #112] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+108 + ldr r2, [r4, #104] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+112 + ldr r2, [r4, #0] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+116 + ldrh r2, [r4, #190] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+120 + ldrh r2, [r4, #12] + add r5, r5, r0 + mov r0, r5 + bl sprintf + movw r3, #2556 + ldrh r2, [r4, r3] + ldr r1, .L251+124 + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+128 + ldr r2, [r4, #16] + add r5, r5, r0 + mov r0, r5 + bl sprintf + mov r3, #2560 + ldrh r2, [r4, r3] + ldr r1, .L251+132 + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+136 + ldrh r2, [r4, #124] + add r5, r5, r0 + mov r0, r5 + bl sprintf + movw r3, #2278 + ldrh r2, [r4, r3] + ldr r1, .L251+140 + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+144 + ldrb r2, [r4, #2282] @ zero_extendqisi2 + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldrh r2, [r4, r6] + ldr r1, .L251+148 + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+152 + ldrb r2, [r4, #2284] @ zero_extendqisi2 + add r5, r5, r0 + mov r0, r5 + bl sprintf + movw r3, #2280 + ldrh r2, [r4, r3] + ldr r1, .L251+156 + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldrh r3, [r4, r6] + ldr r2, [r4, #2256] + add r6, r6, #48 + ldr r1, .L251+160 + mov r3, r3, asl #1 + ldrh r2, [r2, r3] + add r5, r5, r0 + mov r0, r5 + bl sprintf + movw r3, #2326 + ldrh r2, [r4, r3] + ldr r1, .L251+164 + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+168 + ldrb r2, [r4, #2330] @ zero_extendqisi2 + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldrh r2, [r4, r6] + ldr r1, .L251+172 + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+176 + ldrb r2, [r4, #2332] @ zero_extendqisi2 + add r5, r5, r0 + mov r0, r5 + bl sprintf + movw r3, #2328 + ldrh r2, [r4, r3] + ldr r1, .L251+180 + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldrh r3, [r4, r6] + ldr r2, [r4, #2256] + add r6, r6, #248 + ldr r1, .L251+184 + mov r3, r3, asl #1 + ldrh r2, [r2, r3] + add r5, r5, r0 + mov r0, r5 + bl sprintf + movw r3, #2374 + ldrh r2, [r4, r3] + ldr r1, .L251+188 + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+192 + ldrb r2, [r4, #2378] @ zero_extendqisi2 + add r5, r5, r0 + mov r0, r5 + bl sprintf + movw r3, #2372 + ldrh r2, [r4, r3] + ldr r1, .L251+196 + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+200 + ldrb r2, [r4, #2380] @ zero_extendqisi2 + add r5, r5, r0 + mov r0, r5 + bl sprintf + movw r3, #2376 + ldrh r2, [r4, r3] + ldr r1, .L251+204 + add r5, r5, r0 + mov r0, r5 + bl sprintf + movw r3, #2574 + ldrh r2, [r4, r3] + ldr r1, .L251+208 + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+212 + ldrb r2, [r4, #2578] @ zero_extendqisi2 + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+216 + ldrh r2, [r4, r6] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+220 + ldrb r2, [r4, #2580] @ zero_extendqisi2 + add r5, r5, r0 + mov r0, r5 + bl sprintf + mov r3, #2576 + ldrh r2, [r4, r3] + ldr r1, .L251+224 + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, [r4, #2708] + ldr r3, [r4, #2436] + ldr r2, [r4, #2620] + str r1, [sp, #0] + ldr r1, [r4, #2700] + orr r2, r3, r2, asl #8 + str r1, [sp, #4] + ldr r1, .L251+228 + ldr r3, [r4, #2704] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+232 + ldr r2, [r4, #2696] + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+236 + ldr r2, [r4, #2720] + add r5, r5, r0 + mov r0, r5 + bl sprintf + mov r3, #3136 + ldrh r2, [r4, r3] + ldr r1, .L251+240 + add r5, r5, r0 + mov r0, r5 + bl sprintf + movw r3, #3138 + ldrh r2, [r4, r3] + ldr r1, .L251+244 + add r5, r5, r0 + mov r0, r5 + bl sprintf + ldr r1, .L251+248 + ldr r2, [r4, #3140] + add r5, r5, r0 + mov r0, r5 + bl sprintf + movw r3, #3144 + ldrh r2, [r4, r3] + ldr r1, .L251+252 + add r5, r5, r0 + mov r0, r5 + bl sprintf + add r5, r5, r0 + bl GetFreeBlockMinEraseCount + ldr r1, .L251+256 + mov r2, r0 + mov r0, r5 + bl sprintf + add r5, r5, r0 + ldrh r0, [r4, r7] + bl GetFreeBlockMaxEraseCount + ldr r1, .L251+260 + mov r2, r0 + mov r0, r5 + bl sprintf + ldr r3, .L251+264 + ldr r3, [r3, #0] + cmp r3, #1 + add r5, r5, r0 + bne .L247 +.L242: + ldrh r3, [r4, r6] + movw r2, #65535 + cmp r3, r2 + beq .L244 + ldr r2, [r4, #2256] + mov r3, r3, asl #1 + mov r0, r5 + ldr r1, .L251+268 + ldrh r2, [r2, r3] + bl sprintf + add r5, r5, r0 +.L244: + mov r0, #0 + ldr r4, .L251 + bl List_get_gc_head_node + mov r6, #0 + movw sl, #65535 + mov r9, #6 + uxth r3, r0 +.L246: + cmp r3, sl + beq .L245 + ldr r1, [r4, #2256] + mov r2, r3, asl #1 + mul r7, r9, r3 + mov r0, r5 + ldrh r1, [r1, r2] + str r1, [sp, #0] + ldr r1, [r4, #2248] + add r1, r1, r7 + ldrh r1, [r1, #4] + str r1, [sp, #4] + ldr r1, [r4, #2244] + ldrh r2, [r1, r2] + ldr r1, .L251+272 + str r2, [sp, #8] + mov r2, r6 + bl sprintf + add r6, r6, #1 + ldr r3, [r4, #2248] + cmp r6, #16 + ldrh r3, [r3, r7] + add r5, r5, r0 + bne .L246 +.L245: + ldr r6, .L251 + mov r4, #0 + movw sl, #65535 + mov r9, #6 + ldr r2, [r6, #2268] + ldr r3, [r6, #2248] + rsb r3, r3, r2 + ldr r2, .L251+276 + mov r3, r3, asr #1 + mul r3, r2, r3 + uxth r3, r3 +.L248: + cmp r3, sl + beq .L247 + mul r7, r9, r3 + ldr r2, [r6, #2248] + mov r0, r5 + add r2, r2, r7 + ldrh r2, [r2, #4] + str r2, [sp, #0] + mov r2, r3, asl #1 + ldr r1, [r6, #2244] + ldrh r2, [r1, r2] + ldr r1, .L251+280 + str r2, [sp, #4] + mov r2, r4 + bl sprintf + add r4, r4, #1 + ldr r3, [r6, #2248] + cmp r4, #4 + ldrh r3, [r3, r7] + add r5, r5, r0 + bne .L248 +.L247: + rsb r0, r8, r5 + add sp, sp, #16 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, pc} +.L252: + .align 2 +.L251: + .word .LANCHOR0 + .word .LC2 + .word .LC3 + .word .LC4 + .word .LC5 + .word .LC6 + .word .LC7 + .word .LC8 + .word .LC9 + .word .LC10 + .word .LC11 + .word .LC12 + .word .LC13 + .word .LC14 + .word .LC15 + .word .LC16 + .word .LC17 + .word .LC18 + .word .LC19 + .word .LC20 + .word .LC21 + .word .LC22 + .word .LC23 + .word .LC24 + .word .LC25 + .word .LC26 + .word .LC27 + .word .LC28 + .word .LC29 + .word .LC30 + .word .LC31 + .word .LC32 + .word .LC33 + .word .LC34 + .word .LC35 + .word .LC36 + .word .LC37 + .word .LC38 + .word .LC39 + .word .LC40 + .word .LC41 + .word .LC42 + .word .LC43 + .word .LC44 + .word .LC45 + .word .LC46 + .word .LC47 + .word .LC48 + .word .LC49 + .word .LC50 + .word .LC51 + .word .LC52 + .word .LC53 + .word .LC54 + .word .LC55 + .word .LC56 + .word .LC57 + .word .LC58 + .word .LC59 + .word .LC60 + .word .LC61 + .word .LC62 + .word .LC63 + .word .LC64 + .word .LC65 + .word .LC66 + .word .LANCHOR2 + .word .LC67 + .word .LC68 + .word -1431655765 + .word .LC69 + .fnend + .size FtlPrintInfo2buf, .-FtlPrintInfo2buf + .align 2 + .global rknand_proc_ftlread + .type rknand_proc_ftlread, %function +rknand_proc_ftlread: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, lr} + .save {r3, r4, r5, lr} + mov r4, r0 + ldr r1, .L254 + ldr r2, .L254+4 + bl sprintf + add r5, r4, r0 + mov r0, r5 + bl FtlPrintInfo2buf + add r0, r5, r0 + rsb r0, r4, r0 + ldmfd sp!, {r3, r4, r5, pc} +.L255: + .align 2 +.L254: + .word .LC70 + .word .LC71 + .fnend + .size rknand_proc_ftlread, .-rknand_proc_ftlread + .align 2 + .global GetSwlReplaceBlock + .type GetSwlReplaceBlock, %function +GetSwlReplaceBlock: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + ldr r3, .L283 + stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r4, r5, r6, r7, r8, r9, sl, fp, lr} + .pad #20 + sub sp, sp, #20 + ldr r1, [r3, #2492] + ldr r2, [r3, #2504] + cmp r1, r2 + bcs .L257 + mov r2, #0 + ldrh r1, [r3, #12] + str r2, [r3, #2484] + ldr r0, [r3, #2244] + b .L258 +.L259: + ldrh lr, [r0], #2 + add r2, r2, #1 + ldr ip, [r3, #2484] + add ip, lr, ip + str ip, [r3, #2484] +.L258: + cmp r2, r1 + ldr r4, .L283 + bcc .L259 + ldr r5, [r4, #2484] + mov r0, r5 + bl __aeabi_uidiv + ldrh r1, [r4, #62] + str r0, [r4, #2492] + ldr r0, [r4, #2488] + rsb r0, r0, r5 + bl __aeabi_uidiv + str r0, [r4, #2484] + b .L260 +.L257: + ldr r2, [r3, #2500] + cmp r1, r2 + addhi r2, r2, #1 + strhi r2, [r3, #2500] + movhi r2, #0 + bhi .L261 + b .L260 +.L262: + ldr r0, [r3, #2244] + mov r1, r2, asl #1 + add r2, r2, #1 + ldrh ip, [r0, r1] + add ip, ip, #1 + strh ip, [r0, r1] @ movhi +.L261: + ldrh r1, [r3, #12] + cmp r2, r1 + bcc .L262 +.L260: + ldr r3, .L283 + ldr r6, [r3, #2504] + ldr r5, [r3, #2492] + add r2, r6, #256 + cmp r2, r5 + mov r2, r3 + bls .L263 + ldr r1, [r3, #2500] + add r0, r6, #768 + cmp r0, r1 + bls .L263 + ldr r3, [r3, #2436] + cmp r3, #0 + beq .L281 + cmp r6, #30 + bhi .L281 +.L263: + mov r3, #2272 + ldrh r0, [r2, r3] + add r0, r0, r0, asl #1 + ubfx r0, r0, #2, #16 + bl GetFreeBlockMaxEraseCount + add r3, r6, #64 + cmp r0, r3 + mov r8, r0 + bcs .L265 + cmp r6, #30 + bhi .L281 +.L265: + ldr r2, .L283 + ldr r3, [r2, #2252] + cmp r3, #0 + beq .L281 + movw r7, #65535 + ldr r1, [r2, #2248] + mov r4, r7 + ldr r2, [r2, #2244] + mov sl, r7 + ldr ip, .L283+4 + mov fp, #6 + b .L266 +.L269: + ldrh r9, [r3, #4] + cmp r9, #0 + beq .L267 + rsb r3, r1, r3 + mov r3, r3, asr #1 + mul r3, ip, r3 + uxth r3, r3 + mov r9, r3, asl #1 + ldrh r9, [r2, r9] + cmp r9, r6 + bls .L278 + cmp r9, r7 + movcc r7, r9 + movcc r4, r3 +.L267: + mla r3, fp, r0, r1 +.L266: + ldrh r0, [r3, #0] + cmp r0, sl + bne .L269 + b .L268 +.L278: + mov r4, r3 +.L268: + movw r3, #65535 + cmp r4, r3 + beq .L264 + mov sl, r4, asl #1 + ldr fp, .L283 + ldrh r9, [r2, sl] + cmp r9, r6 + bls .L270 + bl GetFreeBlockMinEraseCount + cmp r0, r6 + strhi r7, [fp, #2504] +.L270: + cmp r9, #29 + ldr r2, [fp, #2436] + movhi r3, #0 + movls r3, #1 + cmp r2, #0 + moveq r3, #0 + cmp r3, #0 + beq .L271 + add r3, r9, #10 + cmp r3, r5 + bls .L272 + ldr r3, .L283 + ldrh r3, [r3, #62] + cmp r3, r9 + bls .L271 +.L272: + ldr r6, .L283 + movw r3, #2264 + ldrh r3, [r6, r3] + cmp r3, #64 + bls .L271 + ldr r3, [r6, #2244] + mov r1, r4 + ldr r0, .L283+8 + ldrh r2, [r3, sl] + bl printk + b .L282 +.L271: + cmp r9, r5 + bcs .L281 + add r3, r9, #128 + cmp r8, r3 + ble .L281 + add r3, r9, #256 + ldr r6, .L283 + cmp r3, r5 + bcc .L273 + ldr r3, [r6, #2500] + add r9, r9, #768 + cmp r9, r3 + bcs .L281 +.L273: + ldr r3, [r6, #2256] + mov r1, r4 + ldr r0, .L283+12 + mov r2, r5 + ldrh r3, [r3, sl] + str r3, [sp, #0] + ldr r3, [r6, #2244] + ldrh r3, [r3, sl] + stmib sp, {r3, r8} + ldr r3, [r6, #2500] + bl printk +.L282: + mov r3, #1 + str r3, [r6, #3148] + b .L264 +.L281: + movw r4, #65535 +.L264: + mov r0, r4 + add sp, sp, #20 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} +.L284: + .align 2 +.L283: + .word .LANCHOR0 + .word -1431655765 + .word .LC72 + .word .LC73 + .fnend + .size GetSwlReplaceBlock, .-GetSwlReplaceBlock + .align 2 + .global free_data_superblock + .type free_data_superblock, %function +free_data_superblock: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + movw r2, #65535 + cmp r0, r2 + stmfd sp!, {r3, lr} + .save {r3, lr} + beq .L286 + ldr r2, .L287 + mov r3, r0, asl #1 + mov r1, #0 + ldr r2, [r2, #2256] + strh r1, [r2, r3] @ movhi + bl INSERT_FREE_LIST +.L286: + mov r0, #0 + ldmfd sp!, {r3, pc} +.L288: + .align 2 +.L287: + .word .LANCHOR0 + .fnend + .size free_data_superblock, .-free_data_superblock + .align 2 + .global get_new_active_ppa + .type get_new_active_ppa, %function +get_new_active_ppa: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, lr} + .save {r3, r4, r5, lr} + movw r3, #65535 + ldrh r2, [r0, #0] + mov r4, r0 + cmp r2, r3 + bne .L290 + ldr r0, .L300 + movw r2, #2710 + ldr r1, .L300+4 + bl printk +.L290: + ldr r3, .L300+8 + ldrh r2, [r4, #2] + ldrh r3, [r3, #72] + cmp r2, r3 + bne .L291 + ldr r0, .L300 + movw r2, #2711 + ldr r1, .L300+4 + bl printk +.L291: + ldrh r3, [r4, #4] + cmp r3, #0 + bne .L292 + ldr r0, .L300 + movw r2, #2712 + ldr r1, .L300+4 + bl printk +.L292: + ldrb r3, [r4, #6] @ zero_extendqisi2 + mov r2, #0 + ldr r1, .L300+8 + strb r2, [r4, #10] + add r3, r4, r3, asl #1 + ldrh r0, [r1, #4] + movw r1, #65535 + ldrh r3, [r3, #16] + b .L293 +.L295: + ldrb r3, [r4, #6] @ zero_extendqisi2 + add r3, r3, #1 + uxtb r3, r3 + strb r3, [r4, #6] + cmp r3, r0 + streqb r2, [r4, #6] + ldreqh r3, [r4, #2] + addeq r3, r3, #1 + streqh r3, [r4, #2] @ movhi + ldrb r3, [r4, #6] @ zero_extendqisi2 + add r3, r4, r3, asl #1 + ldrh r3, [r3, #16] +.L293: + cmp r3, r1 + beq .L295 + ldrh r5, [r4, #2] + movw r1, #65535 + ldrh r2, [r4, #4] + orr r5, r5, r3, asl #10 + ldr r3, .L300+8 + sub r2, r2, #1 + ldrh r0, [r3, #4] + uxth r2, r2 + ldrb r3, [r4, #6] @ zero_extendqisi2 + strh r2, [r4, #4] @ movhi +.L297: + add r3, r3, #1 + uxtb r3, r3 + cmp r3, r0 + ldreqh r3, [r4, #2] + addeq r3, r3, #1 + streqh r3, [r4, #2] @ movhi + moveq r3, #0 + add ip, r4, r3, asl #1 + ldrh ip, [ip, #16] + cmp ip, r1 + beq .L297 + strb r3, [r4, #6] + ldr r3, .L300+8 + ldrh r1, [r4, #2] + ldrh r3, [r3, #72] + cmp r1, r3 + bne .L298 + cmp r2, #0 + beq .L298 + ldr r0, .L300 + movw r2, #2733 + ldr r1, .L300+4 + bl printk +.L298: + mov r0, r5 + ldmfd sp!, {r3, r4, r5, pc} +.L301: + .align 2 +.L300: + .word .LC1 + .word .LANCHOR1+137 + .word .LANCHOR0 + .fnend + .size get_new_active_ppa, .-get_new_active_ppa + .align 2 + .global FtlGcBufInit + .type FtlGcBufInit, %function +FtlGcBufInit: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + ldr r3, .L310 + mov r1, #0 + stmfd sp!, {r4, r5, r6, r7, r8, lr} + .save {r4, r5, r6, r7, r8, lr} + mov r7, #12 + str r1, [r3, #3152] + mov r6, #1 + mov r5, #20 + b .L303 +.L304: + mul r2, r7, r1 + ldr ip, [r3, #3156] + add r0, ip, r2 + str r6, [r0, #8] + ldrh r0, [r3, #82] + mul r0, r0, r1 + add r4, r0, #3 + cmp r0, #0 + movlt r0, r4 + ldr r4, [r3, #3160] + bic r0, r0, #3 + add r0, r4, r0 + str r0, [ip, r2] + ldrh r0, [r3, #84] + ldr r4, [r3, #3156] + mul r0, r0, r1 + add ip, r4, r2 + add r8, r0, #3 + cmp r0, #0 + movlt r0, r8 + ldr r8, [r3, #3164] + bic r0, r0, #3 + add r0, r8, r0 + str r0, [ip, #4] + ldr r0, [r3, #3168] + ldr r2, [r4, r2] + mla r0, r5, r1, r0 + add r1, r1, #1 + uxth r1, r1 + str r2, [r0, #8] + ldr r2, [ip, #4] + str r2, [r0, #12] +.L303: + ldrh r2, [r3, #4] + cmp r1, r2 + bcc .L304 + b .L309 +.L306: + mul r1, r5, r2 + ldr ip, [r3, #3156] + add r0, ip, r1 + str r4, [r0, #8] + ldrh r0, [r3, #82] + mul r0, r0, r2 + add r6, r0, #3 + cmp r0, #0 + movlt r0, r6 + ldr r6, [r3, #3160] + bic r0, r0, #3 + add r0, r6, r0 + str r0, [ip, r1] + ldr r0, [r3, #3156] + add r0, r0, r1 + ldrh r1, [r3, #84] + mul r1, r1, r2 + add r2, r2, #1 + uxth r2, r2 + add ip, r1, #3 + cmp r1, #0 + movlt r1, ip + ldr ip, [r3, #3164] + bic r1, r1, #3 + add r1, ip, r1 + str r1, [r0, #4] + b .L308 +.L309: + ldr r3, .L310 + mov r5, #12 + mov r4, #0 +.L308: + ldr r1, [r3, #3172] + cmp r2, r1 + bcc .L306 + ldmfd sp!, {r4, r5, r6, r7, r8, pc} +.L311: + .align 2 +.L310: + .word .LANCHOR0 + .fnend + .size FtlGcBufInit, .-FtlGcBufInit + .align 2 + .global FtlGcBufFree + .type FtlGcBufFree, %function +FtlGcBufFree: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + ldr r3, .L319 + stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r4, r5, r6, r7, r8, r9, sl, fp, lr} + mov r5, #20 + ldr r6, [r3, #3172] + mov fp, #12 + ldr ip, [r3, #3156] + mov r3, #0 + mov r4, r3 + b .L313 +.L316: + mul sl, fp, r2 + add r8, ip, sl + ldr r9, [ip, sl] + ldr sl, [r7, #8] + cmp r9, sl + streq r4, [r8, #8] + beq .L315 +.L314: + add r2, r2, #1 + uxth r2, r2 +.L318: + cmp r2, r6 + bcc .L316 +.L315: + add r3, r3, #1 + uxth r3, r3 +.L313: + cmp r3, r1 + ldmcsfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + mla r7, r5, r3, r0 + mov r2, #0 + b .L318 +.L320: + .align 2 +.L319: + .word .LANCHOR0 + .fnend + .size FtlGcBufFree, .-FtlGcBufFree + .align 2 + .global FtlGcBufAlloc + .type FtlGcBufAlloc, %function +FtlGcBufAlloc: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + ldr r3, .L328 + stmfd sp!, {r4, r5, r6, r7, r8, sl, lr} + .save {r4, r5, r6, r7, r8, sl, lr} + mov r6, #12 + ldr r8, [r3, #3172] + mov r5, #1 + ldr r7, [r3, #3156] + mov r4, #20 + mov r3, #0 + b .L322 +.L325: + mla ip, r6, r2, r7 + ldr sl, [ip, #8] + cmp sl, #0 + bne .L323 + mla r2, r4, r3, r0 + ldr sl, [ip, #0] + str r5, [ip, #8] + str sl, [r2, #8] + ldr ip, [ip, #4] + str ip, [r2, #12] + b .L324 +.L323: + add r2, r2, #1 + uxth r2, r2 + b .L326 +.L327: + mov r2, #0 +.L326: + cmp r2, r8 + bcc .L325 +.L324: + add r3, r3, #1 + uxth r3, r3 +.L322: + cmp r3, r1 + bcc .L327 + ldmfd sp!, {r4, r5, r6, r7, r8, sl, pc} +.L329: + .align 2 +.L328: + .word .LANCHOR0 + .fnend + .size FtlGcBufAlloc, .-FtlGcBufAlloc + .align 2 + .global IsBlkInGcList + .type IsBlkInGcList, %function +IsBlkInGcList: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + ldr r3, .L335 + movw r2, #3176 + ldrh r1, [r3, r2] + ldr r2, [r3, #3180] + mov r3, #0 + b .L331 +.L333: + ldrh ip, [r2], #2 + cmp ip, r0 + beq .L334 + add r3, r3, #1 + uxth r3, r3 +.L331: + cmp r3, r1 + bne .L333 + mov r0, #0 + bx lr +.L334: + mov r0, #1 + bx lr +.L336: + .align 2 +.L335: + .word .LANCHOR0 + .fnend + .size IsBlkInGcList, .-IsBlkInGcList + .align 2 + .global FtlGcUpdatePage + .type FtlGcUpdatePage, %function +FtlGcUpdatePage: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, r6, r7, lr} + .save {r3, r4, r5, r6, r7, lr} + mov r4, r0 + ubfx r0, r0, #10, #16 + mov r5, r1 + mov r6, r2 + bl P2V_block_in_plane + ldr r3, .L341 + movw r2, #3176 + ldrh ip, [r3, r2] + ldr r2, [r3, #3180] + mov r3, #0 + mov r1, r2 + b .L338 +.L340: + ldrh r7, [r1], #2 + cmp r7, r0 + beq .L339 + add r3, r3, #1 + uxth r3, r3 +.L338: + cmp r3, ip + bne .L340 + mov r3, r3, asl #1 + strh r0, [r2, r3] @ movhi + movw r3, #3176 + ldr r2, .L341 + ldrh r1, [r2, r3] + add r1, r1, #1 + strh r1, [r2, r3] @ movhi +.L339: + ldr r3, .L341 + movw r2, #3188 + mov r0, #12 + ldrh r1, [r3, r2] + mul r1, r0, r1 + ldr r0, [r3, #3184] + add ip, r0, r1 + stmib ip, {r5, r6} + str r4, [r0, r1] + ldrh r1, [r3, r2] + add r1, r1, #1 + strh r1, [r3, r2] @ movhi + ldmfd sp!, {r3, r4, r5, r6, r7, pc} +.L342: + .align 2 +.L341: + .word .LANCHOR0 + .fnend + .size FtlGcUpdatePage, .-FtlGcUpdatePage + .align 2 + .global FtlGcRefreshBlock + .type FtlGcRefreshBlock, %function +FtlGcRefreshBlock: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, lr} + .save {r3, r4, r5, lr} + mov r4, r0 + mov r1, r4 + ldr r0, .L346 + bl printk + ldr r3, .L346+4 + movw ip, #3190 + ldrh r5, [r3, ip] + cmp r5, r4 + beq .L344 + movw r2, #3192 + ldrh r0, [r3, r2] + cmp r0, r4 + beq .L344 + movw r1, #65535 + cmp r5, r1 + streqh r4, [r3, ip] @ movhi + beq .L344 + cmp r0, r1 + streqh r4, [r3, r2] @ movhi +.L344: + mov r0, #0 + ldmfd sp!, {r3, r4, r5, pc} +.L347: + .align 2 +.L346: + .word .LC74 + .word .LANCHOR0 + .fnend + .size FtlGcRefreshBlock, .-FtlGcRefreshBlock + .align 2 + .global FtlGcMarkBadPhyBlk + .type FtlGcMarkBadPhyBlk, %function +FtlGcMarkBadPhyBlk: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, r6, r7, lr} + .save {r3, r4, r5, r6, r7, lr} + mov r4, r0 + bl P2V_block_in_plane + ldr r5, .L353 + movw r7, #3194 + mov r2, r4 + ldrh r1, [r5, r7] + mov r6, r0 + ldr r0, .L353+4 + bl printk + mov r0, r6 + bl FtlGcRefreshBlock + ldr r3, [r5, #2436] + cmp r3, #0 + beq .L349 + ldr r3, [r5, #2244] + mov r6, r6, asl #1 + ldrh r2, [r3, r6] + cmp r2, #29 + subhi r2, r2, #30 + strhih r2, [r3, r6] @ movhi +.L349: + ldrh r1, [r5, r7] + mov r3, #0 + ldr r2, .L353+8 + b .L350 +.L352: + ldrh r0, [r2, #2]! + cmp r0, r4 + beq .L351 + add r3, r3, #1 + uxth r3, r3 +.L350: + cmp r3, r1 + bne .L352 + cmp r3, #15 + bhi .L351 + ldr r2, .L353 + movw r1, #3196 + add r0, r2, r3, asl #1 + add r3, r3, #1 + strh r4, [r0, r1] @ movhi + movw r1, #3194 + strh r3, [r2, r1] @ movhi +.L351: + mov r0, #0 + ldmfd sp!, {r3, r4, r5, r6, r7, pc} +.L354: + .align 2 +.L353: + .word .LANCHOR0 + .word .LC75 + .word .LANCHOR0+3194 + .fnend + .size FtlGcMarkBadPhyBlk, .-FtlGcMarkBadPhyBlk + .align 2 + .global FtlGcReFreshBadBlk + .type FtlGcReFreshBadBlk, %function +FtlGcReFreshBadBlk: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, lr} + .save {r3, r4, r5, lr} + movw r2, #3194 + ldr r3, .L358 + ldrh r2, [r3, r2] + cmp r2, #0 + beq .L356 + movw r1, #3190 + ldrh r0, [r3, r1] + movw r1, #65535 + cmp r0, r1 + bne .L356 + movw r4, #3230 + ldr r5, .L358 + ldrh r1, [r3, r4] + cmp r1, r2 + movcs r2, #0 + strcsh r2, [r3, r4] @ movhi + ldrh r2, [r5, r4] + movw r3, #3196 + add r2, r5, r2, asl #1 + ldrh r0, [r2, r3] + bl P2V_block_in_plane + bl FtlGcRefreshBlock + ldrh r3, [r5, r4] + add r3, r3, #1 + strh r3, [r5, r4] @ movhi +.L356: + mov r0, #0 + ldmfd sp!, {r3, r4, r5, pc} +.L359: + .align 2 +.L358: + .word .LANCHOR0 + .fnend + .size FtlGcReFreshBadBlk, .-FtlGcReFreshBadBlk + .align 2 + .global FlashReadPages + .type FlashReadPages, %function +FlashReadPages: + .fnstart + @ args = 0, pretend = 0, frame = 8 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r0, r1, r2, r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r0, r1, r2, r4, r5, r6, r7, r8, r9, sl, fp, lr} + mov r9, r1 + ldr sl, .L367 + mov r4, r0 + mov r5, #0 + ldr r6, .L367+4 + ldrh r3, [sl, #12] + str r3, [sp, #4] + b .L361 +.L366: + ldr r3, [r4, #8] + cmp r3, #0 + beq .L362 + ldr r3, [r4, #12] + cmp r3, #0 + bne .L363 +.L362: + ldr r0, .L367+8 + mov r2, #45 + ldr r1, .L367+12 + bl printk +.L363: + ldrh r7, [sl, #8] + ldr fp, [r4, #4] + mov r7, r7, lsr #1 + ubfx r8, fp, #10, #16 + mov fp, fp, asl #22 + mov r1, r7 + mov r0, r8 + bl __aeabi_uidiv + ldrh r3, [sl, #10] + mov fp, fp, lsr #22 + ldr ip, [r6, #12] + ldr r2, [r4, #8] + mov r3, r3, asl #1 + uxth r0, r0 + mls r8, r7, r0, r8 + uxtb r7, r0 + mov r0, r7 + mla r8, r8, r3, fp + ldr r3, [r4, #12] + mov r1, r8 + blx ip + ldr r2, [r4, #8] + ldr r3, [r4, #12] + ldr lr, [sp, #4] + add r2, r2, #2048 + add r3, r3, #8 + add r1, r8, lr + str r0, [r4, #0] + mov r0, r7 + ldr ip, [r6, #12] + blx ip + cmn r0, #1 + beq .L364 + ldr r3, [r4, #12] + ldr r2, [r3, #12] + cmn r2, #1 + bne .L365 + ldr r2, [r3, #8] + cmn r2, #1 + bne .L365 + ldr r3, [r3, #0] + cmn r3, #1 + beq .L365 +.L364: + mvn r3, #0 + str r3, [r4, #0] +.L365: + add r5, r5, #1 + add r4, r4, #20 +.L361: + cmp r5, r9 + bne .L366 + mov r0, #0 + ldmfd sp!, {r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, pc} +.L368: + .align 2 +.L367: + .word g_nand_phy_info + .word g_nand_ops + .word .LC1 + .word .LANCHOR1+156 + .fnend + .size FlashReadPages, .-FlashReadPages + .align 2 + .global FtlGetLastWrittenPage + .type FtlGetLastWrittenPage, %function +FtlGetLastWrittenPage: + .fnstart + @ args = 0, pretend = 0, frame = 88 + @ frame_needed = 0, uses_anonymous_args = 0 + ldr r3, .L380 + cmp r1, #1 + stmfd sp!, {r4, r5, r6, r7, r8, sl, lr} + .save {r4, r5, r6, r7, r8, sl, lr} + .pad #92 + sub sp, sp, #92 + ldreqh r4, [r3, #74] + add r7, sp, #4 + ldrneh r4, [r3, #72] + mov r5, r1 + ldr r3, .L380+4 + mov sl, r0, asl #10 + sub r4, r4, #1 + mov r0, r7 + mov r1, #1 + mov r2, r5 + uxth r4, r4 + str r3, [sp, #12] + add r3, sp, #24 + str r3, [sp, #16] + sxth r3, r4 + orr r3, r3, sl + str r3, [sp, #8] + bl FlashReadPages + ldr r3, [sp, #24] + cmn r3, #1 + bne .L373 + b .L379 +.L376: + add r6, r6, r3 + mov r0, r7 + mov r1, #1 + mov r2, r5 + add r6, r6, r6, lsr #31 + ubfx r6, r6, #1, #16 + sxth r3, r6 + orr r3, r3, sl + str r3, [sp, #8] + bl FlashReadPages + ldr r3, [sp, #24] + cmn r3, #1 + bne .L374 + ldr r3, [sp, #28] + cmn r3, #1 + subeq r4, r6, #1 + uxtheq r4, r4 + beq .L378 +.L374: + add r6, r6, #1 + uxth r8, r6 + b .L378 +.L379: + mov r8, #0 +.L378: + sxth r6, r8 + sxth r3, r4 + cmp r6, r3 + ble .L376 +.L373: + sxth r0, r4 + add sp, sp, #92 + ldmfd sp!, {r4, r5, r6, r7, r8, sl, pc} +.L381: + .align 2 +.L380: + .word .LANCHOR0 + .word .LANCHOR0+3232 + .fnend + .size FtlGetLastWrittenPage, .-FtlGetLastWrittenPage + .align 2 + .global FtlLoadFactoryBbt + .type FtlLoadFactoryBbt, %function +FtlLoadFactoryBbt: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + .save {r4, r5, r6, r7, r8, r9, sl, lr} + mov r5, #0 + ldr r8, .L389 + ldr r6, .L389+4 + ldr sl, [r8, #-836] + add r7, r6, #136 + ldr r3, [r6, #2240] + str sl, [r8, #-844] + str r3, [r8, #-848] + b .L383 +.L388: + ldrh r4, [r6, #68] + mvn r3, #0 + movw r9, #61664 + strh r3, [r7], #2 @ movhi + add r4, r4, r3 + uxth r4, r4 + b .L384 +.L387: + mla r3, r3, r5, r4 + mov r1, #1 + ldr r0, .L389+8 + mov r2, r1 + mov r3, r3, asl #10 + str r3, [r8, #-852] + bl FlashReadPages + ldr r3, [r8, #-856] + cmn r3, #1 + beq .L385 + ldrh r3, [sl, #0] + cmp r3, r9 + streqh r4, [r7, #-2] @ movhi + beq .L386 +.L385: + sub r4, r4, #1 + uxth r4, r4 +.L384: + ldrh r3, [r6, #68] + sub r2, r3, #16 + cmp r4, r2 + bgt .L387 +.L386: + add r5, r5, #1 +.L383: + ldrh r3, [r6, #26] + cmp r5, r3 + bcc .L388 + mov r0, #0 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, pc} +.L390: + .align 2 +.L389: + .word .LANCHOR3 + .word .LANCHOR0 + .word .LANCHOR3-856 + .fnend + .size FtlLoadFactoryBbt, .-FtlLoadFactoryBbt + .align 2 + .global FlashProgPages + .type FlashProgPages, %function +FlashProgPages: + .fnstart + @ args = 0, pretend = 0, frame = 40 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r4, r5, r6, r7, r8, r9, sl, fp, lr} + .pad #44 + sub sp, sp, #44 + ldr r9, .L404 + mov r4, r0 + str r1, [sp, #0] + mov r5, r0 + str r2, [sp, #8] + mov r6, #0 + ldrh r1, [r9, #12] + str r3, [sp, #12] + ldr r7, .L404+4 + str r1, [sp, #4] + b .L392 +.L397: + ldr r3, [r5, #8] + cmp r3, #0 + beq .L393 + ldr r3, [r5, #12] + cmp r3, #0 + bne .L394 +.L393: + ldr r0, .L404+8 + mov r2, #73 + ldr r1, .L404+12 + bl printk +.L394: + ldrh r8, [r9, #8] + add r6, r6, #1 + ldr fp, [r5, #4] + mov r8, r8, lsr #1 + ubfx sl, fp, #10, #16 + mov fp, fp, asl #22 + mov r1, r8 + mov r0, sl + bl __aeabi_uidiv + ldrh r3, [r9, #10] + mov fp, fp, lsr #22 + ldr r2, [r5, #8] + ldr ip, [r7, #8] + mov r3, r3, asl #1 + uxth r0, r0 + mls sl, r8, r0, sl + uxtb r8, r0 + mov r0, r8 + mla sl, sl, r3, fp + ldr r3, [r5, #12] + mov r1, sl + blx ip + ldr lr, .L404+4 + ldr r2, [r5, #8] + add r2, r2, #2048 + cmp r0, #0 + str r0, [r5, #0] + mov r0, r8 + mvnne r3, #0 + strne r3, [r5, #0] + ldr r3, [r5, #12] + ldr ip, [lr, #8] + ldr lr, [sp, #4] + add r3, r3, #8 + add r1, sl, lr + blx ip + cmp r0, #0 + mvnne r3, #0 + strne r3, [r5, #0] + add r5, r5, #20 +.L392: + ldr r1, [sp, #0] + cmp r6, r1 + bne .L397 + ldr r3, [sp, #12] + cmp r3, #0 + beq .L398 + ldr r5, .L404+16 + mov r6, #0 + sub r7, r5, #832 + b .L399 +.L403: + mov r3, #0 + str r3, [r5, #-832] + str r3, [r5, #3264] + add r0, sp, #20 + ldr r3, [r4, #4] + mov r1, #1 + ldr r2, [sp, #8] + str r7, [sp, #28] + str r3, [sp, #24] + ldr r3, .L404+20 + str r3, [sp, #32] + bl FlashReadPages + ldr r8, [sp, #20] + cmn r8, #1 + bne .L400 + ldr r0, .L404+24 + ldr r1, [r4, #4] + bl printk + str r8, [r4, #0] +.L400: + ldr r3, [r4, #12] + cmp r3, #0 + beq .L401 + ldr r2, [r3, #0] + ldr r3, [r5, #3264] + cmp r2, r3 + beq .L401 + ldr r0, .L404+28 + ldr r1, [r4, #4] + bl printk + mvn r3, #0 + str r3, [r4, #0] +.L401: + ldr r3, [r4, #8] + cmp r3, #0 + beq .L402 + ldr r2, [r3, #0] + ldr r3, [r5, #-832] + cmp r2, r3 + beq .L402 + ldr r0, .L404+32 + ldr r1, [r4, #4] + bl printk + mvn r3, #0 + str r3, [r4, #0] +.L402: + add r6, r6, #1 + add r4, r4, #20 +.L399: + ldr r1, [sp, #0] + cmp r6, r1 + bne .L403 +.L398: + mov r0, #0 + add sp, sp, #44 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} +.L405: + .align 2 +.L404: + .word g_nand_phy_info + .word g_nand_ops + .word .LC1 + .word .LANCHOR1+171 + .word .LANCHOR3 + .word .LANCHOR3+3264 + .word .LC76 + .word .LC77 + .word .LC78 + .fnend + .size FlashProgPages, .-FlashProgPages + .align 2 + .global FlashEraseBlocks + .type FlashEraseBlocks, %function +FlashEraseBlocks: + .fnstart + @ args = 0, pretend = 0, frame = 8 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r0, r1, r2, r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r0, r1, r2, r4, r5, r6, r7, r8, r9, sl, fp, lr} + mov r4, r0 + ldr r7, .L411 + mov r5, #0 + str r2, [sp, #4] + ldr r6, .L411+4 + ldrh r2, [r7, #12] + mov fp, r6 + str r2, [sp, #0] + b .L407 +.L410: + ldrh sl, [r7, #8] + add r5, r5, #1 + ldr r9, [r4, #4] + mov sl, sl, lsr #1 + ubfx r8, r9, #10, #16 + mov r9, r9, asl #22 + mov r1, sl + mov r0, r8 + bl __aeabi_uidiv + ldrh r3, [r7, #10] + mov r9, r9, lsr #22 + mov r3, r3, asl #1 + uxth r0, r0 + mls r8, sl, r0, r8 + uxtb sl, r0 + mov r0, sl + mla r8, r8, r3, r9 + ldr r3, [r6, #4] + mov r1, r8 + blx r3 + ldr r2, [sp, #0] + add r1, r8, r2 + cmp r0, #0 + str r0, [r4, #0] + mov r0, sl + mvnne r3, #0 + strne r3, [r4, #0] + ldr r3, [fp, #4] + blx r3 + cmp r0, #0 + mvnne r3, #0 + strne r3, [r4, #0] + add r4, r4, #20 +.L407: + ldr r3, [sp, #4] + cmp r5, r3 + bne .L410 + mov r0, #0 + ldmfd sp!, {r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, pc} +.L412: + .align 2 +.L411: + .word g_nand_phy_info + .word g_nand_ops + .fnend + .size FlashEraseBlocks, .-FlashEraseBlocks + .align 2 + .global FtlFreeSysBlkQueueIn + .type FtlFreeSysBlkQueueIn, %function +FtlFreeSysBlkQueueIn: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, lr} + .save {r4, r5, r6, lr} + mov r5, r0 + ldr r4, .L416 + ldrh r3, [r4, #190] + cmp r3, #1024 + ldmeqfd sp!, {r4, r5, r6, pc} + cmp r1, #0 + beq .L415 + bl P2V_block_in_plane + ldr r3, .L416+4 + mov r1, #1 + mov r2, r1 + mov r6, r0 + ldr r0, [r3, #3776] + mov r3, r5, asl #10 + mov r6, r6, asl #1 + str r3, [r0, #4] + bl FlashEraseBlocks + ldr r3, [r4, #2244] + ldrh r2, [r3, r6] + add r2, r2, #1 + strh r2, [r3, r6] @ movhi + ldr r3, [r4, #2496] + add r3, r3, #1 + str r3, [r4, #2496] +.L415: + ldr r3, .L416 + ldrh r2, [r3, #190] + add r2, r2, #1 + strh r2, [r3, #190] @ movhi + ldrh r2, [r3, #188] + add r1, r3, r2, asl #1 + add r2, r2, #1 + bic r2, r2, #64512 + strh r5, [r1, #192] @ movhi + strh r2, [r3, #188] @ movhi + ldmfd sp!, {r4, r5, r6, pc} +.L417: + .align 2 +.L416: + .word .LANCHOR0 + .word .LANCHOR3 + .fnend + .size FtlFreeSysBlkQueueIn, .-FtlFreeSysBlkQueueIn + .align 2 + .global FtlLowFormatEraseBlock + .type FtlLowFormatEraseBlock, %function +FtlLowFormatEraseBlock: + .fnstart + @ args = 0, pretend = 0, frame = 16 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r4, r5, r6, r7, r8, r9, sl, fp, lr} + mov r7, #0 + ldr r8, .L446 + .pad #20 + sub sp, sp, #20 + mov sl, r0 + mov r6, r1 + mov r4, r7 + mov r5, r7 + str r0, [r8, #3780] + mov fp, #20 + ldr r9, .L446+4 + b .L419 +.L423: + mul r3, fp, r7 + ldr r2, [r8, #3776] + mov r1, #0 + str r1, [r2, r3] + add r3, r9, r7 + mov r1, sl + ldrb r0, [r3, #30] @ zero_extendqisi2 + bl V2P_block + cmp r6, #0 + str r0, [sp, #4] + beq .L420 + bl IsBlkInVendorPart + cmp r0, #0 + bne .L421 +.L420: + ldr r0, [sp, #4] + bl FtlBbmIsBadBlock + cmp r0, #0 + addne r5, r5, #1 + uxthne r5, r5 + bne .L421 + ldr r3, [r8, #3776] + ldr r1, [sp, #4] + mla r3, fp, r4, r3 + mov r2, r1, asl #10 + str r2, [r3, #4] + ldr r2, [r8, #3784] + str r2, [r3, #8] + ldrh r2, [r9, #84] + mul r2, r2, r4 + add r4, r4, #1 + uxth r4, r4 + add r1, r2, #3 + cmp r2, #0 + movlt r2, r1 + ldr r1, [r8, #3788] + bic r2, r2, #3 + add r2, r1, r2 + str r2, [r3, #12] +.L421: + add r7, r7, #1 + uxth r7, r7 +.L419: + ldrh r3, [r9, #4] + cmp r3, r7 + bhi .L423 + cmp r4, #0 + beq .L425 + ldr r7, .L446 + mov r1, #0 + mov r2, r4 + mov r8, #0 + mov r9, r8 + ldr r0, [r7, #3776] + bl FlashEraseBlocks +.L427: + ldr r3, [r7, #3776] + add r2, r3, r8 + ldr r3, [r3, r8] + cmn r3, #1 + bne .L426 + ldr r0, [r2, #4] + add r5, r5, #1 + ubfx r0, r0, #10, #16 + uxth r5, r5 + bl FtlBbmMapBadBlock +.L426: + add r9, r9, #1 + add r8, r8, #20 + uxth r9, r9 + cmp r9, r4 + bne .L427 +.L428: + cmp r6, #0 + mov r8, #0 + mov r7, r6 + streq r6, [sp, #4] + ldrne r3, .L446+4 + moveq r9, #1 + moveq r1, #6 + streq r1, [sp, #8] + ldrneh r9, [r3, #74] + movne r3, #1 + strne r3, [sp, #4] + movne r2, r9, lsr #2 + strne r2, [sp, #8] +.L436: + mov r6, #0 + ldr fp, .L446 + mov r4, r6 + b .L429 +.L432: + mov r1, #20 + ldr r2, [fp, #3776] + mul r3, r1, r6 + mov r1, #0 + str r1, [r2, r3] + mov r1, sl + ldr r2, .L446+4 + add r3, r2, r6 + ldrb r0, [r3, #30] @ zero_extendqisi2 + bl V2P_block + cmp r7, #0 + str r0, [sp, #12] + beq .L430 + bl IsBlkInVendorPart + cmp r0, #0 + bne .L431 +.L430: + ldr r0, [sp, #12] + bl FtlBbmIsBadBlock + cmp r0, #0 + bne .L431 + ldr r3, [fp, #3776] + mov r1, #20 + mla r3, r1, r4, r3 + ldr r1, [sp, #12] + add r2, r8, r1, asl #10 + ldr r1, .L446+4 + str r2, [r3, #4] + ldr r2, [fp, #3792] + str r2, [r3, #8] + ldrh r2, [r1, #84] + mul r2, r2, r4 + add r4, r4, #1 + uxth r4, r4 + add r1, r2, #3 + cmp r2, #0 + movlt r2, r1 + ldr r1, [fp, #3784] + bic r2, r2, #3 + add r2, r1, r2 + str r2, [r3, #12] +.L431: + add r6, r6, #1 + uxth r6, r6 +.L429: + ldr r2, .L446+4 + ldrh r3, [r2, #4] + cmp r3, r6 + bhi .L432 + cmp r4, #0 + beq .L425 + ldr r6, .L446 + mov r1, r4 + ldr r2, [sp, #4] + mov r3, #1 + mov fp, #0 + ldr r0, [r6, #3776] + bl FlashProgPages + mov ip, r7 + mov r7, r4 + mov r4, fp +.L435: + ldr r2, [r6, #3776] + add r1, r2, fp + ldr r2, [r2, fp] + cmp r2, #0 + beq .L434 + ldr r0, [r1, #4] + add r5, r5, #1 + str ip, [sp, #0] + ubfx r0, r0, #10, #16 + uxth r5, r5 + bl FtlBbmMapBadBlock + ldr ip, [sp, #0] +.L434: + add r4, r4, #1 + add fp, fp, #20 + uxth r4, r4 + cmp r4, r7 + bne .L435 + ldr r3, [sp, #8] + mov r4, r7 + mov r7, ip + add r8, r8, r3 + uxth r8, r8 + cmp r8, r9 + bcc .L436 + ldr r9, .L446 + mov r7, #0 + mov r6, ip + mov r8, r7 +.L438: + cmp r6, #0 + beq .L437 + ldr r3, [r9, #3776] + add r2, r3, r7 + ldr r3, [r3, r7] + cmp r3, #0 + bne .L437 + ldr r0, [r2, #4] + mov r1, #1 + ubfx r0, r0, #10, #16 + bl FtlFreeSysBlkQueueIn +.L437: + add r8, r8, #1 + add r7, r7, #20 + uxth r8, r8 + cmp r8, r4 + bne .L438 + cmp sl, #63 + movhi sl, #0 + movls sl, #1 + cmp r6, #0 + moveq r6, sl + orrne r6, sl, #1 + cmp r6, #0 + beq .L425 + ldr r3, .L446 + mov r2, r8 + ldr r1, [sp, #4] + ldr r0, [r3, #3776] + bl FlashEraseBlocks +.L425: + mov r0, r5 + add sp, sp, #20 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} +.L447: + .align 2 +.L446: + .word .LANCHOR3 + .word .LANCHOR0 + .fnend + .size FtlLowFormatEraseBlock, .-FtlLowFormatEraseBlock + .align 2 + .global ftl_memset + .type ftl_memset, %function +ftl_memset: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + cmp r2, #0 + stmfd sp!, {r4, lr} + .save {r4, lr} + mov r4, r0 + beq .L449 + bl memset +.L449: + mov r0, r4 + ldmfd sp!, {r4, pc} + .fnend + .size ftl_memset, .-ftl_memset + .align 2 + .global FlashGetBadBlockList + .type FlashGetBadBlockList, %function +FlashGetBadBlockList: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, lr} + .save {r3, r4, r5, lr} + mov r2, #256 + mov r5, r1 + mov r1, #255 + mov r4, r0 + bl ftl_memset + ldr r3, .L454 + mov r0, r4 + mov r1, r5 + ldr r3, [r3, #0] + blx r3 + uxth r3, r0 + cmp r3, #50 + bls .L451 + mov r0, r4 + mov r1, #255 + mov r2, #256 + bl ftl_memset + mov r3, #0 +.L451: + mov r0, #0 + b .L452 +.L453: + add r0, r0, #1 + ldrh r2, [r4, #0] + uxth r0, r0 + mov r2, r2, lsr #1 + strh r2, [r4], #2 @ movhi +.L452: + cmp r0, r3 + bne .L453 + ldmfd sp!, {r3, r4, r5, pc} +.L455: + .align 2 +.L454: + .word g_nand_ops + .fnend + .size FlashGetBadBlockList, .-FlashGetBadBlockList + .align 2 + .global FlashTestBlk + .type FlashTestBlk, %function +FlashTestBlk: + .fnstart + @ args = 0, pretend = 0, frame = 88 + @ frame_needed = 0, uses_anonymous_args = 0 + cmp r0, #11 + stmfd sp!, {r4, r5, lr} + .save {r4, r5, lr} + mov r4, r0 + .pad #92 + sub sp, sp, #92 + movls r4, #0 + bls .L457 +.L458: + ldr r5, .L461 + add r0, sp, #24 + mov r1, #165 + mov r2, #32 + str r0, [sp, #16] + mov r4, r4, asl #10 + str r5, [sp, #12] + bl ftl_memset + mov r1, #90 + mov r2, #8 + mov r0, r5 + bl ftl_memset + mov r1, #1 + mov r2, r1 + add r0, sp, #4 + str r4, [sp, #8] + bl FlashEraseBlocks + mov r1, #1 + add r0, sp, #4 + mov r2, r1 + mov r3, r1 + bl FlashProgPages + ldr r4, [sp, #4] + add r0, sp, #4 + mov r1, #0 + cmp r4, #0 + mov r2, #1 + mvnne r4, #0 + bl FlashEraseBlocks +.L457: + mov r0, r4 + add sp, sp, #92 + ldmfd sp!, {r4, r5, pc} +.L462: + .align 2 +.L461: + .word .LANCHOR0+3232 + .fnend + .size FlashTestBlk, .-FlashTestBlk + .align 2 + .global FtlGcPageVarInit + .type FtlGcPageVarInit, %function +FtlGcPageVarInit: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, lr} + .save {r4, lr} + movw r2, #3176 + ldr r4, .L464 + mov r3, #0 + mov r1, #255 + strh r3, [r4, r2] @ movhi + add r2, r2, #12 + ldr r0, [r4, #3180] + strh r3, [r4, r2] @ movhi + ldrh r2, [r4, #76] + mov r2, r2, asl #1 + bl ftl_memset + ldrh r3, [r4, #76] + mov r2, #12 + ldr r0, [r4, #3184] + mov r1, #255 + mul r2, r2, r3 + bl ftl_memset + ldmfd sp!, {r4, lr} + b FtlGcBufInit +.L465: + .align 2 +.L464: + .word .LANCHOR0 + .fnend + .size FtlGcPageVarInit, .-FtlGcPageVarInit + .align 2 + .global FtlGcScanTempBlk + .type FtlGcScanTempBlk, %function +FtlGcScanTempBlk: + .fnstart + @ args = 0, pretend = 0, frame = 24 + @ frame_needed = 0, uses_anonymous_args = 0 + ldr r3, .L487 + stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r4, r5, r6, r7, r8, r9, sl, fp, lr} + .pad #28 + sub sp, sp, #28 + ldrh r4, [r3, #4] + movw r3, #65535 + mov r5, r0 + str r1, [sp, #12] + cmp r4, r3 + beq .L483 + cmp r4, #0 + bne .L467 + b .L468 +.L483: + mov r4, #0 +.L467: + ldr r3, .L487+4 + ldr fp, [sp, #12] + ldrh r3, [r3, #72] + cmp fp, r3 + bne .L469 +.L468: + bl FtlGcPageVarInit +.L469: + mov r7, #0 + movw r9, #65535 +.L478: + ldrh r3, [r5, #0] + mov r1, #0 + strb r1, [r5, #8] + cmp r3, r9 + beq .L484 +.L471: + mov sl, r5 +.L485: + ldr r3, .L487+4 + ldr r2, .L487+8 + ldrh r8, [r3, #4] + ldr r6, [r2, #3796] + ldr lr, [r3, #3160] + ldr r2, [r3, #3164] + ldrh ip, [r3, #82] + ldrh r3, [r3, #84] + str r2, [sp, #16] + mov r2, sl + str r3, [sp, #20] + mov r3, #0 + mov r5, r3 + b .L472 +.L474: + ldrh r0, [r2, #16] + cmp r0, r9 + beq .L473 + mov fp, #20 + orr r0, r4, r0, asl #10 + mla r1, fp, r5, r6 + str r0, [r1, #4] + mul r0, ip, r5 + add fp, r0, #3 + cmp r0, #0 + movlt r0, fp + ldr fp, [sp, #20] + bic r0, r0, #3 + add r0, lr, r0 + str r0, [r1, #8] + mul r0, fp, r5 + add r5, r5, #1 + uxth r5, r5 + add fp, r0, #3 + cmp r0, #0 + movlt r0, fp + ldr fp, [sp, #16] + bic r0, r0, #3 + add r0, fp, r0 + str r0, [r1, #12] +.L473: + add r3, r3, #1 + add r2, r2, #2 + uxth r3, r3 +.L472: + cmp r3, r8 + bne .L474 + ldr r8, .L487+8 + mov r1, r5 + mov r2, #0 + mov r6, #0 + mov fp, r6 + ldr r0, [r8, #3796] + bl FlashReadPages + b .L475 +.L479: + ldr r2, .L487+8 + ldr r1, [r2, #3796] + add r3, r1, r6 + ldr r8, [r3, #4] + stmib sp, {r1, r3} + ubfx r0, r8, #10, #16 + bl P2V_plane + ldr r1, [sp, #4] + ldr r3, [sp, #8] + ldr r1, [r1, r6] + cmp r1, #0 + mov r2, r0 + bne .L476 + ldr r3, [r3, #12] + add r6, r6, #20 + ldrh r1, [r3, #0] + cmp r1, r9 + ldreq r3, .L487+8 + moveq r1, #1 + moveq r5, sl + streq r1, [r3, #3800] + beq .L470 +.L477: + add fp, fp, #1 + ldr r0, [r3, #12] + mov r1, r8 + ldr r2, [r3, #8] + bl FtlGcUpdatePage + uxth fp, fp + b .L475 +.L476: + ldr r2, .L487+4 + mov fp, #0 @ movhi + ldrh r3, [sl, #0] + mov r5, sl + mov r4, #0 + ldr r2, [r2, #2256] + mov r3, r3, asl #1 + strh fp, [r2, r3] @ movhi + ldrh r0, [sl, #0] + bl INSERT_FREE_LIST + mvn r3, #0 + strh r3, [sl, #0] @ movhi + bl FtlGcPageVarInit + b .L478 +.L475: + cmp fp, r5 + bne .L479 + ldr r3, [sp, #12] + add r7, r7, #1 + add r4, r4, #1 + cmp r7, r3 + ldr r3, .L487+4 + uxth r4, r4 + bcc .L480 + ldr r2, .L487 + ldrh r1, [r2, #4] + cmp r1, r9 + beq .L480 + add r1, r1, r7 + strh r1, [r2, #4] @ movhi + ldrh r2, [r3, #72] + cmp r2, r4 + bhi .L481 +.L480: + ldrh r3, [r3, #72] + cmp r3, r4 + bhi .L485 + mov r5, sl +.L484: + mov r2, #0 +.L470: + ldr r3, .L487 + mvn r1, #0 + strh r4, [r5, #2] @ movhi + mov r0, r5 + strb r2, [r5, #6] + strh r1, [r3, #4] @ movhi + mov r1, r4 + bl ftl_sb_update_avl_pages +.L481: + mvn r0, #0 + add sp, sp, #28 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} +.L488: + .align 2 +.L487: + .word .LANCHOR2 + .word .LANCHOR0 + .word .LANCHOR3 + .fnend + .size FtlGcScanTempBlk, .-FtlGcScanTempBlk + .align 2 + .global SupperBlkListInit + .type SupperBlkListInit, %function +SupperBlkListInit: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + .save {r4, r5, r6, r7, r8, r9, sl, lr} + mov r2, #6 + ldr r4, .L499 + mov r1, #0 + mov r7, #0 + mov r8, r7 + mov r5, r7 + ldrh r3, [r4, #14] + mov r9, r4 + ldr r0, [r4, #2248] + mul r2, r2, r3 + bl ftl_memset + movw r3, #2264 + strh r7, [r4, r3] @ movhi + mov r3, #2272 + str r7, [r4, #2268] + str r7, [r4, #2252] + str r7, [r4, #2260] + strh r7, [r4, r3] @ movhi + b .L490 +.L492: + add r3, r4, sl + mov r1, r5 + add sl, sl, #1 + ldrb r0, [r3, #30] @ zero_extendqisi2 + bl V2P_block + uxth sl, sl + bl FtlBbmIsBadBlock + cmp r0, #0 + ldreqh r3, [r4, #72] + addeq r6, r6, r3 + uxtheq r6, r6 + b .L496 +.L498: + mov r6, #0 + mov sl, r6 +.L496: + ldrh r3, [r4, #4] + cmp r3, sl + bhi .L492 + cmp r6, #0 + beq .L493 + mov r1, r6 + mov r0, #32768 + bl __aeabi_idiv + uxth r6, r0 +.L493: + ldr r3, [r9, #2248] + mov r2, #6 + mla r3, r2, r5, r3 + strh r6, [r3, #4] @ movhi + movw r3, #2276 + ldrh r3, [r9, r3] + cmp r3, r5 + beq .L494 + movw r3, #2324 + ldrh r3, [r4, r3] + cmp r3, r5 + beq .L494 + movw r3, #2372 + ldrh r3, [r4, r3] + cmp r3, r5 + beq .L494 + ldr r2, [r4, #2256] + mov r3, r5, asl #1 + ldrh r3, [r2, r3] + cmp r3, #0 + bne .L495 + add r7, r7, #1 + mov r0, r5 + uxth r7, r7 + bl INSERT_FREE_LIST + b .L494 +.L495: + add r8, r8, #1 + mov r0, r5 + uxth r8, r8 + bl INSERT_DATA_LIST +.L494: + add r5, r5, #1 + uxth r5, r5 +.L490: + ldrh r3, [r4, #12] + ldr r2, .L499 + cmp r5, r3 + bcc .L498 + movw r1, #2264 + strh r8, [r2, r1] @ movhi + mov r1, #2272 + strh r7, [r2, r1] @ movhi + add r7, r8, r7 + cmp r7, r3 + ble .L497 + ldr r0, .L499+4 + movw r2, #2108 + ldr r1, .L499+8 + bl printk +.L497: + mov r0, #0 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, pc} +.L500: + .align 2 +.L499: + .word .LANCHOR0 + .word .LC1 + .word .LANCHOR1+186 + .fnend + .size SupperBlkListInit, .-SupperBlkListInit + .align 2 + .global FtlL2PDataInit + .type FtlL2PDataInit, %function +FtlL2PDataInit: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, r6, r7, lr} + .save {r3, r4, r5, r6, r7, lr} + mov r1, #0 + ldr r4, .L504 + mov r6, #12 + ldr r5, .L504+4 + ldr r2, [r4, #100] + ldr r0, [r5, #3804] + mov r2, r2, asl #1 + bl ftl_memset + ldrh r3, [r4, #82] + ldrh r2, [r4, #110] + mov r1, #255 + ldr r0, [r5, #3808] + mul r2, r2, r3 + bl ftl_memset + mov r3, #0 + mov ip, r3 + mvn r0, #0 + b .L502 +.L503: + mul r2, r6, r3 + ldr r1, [r4, #2420] + add r7, r1, r2 + str ip, [r7, #4] + strh r0, [r1, r2] @ movhi + ldr r1, [r4, #2420] + ldr r7, [r5, #3808] + add r2, r1, r2 + ldrh r1, [r4, #82] + mul r1, r3, r1 + add r3, r3, #1 + uxth r3, r3 + bic r1, r1, #3 + add r1, r7, r1 + str r1, [r2, #8] +.L502: + ldrh r1, [r4, #110] + ldr r2, .L504 + cmp r1, r3 + bhi .L503 + ldr r3, .L504+4 + movw r0, #3814 + mvn r1, #0 + strh r1, [r3, r0] @ movhi + movw r0, #3812 + strh r1, [r3, r0] @ movhi + movw r1, #3822 + ldr r0, [r2, #100] + strh r0, [r3, r1] @ movhi + movw r1, #3816 + ldr r0, .L504+8 + strh r0, [r3, r1] @ movhi + add r1, r1, #36 + ldrh r0, [r3, r1] + movw r1, #3820 + strh r0, [r3, r1] @ movhi + ldrh r1, [r2, #108] + movw r2, #3818 + strh r1, [r3, r2] @ movhi + ldr r2, [r3, #3856] + str r2, [r3, #3824] + ldr r2, [r3, #3860] + str r2, [r3, #3828] + ldr r2, [r3, #3804] + str r2, [r3, #3832] + ldr r2, [r3, #3864] + str r2, [r3, #3836] + ldmfd sp!, {r3, r4, r5, r6, r7, pc} +.L505: + .align 2 +.L504: + .word .LANCHOR0 + .word .LANCHOR3 + .word -3902 + .fnend + .size FtlL2PDataInit, .-FtlL2PDataInit + .align 2 + .global FtlScanSysBlk + .type FtlScanSysBlk, %function +FtlScanSysBlk: + .fnstart + @ args = 0, pretend = 0, frame = 24 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r4, r5, r6, r7, r8, r9, sl, fp, lr} + movw r3, #3852 + ldr r5, .L565 + mov r6, #0 + ldr r4, .L565+4 + .pad #28 + sub sp, sp, #28 + mov r1, r6 + ldr r2, [r5, #100] + strh r6, [r4, r3] @ movhi + mov r9, r4 + strh r6, [r5, #116] @ movhi + mov r2, r2, asl #2 + ldr r0, [r4, #3860] + bl ftl_memset + ldr r2, [r5, #100] + mov r1, r6 + ldr r0, [r4, #3856] + mov r2, r2, asl #1 + bl ftl_memset + ldrh r2, [r5, #92] + mov r1, r6 + ldr r0, [r4, #3868] + mov r2, r2, asl #2 + bl ftl_memset + ldrh r2, [r5, #92] + ldr r0, [r5, #120] + mov r1, r6 + mov r2, r2, asl #1 + bl ftl_memset + add r0, r5, #2560 + mov r1, #255 + mov r2, #12 + bl ftl_memset + ldrh r5, [r5, #12] + str r5, [sp, #8] + b .L507 +.L509: + add r3, r5, r6 + ldr r1, [sp, #8] + ldrb r0, [r3, #30] @ zero_extendqisi2 + bl V2P_block + mov r8, r0 + bl FtlBbmIsBadBlock + cmp r0, #0 + bne .L508 + ldr r3, [r4, #3796] + mov r8, r8, asl #10 + ldr r2, [r5, #3160] + mla r3, r7, sl, r3 + str r2, [r3, #8] + ldrh r2, [r5, #84] + str r8, [r3, #4] + mul r2, r2, sl + add sl, sl, #1 + uxth sl, sl + add r1, r2, #3 + cmp r2, #0 + movlt r2, r1 + ldr r1, [r5, #3164] + bic r2, r2, #3 + add r2, r1, r2 + str r2, [r3, #12] +.L508: + add r6, r6, #1 + uxth r6, r6 + b .L543 +.L557: + mov sl, #0 + mov r7, #20 + mov r6, sl +.L543: + ldrh r3, [r5, #4] + cmp r3, r6 + bhi .L509 + cmp sl, #0 + beq .L510 + ldr r0, [r4, #3796] + mov r1, sl + mov r2, #1 + mov r6, #0 + bl FlashReadPages + str r6, [sp, #12] + str sl, [sp, #20] +.L542: + ldr r3, [r4, #3796] + add r2, r3, r6 + ldr r3, [r3, r6] + ldr r7, [r2, #4] + cmn r3, #1 + ldr r5, [r2, #12] + ubfx r7, r7, #10, #16 + bne .L511 + mov r8, #16 +.L513: + ldr r0, [r4, #3796] + mov r1, #1 + mov r2, r1 + add r0, r0, r6 + ldr r3, [r0, #4] + add r3, r3, #1 + str r3, [r0, #4] + bl FlashReadPages + ldrh r3, [r5, #0] + movw r0, #65535 + cmp r3, r0 + ldreq r3, [r9, #3796] + mvneq r2, #0 + streq r2, [r3, r6] + beq .L511 +.L512: + ldr r3, [r4, #3796] + ldr r3, [r3, r6] + cmn r3, #1 + bne .L511 + sub r8, r8, #1 + uxth r8, r8 + cmp r8, #0 + bne .L513 +.L511: + ldr r3, [r4, #3796] + ldr r3, [r3, r6] + cmn r3, #1 + beq .L514 + ldr r2, .L565 + ldr r3, [r5, #4] + ldr r1, [r2, #2476] + cmn r1, #1 + beq .L515 + cmp r1, r3 + bhi .L516 +.L515: + cmn r3, #1 + addne r3, r3, #1 + strne r3, [r2, #2476] +.L516: + ldrh r3, [r5, #0] + movw r1, #61604 + cmp r3, r1 + beq .L519 + bhi .L522 + movw r2, #61574 + cmp r3, r2 + bne .L517 + b .L563 +.L522: + movw r2, #61634 + cmp r3, r2 + beq .L520 + movw r2, #65535 + cmp r3, r2 + bne .L517 + b .L564 +.L520: + ldr r8, .L565 + movw r3, #3852 + ldrh r2, [r4, r3] + ldr r3, [r8, #100] + cmp r2, r3 + bls .L523 + ldr r0, .L565+8 + movw r2, #1163 + ldr r1, .L565+12 + bl printk +.L523: + ldr r0, [r8, #100] + movw r2, #3852 + ldrh r1, [r4, r2] + mov sl, r7 + ldr ip, [r4, #3860] + mov r8, r6 + uxth fp, r0 + sub r3, fp, #1 + rsb fp, r1, fp + sub fp, fp, #1 + uxth r3, r3 + sxth fp, fp + b .L524 +.L530: + mov r6, r2, asl #2 + ldr r7, [r5, #4] + str r6, [sp, #16] + ldr r6, [ip, r2, asl #2] + cmp r7, r6 + bls .L525 + ldr ip, [ip, #0] + mov r7, sl + mov r6, r8 + cmp ip, #0 + bne .L526 + cmp r1, r0 + addne r1, r1, #1 + movwne r0, #3852 + strneh r1, [r4, r0] @ movhi +.L526: + mov r0, #0 + sxth sl, r3 + b .L527 +.L528: + ldr r8, [r4, #3860] + add ip, r1, #1 + add r0, r0, #1 + ldr fp, [r8, ip, asl #2] + mov ip, ip, asl #1 + uxth r0, r0 + str fp, [r8, r1, asl #2] + mov r1, r1, asl #1 + ldr r8, [r4, #3856] + ldrh ip, [r8, ip] + strh ip, [r8, r1] @ movhi +.L527: + sxth r1, r0 + cmp r1, sl + bne .L528 + ldr r1, [r9, #3860] + mov r2, r2, asl #1 + ldr r0, [r5, #4] + ldr ip, [sp, #16] + str r0, [r1, ip] + ldr r1, [r9, #3856] + strh r7, [r1, r2] @ movhi + b .L529 +.L525: + sub r3, r3, #1 + uxth r3, r3 +.L524: + sxth r2, r3 + cmp r2, fp + bgt .L530 + mov r7, sl + mov r6, r8 +.L529: + sxth r3, r3 + cmp r3, #0 + blt .L517 + ldr r0, .L565 + movw r2, #3852 + ldrh r1, [r4, r2] + ldr r0, [r0, #100] + rsb r0, r1, r0 + sub r0, r0, #1 + sxth r0, r0 + cmp r3, r0 + bgt .L517 + add r1, r1, #1 + strh r1, [r4, r2] @ movhi + ldr r2, [r4, #3860] + ldr r1, [r5, #4] + str r1, [r2, r3, asl #2] + mov r3, r3, asl #1 + ldr r2, [r4, #3856] + b .L541 +.L563: + ldr r8, .L565 + ldrh r2, [r8, #116] + ldrh r3, [r8, #92] + cmp r2, r3 + bls .L531 + ldr r0, .L565+8 + movw r2, #1204 + ldr r1, .L565+12 + bl printk +.L531: + ldrh r0, [r8, #92] + mov sl, r7 + ldrh r1, [r8, #116] + mov r8, r6 + sub fp, r0, #1 + ldr ip, [r4, #3868] + uxth r3, fp + rsb fp, r1, fp + b .L532 +.L538: + mov r6, r2, asl #2 + ldr r7, [r5, #4] + str r6, [sp, #16] + ldr r6, [ip, r2, asl #2] + cmp r7, r6 + bls .L533 + ldr ip, [ip, #0] + mov r7, sl + mov r6, r8 + cmp ip, #0 + bne .L534 + cmp r1, r0 + addne r1, r1, #1 + ldrne r0, .L565 + strneh r1, [r0, #116] @ movhi +.L534: + mov r0, #0 + sxth fp, r3 + ldr sl, .L565 + mov r8, r3 + str r2, [sp, #4] + b .L535 +.L536: + ldr ip, [r4, #3868] + add r1, r3, #1 + add r0, r0, #1 + ldr r2, [ip, r1, asl #2] + mov r1, r1, asl #1 + uxth r0, r0 + str r2, [ip, r3, asl #2] + mov r3, r3, asl #1 + ldr ip, [sl, #120] + ldrh r1, [ip, r1] + strh r1, [ip, r3] @ movhi +.L535: + sxth r3, r0 + cmp r3, fp + bne .L536 + ldr r1, [r9, #3868] + mov r3, r8 + ldr r0, [r5, #4] + ldr ip, [sp, #16] + ldr r2, [sp, #4] + str r0, [r1, ip] + ldr r1, .L565 + mov r2, r2, asl #1 + ldr r1, [r1, #120] + strh r7, [r1, r2] @ movhi + b .L537 +.L533: + sub r3, r3, #1 + uxth r3, r3 +.L532: + sxth r2, r3 + cmp r2, fp + bgt .L538 + mov r7, sl + mov r6, r8 +.L537: + sxth r3, r3 + cmp r3, #0 + blt .L517 + ldr r2, .L565 + ldrh r0, [r2, #92] + ldrh r1, [r2, #116] + sub r0, r0, #1 + rsb r0, r1, r0 + sxth r0, r0 + cmp r3, r0 + bgt .L517 + add r1, r1, #1 + ldr r0, [r5, #4] + strh r1, [r2, #116] @ movhi + ldr r1, [r4, #3868] + str r0, [r1, r3, asl #2] + mov r3, r3, asl #1 + ldr r2, [r2, #120] + b .L541 +.L519: + mov r1, #2560 + movw r0, #65535 + ldrh r2, [r2, r1] + ldr r3, .L565 + cmp r2, r0 + beq .L562 +.L539: + movw r2, #2564 + ldrh r0, [r3, r2] + movw r2, #65535 + cmp r0, r2 + beq .L540 + mov r1, #1 + bl FtlFreeSysBlkQueueIn +.L540: + ldr r3, .L565 + ldr r2, [r5, #4] + ldr r1, [r3, #2568] + cmp r1, r2 + movw r2, #2564 + bcs .L541 + mov r1, #2560 + ldrh r0, [r3, r1] + strh r0, [r3, r2] @ movhi +.L562: + ldr r2, [r5, #4] + strh r7, [r3, r1] @ movhi + str r2, [r3, #2568] + b .L517 +.L541: + strh r7, [r3, r2] @ movhi + b .L517 +.L564: + mov r0, r7 + mov r1, #0 + b .L561 +.L514: + mov r0, r7 + mov r1, #1 +.L561: + bl FtlFreeSysBlkQueueIn +.L517: + ldr ip, [sp, #12] + add r6, r6, #20 + add r3, ip, #1 + ldr ip, [sp, #20] + uxth r3, r3 + str r3, [sp, #12] + cmp r3, ip + bne .L542 +.L510: + ldr r6, [sp, #8] + add r3, r6, #1 + uxth r3, r3 + str r3, [sp, #8] +.L507: + ldr r5, .L565 + ldr ip, [sp, #8] + ldrh r3, [r5, #14] + cmp r3, ip + bhi .L557 + ldr r1, .L565+4 + ldr r2, [r1, #3856] + ldrh r3, [r2, #0] + cmp r3, #0 + bne .L544 + movw r0, #3852 + ldrh r1, [r1, r0] + cmp r1, #0 + ldrne r0, [r5, #100] + bne .L545 + b .L544 +.L549: + mov r1, r1, asl #1 + ldrh r1, [r2, r1] + cmp r1, #0 + beq .L546 + ldr r7, .L565 + sxth r6, r3 + ldr r1, .L565+4 + mov r5, #0 + b .L547 +.L548: + ldr ip, [r1, #3856] + mov r0, r2, asl #1 + rsb r4, r6, r2 + add r3, r3, #1 + ldrh sl, [ip, r0] + mov r8, r4, asl #1 + uxth r3, r3 + strh sl, [ip, r8] @ movhi + ldr ip, [r1, #3860] + ldr r2, [ip, r2, asl #2] + str r2, [ip, r4, asl #2] + ldr r2, [r1, #3856] + strh r5, [r2, r0] @ movhi +.L547: + ldr r0, [r7, #100] + sxth r2, r3 + cmp r2, r0 + bcc .L548 + b .L544 +.L546: + add r3, r3, #1 + uxth r3, r3 +.L545: + sxth r1, r3 + cmp r1, r0 + bcc .L549 +.L544: + ldr r2, .L565 + ldr r1, [r2, #120] + ldrh r3, [r1, #0] + cmp r3, #0 + bne .L550 + ldrh r0, [r2, #116] + cmp r0, #0 + ldrneh r2, [r2, #92] + bne .L551 + b .L550 +.L555: + mov ip, r0, asl #1 + ldrh ip, [r1, ip] + cmp ip, #0 + beq .L552 + ldr r1, .L565 + mov r6, #0 + ldr r7, .L565+4 + b .L553 +.L554: + ldr r4, [r1, #120] + mov ip, r2, asl #1 + rsb r5, r0, r2 + add r3, r3, #1 + ldrh sl, [r4, ip] + mov r8, r5, asl #1 + uxth r3, r3 + strh sl, [r4, r8] @ movhi + ldr r4, [r7, #3868] + ldr r2, [r4, r2, asl #2] + str r2, [r4, r5, asl #2] + ldr r2, [r1, #120] + strh r6, [r2, ip] @ movhi +.L553: + ldrh ip, [r1, #92] + sxth r2, r3 + cmp r2, ip + blt .L554 + b .L550 +.L552: + add r3, r3, #1 + uxth r3, r3 +.L551: + sxth r0, r3 + cmp r0, r2 + blt .L555 +.L550: + ldr r2, .L565+4 + movw r3, #3852 + ldrh r2, [r2, r3] + ldr r3, .L565 + ldr r3, [r3, #100] + cmp r2, r3 + bls .L556 + ldr r0, .L565+8 + movw r2, #1329 + ldr r1, .L565+12 + bl printk +.L556: + mov r0, #0 + add sp, sp, #28 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} +.L566: + .align 2 +.L565: + .word .LANCHOR0 + .word .LANCHOR3 + .word .LC1 + .word .LANCHOR1+204 + .fnend + .size FtlScanSysBlk, .-FtlScanSysBlk + .align 2 + .global ftl_free_no_use_map_blk + .type ftl_free_no_use_map_blk, %function +ftl_free_no_use_map_blk: + .fnstart + @ args = 0, pretend = 0, frame = 8 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r0, r1, r2, r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r0, r1, r2, r4, r5, r6, r7, r8, r9, sl, fp, lr} + mov r4, r0 + ldrh r2, [r0, #10] + mov r1, #0 + ldr r5, [r0, #20] + ldr r6, [r0, #12] + ldr r7, [r0, #24] + mov r2, r2, asl #1 + mov r0, r5 + bl ftl_memset + mov r3, #0 + b .L568 +.L572: + ldr r0, [r7, r3, asl #2] + mov r2, #0 + ubfx r0, r0, #10, #16 + b .L569 +.L571: + mov r1, r2, asl #1 + add r2, r2, #1 + ldrh ip, [r6, r1] + uxth r2, r2 + cmp ip, r0 + ldreqh ip, [r5, r1] + addeq ip, ip, #1 + streqh ip, [r5, r1] @ movhi +.L569: + ldrh r1, [r4, #10] + cmp r1, r2 + bhi .L571 + add r3, r3, #1 + uxth r3, r3 +.L568: + ldrh r2, [r4, #6] + cmp r2, r3 + bhi .L572 + mov sl, #0 + ldrh fp, [r5, #0] + mov r7, sl + ldr r3, .L578 + b .L573 +.L577: + ldrh r2, [r4, #0] + cmp r2, r7 + bne .L574 + ldrh r1, [r4, #2] + ldrh r2, [r3, #74] + cmp r1, r2 + movcc r1, r7, asl #1 + strcch r2, [r5, r1] @ movhi +.L574: + mov r9, r7, asl #1 + ldrh r8, [r5, r9] + cmp fp, r8 + movhi sl, r7 + movhi fp, r8 + cmp r8, #0 + bne .L576 + ldrh r0, [r6, r9] + cmp r0, #0 + beq .L576 + mov r1, #1 + str r3, [sp, #4] + bl FtlFreeSysBlkQueueIn + strh r8, [r6, r9] @ movhi + ldr r3, [sp, #4] + ldrh r2, [r4, #8] + sub r2, r2, #1 + strh r2, [r4, #8] @ movhi +.L576: + add r7, r7, #1 + uxth r7, r7 +.L573: + ldrh r2, [r4, #10] + cmp r2, r7 + bhi .L577 + mov r0, sl + ldmfd sp!, {r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, pc} +.L579: + .align 2 +.L578: + .word .LANCHOR0 + .fnend + .size ftl_free_no_use_map_blk, .-ftl_free_no_use_map_blk + .align 2 + .global Ftl_write_map_blk_to_last_page + .type Ftl_write_map_blk_to_last_page, %function +Ftl_write_map_blk_to_last_page: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, r6, r7, lr} + .save {r3, r4, r5, r6, r7, lr} + movw r2, #65535 + ldrh r3, [r0, #0] + mov r4, r0 + ldr r5, [r0, #12] + cmp r3, r2 + ldr r7, [r0, #24] + bne .L581 + ldrh r3, [r0, #8] + cmp r3, #0 + beq .L582 + ldr r0, .L587 + mov r2, #592 + ldr r1, .L587+4 + bl printk +.L582: + ldrh r3, [r4, #8] + add r3, r3, #1 + strh r3, [r4, #8] @ movhi + bl FtlFreeSysBlkQueueOut + mov r3, #0 + strh r0, [r5, #0] @ movhi + strh r3, [r4, #2] @ movhi + strh r3, [r4, #0] @ movhi + ldr r3, [r4, #28] + add r3, r3, #1 + str r3, [r4, #28] + b .L583 +.L581: + mov r3, r3, asl #1 + ldr r2, .L587+8 + mov r1, #255 + ldrh r6, [r5, r3] + ldr r5, .L587+12 + ldrh r3, [r0, #2] + orr r3, r3, r6, asl #10 + str r3, [r2, #-852] + ldr r3, [r5, #2240] + str r3, [r2, #-848] + ldr r3, [r2, #-836] + str r3, [r2, #-844] + ldr r2, [r0, #28] + str r2, [r3, #4] + ldr r2, .L587+16 + strh r2, [r3, #8] @ movhi + ldrh r2, [r0, #4] + strh r6, [r3, #2] @ movhi + strh r2, [r3, #0] @ movhi + ldrh r2, [r5, #74] + ldr r0, [r5, #2240] + mov r2, r2, asl #3 + bl ftl_memset + mov r2, #0 + mov r3, r2 + b .L584 +.L586: + ldr r1, [r7, r3, asl #2] + cmp r6, r1, lsr #10 + bne .L585 + add r2, r2, #1 + ldr r1, [r5, #2240] + uxth r2, r2 + str r3, [r1, r2, asl #3] + ldr r1, [r5, #2240] + ldr r0, [r7, r3, asl #2] + add r1, r1, r2, asl #3 + str r0, [r1, #4] +.L585: + add r3, r3, #1 + uxth r3, r3 +.L584: + ldrh r1, [r4, #6] + cmp r1, r3 + bhi .L586 + mov r1, #1 + mov r3, #0 + ldr r0, .L587+20 + mov r2, r1 + bl FlashProgPages + ldrh r3, [r4, #2] + mov r0, r4 + add r3, r3, #1 + strh r3, [r4, #2] @ movhi + bl ftl_map_blk_gc +.L583: + mov r0, #0 + ldmfd sp!, {r3, r4, r5, r6, r7, pc} +.L588: + .align 2 +.L587: + .word .LC1 + .word .LANCHOR1+218 + .word .LANCHOR3 + .word .LANCHOR0 + .word -1291 + .word .LANCHOR3-856 + .fnend + .size Ftl_write_map_blk_to_last_page, .-Ftl_write_map_blk_to_last_page + .align 2 + .global FtlMapWritePage + .type FtlMapWritePage, %function +FtlMapWritePage: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r3, r4, r5, r6, r7, r8, r9, sl, fp, lr} + mov r4, r0 + ldr r7, .L605 + mov r9, r1 + ldr r5, .L605+4 + mov fp, r2 + mov r6, #0 +.L603: + ldr r3, [r7, #2460] + add r3, r3, #1 + str r3, [r7, #2460] + ldrh r3, [r7, #74] + ldrh r2, [r4, #2] + sub r3, r3, #1 + cmp r2, r3 + bge .L591 + ldrh r3, [r4, #0] + movw r2, #65535 + cmp r3, r2 + bne .L592 +.L591: + mov r0, r4 + bl Ftl_write_map_blk_to_last_page +.L592: + ldrh r3, [r4, #0] + ldr r2, [r4, #12] + mov r3, r3, asl #1 + ldrh r3, [r2, r3] + cmp r3, #0 + bne .L593 + ldr r0, .L605+8 + movw r2, #650 + ldr r1, .L605+12 + bl printk +.L593: + ldrh r2, [r4, #0] + ldrh r3, [r4, #10] + cmp r2, r3 + bcc .L594 + ldr r0, .L605+8 + movw r2, #651 + ldr r1, .L605+12 + bl printk +.L594: + ldrh r3, [r4, #0] + mov r1, #0 + ldr r2, [r4, #12] + ldr r0, [r5, #-836] + mov r3, r3, asl #1 + ldr r8, .L605+4 + ldrh sl, [r2, r3] + mov r2, #16 + ldrh r3, [r4, #2] + str fp, [r5, #-848] + orr r3, r3, sl, asl #10 + str r0, [r5, #-844] + str r3, [r5, #-852] + bl ftl_memset + ldr r3, [r5, #-844] + mov r1, #1 + ldr r2, [r4, #28] + sub r0, r8, #856 + strh r9, [r3, #8] @ movhi + str r2, [r3, #4] + ldrh r2, [r4, #4] + strh sl, [r3, #2] @ movhi + strh r2, [r3, #0] @ movhi + mov r2, r1 + mov r3, r1 + bl FlashProgPages + ldrh r3, [r4, #2] + add r3, r3, #1 + uxth r3, r3 + strh r3, [r4, #2] @ movhi + ldr r2, [r5, #-856] + cmn r2, #1 + bne .L595 + ldr r0, .L605+16 + add r6, r6, #1 + ldr r1, [r5, #-852] + bl printk + ldrh r3, [r4, #2] + uxth r6, r6 + cmp r3, #2 + ldrlsh r3, [r7, #74] + subls r3, r3, #1 + strlsh r3, [r4, #2] @ movhi + cmp r6, #3 + bls .L597 + ldr r3, .L605+4 + mov r2, r6 + ldr r0, .L605+20 + ldr r1, [r3, #-852] + bl printk +.L598: + b .L598 +.L597: + ldr r3, [r4, #32] + cmp r3, #0 + beq .L603 +.L604: + b .L604 +.L595: + cmp r3, #1 + beq .L603 + ldr r2, [r8, #-852] + mov r0, #0 + ldr r3, [r4, #24] + str r2, [r3, r9, asl #2] + ldmfd sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, pc} +.L606: + .align 2 +.L605: + .word .LANCHOR0 + .word .LANCHOR3 + .word .LC1 + .word .LANCHOR1+249 + .word .LC79 + .word .LC80 + .fnend + .size FtlMapWritePage, .-FtlMapWritePage + .align 2 + .global ftl_map_blk_gc + .type ftl_map_blk_gc, %function +ftl_map_blk_gc: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r3, r4, r5, r6, r7, r8, r9, sl, fp, lr} + mov r4, r0 + ldr r5, [r0, #12] + ldr r8, [r0, #24] + bl ftl_free_no_use_map_blk + ldrh r3, [r4, #10] + ldrh r2, [r4, #8] + sub r3, r3, #4 + cmp r2, r3 + blt .L608 + uxth r0, r0 + mov r0, r0, asl #1 + ldrh r7, [r5, r0] + cmp r7, #0 + beq .L608 + ldr r3, [r4, #32] + cmp r3, #0 + bne .L608 + mov r2, #1 + str r2, [r4, #32] + strh r3, [r5, r0] @ movhi + ldrh r3, [r4, #8] + ldrh r2, [r4, #2] + sub r3, r3, #1 + strh r3, [r4, #8] @ movhi + ldr r3, .L616 + ldrh r3, [r3, #74] + cmp r2, r3 + bcc .L609 + mov r0, r4 + bl ftl_map_blk_alloc_new_blk +.L609: + ldr r6, .L616+4 + mov r5, #0 + mov r9, r6 + b .L610 +.L614: + ldr r3, [r8, r5, asl #2] + mov fp, r5, asl #2 + cmp r7, r3, lsr #10 + bne .L611 + ldr r3, [r6, #3872] + mov r1, #1 + ldr sl, [r6, #-836] + mov r2, r1 + ldr r0, .L616+8 + str r3, [r6, #-848] + str sl, [r6, #-844] + ldr r3, [r8, r5, asl #2] + str r3, [r6, #-852] + bl FlashReadPages + ldrh r3, [sl, #8] + cmp r3, r5 + beq .L612 + ldr r0, .L616+12 + mov r2, #564 + ldr r1, .L616+16 + bl printk +.L612: + ldr r3, [r9, #-856] + cmn r3, #1 + moveq r3, #0 + streq r3, [r8, fp] + beq .L611 + mov r0, r4 + mov r1, r5 + ldr r2, [r6, #-848] + bl FtlMapWritePage +.L611: + add r5, r5, #1 + uxth r5, r5 +.L610: + ldrh r3, [r4, #6] + cmp r3, r5 + bhi .L614 + mov r0, r7 + mov r1, #1 + bl FtlFreeSysBlkQueueIn + mov r3, #0 + str r3, [r4, #32] +.L608: + ldr r3, .L616 + ldrh r2, [r4, #2] + ldrh r3, [r3, #74] + cmp r2, r3 + bcc .L615 + mov r0, r4 + bl ftl_map_blk_alloc_new_blk +.L615: + mov r0, #0 + ldmfd sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, pc} +.L617: + .align 2 +.L616: + .word .LANCHOR0 + .word .LANCHOR3 + .word .LANCHOR3-856 + .word .LC1 + .word .LANCHOR1+265 + .fnend + .size ftl_map_blk_gc, .-ftl_map_blk_gc + .align 2 + .global FtlMapTblRecovery + .type FtlMapTblRecovery, %function +FtlMapTblRecovery: + .fnstart + @ args = 0, pretend = 0, frame = 24 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r4, r5, r6, r7, r8, r9, sl, fp, lr} + .pad #28 + sub sp, sp, #28 + ldr r3, [r0, #16] + mov r4, r0 + ldrh r8, [r0, #6] + mov r1, #0 + ldr r9, [r0, #24] + str r3, [sp, #16] + ldrh r3, [r0, #8] + mov r2, r8, asl #2 + ldr fp, [r0, #12] + mov r0, r9 + ldr r6, .L638 + str r3, [sp, #8] + bl ftl_memset + ldr r3, .L638+4 + ldr r2, [r6, #2240] + ldr r5, [r3, #-836] + str r2, [r3, #-848] + mov r2, #1 + str r2, [r4, #36] + str r5, [r3, #-844] + mvn r3, #0 + strh r3, [r4, #0] @ movhi + strh r3, [r4, #2] @ movhi + mov r3, #0 + str r3, [r4, #32] + str r3, [r4, #28] + str r3, [sp, #4] + ldr r3, [sp, #8] + sub r3, r3, #1 + str r3, [sp, #12] + b .L619 +.L632: + ldr r1, [sp, #12] + cmp r3, r1 + bne .L620 + mov r3, r1, asl #1 + mov r1, #1 + add r2, fp, r3 + str r2, [sp, #8] + ldrh r0, [fp, r3] + mov r7, #0 + bl FtlGetLastWrittenPage + ldr r1, [sp, #12] + ldr r2, [sp, #16] + ldr r6, .L638+4 + uxth r0, r0 + add r3, r0, #1 + strh r3, [r4, #2] @ movhi + ldr r3, [sp, #4] + sxth sl, r0 + add sl, sl, #1 + strh r3, [r4, #0] @ movhi + ldr r3, [r2, r1, asl #2] + str r3, [r4, #28] + b .L621 +.L623: + ldr r1, [sp, #8] + ldr r0, .L638+8 + ldrh r2, [r1, #0] + mov r1, #1 + orr r3, r3, r2, asl #10 + mov r2, r1 + str r3, [r6, #-852] + bl FlashReadPages + ldr r3, [r6, #-856] + cmn r3, #1 + beq .L622 + ldrh r3, [r5, #8] + cmp r3, r8 + bcs .L622 + ldrh r2, [r4, #4] + ldrh r1, [r5, #0] + cmp r1, r2 + ldreq r2, [r6, #-852] + streq r2, [r9, r3, asl #2] +.L622: + add r7, r7, #1 + uxth r7, r7 +.L621: + sxth r3, r7 + cmp r3, sl + blt .L623 + b .L624 +.L620: + ldr r7, .L638+4 + mov r3, r3, asl #1 + ldr r2, [r6, #2240] + mov r1, #1 + sub r0, r7, #856 + str r2, [r7, #-848] + add r2, fp, r3 + str r2, [sp, #20] + ldrh r2, [fp, r3] + ldrh r3, [r6, #74] + sub r3, r3, #1 + orr r3, r3, r2, asl #10 + mov r2, r1 + str r3, [r7, #-852] + bl FlashReadPages + ldr r3, [r7, #-856] + cmn r3, #1 + beq .L635 + ldrh r2, [r5, #0] + ldrh r3, [r4, #4] + cmp r2, r3 + bne .L635 + ldrh r2, [r5, #8] + movw r3, #64245 + cmp r2, r3 + bne .L635 + b .L636 +.L628: + ldr r1, [r6, #2240] + mov r0, r2, asl #3 + add r3, r3, #1 + ldr r2, [r1, r2, asl #3] + uxth r3, r3 + uxth r2, r2 + cmp r2, r8 + addcc r1, r1, r0 + ldrcc r1, [r1, #4] + strcc r1, [r9, r2, asl #2] + b .L626 +.L636: + mov r3, #0 +.L626: + ldrh r1, [r6, #74] + sxth r2, r3 + sub r1, r1, #1 + cmp r2, r1 + blt .L628 + b .L629 +.L631: + ldr r1, [sp, #20] + ldr r0, .L638+8 + ldrh r2, [r1, #0] + mov r1, #1 + orr r3, r3, r2, asl #10 + mov r2, r1 + str r3, [sl, #-852] + bl FlashReadPages + ldr r3, [sl, #-856] + cmn r3, #1 + beq .L630 + ldrh r3, [r5, #8] + cmp r3, r8 + bcs .L630 + ldrh r2, [r4, #4] + ldrh r1, [r5, #0] + cmp r1, r2 + ldreq r2, [sl, #-852] + streq r2, [r9, r3, asl #2] +.L630: + add r7, r7, #1 + uxth r7, r7 + b .L637 +.L635: + ldr sl, .L638+4 + mov r7, #0 +.L637: + ldrh r2, [r6, #74] + sxth r3, r7 + cmp r3, r2 + blt .L631 +.L629: + ldr r2, [sp, #4] + add r3, r2, #1 + uxth r3, r3 + str r3, [sp, #4] +.L619: + ldr r1, [sp, #4] + ldr r2, [sp, #8] + sxth r3, r1 + cmp r3, r2 + blt .L632 +.L624: + mov r0, r4 + bl ftl_free_no_use_map_blk + ldr r3, .L638 + ldrh r2, [r4, #2] + ldrh r3, [r3, #74] + cmp r2, r3 + bne .L633 + mov r0, r4 + bl ftl_map_blk_alloc_new_blk +.L633: + mov r0, r4 + bl ftl_map_blk_gc + mov r0, r4 + bl ftl_map_blk_gc + mov r0, #0 + add sp, sp, #28 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} +.L639: + .align 2 +.L638: + .word .LANCHOR0 + .word .LANCHOR3 + .word .LANCHOR3-856 + .fnend + .size FtlMapTblRecovery, .-FtlMapTblRecovery + .align 2 + .global FtlLoadMapInfo + .type FtlLoadMapInfo, %function +FtlLoadMapInfo: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, lr} + .save {r3, lr} + bl FtlL2PDataInit + ldr r0, .L641 + bl FtlMapTblRecovery + mov r0, #0 + ldmfd sp!, {r3, pc} +.L642: + .align 2 +.L641: + .word .LANCHOR3+3812 + .fnend + .size FtlLoadMapInfo, .-FtlLoadMapInfo + .align 2 + .global FtlLoadVonderInfo + .type FtlLoadVonderInfo, %function +FtlLoadVonderInfo: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + ldr r2, .L644 + movw r1, #3886 + stmfd sp!, {r3, lr} + .save {r3, lr} + ldr r3, .L644+4 + ldrh r0, [r2, #92] + strh r0, [r3, r1] @ movhi + movw r1, #3880 + ldr r0, .L644+8 + strh r0, [r3, r1] @ movhi + add r1, r1, #4 + ldrh r0, [r2, #116] + strh r0, [r3, r1] @ movhi + movw r1, #3882 + ldrh r0, [r2, #94] + ldr r2, [r2, #120] + strh r0, [r3, r1] @ movhi + str r2, [r3, #3888] + ldr r2, [r3, #3868] + ldr r0, .L644+12 + str r2, [r3, #3892] + ldr r2, [r3, #3916] + str r2, [r3, #3896] + ldr r2, [r3, #3920] + str r2, [r3, #3900] + bl FtlMapTblRecovery + mov r0, #0 + ldmfd sp!, {r3, pc} +.L645: + .align 2 +.L644: + .word .LANCHOR0 + .word .LANCHOR3 + .word -3962 + .word .LANCHOR3+3876 + .fnend + .size FtlLoadVonderInfo, .-FtlLoadVonderInfo + .align 2 + .global flush_l2p_region + .type flush_l2p_region, %function +flush_l2p_region: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, lr} + .save {r3, r4, r5, lr} + mov r4, #12 + ldr r5, .L647 + mul r4, r4, r0 + ldr r0, .L647+4 + ldr r2, [r5, #2420] + add r3, r2, r4 + ldrh r1, [r2, r4] + ldr r2, [r3, #8] + bl FtlMapWritePage + ldr r3, [r5, #2420] + mov r0, #0 + add r4, r3, r4 + ldr r3, [r4, #4] + bic r3, r3, #-2147483648 + str r3, [r4, #4] + ldmfd sp!, {r3, r4, r5, pc} +.L648: + .align 2 +.L647: + .word .LANCHOR0 + .word .LANCHOR3+3812 + .fnend + .size flush_l2p_region, .-flush_l2p_region + .align 2 + .global FtlMapBlkWriteDump_data + .type FtlMapBlkWriteDump_data, %function +FtlMapBlkWriteDump_data: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, lr} + .save {r4, r5, r6, lr} + mov r4, r0 + ldr r2, [r0, #36] + ldrh r6, [r0, #6] + cmp r2, #0 + ldr r3, [r0, #24] + ldmeqfd sp!, {r4, r5, r6, pc} + ldr r5, .L653 + sub r6, r6, #1 + mov r2, #0 + str r2, [r0, #36] + uxth r6, r6 + ldr r0, [r5, #3872] + ldr r2, [r5, #-836] + str r0, [r5, #-848] + str r2, [r5, #-844] + ldr r3, [r3, r6, asl #2] + cmp r3, #0 + str r3, [r5, #-852] + beq .L651 + mov r1, #1 + sub r0, r5, #856 + mov r2, r1 + bl FlashReadPages + b .L652 +.L651: + ldr r3, .L653+4 + mov r1, #255 + ldrh r2, [r3, #82] + bl ftl_memset +.L652: + mov r0, r4 + mov r1, r6 + ldr r2, [r5, #-848] + ldmfd sp!, {r4, r5, r6, lr} + b FtlMapWritePage +.L654: + .align 2 +.L653: + .word .LANCHOR3 + .word .LANCHOR0 + .fnend + .size FtlMapBlkWriteDump_data, .-FtlMapBlkWriteDump_data + .align 2 + .global load_l2p_region + .type load_l2p_region, %function +load_l2p_region: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, r6, r7, r8, sl, lr} + .save {r3, r4, r5, r6, r7, r8, sl, lr} + mov r5, r0 + ldr r3, .L661 + mov r7, r1 + ldrh r3, [r3, #108] + cmp r3, r0 + bcs .L656 + ldr r0, .L661+4 + movw r2, #446 + ldr r1, .L661+8 + bl printk +.L656: + ldr r4, .L661+12 + mov r8, #12 + ldr r6, .L661 + ldr r3, [r4, #3864] + ldr sl, [r3, r5, asl #2] + cmp sl, #0 + bne .L657 + mul r8, r8, r7 + ldr r3, [r6, #2420] + mov r1, #255 + ldrh r2, [r6, #82] + add r3, r3, r8 + ldr r0, [r3, #8] + bl ftl_memset + ldr r3, [r6, #2420] + strh r5, [r3, r8] @ movhi + ldr r3, [r6, #2420] + add r8, r3, r8 + str sl, [r8, #4] + b .L658 +.L657: + mul r8, r8, r7 + ldr r3, [r6, #2420] + mov r1, #1 + sub r0, r4, #856 + mov r2, r1 + str sl, [r4, #-852] + add r3, r3, r8 + ldr r3, [r3, #8] + str r3, [r4, #-848] + ldr r3, [r4, #-836] + str r3, [r4, #-844] + bl FlashReadPages + ldr r7, [r4, #-844] + ldrh r3, [r7, #8] + cmp r3, r5 + beq .L659 + mov r1, r5 + mov r2, sl + ldr r0, .L661+16 + bl printk + mov r2, #4 + mov r3, r2 + ldr r0, .L661+20 + ldr r1, [r4, #-844] + bl rknand_print_hex + ldr r0, .L661+24 + ldr r1, [r4, #3864] + mov r2, #4 + ldrh r3, [r6, #108] + bl rknand_print_hex +.L659: + ldrh r3, [r7, #8] + cmp r3, r5 + beq .L660 + ldr r0, .L661+4 + movw r2, #467 + ldr r1, .L661+8 + bl printk +.L660: + ldr r3, .L661 + mov r1, #0 + ldr r3, [r3, #2420] + add r2, r3, r8 + str r1, [r2, #4] + strh r5, [r3, r8] @ movhi +.L658: + mov r0, #0 + ldmfd sp!, {r3, r4, r5, r6, r7, r8, sl, pc} +.L662: + .align 2 +.L661: + .word .LANCHOR0 + .word .LC1 + .word .LANCHOR1+280 + .word .LANCHOR3 + .word .LC81 + .word .LC82 + .word .LC83 + .fnend + .size load_l2p_region, .-load_l2p_region + .align 2 + .global log2phys + .type log2phys, %function +log2phys: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, r7, r8, lr} + .save {r4, r5, r6, r7, r8, lr} + mvn r3, #0 + ldr r7, .L673 + mov r6, r1 + mov r8, r2 + ldrh r5, [r7, #80] + add r5, r5, #7 + mov r4, r0, lsr r5 + bic r5, r0, r3, asl r5 + ldr r3, [r7, #2440] + uxth r4, r4 + cmp r0, r3 + uxth r5, r5 + bcc .L664 + ldr r0, .L673+4 + movw r2, #759 + ldr r1, .L673+8 + bl printk +.L664: + mov r3, #0 + ldrh r1, [r7, #110] + ldr r2, [r7, #2420] + mov r7, r3 + b .L665 +.L671: + add r3, r3, #12 + add r0, r2, r3 + ldrh r0, [r0, #-12] + cmp r0, r4 + bne .L666 +.L667: + cmp r8, #0 + ldr r3, .L673 + mov r2, #12 + bne .L668 + ldr r3, [r3, #2420] + mla r2, r2, r7, r3 + ldr r3, [r2, #8] + ldr r3, [r3, r5, asl #2] + str r3, [r6, #0] + b .L669 +.L668: + mul r2, r2, r7 + ldr r1, [r3, #2420] + ldr r0, [r6, #0] + add r1, r1, r2 + ldr r1, [r1, #8] + str r0, [r1, r5, asl #2] + ldr r1, [r3, #2420] + add r2, r1, r2 + ldr r1, [r2, #4] + orr r1, r1, #-2147483648 + str r1, [r2, #4] + movw r2, #2424 + strh r4, [r3, r2] @ movhi +.L669: + ldr r3, .L673 + mov r2, #12 + mov r0, #0 + ldr r3, [r3, #2420] + mla r7, r2, r7, r3 + ldr r3, [r7, #4] + cmn r3, #1 + addne r3, r3, #1 + strne r3, [r7, #4] + ldmfd sp!, {r4, r5, r6, r7, r8, pc} +.L666: + add r7, r7, #1 + uxth r7, r7 +.L665: + cmp r7, r1 + bne .L671 + bl select_l2p_ram_region + mov r3, #12 + ldr r2, .L673 + ldr r2, [r2, #2420] + mul r3, r3, r0 + mov r7, r0 + add r1, r2, r3 + ldrh r2, [r2, r3] + movw r3, #65535 + cmp r2, r3 + beq .L672 + ldr r3, [r1, #4] + cmp r3, #0 + bge .L672 + bl flush_l2p_region +.L672: + mov r0, r4 + mov r1, r7 + bl load_l2p_region + b .L667 +.L674: + .align 2 +.L673: + .word .LANCHOR0 + .word .LC1 + .word .LANCHOR1+296 + .fnend + .size log2phys, .-log2phys + .align 2 + .type FtlReadRefresh.part.10, %function +FtlReadRefresh.part.10: + .fnstart + @ args = 0, pretend = 0, frame = 88 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, lr} + .save {r4, r5, lr} + .pad #92 + sub sp, sp, #92 + ldr r4, .L680 + mov r5, #2048 +.L678: + ldr r0, [r4, #2708] + ldr r3, [r4, #2440] + cmp r0, r3 + bcs .L676 + mov r2, #0 + mov r1, sp + bl log2phys + ldr r2, [sp, #0] + ldr r3, [r4, #2708] + cmn r2, #1 + add r3, r3, #1 + str r3, [r4, #2708] + beq .L677 + str r3, [sp, #20] + add r0, sp, #88 + ldr r3, .L680+4 + mov r1, #1 + str r2, [sp, #8] + mov r2, #0 + str r2, [r0, #-84]! + str r3, [sp, #12] + add r3, sp, #24 + str r3, [sp, #16] + bl FlashReadPages + ldr r3, [sp, #4] + cmp r3, #256 + bne .L676 + ldr r0, [sp, #0] + ubfx r0, r0, #10, #16 + bl P2V_block_in_plane + bl FtlGcRefreshBlock + b .L676 +.L677: + subs r5, r5, #1 + bne .L678 +.L676: + mvn r0, #0 + add sp, sp, #92 + ldmfd sp!, {r4, r5, pc} +.L681: + .align 2 +.L680: + .word .LANCHOR0 + .word .LANCHOR0+3232 + .fnend + .size FtlReadRefresh.part.10, .-FtlReadRefresh.part.10 + .align 2 + .global FtlReadRefresh + .type FtlReadRefresh, %function +FtlReadRefresh: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + ldr r2, .L688 + stmfd sp!, {r4, lr} + .save {r4, lr} + ldr r3, [r2, #2704] + cmp r3, #0 + mov r3, r2 + beq .L683 + ldr r1, [r2, #2708] + ldr r3, [r2, #2440] + cmp r1, r3 + bcs .L684 + ldmfd sp!, {r4, lr} + b FtlReadRefresh.part.10 +.L684: + mov r3, #0 + str r3, [r2, #2704] + str r3, [r2, #2708] + ldr r3, [r2, #2444] + str r3, [r2, #2700] + b .L685 +.L683: + ldr r1, [r2, #2700] + ldr ip, [r2, #2500] + ldr r0, [r2, #2436] + ldr r2, [r2, #2444] + add r4, r2, #1048576 + cmp r1, r4 + bhi .L686 + add r0, r0, ip, lsr #10 + mov ip, #33554432 + add r1, r1, ip, asr r0 + cmp r1, r2 + bcc .L686 + ldrb r1, [r3, #2536] @ zero_extendqisi2 + cmp r1, #0 + bne .L685 +.L686: + mov r1, #1 + str r2, [r3, #2700] + str r1, [r3, #2704] + mov r1, #0 + str r1, [r3, #2708] +.L685: + mov r0, #0 + ldmfd sp!, {r4, pc} +.L689: + .align 2 +.L688: + .word .LANCHOR0 + .fnend + .size FtlReadRefresh, .-FtlReadRefresh + .align 2 + .global ftl_scan_all_data + .type ftl_scan_all_data, %function +ftl_scan_all_data: + .fnstart + @ args = 0, pretend = 0, frame = 8 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, r7, r8, lr} + .save {r4, r5, r6, r7, r8, lr} + mov r1, #0 + ldr r5, .L696 + .pad #32 + sub sp, sp, #32 + ldr r0, .L696+4 + mov r4, #0 + bl printk + ldr r7, .L696+8 + mov r6, r5 + b .L691 +.L695: + mov r0, r4 + add r1, sp, #28 + mov r2, #0 + bl log2phys + movs r3, r4, asl #21 + bne .L692 + ldr r0, .L696+12 + mov r1, r4 + ldr r2, [sp, #28] + bl printk +.L692: + ldr r3, [sp, #28] + cmn r3, #1 + beq .L693 + str r3, [r5, #-852] + mov r2, #0 + ldr r3, [r7, #2240] + mov r1, #1 + ldr r8, [r5, #-836] + ldr r0, .L696+16 + str r3, [r5, #-848] + str r4, [r5, #-840] + str r8, [r5, #-844] + str r2, [r5, #-856] + bl FlashReadPages + ldr r3, [r5, #-856] + cmn r3, #1 + cmpne r3, #256 + beq .L694 + ldr r3, [r8, #8] + cmp r3, r4 + beq .L693 +.L694: + ldr r3, [r6, #-844] + ldr r2, [r6, #-848] + ldr r0, .L696+20 + ldr r1, [r3, #4] + str r1, [sp, #0] + ldr r1, [r3, #8] + str r1, [sp, #4] + ldr r1, [r3, #12] + str r1, [sp, #8] + ldr r1, [r2, #0] + str r1, [sp, #12] + mov r1, r4 + ldr r2, [r2, #4] + str r2, [sp, #16] + ldr r2, [r6, #-852] + ldr r3, [r3, #0] + bl printk +.L693: + add r4, r4, #1 +.L691: + ldr r3, [r7, #2440] + cmp r4, r3 + bcc .L695 + add sp, sp, #32 + ldmfd sp!, {r4, r5, r6, r7, r8, pc} +.L697: + .align 2 +.L696: + .word .LANCHOR3 + .word .LC84 + .word .LANCHOR0 + .word .LC85 + .word .LANCHOR3-856 + .word .LC86 + .fnend + .size ftl_scan_all_data, .-ftl_scan_all_data + .align 2 + .global FtlReUsePrevPpa + .type FtlReUsePrevPpa, %function +FtlReUsePrevPpa: + .fnstart + @ args = 0, pretend = 0, frame = 8 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r0, r1, r2, r4, r5, r6, r7, lr} + .save {r0, r1, r2, r4, r5, r6, r7, lr} + mov r7, r0 + ubfx r0, r1, #10, #16 + str r1, [sp, #4] + bl P2V_block_in_plane + ldr r2, .L705 + ldr r3, [r2, #2256] + mov r4, r0, asl #1 + mov r5, r0 + ldrh r1, [r3, r4] + cmp r1, #0 + addne r1, r1, #1 + strneh r1, [r3, r4] @ movhi + bne .L700 + ldr r3, [r2, #2268] + cmp r3, #0 + beq .L700 + mov r0, #2272 + mov ip, #6 + ldrh lr, [r2, r0] + ldr r2, [r2, #2248] + ldr r0, .L705+4 + rsb r3, r2, r3 + mov r3, r3, asr #1 + mul r3, r0, r3 + movw r0, #65535 + uxth r3, r3 + b .L701 +.L704: + cmp r3, r5 + bne .L702 + ldr r6, .L705 + mov r1, r5 + ldr r0, .L705+8 + bl List_remove_node + mov r3, #2272 + ldrh r3, [r6, r3] + cmp r3, #0 + bne .L703 + ldr r0, .L705+12 + movw r2, #1640 + ldr r1, .L705+16 + bl printk +.L703: + mov r3, #2272 + mov r0, r5 + ldrh r2, [r6, r3] + sub r2, r2, #1 + strh r2, [r6, r3] @ movhi + bl INSERT_DATA_LIST + ldr r3, [r6, #2256] + ldrh r2, [r3, r4] + add r2, r2, #1 + strh r2, [r3, r4] @ movhi + b .L700 +.L702: + mul r3, ip, r3 + ldrh r3, [r2, r3] + cmp r3, r0 + beq .L700 + add r1, r1, #1 + uxth r1, r1 +.L701: + cmp r1, lr + bne .L704 +.L700: + mov r0, r7 + add r1, sp, #4 + mov r2, #1 + bl log2phys + ldmfd sp!, {r1, r2, r3, r4, r5, r6, r7, pc} +.L706: + .align 2 +.L705: + .word .LANCHOR0 + .word -1431655765 + .word .LANCHOR0+2268 + .word .LC1 + .word .LANCHOR1+305 + .fnend + .size FtlReUsePrevPpa, .-FtlReUsePrevPpa + .align 2 + .global ftl_check_vpc + .type ftl_check_vpc, %function +ftl_check_vpc: + .fnstart + @ args = 0, pretend = 0, frame = 8 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r0, r1, r4, r5, r6, r7, r8, r9, sl, lr} + .save {r0, r1, r4, r5, r6, r7, r8, r9, sl, lr} + mov r4, #0 + ldr r1, .L720 + ldr r0, .L720+4 + bl printk + ldr r0, .L720+8 + mov r1, #0 + mov r2, #8192 + bl ftl_memset + ldr r6, .L720+12 + ldr r5, .L720+16 + b .L708 +.L710: + mov r0, r4 + add r1, sp, #4 + mov r2, #0 + bl log2phys + ldr r0, [sp, #4] + cmn r0, #1 + beq .L709 + ubfx r0, r0, #10, #16 + bl P2V_block_in_plane + add r0, r5, r0, asl #1 + add r0, r0, #3920 + ldrh r3, [r0, #4] + add r3, r3, #1 + strh r3, [r0, #4] @ movhi +.L709: + add r4, r4, #1 +.L708: + ldr r3, [r6, #2440] + cmp r4, r3 + bcc .L710 + mov r4, #0 + ldr r7, .L720+12 + mov r5, r4 + ldr sl, .L720+16 + movw r9, #65535 + b .L711 +.L713: + mov r8, r5, asl #1 + ldr r3, [r7, #2256] + add r6, sl, r8 + add r6, r6, #3920 + ldrh r2, [r3, r8] + ldrh r3, [r6, #4] + add r6, r6, #4 + cmp r2, r3 + beq .L712 + ldr r0, .L720+20 + mov r1, r5 + bl printk + ldr r3, [r7, #2256] + ldrh r3, [r3, r8] + cmp r3, r9 + beq .L712 + ldrh r2, [r6, #0] + cmp r2, r3 + movhi r4, #1 +.L712: + add r5, r5, #1 + uxth r5, r5 +.L711: + ldrh r2, [r7, #12] + ldr r3, .L720+12 + cmp r2, r5 + bhi .L713 + ldr r2, [r3, #2268] + cmp r2, #0 + beq .L714 + ldr r5, [r3, #2248] + mov r1, #2272 + ldrh r8, [r3, r1] + mov r6, #0 + rsb r2, r5, r2 + ldr r5, .L720+24 + mov r7, r3 + ldr sl, .L720+16 + mov r2, r2, asr #1 + movw r9, #65535 + mul r5, r5, r2 + uxth r5, r5 + b .L715 +.L717: + ldr r2, [r7, #2256] + mov r3, r5, asl #1 + ldrh r2, [r2, r3] + cmp r2, #0 + beq .L716 + add r3, sl, r3 + ldr r0, .L720+28 + add r3, r3, #3920 + mov r1, r5 + add r3, r3, #4 + mov r4, #1 + ldrh r3, [r3, #0] + bl printk +.L716: + mov r2, #6 + ldr r3, [r7, #2248] + mul r5, r2, r5 + ldrh r5, [r3, r5] + cmp r5, r9 + beq .L714 + add r6, r6, #1 + uxth r6, r6 +.L715: + cmp r6, r8 + bne .L717 +.L714: + cmp r4, #0 + beq .L707 + ldr r0, .L720+32 + movw r2, #2299 + ldr r1, .L720 + bl printk +.L707: + ldmfd sp!, {r2, r3, r4, r5, r6, r7, r8, r9, sl, pc} +.L721: + .align 2 +.L720: + .word .LANCHOR1+321 + .word .LC87 + .word .LANCHOR3+3924 + .word .LANCHOR0 + .word .LANCHOR3 + .word .LC88 + .word -1431655765 + .word .LC89 + .word .LC1 + .fnend + .size ftl_check_vpc, .-ftl_check_vpc + .align 2 + .global FtlFreeSysBlkQueueInit + .type FtlFreeSysBlkQueueInit, %function +FtlFreeSysBlkQueueInit: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + ldr r3, .L723 + mov r2, #2048 + stmfd sp!, {r4, lr} + .save {r4, lr} + mov r4, #0 + strh r0, [r3, #184] @ movhi + mov r1, r4 + strh r4, [r3, #186] @ movhi + add r0, r3, #192 + strh r4, [r3, #188] @ movhi + strh r4, [r3, #190] @ movhi + bl ftl_memset + mov r0, r4 + ldmfd sp!, {r4, pc} +.L724: + .align 2 +.L723: + .word .LANCHOR0 + .fnend + .size FtlFreeSysBlkQueueInit, .-FtlFreeSysBlkQueueInit + .align 2 + .global FtlBbtMemInit + .type FtlBbtMemInit, %function +FtlBbtMemInit: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + ldr r0, .L726 + mvn r3, #0 + mov r1, #255 + mov r2, #16 + strh r3, [r0, #124] @ movhi + mov r3, #0 + strh r3, [r0, #130] @ movhi + add r0, r0, #136 + b ftl_memset +.L727: + .align 2 +.L726: + .word .LANCHOR0 + .fnend + .size FtlBbtMemInit, .-FtlBbtMemInit + .align 2 + .global FtlLoadBbt + .type FtlLoadBbt, %function +FtlLoadBbt: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, r7, r8, lr} + .save {r4, r5, r6, r7, r8, lr} + ldr r6, .L747 + ldr r8, .L747+4 + ldr r4, [r6, #-836] + mov r7, r6 + ldr r3, [r8, #2240] + str r4, [r6, #-844] + str r3, [r6, #-848] + bl FtlBbtMemInit + ldrh r5, [r8, #68] + sub r5, r5, #1 + uxth r5, r5 + b .L729 +.L733: + mov r1, #1 + mov r3, r5, asl #10 + ldr r0, .L747+8 + mov r2, r1 + str r3, [r6, #-852] + bl FlashReadPages + ldr r3, [r6, #-856] + cmn r3, #1 + bne .L730 + ldr r3, [r6, #-852] + mov r1, #1 + ldr r0, .L747+8 + mov r2, r1 + add r3, r3, #1 + str r3, [r6, #-852] + bl FlashReadPages +.L730: + ldr r3, [r7, #-856] + cmn r3, #1 + beq .L731 + ldrh r2, [r4, #0] + movw r3, #61649 + cmp r2, r3 + bne .L731 + ldr r3, .L747+4 + ldr r2, [r4, #4] + strh r5, [r3, #124] @ movhi + str r2, [r3, #132] + ldrh r2, [r4, #8] + strh r2, [r3, #128] @ movhi + b .L732 +.L731: + sub r5, r5, #1 + uxth r5, r5 +.L729: + ldrh r3, [r8, #68] + sub r3, r3, #16 + cmp r5, r3 + bgt .L733 +.L732: + ldr r5, .L747+4 + movw r3, #65535 + ldrh r2, [r5, #124] + cmp r2, r3 + beq .L744 + ldrh r2, [r5, #128] + cmp r2, r3 + beq .L735 + ldr r6, .L747 + mov r1, #1 + mov r2, r2, asl #10 + sub r0, r6, #856 + str r2, [r6, #-852] + mov r2, r1 + bl FlashReadPages + ldr r3, [r6, #-856] + cmn r3, #1 + beq .L735 + ldrh r2, [r4, #0] + movw r3, #61649 + cmp r2, r3 + bne .L735 + ldr r3, [r4, #4] + ldr r2, [r5, #132] + cmp r3, r2 + strhi r3, [r5, #132] + ldrhih r2, [r5, #128] + ldrhih r3, [r4, #8] + strhih r2, [r5, #124] @ movhi + strhih r3, [r5, #128] @ movhi +.L735: + ldr r7, .L747+4 + mov r1, #1 + mov r6, #0 + ldr r5, .L747 + ldrh r0, [r7, #124] + bl FtlGetLastWrittenPage + add r3, r0, #1 + mov r8, r0 + strh r3, [r7, #126] @ movhi + b .L736 +.L739: + ldrh r2, [r7, #124] + mov r1, #1 + ldr r0, .L747+8 + orr r3, r3, r2, asl #10 + str r3, [r5, #-852] + ldr r3, [r7, #2240] + mov r2, r1 + str r3, [r5, #-848] + bl FlashReadPages + ldr r3, [r5, #-856] + cmn r3, #1 + beq .L737 + ldrh r2, [r4, #0] + movw r3, #61649 + cmp r2, r3 + beq .L738 +.L737: + sub r6, r6, #1 + uxth r6, r6 +.L736: + add r3, r6, r8 + sxth r3, r3 + cmp r3, #0 + bge .L739 + b .L746 +.L738: + ldrh r2, [r4, #10] + ldr r3, .L747+4 + ldrh r0, [r4, #12] + strh r2, [r3, #130] @ movhi + movw r2, #65535 + cmp r0, r2 + beq .L741 + ldr r2, [r3, #0] + cmp r0, r2 + beq .L741 + ldrh r3, [r3, #14] + mov r3, r3, lsr #2 + cmp r2, r3 + bcs .L741 + cmp r0, r3 + bcs .L741 + bl FtlSysBlkNumInit +.L741: + ldr r5, .L747+12 + mov r4, #0 + ldr r7, .L747+16 + movw r6, #3940 + sub r8, r5, #148 + b .L742 +.L743: + ldr r3, .L747 + ldrh r2, [r7, r6] + ldr r0, [r5, #4]! + ldr r1, [r3, #-848] + mov r2, r2, asl #2 + mla r1, r4, r2, r1 + bl memcpy + add r4, r4, #1 +.L742: + ldrh r3, [r8, #26] + cmp r4, r3 + bcc .L743 + mov r0, #0 + ldmfd sp!, {r4, r5, r6, r7, r8, pc} +.L744: + mvn r0, #0 + ldmfd sp!, {r4, r5, r6, r7, r8, pc} +.L746: + ldr r1, .L747+20 + mov r2, #254 + ldr r0, .L747+24 + bl printk + b .L738 +.L748: + .align 2 +.L747: + .word .LANCHOR3 + .word .LANCHOR0 + .word .LANCHOR3-856 + .word .LANCHOR0+148 + .word .LANCHOR4 + .word .LANCHOR1+335 + .word .LC1 + .fnend + .size FtlLoadBbt, .-FtlLoadBbt + .align 2 + .global FtlBbt2Bitmap + .type FtlBbt2Bitmap, %function +FtlBbt2Bitmap: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + ldr r2, .L754 + stmfd sp!, {r3, r4, r5, r6, r7, r8, sl, lr} + .save {r3, r4, r5, r6, r7, r8, sl, lr} + movw r3, #3940 + ldrh r2, [r2, r3] + mov r6, r0 + mov r5, r1 + mov r0, r1 + mov r1, #0 + ldr r8, .L754+4 + mov r2, r2, asl #2 + mov r4, #0 + bl ftl_memset + movw sl, #65535 + mov r7, #1 +.L752: + ldrh r3, [r6, r4] + cmp r3, sl + ldmeqfd sp!, {r3, r4, r5, r6, r7, r8, sl, pc} + ldrh r2, [r8, #68] + cmp r2, r3 + bhi .L751 + ldr r0, .L754+8 + mov r2, #74 + ldr r1, .L754+12 + bl printk +.L751: + ldrh r2, [r6, r4] + add r4, r4, #2 + cmp r4, #1024 + mov r3, r2, lsr #5 + and r2, r2, #31 + ldr r1, [r5, r3, asl #2] + orr r2, r1, r7, asl r2 + str r2, [r5, r3, asl #2] + bne .L752 + ldmfd sp!, {r3, r4, r5, r6, r7, r8, sl, pc} +.L755: + .align 2 +.L754: + .word .LANCHOR4 + .word .LANCHOR0 + .word .LC1 + .word .LANCHOR1+346 + .fnend + .size FtlBbt2Bitmap, .-FtlBbt2Bitmap + .align 2 + .global FtlVariablesInit + .type FtlVariablesInit, %function +FtlVariablesInit: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, lr} + .save {r4, r5, r6, lr} + movw r2, #3948 + ldr r6, .L757 + mvn r3, #0 + ldr r5, .L757+4 + mov r4, #0 + mov r1, r4 + strh r3, [r6, r2] @ movhi + ldr r2, .L757+8 + ldr r0, [r5, #120] + str r3, [r6, #3956] + str r4, [r2, #3800] + ldrh r2, [r5, #92] + str r4, [r6, #3944] + str r4, [r6, #3952] + mov r2, r2, asl #1 + str r4, [r5, #2436] + strh r4, [r5, #116] @ movhi + bl ftl_memset + ldrh r2, [r5, #14] + mov r1, r4 + ldr r0, [r5, #2244] + mov r2, r2, asl #1 + bl ftl_memset + ldrh r2, [r5, #14] + mov r1, r4 + ldr r0, [r6, #3960] + mov r2, r2, asl #1 + bl ftl_memset + mov r1, r4 + mov r2, #48 + ldr r0, .L757+12 + bl ftl_memset + mov r1, r4 + mov r2, #512 + add r0, r5, #2624 + bl ftl_memset + bl FtlGcBufInit + bl FtlL2PDataInit + mov r0, r4 + ldmfd sp!, {r4, r5, r6, pc} +.L758: + .align 2 +.L757: + .word .LANCHOR4 + .word .LANCHOR0 + .word .LANCHOR3 + .word .LANCHOR0+2508 + .fnend + .size FtlVariablesInit, .-FtlVariablesInit + .align 2 + .global FtlMemInit + .type FtlMemInit, %function +FtlMemInit: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + .save {r4, r5, r6, r7, r8, r9, sl, lr} + movw r3, #65535 + ldr r5, .L790 + movw r2, #3190 + ldr r4, .L790+4 + mov r6, #0 + mov r0, #256 + mov r7, #12 + str r3, [r5, #3972] + mov sl, #20 + ldr r3, .L790+8 + ldrh r1, [r4, #78] + str r6, [r4, #2620] + str r6, [r3, #3780] + mvn r3, #0 + strh r3, [r4, r2] @ movhi + add r2, r2, #2 + str r6, [r4, #2476] + strh r3, [r4, r2] @ movhi + mov r3, #3136 + mov r2, #32 + strh r2, [r4, r3] @ movhi + add r3, r3, #2 + mov r2, #128 + str r6, [r4, #2480] + strh r2, [r4, r3] @ movhi + add r3, r3, #6 + str r6, [r4, #2464] + strh r6, [r4, r3] @ movhi + add r3, r3, #50 + str r6, [r4, #2452] + strh r6, [r4, r3] @ movhi + add r3, r3, #36 + str r6, [r4, #2448] + strh r6, [r4, r3] @ movhi + str r6, [r4, #2456] + str r6, [r4, #2460] + str r6, [r4, #2444] + str r6, [r4, #2484] + str r6, [r4, #2488] + str r6, [r4, #2496] + str r6, [r4, #2500] + str r6, [r4, #2504] + str r6, [r4, #3148] + str r6, [r4, #3140] + str r6, [r5, #3964] + str r6, [r5, #3968] + str r6, [r5, #3976] + bl __aeabi_idiv + ldrh r3, [r4, #4] + str r6, [r5, #3984] + ldr r6, .L790+8 + mov r3, r3, asl #2 + cmp r0, r3 + str r0, [r5, #3980] + ldrh r0, [r4, #76] + strhi r3, [r5, #3980] + mov r0, r0, asl #1 + bl ftl_malloc + str r0, [r4, #3180] + ldrh r0, [r4, #76] + mul r0, r7, r0 + bl ftl_malloc + ldrh r8, [r4, #4] + mul r8, sl, r8 + mov r9, r8, asl #2 + str r0, [r4, #3184] + mov r0, r9 + bl ftl_malloc + str r0, [r6, #3796] + mov r0, r8 + bl ftl_malloc + str r0, [r5, #3988] + mov r0, r9 + bl ftl_malloc + str r0, [r5, #3992] + mov r0, r8 + bl ftl_malloc + str r0, [r6, #3776] + mov r0, r8 + bl ftl_malloc + str r0, [r4, #3168] + ldr r0, [r5, #3980] + mul r0, sl, r0 + bl ftl_malloc + ldrh r3, [r4, #4] + ldrh r8, [r4, #82] + mov r3, r3, asl #1 + add r3, r3, #1 + str r3, [r4, #3172] + str r0, [r5, #3996] + mov r0, r8 + bl ftl_malloc + str r0, [r4, #2240] + mov r0, r8 + bl ftl_malloc + str r0, [r6, #3872] + mov r0, r8 + bl ftl_malloc + str r0, [r5, #4000] + ldr r0, [r4, #3172] + mul r0, r0, r8 + bl ftl_malloc + str r0, [r4, #3160] + ldr r0, [r5, #3980] + mul r0, r0, r8 + bl ftl_malloc + str r0, [r5, #4004] + mov r0, r8 + bl ftl_malloc + str r0, [r6, #3792] + mov r0, r8 + bl ftl_malloc + str r0, [r6, #3784] + ldr r0, [r4, #3172] + mul r0, r7, r0 + bl ftl_malloc + ldrh r3, [r4, #84] + ldrh r8, [r4, #4] + mul r8, r8, r3 + str r0, [r4, #3156] + mov r0, r8 + bl ftl_malloc + str r0, [r6, #-836] + mov r0, r8, asl #2 + bl ftl_malloc + ldrh r3, [r4, #84] + movw r8, #4012 + str r0, [r6, #3788] + ldr r0, [r4, #3172] + mul r0, r0, r3 + bl ftl_malloc + ldrh r3, [r4, #84] + str r0, [r4, #3164] + ldr r0, [r5, #3980] + mul r0, r0, r3 + bl ftl_malloc + str r0, [r5, #4008] + ldrh r0, [r4, #14] + mov r0, r0, asl #1 + uxth r0, r0 + strh r0, [r5, r8] @ movhi + bl ftl_malloc + str r0, [r5, #3960] + ldrh r0, [r5, r8] + add r0, r0, #544 + add r0, r0, #3 + mov r0, r0, lsr #9 + strh r0, [r5, r8] @ movhi + mov r0, r0, asl #9 + bl ftl_malloc + ldrh r8, [r4, #14] + mov r8, r8, asl #1 + str r0, [r5, #4016] + add r0, r0, #32 + str r0, [r4, #2244] + mov r0, r8 + bl ftl_malloc + str r0, [r5, #4020] + mov r0, r8 + bl ftl_malloc + ldr r8, [r4, #100] + mov r8, r8, asl #1 + str r0, [r4, #2256] + mov r0, r8 + bl ftl_malloc + str r0, [r6, #3856] + mov r0, r8 + bl ftl_malloc + str r0, [r6, #3804] + ldrh r0, [r4, #14] + mov r0, r0, lsr #3 + add r0, r0, #4 + bl ftl_malloc + str r0, [r4, #2432] + ldrh r0, [r4, #92] + mov r0, r0, asl #1 + bl ftl_malloc + str r0, [r4, #120] + ldrh r0, [r4, #92] + mov r0, r0, asl #1 + bl ftl_malloc + str r0, [r6, #3916] + ldrh r0, [r4, #92] + mov r0, r0, asl #2 + bl ftl_malloc + str r0, [r6, #3868] + ldrh r0, [r4, #94] + mov r0, r0, asl #2 + bl ftl_malloc + ldrh r2, [r4, #94] + mov r1, #0 + mov r2, r2, asl #2 + str r0, [r6, #3920] + bl ftl_memset + ldrh r0, [r4, #108] + mov r0, r0, asl #2 + bl ftl_malloc + str r0, [r6, #3864] + ldr r0, [r4, #100] + mov r0, r0, asl #2 + bl ftl_malloc + str r0, [r6, #3860] + ldrh r0, [r4, #110] + mul r0, r7, r0 + bl ftl_malloc + ldrh r3, [r4, #110] + str r0, [r4, #2420] + ldrh r0, [r4, #82] + mul r0, r0, r3 + bl ftl_malloc + ldrh r3, [r4, #14] + str r0, [r6, #3808] + mov r0, #6 + mul r0, r0, r3 + bl ftl_malloc + ldrh r3, [r4, #68] + ldrh r2, [r4, #26] + movw r6, #3940 + add r3, r3, #31 + mov r3, r3, lsr #5 + strh r3, [r5, r6] @ movhi + mul r3, r2, r3 + str r0, [r4, #2248] + mov r0, r3, asl #2 + bl ftl_malloc + ldrh r1, [r5, r6] + mov r3, #1 + mov r1, r1, asl #2 + mov r2, r1 + str r0, [r4, #152] + ldr r0, .L790+12 + ldrh r4, [r4, #26] + sub ip, r0, #152 + b .L761 +.L762: + ldr r5, [ip, #152] + add r3, r3, #1 + add r5, r5, r2 + add r2, r2, r1 + str r5, [r0, #4]! +.L761: + cmp r3, r4 + bcc .L762 + ldr r0, .L790+16 + mov r2, #0 + mov r1, r2 + add r0, r0, r3, asl #2 + b .L763 +.L764: + add ip, r0, r2 + add r3, r3, #1 + add r2, r2, #4 + str r1, [ip, #28] +.L763: + cmp r3, #7 + bls .L764 + ldr r3, .L790+8 + ldr r2, [r3, #3856] + cmp r2, #0 + beq .L789 +.L765: + ldr r2, [r3, #3804] + cmp r2, #0 + beq .L789 +.L767: + ldr r2, [r3, #3864] + cmp r2, #0 + beq .L789 +.L768: + ldr r2, [r3, #3860] + cmp r2, #0 + beq .L789 +.L769: + ldr r2, .L790+4 + ldr r1, [r2, #2420] + cmp r1, #0 + beq .L789 +.L770: + ldr r3, [r3, #3808] + cmp r3, #0 + beq .L789 +.L771: + ldr r3, [r2, #2248] + cmp r3, #0 + beq .L789 +.L772: + ldr r3, [r2, #152] + cmp r3, #0 + beq .L789 +.L773: + ldr r3, [r2, #2256] + cmp r3, #0 + beq .L789 +.L774: + ldr r3, .L790+4 + ldr r2, [r3, #3180] + cmp r2, #0 + beq .L789 + ldr r2, [r3, #3184] + cmp r2, #0 + beq .L789 +.L776: + ldr r1, .L790+8 + ldr r2, [r1, #3796] + cmp r2, #0 + beq .L789 + ldr r2, .L790 + ldr r0, [r2, #3992] + cmp r0, #0 + beq .L789 + ldr r0, [r1, #3776] + cmp r0, #0 + beq .L789 + ldr r0, [r3, #3168] + cmp r0, #0 + beq .L789 + ldr r0, [r2, #3988] + cmp r0, #0 + beq .L789 +.L778: + ldr r3, [r3, #2240] + cmp r3, #0 + beq .L789 + ldr r3, [r1, #3872] + cmp r3, #0 + beq .L789 + ldr r3, [r2, #4000] + cmp r3, #0 + beq .L789 + ldr r3, .L790+4 + ldr r2, [r3, #3160] + cmp r2, #0 + beq .L789 + ldr r2, .L790+8 + ldr r1, [r2, #3792] + cmp r1, #0 + beq .L789 + ldr r1, [r2, #3784] + cmp r1, #0 + beq .L789 + ldr r1, [r3, #3156] + cmp r1, #0 + beq .L789 +.L780: + ldr r1, [r2, #-836] + cmp r1, #0 + beq .L789 + ldr r2, [r2, #3788] + cmp r2, #0 + beq .L789 + ldr r2, [r3, #3164] + cmp r2, #0 + beq .L789 +.L782: + ldr r2, [r3, #2244] + cmp r2, #0 + beq .L789 + ldr r2, .L790 + ldr r2, [r2, #3960] + cmp r2, #0 + beq .L789 +.L784: + ldr r3, [r3, #120] + cmp r3, #0 + beq .L789 +.L785: + ldr r3, .L790+8 + ldr r2, [r3, #3916] + cmp r2, #0 + beq .L789 +.L786: + ldr r2, [r3, #3868] + cmp r2, #0 + beq .L789 +.L787: + ldr r3, [r3, #3920] + cmp r3, #0 + bne .L788 +.L789: + ldr r0, .L790+20 + ldr r1, .L790+24 + bl printk + mvn r0, #0 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, pc} +.L788: + mov r0, #0 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, pc} +.L791: + .align 2 +.L790: + .word .LANCHOR4 + .word .LANCHOR0 + .word .LANCHOR3 + .word .LANCHOR0+152 + .word .LANCHOR0+124 + .word .LC90 + .word .LANCHOR1+360 + .fnend + .size FtlMemInit, .-FtlMemInit + .align 2 + .global FtlLoadSysInfo + .type FtlLoadSysInfo, %function +FtlLoadSysInfo: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, r6, r7, lr} + .save {r3, r4, r5, r6, r7, lr} + mov r1, #0 + ldr r4, .L812 + ldr r5, .L812+4 + ldr r3, [r4, #2240] + ldrh r2, [r4, #12] + ldr r0, [r4, #2256] + str r3, [r5, #-848] + ldr r3, [r5, #-836] + mov r2, r2, asl #1 + str r3, [r5, #-844] + bl ftl_memset + mov r3, #2560 + ldrh r0, [r4, r3] + movw r3, #65535 + cmp r0, r3 + beq .L808 + mov r1, #1 + mov r6, #0 + bl FtlGetLastWrittenPage + movw r3, #2562 + add r2, r0, #1 + mov r7, r0 + strh r2, [r4, r3] @ movhi + b .L794 +.L797: + mov r2, #2560 + mov r1, #1 + ldrh r2, [r4, r2] + ldr r0, .L812+8 + orr r3, r3, r2, asl #10 + str r3, [r5, #-852] + ldr r3, [r4, #2240] + mov r2, r1 + str r3, [r5, #-848] + bl FlashReadPages + ldr r3, [r5, #-856] + cmn r3, #1 + beq .L795 + ldr r3, [r4, #2240] + ldr r2, [r3, #0] + ldr r3, .L812+12 + cmp r2, r3 + bne .L795 + ldr r3, [r5, #-836] + ldrh r2, [r3, #0] + movw r3, #61604 + cmp r2, r3 + beq .L796 +.L795: + sub r6, r6, #1 + uxth r6, r6 +.L794: + add r3, r6, r7 + sxth r3, r3 + cmp r3, #0 + bge .L797 + b .L811 +.L796: + ldr r5, .L812 + ldrh r2, [r5, #12] + ldrh r3, [r5, #82] + add r2, r2, #24 + cmp r3, r2, asl #1 + bcs .L799 + ldr r0, .L812+16 + movw r2, #1391 + ldr r1, .L812+20 + bl printk +.L799: + ldr r6, .L812+4 + mov r2, #48 + ldr r0, .L812+24 + ldr r4, .L812 + ldr r7, [r6, #-848] + mov r1, r7 + bl memcpy + ldrh r2, [r5, #12] + add r1, r7, #48 + ldr r0, [r5, #2256] + mov r2, r2, asl #1 + bl memcpy + ldrh r1, [r5, #12] + ldr r3, [r6, #-848] + ldr r0, [r5, #2432] + mov r2, r1, lsr #3 + add r1, r1, #24 + add r2, r2, #4 + mov r1, r1, lsr #1 + add r1, r3, r1, asl #2 + bl memcpy + ldr r2, [r5, #2508] + ldr r3, .L812+12 + cmp r2, r3 + bne .L808 + movw r3, #2516 + ldrb r2, [r4, #2518] @ zero_extendqisi2 + ldrh r5, [r4, r3] + add r3, r3, #50 + strh r5, [r4, r3] @ movhi + ldrh r3, [r4, #26] + cmp r2, r3 + bne .L808 + ldr r3, .L812+28 + ldrh r2, [r4, #78] + ldr r6, [r4, #16] + str r5, [r3, #4024] + ldrh r3, [r4, #72] + ldrh r0, [r4, #130] + ldrh r1, [r4, #4] + mul r3, r5, r3 + rsb r0, r0, r6 + rsb r0, r5, r0 + str r3, [r4, #2440] + mul r3, r2, r3 + str r3, [r4, #112] + bl __aeabi_uidiv + cmp r5, r6 + movw r3, #2556 + strh r0, [r4, r3] @ movhi + bls .L800 + ldr r0, .L812+16 + movw r2, #1413 + ldr r1, .L812+20 + bl printk +.L800: + ldr r3, .L812 + movw r2, #2522 + movw r0, #2278 + movw r5, #65535 + ldrh r1, [r3, r2] + movw r2, #2276 + strh r1, [r3, r2] @ movhi + add r2, r2, #248 + ldrh r2, [r3, r2] + mov ip, r2, lsr #6 + and r2, r2, #63 + strb r2, [r3, #2282] + ldrb r2, [r3, #2519] @ zero_extendqisi2 + strh ip, [r3, r0] @ movhi + mvn r0, #0 + movw ip, #2574 + strb r2, [r3, #2284] + movw r2, #2572 + strh r0, [r3, r2] @ movhi + movw r0, #2526 + mov r2, #0 + strh r2, [r3, ip] @ movhi + ldrh ip, [r3, r0] + movw r0, #2324 + strb r2, [r3, #2578] + strb r2, [r3, #2580] + strh ip, [r3, r0] @ movhi + mov r0, #2528 + ldrh r0, [r3, r0] + movw ip, #2326 + str r2, [r3, #2464] + str r2, [r3, #2452] + mov r4, r0, lsr #6 + and r0, r0, #63 + strb r0, [r3, #2330] + ldrb r0, [r3, #2520] @ zero_extendqisi2 + strh r4, [r3, ip] @ movhi + str r2, [r3, #2444] + strb r0, [r3, #2332] + movw r0, #2530 + ldrh ip, [r3, r0] + movw r0, #2372 + str r2, [r3, #2460] + str r2, [r3, #2488] + strh ip, [r3, r0] @ movhi + add r0, r0, #160 + movw ip, #2374 + str r2, [r3, #2500] + ldrh r0, [r3, r0] + mov r4, r0, lsr #6 + and r0, r0, #63 + strb r0, [r3, #2378] + ldrb r0, [r3, #2521] @ zero_extendqisi2 + strh r4, [r3, ip] @ movhi + strb r0, [r3, #2380] + ldr r0, [r3, #2540] + str r0, [r3, #2484] + str r2, [r3, #2456] + ldr r2, [r3, #2548] + ldr r0, [r3, #2476] + cmp r2, r0 + strhi r2, [r3, #2476] + ldr r2, [r3, #2544] + ldr r3, [r3, #2480] + cmp r2, r3 + ldrhi r3, .L812 + strhi r2, [r3, #2480] + cmp r1, r5 + beq .L803 + ldr r0, .L812+32 + bl make_superblock +.L803: + ldr r4, .L812 + movw r3, #2324 + ldrh r3, [r4, r3] + cmp r3, r5 + beq .L804 + ldr r0, .L812+36 + bl make_superblock +.L804: + movw r3, #2372 + ldrh r3, [r4, r3] + movw r4, #65535 + cmp r3, r4 + beq .L805 + ldr r0, .L812+40 + bl make_superblock +.L805: + ldr r2, .L812 + movw r3, #2572 + ldrh r3, [r2, r3] + cmp r3, r4 + beq .L809 + ldr r0, .L812+44 + bl make_superblock + mov r0, #0 + ldmfd sp!, {r3, r4, r5, r6, r7, pc} +.L808: + mvn r0, #0 + ldmfd sp!, {r3, r4, r5, r6, r7, pc} +.L809: + mov r0, #0 + ldmfd sp!, {r3, r4, r5, r6, r7, pc} +.L811: + ldr r1, .L812+20 + movw r2, #1389 + ldr r0, .L812+16 + bl printk + b .L796 +.L813: + .align 2 +.L812: + .word .LANCHOR0 + .word .LANCHOR3 + .word .LANCHOR3-856 + .word 1179929683 + .word .LC1 + .word .LANCHOR1+371 + .word .LANCHOR0+2508 + .word .LANCHOR4 + .word .LANCHOR0+2276 + .word .LANCHOR0+2324 + .word .LANCHOR0+2372 + .word .LANCHOR0+2572 + .fnend + .size FtlLoadSysInfo, .-FtlLoadSysInfo + .align 2 + .global FtlVpcTblFlush + .type FtlVpcTblFlush, %function +FtlVpcTblFlush: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r3, r4, r5, r6, r7, r8, r9, sl, fp, lr} + mov r7, #0 + ldr r4, .L826 + mov r1, #255 + ldr r6, .L826+4 + movw r9, #65535 + ldr r3, [r4, #2240] + mov fp, r4 + ldr r5, [r6, #-836] + str r3, [r6, #-848] + mov r3, #2560 + ldrh r3, [r4, r3] + str r5, [r6, #-844] + str r7, [r5, #12] + strh r3, [r5, #2] @ movhi + ldr r3, .L826+8 + strh r3, [r5, #0] @ movhi + ldr r3, [r4, #2568] + str r7, [r5, #8] + str r3, [r5, #4] + ldr r3, .L826+12 + str r3, [r4, #2508] + ldr r3, .L826+16 + str r3, [r4, #2512] + movw r3, #2566 + ldrh r2, [r4, r3] + movw r3, #2516 + strh r2, [r4, r3] @ movhi + ldrh r3, [r4, #26] + strb r3, [r4, #2518] + movw r3, #2276 + ldrh r2, [r4, r3] + add r3, r3, #246 + strh r2, [r4, r3] @ movhi + movw r3, #2278 + ldrh r2, [r4, r3] + ldrb r3, [r4, #2282] @ zero_extendqisi2 + orr r2, r3, r2, asl #6 + movw r3, #2524 + strh r2, [r4, r3] @ movhi + ldrb r3, [r4, #2284] @ zero_extendqisi2 + strb r3, [r4, #2519] + movw r3, #2324 + ldrh r2, [r4, r3] + add r3, r3, #202 + strh r2, [r4, r3] @ movhi + movw r3, #2326 + ldrh r2, [r4, r3] + ldrb r3, [r4, #2330] @ zero_extendqisi2 + orr r2, r3, r2, asl #6 + mov r3, #2528 + strh r2, [r4, r3] @ movhi + ldrb r3, [r4, #2332] @ zero_extendqisi2 + strb r3, [r4, #2520] + movw r3, #2372 + ldrh r2, [r4, r3] + add r3, r3, #158 + strh r2, [r4, r3] @ movhi + movw r3, #2374 + ldrh r2, [r4, r3] + ldrb r3, [r4, #2378] @ zero_extendqisi2 + ldr r0, [r6, #-848] + orr r2, r3, r2, asl #6 + movw r3, #2532 + strh r2, [r4, r3] @ movhi + ldrb r3, [r4, #2380] @ zero_extendqisi2 + ldrh r2, [r4, #82] + strb r3, [r4, #2521] + ldr r3, [r4, #2484] + str r3, [r4, #2540] + ldr r3, [r4, #2476] + str r3, [r4, #2548] + ldr r3, [r4, #2480] + str r3, [r4, #2544] + bl ftl_memset + ldr r1, .L826+20 + mov r2, #48 + ldr r0, [r6, #-848] + bl memcpy + ldrh r2, [r4, #12] + ldr r0, [r6, #-848] + ldr r1, [r4, #2256] + mov r2, r2, asl #1 + add r0, r0, #48 + bl memcpy + ldrh r2, [r4, #12] + ldr r3, [r6, #-848] + add r0, r2, #24 + ldr r1, [r4, #2432] + mov r2, r2, lsr #3 + mov r0, r0, lsr #1 + add r2, r2, #4 + add r0, r3, r0, asl #2 + bl memcpy + mov r0, r7 + bl FtlUpdateVaildLpn +.L825: + ldr r3, [r4, #2240] + mov sl, #2560 + ldrh r2, [r4, sl] + movw r8, #2562 + mov r1, #1 + ldr r0, .L826+24 + str r3, [r6, #-848] + ldr r3, [r6, #-836] + str r3, [r6, #-844] + ldrh r3, [r4, r8] + orr r3, r3, r2, asl #10 + mov r2, r1 + str r3, [r6, #-852] + mov r3, r1 + bl FlashProgPages + ldrh r3, [r4, #74] + ldrh r2, [r4, r8] + sub r3, r3, #1 + cmp r2, r3 + blt .L816 + ldrh r2, [r4, sl] + movw r3, #2564 + ldrh r9, [r4, r3] + strh r2, [r4, r3] @ movhi + mov r3, #0 + strh r3, [r4, r8] @ movhi + bl FtlFreeSysBlkQueueOut + ldr r3, [r4, #2476] + mov r1, #1 + add r2, r3, #1 + str r2, [r4, #2476] + str r3, [r4, #2568] + mov r2, r0, asl #10 + strh r0, [r4, sl] @ movhi + str r2, [r6, #-852] + mov r2, r1 + str r3, [r5, #4] + mov r3, r1 + strh r0, [r5, #2] @ movhi + ldr r0, .L826+24 + bl FlashProgPages +.L816: + movw r8, #2562 + ldr r2, [r6, #-856] + ldrh r3, [r4, r8] + cmn r2, #1 + add r3, r3, #1 + uxth r3, r3 + strh r3, [r4, r8] @ movhi + bne .L817 + cmp r3, #1 + bne .L818 + ldr r0, .L826+28 + movw r2, #1076 + ldr r1, .L826+32 + bl printk +.L818: + ldrh r3, [fp, r8] + add r7, r7, #1 + cmp r3, #1 + uxth r7, r7 + ldreqh r2, [r4, #74] + movweq r3, #2562 + subeq r2, r2, #1 + streqh r2, [r4, r3] @ movhi + cmp r7, #3 + bls .L825 + ldr r3, .L826+4 + mov r2, r7 + ldr r0, .L826+36 + ldr r1, [r3, #-852] + bl printk +.L821: + b .L821 +.L817: + cmp r3, #1 + beq .L825 + movw r3, #65535 + cmp r9, r3 + beq .L822 + mov r0, r9 + mov r1, #1 + bl FtlFreeSysBlkQueueIn +.L822: + mov r0, #0 + ldmfd sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, pc} +.L827: + .align 2 +.L826: + .word .LANCHOR0 + .word .LANCHOR3 + .word -3932 + .word 1179929683 + .word 1342177344 + .word .LANCHOR0+2508 + .word .LANCHOR3-856 + .word .LC1 + .word .LANCHOR1+386 + .word .LC91 + .fnend + .size FtlVpcTblFlush, .-FtlVpcTblFlush + .align 2 + .global FtlVendorPartRead + .type FtlVendorPartRead, %function +FtlVendorPartRead: + .fnstart + @ args = 0, pretend = 0, frame = 96 + @ frame_needed = 0, uses_anonymous_args = 0 + ldr r3, .L838 + stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r4, r5, r6, r7, r8, r9, sl, fp, lr} + mov r8, r2 + ldrh sl, [r3, #80] + add r2, r1, r0 + ldrh r3, [r3, #66] + .pad #100 + sub sp, sp, #100 + mov r6, r0 + mov r5, r1 + cmp r2, r3 + mvnhi r7, #0 + bhi .L829 + mov sl, r0, lsr sl + mov r7, #0 + ldr r9, .L838+4 + mov sl, sl, asl #2 + b .L830 +.L835: + ldr r2, .L838+8 + mov r0, r6 + ldr r3, [r2, #3920] + ldr fp, [r3, sl] + ldr r3, .L838 + ldrh r4, [r3, #78] + mov r1, r4 + bl __aeabi_uidivmod + uxth r3, r1 + rsb r4, r3, r4 + uxth r4, r4 + cmp r4, r5 + uxthhi r4, r5 + cmp fp, #0 + beq .L832 + ldr r2, [r9, #4000] + mov r1, #1 + add r0, sp, #12 + str r3, [sp, #4] + str fp, [sp, #16] + str r2, [sp, #20] + add r2, sp, #32 + str r2, [sp, #24] + mov r2, r1 + bl FlashReadPages + ldr r2, [sp, #12] + ldr r3, [sp, #4] + mov r0, r8 + cmn r2, #1 + moveq r7, r2 + ldr r2, .L838+4 + ldr r1, [r2, #4000] + mov r2, r4, asl #9 + add r1, r1, r3, asl #9 + bl memcpy + b .L834 +.L832: + mov r0, r8 + mov r1, fp + mov r2, r4, asl #9 + bl ftl_memset +.L834: + rsb r5, r4, r5 + add r6, r6, r4 + add r8, r8, r4, asl #9 + add sl, sl, #4 +.L830: + cmp r5, #0 + bne .L835 +.L829: + mov r0, r7 + add sp, sp, #100 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} +.L839: + .align 2 +.L838: + .word .LANCHOR0 + .word .LANCHOR4 + .word .LANCHOR3 + .fnend + .size FtlVendorPartRead, .-FtlVendorPartRead + .align 2 + .global Ftl_load_ext_data + .type Ftl_load_ext_data, %function +Ftl_load_ext_data: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, lr} + .save {r3, r4, r5, lr} + mov r0, #0 + ldr r4, .L844 + mov r1, #1 + ldr r5, .L844+4 + add r2, r4, #2624 + bl FtlVendorPartRead + ldr r3, [r4, #2624] + cmp r3, r5 + beq .L841 + add r0, r4, #2624 + mov r1, #0 + mov r2, #512 + bl ftl_memset + str r5, [r4, #2624] +.L841: + ldr r2, [r4, #2624] + ldr r3, .L844 + cmp r2, r5 + bne .L842 + ldr r2, [r3, #2712] + str r2, [r3, #2468] + ldr r2, [r3, #2716] + str r2, [r3, #2472] + ldr r2, [r3, #2632] + str r2, [r3, #2464] + ldr r2, [r3, #2636] + str r2, [r3, #2452] + ldr r2, [r3, #2640] + str r2, [r3, #2444] + ldr r2, [r3, #2644] + str r2, [r3, #2460] + ldr r2, [r3, #2652] + str r2, [r3, #2488] + ldr r2, [r3, #2656] + str r2, [r3, #2496] + ldr r2, [r3, #2660] + str r2, [r3, #2448] + ldr r2, [r3, #2664] + str r2, [r3, #2456] + ldr r2, [r3, #2668] + str r2, [r3, #2500] + ldr r2, [r3, #2672] + str r2, [r3, #2504] + ldr r2, [r3, #2684] + str r2, [r3, #2620] +.L842: + ldr r3, .L844+8 + mov r2, #0 + ldr r4, .L844 + str r2, [r3, #3964] + ldr r2, [r4, #2692] + ldr r3, .L844+12 + cmp r2, r3 + bne .L843 + ldr r0, .L844+16 + mov r3, #1 + ldr r1, .L844+20 + str r3, [r4, #2436] + bl printk +.L843: + ldrh r2, [r4, #62] + ldr r3, [r4, #2488] + ldr r0, [r4, #2484] + ldrh r1, [r4, #12] + mla r0, r0, r2, r3 + bl __aeabi_uidiv + str r0, [r4, #2492] + ldmfd sp!, {r3, r4, r5, pc} +.L845: + .align 2 +.L844: + .word .LANCHOR0 + .word 1179929683 + .word .LANCHOR4 + .word 305432421 + .word .LC70 + .word .LC92 + .fnend + .size Ftl_load_ext_data, .-Ftl_load_ext_data + .align 2 + .global FtlLoadEctTbl + .type FtlLoadEctTbl, %function +FtlLoadEctTbl: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, lr} + .save {r3, r4, r5, lr} + movw r5, #4012 + ldr r4, .L848 + mov r0, #64 + ldr r2, [r4, #4016] + ldrh r1, [r4, r5] + bl FtlVendorPartRead + ldr r3, [r4, #4016] + ldr r2, [r3, #0] + ldr r3, .L848+4 + cmp r2, r3 + beq .L847 + ldr r1, .L848+8 + ldr r0, .L848+12 + bl printk + ldrh r2, [r4, r5] + ldr r0, [r4, #4016] + mov r1, #0 + mov r2, r2, asl #9 + bl ftl_memset +.L847: + mov r0, #0 + ldmfd sp!, {r3, r4, r5, pc} +.L849: + .align 2 +.L848: + .word .LANCHOR4 + .word 1112818501 + .word .LC93 + .word .LC70 + .fnend + .size FtlLoadEctTbl, .-FtlLoadEctTbl + .align 2 + .global FtlVendorPartWrite + .type FtlVendorPartWrite, %function +FtlVendorPartWrite: + .fnstart + @ args = 0, pretend = 0, frame = 96 + @ frame_needed = 0, uses_anonymous_args = 0 + ldr r3, .L860 + stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r4, r5, r6, r7, r8, r9, sl, fp, lr} + mov r9, r2 + ldrh r2, [r3, #66] + mov r4, r1 + add r1, r1, r0 + .pad #100 + sub sp, sp, #100 + cmp r1, r2 + mov r6, r0 + ldrh r8, [r3, #80] + mvnhi r7, #0 + bhi .L851 + mov r8, r0, lsr r8 + mov r7, #0 + mov sl, r7 + mov fp, r8, asl #2 + b .L852 +.L857: + ldr r2, .L860+4 + mov r0, r6 + ldr r3, [r2, #3920] + ldr r2, .L860 + ldr r3, [r3, fp] + ldrh r7, [r2, #78] + str r3, [sp, #0] + mov r1, r7 + bl __aeabi_uidivmod + ldr r3, [sp, #0] + ldr r2, .L860+8 + uxth r1, r1 + str r1, [sp, #4] + rsb r5, r1, r7 + uxth r5, r5 + cmp r5, r4 + uxthhi r5, r4 + cmp r3, #0 + beq .L854 + cmp r5, r7 + beq .L854 + str r3, [sp, #16] + mov r1, #1 + ldr r3, [r2, #4000] + add r0, sp, #12 + mov r2, r1 + str r3, [sp, #20] + add r3, sp, #32 + str r3, [sp, #24] + bl FlashReadPages + b .L855 +.L854: + ldr r3, .L860 + mov r1, #0 + ldr r0, [r2, #4000] + ldrh r2, [r3, #82] + bl ftl_memset +.L855: + ldr r7, .L860+8 + mov r3, r5, asl #9 + ldr r2, [sp, #4] + mov r1, r9 + rsb r4, r5, r4 + add r6, r6, r5 + ldr r0, [r7, #4000] + add fp, fp, #4 + str r3, [sp, #0] + add r0, r0, r2, asl #9 + mov r2, r3 + bl memcpy + mov r1, r8 + ldr r0, .L860+12 + add r8, r8, #1 + ldr r2, [r7, #4000] + bl FtlMapWritePage + ldr r3, [sp, #0] + add r9, r9, r3 + cmn r0, #1 + moveq sl, r0 +.L852: + cmp r4, #0 + bne .L857 + mov r7, sl +.L851: + mov r0, r7 + add sp, sp, #100 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} +.L861: + .align 2 +.L860: + .word .LANCHOR0 + .word .LANCHOR3 + .word .LANCHOR4 + .word .LANCHOR3+3876 + .fnend + .size FtlVendorPartWrite, .-FtlVendorPartWrite + .align 2 + .global Ftl_save_ext_data + .type Ftl_save_ext_data, %function +Ftl_save_ext_data: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + ldr r2, .L864 + ldr r3, .L864+4 + ldr r1, [r2, #2624] + cmp r1, r3 + bxne lr + ldr r3, .L864+8 + mov r0, #0 + mov r1, #1 + str r3, [r2, #2628] + ldr r3, [r2, #2468] + str r3, [r2, #2712] + ldr r3, [r2, #2472] + str r3, [r2, #2716] + ldr r3, [r2, #2464] + str r3, [r2, #2632] + ldr r3, [r2, #2452] + str r3, [r2, #2636] + ldr r3, [r2, #2444] + str r3, [r2, #2640] + ldr r3, [r2, #2460] + str r3, [r2, #2644] + ldr r3, [r2, #2488] + str r3, [r2, #2652] + ldr r3, [r2, #2496] + str r3, [r2, #2656] + ldr r3, [r2, #2448] + str r3, [r2, #2660] + ldr r3, [r2, #2456] + str r3, [r2, #2664] + ldr r3, [r2, #2500] + str r3, [r2, #2668] + ldr r3, [r2, #2504] + str r3, [r2, #2672] + ldr r3, [r2, #2620] + str r3, [r2, #2684] + ldr r3, .L864+12 + ldr r3, [r3, #3964] + str r3, [r2, #2688] + add r2, r2, #2624 + b FtlVendorPartWrite +.L865: + .align 2 +.L864: + .word .LANCHOR0 + .word 1179929683 + .word 1342177344 + .word .LANCHOR4 + .fnend + .size Ftl_save_ext_data, .-Ftl_save_ext_data + .align 2 + .global FtlEctTblFlush + .type FtlEctTblFlush, %function +FtlEctTblFlush: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, lr} + .save {r3, lr} + ldr r3, .L873 + ldr r2, [r3, #2436] + cmp r2, #0 + moveq r2, #32 + beq .L867 + ldr r2, [r3, #2504] + cmp r2, #29 + movls r2, #4 + movhi r2, #32 +.L867: + ldr r3, .L873+4 + movw r1, #4028 + ldrh ip, [r3, r1] + cmp ip, #31 + addls ip, ip, #1 + strlsh ip, [r3, r1] @ movhi + movls r2, #1 + cmp r0, #0 + bne .L869 + ldr r1, [r3, #4016] + ldr r0, [r1, #20] + ldr r1, [r1, #16] + add r2, r2, r0 + cmp r1, r2 + bcc .L870 +.L869: + ldr r2, [r3, #4016] + mov r0, #64 + ldr r1, [r2, #16] + str r1, [r2, #20] + ldr r1, .L873+8 + str r1, [r2, #0] + movw r1, #4012 + ldr r2, [r3, #4016] + ldrh r1, [r3, r1] + mov r3, r1, asl #9 + str r3, [r2, #12] + ldr r3, [r2, #8] + add r3, r3, #1 + str r3, [r2, #8] + mov r3, #0 + str r3, [r2, #4] + bl FtlVendorPartWrite + bl Ftl_save_ext_data +.L870: + mov r0, #0 + ldmfd sp!, {r3, pc} +.L874: + .align 2 +.L873: + .word .LANCHOR0 + .word .LANCHOR4 + .word 1112818501 + .fnend + .size FtlEctTblFlush, .-FtlEctTblFlush + .align 2 + .global FtlBbmTblFlush + .type FtlBbmTblFlush, %function +FtlBbmTblFlush: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r0, r1, r4, r5, r6, r7, r8, r9, sl, lr} + .save {r0, r1, r4, r5, r6, r7, r8, r9, sl, lr} + mov r1, #0 + ldr sl, .L887 + mov r5, #0 + ldr r8, .L887+4 + add r7, sl, #148 + ldr r9, .L887+8 + ldr r0, [sl, #2240] + ldr r3, [r8, #-836] + ldrh r2, [sl, #82] + str r0, [r8, #-848] + str r3, [r8, #-844] + bl ftl_memset + b .L876 +.L877: + movw r3, #3940 + ldr r1, [r7, #4]! + ldrh r2, [r9, r3] + ldr r3, [r8, #-848] + mul r0, r2, r5 + mov r2, r2, asl #2 + add r5, r5, #1 + add r0, r3, r0, asl #2 + bl memcpy +.L876: + ldrh r3, [sl, #26] + ldr r4, .L887 + cmp r5, r3 + ldr r6, .L887+4 + blt .L877 + ldr r5, [r6, #-844] + mov r1, #255 + mov r2, #16 + mov r7, #0 + mov r8, r7 + mov sl, r7 + mov r0, r5 + mov r9, r7 + bl ftl_memset + ldr r3, .L887+12 + strh r3, [r5, #0] @ movhi + ldr r3, [r4, #132] + str r3, [r5, #4] + ldrh r3, [r4, #124] + strh r3, [r5, #2] @ movhi + ldrh r3, [r4, #128] + strh r3, [r5, #8] @ movhi + ldrh r3, [r4, #130] + strh r3, [r5, #10] @ movhi + ldr r3, [r4, #0] + strh r3, [r5, #12] @ movhi + b .L886 +.L883: + mov r8, #1 +.L886: + ldr r4, .L887 + str r9, [r6, #-856] + ldr r3, [r4, #2240] + ldrh r1, [r4, #124] + ldrh r2, [r4, #126] + str r3, [r6, #-848] + ldr r3, [r6, #-836] + str r3, [r6, #-844] + orr r3, r2, r1, asl #10 + ldrh r0, [r5, #10] + str r3, [r6, #-852] + ldrh r3, [r4, #128] + str r0, [sp, #0] + ldr r0, .L887+16 + bl printk + mov r1, #1 + mov r2, r1 + mov r3, r1 + ldr r0, .L887+20 + bl FlashProgPages + ldrh r3, [r4, #74] + ldrh r2, [r4, #126] + sub r3, r3, #1 + cmp r2, r3 + blt .L879 + ldr r3, [r4, #132] + mov r1, #1 + ldrh r2, [r4, #124] + add r3, r3, #1 + ldr r0, [r6, #3776] + str r3, [r4, #132] + str r3, [r5, #4] + ldrh r3, [r4, #128] + strh r2, [r5, #8] @ movhi + strh r2, [r4, #128] @ movhi + mov r2, r1 + strh r3, [r4, #124] @ movhi + mov r3, r3, asl #10 + str r3, [r6, #-852] + str r3, [r0, #4] + strh sl, [r4, #126] @ movhi + bl FlashEraseBlocks + mov r1, #1 + ldr r0, .L887+20 + mov r2, r1 + mov r3, r1 + bl FlashProgPages +.L879: + ldr r3, .L887 + ldrh r2, [r3, #126] + add r2, r2, #1 + strh r2, [r3, #126] @ movhi + ldr r3, [r6, #-856] + cmn r3, #1 + bne .L880 + add r7, r7, #1 + ldr r0, .L887+24 + ldr r1, [r6, #-852] + uxth r7, r7 + bl printk + cmp r7, #3 + bls .L886 + ldr r3, .L887+4 + mov r2, r7 + ldr r0, .L887+28 + ldr r1, [r3, #-852] + bl printk +.L882: + b .L882 +.L880: + cmp r8, #0 + beq .L883 + mov r0, #0 + ldmfd sp!, {r2, r3, r4, r5, r6, r7, r8, r9, sl, pc} +.L888: + .align 2 +.L887: + .word .LANCHOR0 + .word .LANCHOR3 + .word .LANCHOR4 + .word -3887 + .word .LC94 + .word .LANCHOR3-856 + .word .LC95 + .word .LC96 + .fnend + .size FtlBbmTblFlush, .-FtlBbmTblFlush + .align 2 + .global FtlGcFreeBadSuperBlk + .type FtlGcFreeBadSuperBlk, %function +FtlGcFreeBadSuperBlk: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + .save {r4, r5, r6, r7, r8, r9, sl, lr} + movw r3, #3194 + ldr r4, .L899 + mov r9, r0 + ldrh r3, [r4, r3] + cmp r3, #0 + movne r6, #0 + movne sl, r4 + bne .L890 + b .L891 +.L897: + add r3, r4, r6 + mov r1, r9 + mov r5, #0 + movw r7, #3194 + ldrb r0, [r3, #30] @ zero_extendqisi2 + bl V2P_block + mov r8, r0 + b .L892 +.L896: + add r3, r4, r5, asl #1 + add r3, r3, #3184 + add r3, r3, #12 + ldrh r3, [r3, #0] + cmp r3, r8 + bne .L893 + mov r1, r8 + ldr r0, .L899+4 + bl printk + mov r0, r8 + bl FtlBbmMapBadBlock + bl FtlBbmTblFlush + ldrh r1, [r4, r7] + mov r3, r5 + b .L894 +.L895: + add r0, r3, #1 + add r3, r4, r3, asl #1 + add r3, r3, #3184 + add r2, r4, r0, asl #1 + add r2, r2, #3184 + add r2, r2, #12 + ldrh r2, [r2, #0] + strh r2, [r3, #12] @ movhi + uxth r3, r0 +.L894: + cmp r3, r1 + bcc .L895 + sub r1, r1, #1 + strh r1, [sl, r7] @ movhi +.L893: + add r5, r5, #1 + uxth r5, r5 +.L892: + ldrh r3, [r4, r7] + cmp r3, r5 + bhi .L896 + add r6, r6, #1 + uxth r6, r6 +.L890: + ldrh r3, [r4, #4] + cmp r3, r6 + bhi .L897 + bl FtlGcReFreshBadBlk +.L891: + mov r0, #0 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, pc} +.L900: + .align 2 +.L899: + .word .LANCHOR0 + .word .LC97 + .fnend + .size FtlGcFreeBadSuperBlk, .-FtlGcFreeBadSuperBlk + .align 2 + .type update_vpc_list.part.11, %function +update_vpc_list.part.11: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, lr} + .save {r4, r5, r6, lr} + mov r6, r0 + ldr r4, .L904 + mov r1, r6 + ldr r0, .L904+4 + movw r5, #2264 + bl List_remove_node + ldrh r3, [r4, r5] + cmp r3, #0 + bne .L902 + ldr r0, .L904+8 + movw r2, #2747 + ldr r1, .L904+12 + bl printk +.L902: + ldrh r3, [r4, r5] + mov r0, r6 + sub r3, r3, #1 + strh r3, [r4, r5] @ movhi + bl free_data_superblock + mov r0, r6 + bl FtlGcFreeBadSuperBlk + mov r3, #2272 + ldrh r2, [r4, r3] + ldrh r3, [r4, r5] + add r2, r2, r3 + ldrh r3, [r4, #12] + cmp r2, r3 + ble .L903 + ldr r0, .L904+8 + movw r2, #2750 + ldr r1, .L904+12 + bl printk +.L903: + mov r0, #1 + ldmfd sp!, {r4, r5, r6, pc} +.L905: + .align 2 +.L904: + .word .LANCHOR0 + .word .LANCHOR0+2252 + .word .LC1 + .word .LANCHOR1+401 + .fnend + .size update_vpc_list.part.11, .-update_vpc_list.part.11 + .align 2 + .global update_vpc_list + .type update_vpc_list, %function +update_vpc_list: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + ldr r2, .L914 + mov r1, r0, asl #1 + stmfd sp!, {r3, lr} + .save {r3, lr} + mov r3, r0 + ldr ip, [r2, #2256] + ldrh r1, [ip, r1] + cmp r1, #0 + bne .L907 + movw r1, #2572 + ldrh r0, [r2, r1] + cmp r0, r3 + mvneq r0, #0 + streqh r0, [r2, r1] @ movhi + beq .L909 + movw r1, #2276 + ldrh r1, [r2, r1] + cmp r1, r3 + beq .L910 + movw r1, #2324 + ldrh r1, [r2, r1] + cmp r1, r3 + beq .L910 + movw r1, #2372 + ldrh r2, [r2, r1] + cmp r2, r3 + beq .L910 +.L909: + mov r0, r3 + ldmfd sp!, {r3, lr} + b update_vpc_list.part.11 +.L907: + bl List_update_data_list +.L910: + mov r0, #0 + ldmfd sp!, {r3, pc} +.L915: + .align 2 +.L914: + .word .LANCHOR0 + .fnend + .size update_vpc_list, .-update_vpc_list + .align 2 + .global decrement_vpc_count + .type decrement_vpc_count, %function +decrement_vpc_count: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, r6, r7, lr} + .save {r3, r4, r5, r6, r7, lr} + movw r3, #65535 + cmp r0, r3 + mov r7, r0 + beq .L917 + ldr r6, .L923 + mov r5, r0, asl #1 + ldr r3, [r6, #2256] + ldrh r4, [r3, r5] + cmp r4, #0 + subne r4, r4, #1 + strneh r4, [r3, r5] @ movhi + bne .L917 + ldr r0, .L923+4 + mov r1, r7 + mov r2, r4 + bl printk + ldr r3, [r6, #2256] + ldrh r5, [r3, r5] + cmp r5, #0 + bne .L919 + ldr r0, .L923+8 + movw r2, #2765 + ldr r1, .L923+12 + mov r4, r5 + bl printk + b .L919 +.L917: + ldr r6, .L923+16 + movw r5, #3948 + movw r3, #65535 + ldrh r0, [r6, r5] + cmp r0, r3 + streqh r7, [r6, r5] @ movhi + beq .L922 + cmp r0, r7 + beq .L922 + bl update_vpc_list + ldr r3, .L923 + strh r7, [r6, r5] @ movhi + ldr r1, [r3, #2252] + ldr r2, [r3, #2248] + rsb r2, r2, r1 + ldr r1, .L923+20 + mov r2, r2, asr #1 + mul r2, r1, r2 + ldr r1, [r3, #2256] + uxth r2, r2 + mov r3, r2, asl #1 + ldrh r3, [r1, r3] + adds r4, r0, #0 + movne r4, #1 + cmp r3, #0 + bne .L919 + cmp r7, r2 + beq .L919 + ldr r1, .L923+12 + movw r2, #2781 + ldr r0, .L923+8 + bl printk + b .L919 +.L922: + mov r4, #0 +.L919: + mov r0, r4 + ldmfd sp!, {r3, r4, r5, r6, r7, pc} +.L924: + .align 2 +.L923: + .word .LANCHOR0 + .word .LC98 + .word .LC1 + .word .LANCHOR1+417 + .word .LANCHOR4 + .word -1431655765 + .fnend + .size decrement_vpc_count, .-decrement_vpc_count + .align 2 + .global FtlSuperblockPowerLostFix + .type FtlSuperblockPowerLostFix, %function +FtlSuperblockPowerLostFix: + .fnstart + @ args = 0, pretend = 0, frame = 24 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, r7, lr} + .save {r4, r5, r6, r7, lr} + mov r4, r0 + .pad #28 + sub sp, sp, #28 + mov r6, #7 + ldr r5, .L930 + ldr r7, .L930+4 + b .L926 +.L929: + ldrh r3, [r4, #4] + cmp r3, #0 + beq .L927 + mov r0, r4 + bl get_new_active_ppa + cmn r0, #1 + str r0, [sp, #8] + beq .L927 + ldr r3, [r5, #2240] + mvn r2, #0 + str r2, [sp, #20] + add r0, sp, #4 + str r3, [sp, #12] + ldr r3, [r7, #-836] + str r3, [sp, #16] + str r2, [r3, #8] + str r2, [r3, #12] + ldrh r2, [r4, #0] + strh r2, [r3, #2] @ movhi + mov r2, #0 + strh r2, [r3, #0] @ movhi + ldr r1, [r5, #2480] + cmn r1, #2 + str r1, [r3, #4] + addne r1, r1, #1 + moveq r1, #0 + mov r3, r2 + str r1, [r5, #2480] + mov r1, #1 + bl FlashProgPages + ldrh r0, [r4, #0] + bl decrement_vpc_count +.L926: + subs r6, r6, #1 + bne .L929 +.L927: + ldr r3, .L930 + ldrh r2, [r4, #0] + ldrh r0, [r4, #4] + ldr r1, [r3, #2256] + mov r2, r2, asl #1 + ldrh ip, [r1, r2] + rsb r0, r0, ip + strh r0, [r1, r2] @ movhi + ldrh r3, [r3, #72] + strh r3, [r4, #2] @ movhi + mov r3, #0 + strb r3, [r4, #6] + strh r3, [r4, #4] @ movhi + add sp, sp, #28 + ldmfd sp!, {r4, r5, r6, r7, pc} +.L931: + .align 2 +.L930: + .word .LANCHOR0 + .word .LANCHOR3 + .fnend + .size FtlSuperblockPowerLostFix, .-FtlSuperblockPowerLostFix + .align 2 + .global FtlRecoverySuperblock + .type FtlRecoverySuperblock, %function +FtlRecoverySuperblock: + .fnstart + @ args = 0, pretend = 0, frame = 56 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r4, r5, r6, r7, r8, r9, sl, fp, lr} + movw r3, #65535 + ldrh r2, [r0, #0] + .pad #60 + sub sp, sp, #60 + mov r4, r0 + cmp r2, r3 + beq .L933 + ldr r2, .L1003 + mov r5, #0 + ldrh r7, [r0, #2] + ldrb fp, [r0, #6] @ zero_extendqisi2 + ldrh r2, [r2, #72] + str r7, [sp, #4] + cmp r2, r7 + str fp, [sp, #20] + streqh r5, [r0, #4] @ movhi + moveq r3, r5 @ movhi + ldrneh r0, [r0, #16] + bne .L935 + b .L1001 +.L936: + add r5, r5, #1 + uxth r5, r5 + add r2, r4, r5, asl #1 + ldrh r0, [r2, #16] +.L935: + cmp r0, r3 + beq .L936 + mov r1, #1 + bl FtlGetLastWrittenPage + cmn r0, #1 + mov sl, r0 + beq .L937 + ldr r3, .L1003 + mov r5, #0 + ldr r2, .L1003+4 + str r4, [sp, #32] + ldrh r9, [r3, #4] + ldr r8, [r2, #3796] + mov r2, r4 + ldr r7, [r3, #3160] + ldrh r6, [r3, #82] + ldr lr, [r3, #3164] + ldrh ip, [r3, #84] + mov r3, r5 + b .L938 +.L937: + ldr r3, [sp, #4] + cmp r3, #0 + beq .L939 + ldr r0, .L1003+8 + movw r2, #1707 + ldr r1, .L1003+12 + bl printk +.L939: + ldr r7, [sp, #20] + cmp r7, r5 + cmpne r7, #0 + beq .L940 + ldr r0, .L1003+8 + movw r2, #1708 + ldr r1, .L1003+12 + bl printk +.L940: + mov r3, #0 + strh r3, [r4, #2] @ movhi + strb r3, [r4, #6] + b .L933 +.L942: + ldrh r0, [r2, #16] + movw fp, #65535 + cmp r0, fp + beq .L941 + mov fp, #20 + orr r0, sl, r0, asl #10 + mla r1, fp, r5, r8 + str r0, [r1, #4] + mul r0, r6, r5 + add fp, r0, #3 + cmp r0, #0 + movlt r0, fp + bic r0, r0, #3 + add r0, r7, r0 + str r0, [r1, #8] + mul r0, ip, r5 + add r5, r5, #1 + uxth r5, r5 + add fp, r0, #3 + cmp r0, #0 + movlt r0, fp + bic r0, r0, #3 + add r0, lr, r0 + str r0, [r1, #12] +.L941: + add r3, r3, #1 + add r2, r2, #2 + uxth r3, r3 +.L938: + cmp r3, r9 + bne .L942 + ldr r6, .L1003+4 + mov r2, #0 + ldr r9, .L1003 + mov r1, r5 + ldr r0, [r6, #3796] + bl FlashReadPages + ldr r2, [r9, #2480] + movw r3, #65535 + str r3, [sp, #8] + uxth r3, sl + ldr r7, [r6, #3796] + str r2, [sp, #16] + mov r6, #0 + mov fp, r3 + b .L943 +.L948: + ldr r3, [r7, #0] + cmp r3, #0 + strne fp, [sp, #8] + bne .L946 + ldr r3, [r7, #12] + ldr r8, [r3, #4] + cmn r8, #1 + beq .L945 + ldr r1, [r9, #2480] + mov r0, r8 + str r3, [sp, #0] + bl ftl_cmp_data_ver + ldr r3, [sp, #0] + cmp r0, #0 + addne r8, r8, #1 + strne r8, [r9, #2480] +.L945: + ldr r3, [r3, #0] + cmn r3, #1 + bne .L946 + ldr r3, .L1003+4 + mov r2, #20 + uxth fp, sl + ldr r3, [r3, #3796] + mla r6, r2, r6, r3 + ldr r0, [r6, #4] + b .L998 +.L946: + add r6, r6, #1 + add r7, r7, #20 + uxth r6, r6 +.L943: + cmp r6, r5 + bne .L948 + ldr r3, .L1003+4 + add fp, sl, #1 + uxth fp, fp + ldr r3, [r3, #3796] + ldr r0, [r3, #4] +.L998: + ubfx r0, r0, #10, #16 + bl P2V_plane + ldr r3, .L1003 + ldr r1, [sp, #4] + ldrh r3, [r3, #72] + cmp r3, fp + streqh fp, [r4, #2] @ movhi + moveq r3, #0 + streqb r3, [r4, #6] + streqh r3, [r4, #4] @ movhi + ldr r3, [sp, #20] + str r0, [sp, #12] + ldr r7, [sp, #12] + cmp r7, r3 + cmpeq fp, r1 + beq .L1002 +.L950: + ldr r7, [sp, #8] + movw r3, #65535 + ldr r2, [sp, #16] + cmp r7, r3 + sub r5, r2, #1 + bne .L951 + ldrb r3, [r4, #8] @ zero_extendqisi2 + cmp r3, #0 + bne .L952 +.L951: + ldr r3, .L1003+16 + uxth sl, sl + ldr r7, [sp, #4] + movw r9, #65535 + mov r8, r5 + ldr r2, [r3, #3956] + cmn r2, #1 + streq r5, [r3, #3956] + add r3, r7, #7 + cmp sl, r3 + subgt r7, sl, #7 + ldrle r7, [sp, #4] + uxthgt r7, r7 + b .L996 +.L957: + ldrh r1, [r2, #16] + add r3, r3, #1 + add r2, r2, #2 + cmp r1, r9 + uxth r3, r3 + orrne r1, r7, r1, asl #10 + mlane r6, r0, r5, ip + addne r5, r5, #1 + uxthne r5, r5 + strne r1, [r6, #4] +.L962: + cmp r3, lr + bne .L957 + ldr r6, .L1003+4 + mov r2, #0 + mov r1, r5 + ldr r0, [r6, #3796] + bl FlashReadPages + ldr r3, [r6, #3796] + mov r2, #0 + ldr r0, .L1003+16 + b .L958 +.L960: + ldr r1, [r3, #0] + cmp r1, #0 + bne .L997 + ldr r1, [r3, #12] + ldrh ip, [r1, #0] + cmp ip, r9 + beq .L959 + ldr r1, [r1, #4] + cmn r1, #1 + strne r1, [r0, #3956] +.L959: + add r2, r2, #1 + add r3, r3, #20 + uxth r2, r2 +.L958: + cmp r2, r5 + bne .L960 + add r7, r7, #1 + uxth r7, r7 +.L996: + cmp r7, sl + bhi .L961 + ldr r3, .L1003+4 + mov r5, #0 + ldr r1, .L1003 + mov r2, r4 + mov r0, #20 + ldr ip, [r3, #3796] + mov r3, r5 + ldrh lr, [r1, #4] + b .L962 +.L961: + ldr r3, .L1003+16 + mvn r2, #0 + mov r5, r8 + str r2, [r3, #3956] + b .L952 +.L997: + mov r5, r8 +.L952: + ldr r2, .L1003+16 + movw r3, #4030 + mov r1, #1 + ldr r0, .L1003+20 + ldr r6, .L1003 + mov sl, r4 + strh r1, [r2, r3] @ movhi + bl FtlMapBlkWriteDump_data + ldr r9, [sp, #4] + str fp, [sp, #28] +.L963: + ldr r3, .L1003+4 + mov r4, #0 + ldrh lr, [r6, #4] + mov r2, sl + mov r0, #20 + ldr ip, [r3, #3796] + mov r3, r4 + b .L964 +.L966: + ldrh r1, [r2, #16] + movw r7, #65535 + add r3, r3, #1 + add r2, r2, #2 + cmp r1, r7 + uxth r3, r3 + orrne r1, r9, r1, asl #10 + mlane r7, r0, r4, ip + addne r4, r4, #1 + uxthne r4, r4 + strne r1, [r7, #4] +.L964: + cmp r3, lr + bne .L966 + ldr r7, .L1003+4 + mov r1, r4 + mov r2, #0 + ldr r0, [r7, #3796] + bl FlashReadPages + mov r3, #20 + mul r3, r3, r4 + mov r4, #0 + str r3, [sp, #36] + b .L967 +.L990: + ldr fp, [r7, #3796] + add fp, fp, r4 + ldr r8, [fp, #4] + ubfx r0, r8, #10, #16 + str r8, [sp, #52] + bl P2V_plane + ldr r3, [sp, #4] + cmp r9, r3 + bcc .L968 + ldr r1, [sp, #20] + mov r2, r3 + cmp r0, r1 + movcs r3, #0 + movcc r3, #1 + cmp r9, r2 + movne r3, #0 + cmp r3, #0 + bne .L968 + ldr r3, [sp, #12] + ldr r1, [sp, #28] + cmp r0, r3 + cmpeq r9, r1 + beq .L969 + ldr r3, [fp, #0] + cmn r3, #1 + beq .L970 + ldr r8, [fp, #12] + movw r3, #61589 + ldrh r2, [r8, #0] + cmp r2, r3 + bne .L978 +.L971: + ldr r5, [r8, #4] + cmn r5, #1 + beq .L972 + ldr r1, [r6, #2480] + mov r0, r5 + bl ftl_cmp_data_ver + cmp r0, #0 + addne r3, r5, #1 + strne r3, [r6, #2480] +.L972: + ldrh r2, [r8, #0] + movw r3, #61589 + cmp r2, r3 + beq .L973 + ldr r0, .L1003+8 + movw r2, #1857 + ldr r1, .L1003+12 + bl printk +.L973: + ldr r3, [r8, #8] + add r1, sp, #48 + ldr fp, .L1003+16 + mov r2, #0 + str r3, [sp, #8] + ldr r3, [r8, #12] + ldr r0, [sp, #8] + str r3, [sp, #44] + bl log2phys + ldr r1, [fp, #3956] + cmn r1, #1 + beq .L974 + mov r0, r5 + bl ftl_cmp_data_ver + cmp r0, #0 + beq .L974 + ldr r3, [sp, #44] + cmn r3, #1 + beq .L975 + ldr r0, [r7, #3796] + mov r1, #1 + mov r2, #0 + add r0, r0, r4 + ldr fp, [r0, #12] + str r3, [r0, #4] + str fp, [sp, #16] + bl FlashReadPages + ldr r3, [fp, #4] + str r3, [sp, #24] + ldr r3, [r7, #3796] + add fp, r3, r4 + ldr r3, [r3, r4] + cmn r3, #1 + bne .L976 + b .L977 +.L975: + ldr r3, [sp, #52] + ldr r2, [sp, #48] + cmp r2, r3 + bne .L978 + ldr r0, [sp, #8] + add r1, sp, #44 + mov r2, #1 + bl log2phys +.L978: + ldrh r0, [sl, #0] + b .L1000 +.L976: + ldr r3, [sp, #16] + ldr r8, [r3, #8] + ldr r3, [sp, #8] + cmp r8, r3 + bne .L977 + ldr r1, .L1003+16 + ldr r0, [r1, #3956] + ldr r1, [sp, #24] + bl ftl_cmp_data_ver + cmp r0, #0 + beq .L977 + ldr r3, [sp, #48] + ldr r2, [sp, #52] + cmp r3, r2 + beq .L982 +.L979: + ldr r2, [sp, #44] + cmp r3, r2 + beq .L977 + cmn r3, #1 + streq r3, [fp, #0] + beq .L981 + ldr r2, [fp, #12] + mov r0, fp + str r3, [fp, #4] + mov r1, #1 + str r2, [sp, #16] + mov r2, #0 + bl FlashReadPages +.L981: + ldr r3, [r7, #3796] + ldr r3, [r3, r4] + cmn r3, #1 + beq .L982 + ldr r3, [sp, #16] + ldr fp, [r3, #4] + ldr r3, .L1003+16 + mov r1, fp + ldr r0, [r3, #3956] + bl ftl_cmp_data_ver + cmp r0, #0 + beq .L982 + ldr r0, [sp, #24] + mov r1, fp + bl ftl_cmp_data_ver + cmp r0, #0 + beq .L977 +.L982: + mov r0, r8 + ldr r1, [sp, #44] + bl FtlReUsePrevPpa +.L977: + ldrh r0, [sl, #0] + mvn r3, #0 + str r3, [sp, #44] + bl decrement_vpc_count + b .L984 +.L974: + ldr r3, [sp, #52] + ldr r2, [sp, #48] + cmp r2, r3 + beq .L984 + ldr r0, [sp, #8] + add r1, sp, #52 + mov r2, #1 + bl log2phys + ldr fp, [sp, #48] + cmn fp, #1 + beq .L984 + ldr r3, [sp, #44] + cmp fp, r3 + beq .L984 + ubfx r0, fp, #10, #16 + bl P2V_block_in_plane + movw r3, #2276 + ldrh r3, [r6, r3] + cmp r3, r0 + beq .L985 + movw r3, #2324 + ldrh r3, [r6, r3] + cmp r3, r0 + beq .L985 + movw r3, #2372 + ldrh r3, [r6, r3] + cmp r3, r0 + bne .L984 +.L985: + ldr r0, [r7, #3796] + mov r1, #1 + mov r2, #0 + str fp, [r0, #4] + ldr r8, [r0, #12] + bl FlashReadPages + ldr r3, [r7, #3796] + ldr r1, [r8, #4] + ldr r3, [r3, #0] + cmn r3, #1 + beq .L984 + mov r0, r5 + bl ftl_cmp_data_ver + cmp r0, #0 + bne .L984 + ldr r0, [sp, #8] + add r1, sp, #48 + mov r2, #1 + bl log2phys +.L984: + ldr r0, [sp, #44] + cmn r0, #1 + beq .L968 + ubfx r0, r0, #10, #16 + bl P2V_block_in_plane + ldrh r3, [r6, #12] + cmp r3, r0 + mov r8, r0 + bhi .L986 + ldr r0, .L1003+8 + movw r2, #1958 + ldr r1, .L1003+12 + bl printk +.L986: + ldr fp, .L1003 + mov r3, r8, asl #1 + ldr r2, [fp, #2256] + ldrh r3, [r2, r3] + cmp r3, #0 + beq .L987 + mov r0, r8 +.L1000: + bl decrement_vpc_count + b .L968 +.L987: + mov r1, r8 + ldr r0, .L1003+24 + bl printk + b .L968 +.L970: + ldr r3, .L1003+16 + ldr r2, [r3, #4032] + cmp r2, #31 + addls r1, r3, r2, asl #2 + addls r2, r2, #1 + strls r2, [r3, #4032] + strls r8, [r1, #4036] + ldrh r0, [sl, #0] + bl decrement_vpc_count + ldr r3, .L1003+16 + ldr r2, [r3, #3956] + cmn r2, #1 + beq .L999 +.L989: + cmp r2, r5 + bls .L968 +.L999: + str r5, [r3, #3956] +.L968: + add r4, r4, #20 +.L967: + ldr r3, [sp, #36] + cmp r4, r3 + bne .L990 + add r9, r9, #1 + ldrh r3, [r6, #72] + uxth r9, r9 + cmp r9, r3 + bne .L963 + ldr r2, .L1003 + mov r3, #0 + mov r4, sl + strh r9, [sl, #2] @ movhi + strh r3, [sl, #4] @ movhi + ldrh r1, [r2, #4] + movw r2, #65535 + ldr r0, [sp, #32] + b .L991 +.L993: + add r0, r0, #2 + ldrh ip, [r0, #14] + cmp ip, r2 + beq .L992 +.L1001: + strb r3, [r4, #6] + b .L933 +.L992: + add r3, r3, #1 + uxth r3, r3 +.L991: + cmp r3, r1 + bne .L993 + b .L933 +.L969: + ldr fp, [sp, #28] + mov r4, sl + ldr r7, [sp, #12] + strh fp, [sl, #2] @ movhi + strb r7, [sl, #6] +.L1002: + mov r0, r4 + mov r1, fp + mov r2, r7 + bl ftl_sb_update_avl_pages +.L933: + mov r0, #0 + add sp, sp, #60 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} +.L1004: + .align 2 +.L1003: + .word .LANCHOR0 + .word .LANCHOR3 + .word .LC1 + .word .LANCHOR1+437 + .word .LANCHOR4 + .word .LANCHOR3+3812 + .word .LC99 + .fnend + .size FtlRecoverySuperblock, .-FtlRecoverySuperblock + .align 2 + .global allocate_data_superblock + .type allocate_data_superblock, %function +allocate_data_superblock: + .fnstart + @ args = 0, pretend = 0, frame = 24 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r4, r5, r6, r7, r8, r9, sl, fp, lr} + .pad #28 + sub sp, sp, #28 + ldr r4, .L1044 + mov r5, r0 + movw fp, #2264 + mov r7, r4 +.L1041: + mov r3, #2272 + ldrh r2, [r4, r3] + ldrh r3, [r4, fp] + add r2, r2, r3 + ldrh r3, [r4, #12] + cmp r2, r3 + ble .L1007 + ldr r0, .L1044+4 + movw r2, #2577 + ldr r1, .L1044+8 + bl printk +.L1007: + ldr r3, .L1044+12 + cmp r5, r3 + bne .L1037 + mov r3, #2272 + ldrh r2, [r4, r3] + ldr r3, [r4, #3148] + mov r1, r2, lsr #1 + mul ip, r3, r2 + add r0, r1, #1 + add r0, r0, ip, lsr #2 + ldr ip, [r4, #2436] + cmp ip, #0 + uxth r0, r0 + beq .L1036 + ldr ip, [r4, #2504] + cmp ip, #29 + bhi .L1036 + cmp ip, #2 + bls .L1037 + tst r2, #1 + beq .L1009 + cmp r3, #0 + moveq r1, r3 + beq .L1008 + b .L1009 +.L1036: + mov r1, r0 +.L1009: + cmp r1, #0 + subne r1, r1, #1 + uxthne r1, r1 + b .L1008 +.L1037: + mov r1, #0 +.L1008: + ldr r0, .L1044+16 + bl List_pop_index_node + mov r3, #2272 + ldrh r3, [r4, r3] + cmp r3, #0 + uxth r6, r0 + bne .L1010 + ldr r0, .L1044+4 + mov r2, #2592 + ldr r1, .L1044+8 + bl printk +.L1010: + mov r8, #2272 + mov r0, r5 + ldrh r3, [r7, r8] + sub r3, r3, #1 + strh r3, [r7, r8] @ movhi + strh r6, [r5, #0] @ movhi + bl make_superblock + ldrb r3, [r5, #7] @ zero_extendqisi2 + cmp r3, #0 + bne .L1011 + ldr r2, [r4, #2256] + mov r3, r6, asl #1 + mvn r1, #0 + mov r0, r6 + strh r1, [r2, r3] @ movhi + bl INSERT_DATA_LIST + ldrh r3, [r4, fp] + ldrh r2, [r4, r8] + add r2, r2, r3 + ldrh r3, [r4, #12] + cmp r2, r3 + ble .L1041 + ldr r1, .L1044+8 + movw r2, #2603 + ldr r0, .L1044+4 + bl printk + b .L1041 +.L1011: + ldrh r3, [r4, fp] + ldrh r2, [r4, r8] + add r2, r2, r3 + ldrh r3, [r4, #12] + cmp r2, r3 + ble .L1013 + ldr r0, .L1044+4 + movw r2, #2606 + ldr r1, .L1044+8 + bl printk +.L1013: + ldr r3, .L1044+20 + mov r8, #0 + ldrh r1, [r4, #4] + mov r9, r5 + mov r2, r8 + mov r0, r8 + ldr ip, [r3, #3776] + str r1, [sp, #16] + mov r1, r5 + str r5, [sp, #4] + mov r3, ip + str ip, [sp, #20] + b .L1014 +.L1016: + str r0, [r3, #8] + movw r5, #65535 + str r0, [r3, #12] + ldrh lr, [r1, #16] + cmp lr, r5 + beq .L1015 + ldr r5, [sp, #20] + mov ip, #20 + mov lr, lr, asl #10 + mla sl, ip, r8, r5 + add r8, r8, #1 + uxth r8, r8 + str lr, [sl, #4] +.L1015: + add r2, r2, #1 + add r3, r3, #20 + add r1, r1, #2 + uxth r2, r2 +.L1014: + ldr sl, [sp, #16] + cmp r2, sl + bne .L1016 + cmp r8, #0 + ldr r5, [sp, #4] + bne .L1017 + ldr r0, .L1044+4 + movw r2, #2617 + ldr r1, .L1044+8 + bl printk +.L1017: + ldr r3, [r4, #2436] + cmp r3, #0 + beq .L1018 + ldr r3, .L1044+24 + cmp r5, r3 + bne .L1018 + ldr r2, [r4, #2244] + mov r3, r6, asl #1 + ldrh r3, [r2, r3] + cmp r3, #30 + movhi r3, #0 + strhib r3, [r4, #2284] +.L1018: + movw r3, #2572 + ldrh r3, [r7, r3] + cmp r3, r6 + bne .L1019 + ldr r0, .L1044+4 + mov r2, #2624 + ldr r1, .L1044+8 + bl printk +.L1019: + ldrb r3, [r5, #8] @ zero_extendqisi2 + ldr r2, [r4, #2244] + cmp r3, #0 + mov r3, r6, asl #1 + ldrh r1, [r2, r3] + bne .L1020 + cmp r1, #0 + ldrneh r0, [r4, #62] + moveq r1, #2 + addne r1, r1, r0 + strh r1, [r2, r3] @ movhi + ldr r3, [r4, #2484] + mov r0, r6 + mov r1, #0 + add r3, r3, #1 + str r3, [r4, #2484] + b .L1043 +.L1020: + add r1, r1, #1 + strh r1, [r2, r3] @ movhi + ldr r3, [r4, #2488] + mov r0, r6 + mov r1, #1 + add r3, r3, #1 + str r3, [r4, #2488] +.L1043: + bl ftl_set_blk_mode + ldr r3, [r4, #2244] + mov ip, r6, asl #1 + ldr r2, [r4, #2500] + ldr r0, [r7, #2484] + mov sl, #0 + ldrh r3, [r3, ip] + ldrh r1, [r7, #12] + cmp r3, r2 + ldrh r2, [r7, #62] + strhi r3, [r4, #2500] + ldr r3, [r7, #2488] + str ip, [sp, #16] + mla r0, r0, r2, r3 + bl __aeabi_uidiv + ldr r3, .L1044+28 + ldr r3, [r3, #4016] + ldr r2, [r3, #16] + add r2, r2, #1 + str r2, [r3, #16] + ldr r3, .L1044+20 + ldr r3, [r3, #3776] + str r0, [r7, #2492] + b .L1025 +.L1026: + add sl, sl, #1 + ldr r2, [r3, #-16] + uxth sl, sl + bic r2, r2, #1020 + bic r2, r2, #3 + str r2, [r3, #-16] +.L1025: + cmp sl, r8 + add r3, r3, #20 + bne .L1026 + ldr r8, .L1044+20 + mov r2, sl + ldrb r1, [r5, #8] @ zero_extendqisi2 + ldr r0, [r8, #3776] + bl FlashEraseBlocks + mov ip, #20 + mul ip, ip, sl + mov sl, #0 + mov r2, r8 + str r6, [sp, #20] + mov r8, sl + mov r6, ip + b .L1027 +.L1029: + ldr r1, [r2, #3776] + add r0, r1, sl + ldr r1, [r1, sl] + cmn r1, #1 + bne .L1028 + ldr r0, [r0, #4] + add r8, r8, #1 + str r1, [sp, #12] + ubfx r0, r0, #10, #16 + str r2, [sp, #8] + bl FtlBbmMapBadBlock + ldr r1, [sp, #12] + strh r1, [r9, #16] @ movhi + ldrb r1, [r5, #7] @ zero_extendqisi2 + sub r1, r1, #1 + strb r1, [r5, #7] + ldr r2, [sp, #8] +.L1028: + add sl, sl, #20 + add r9, r9, #2 +.L1027: + cmp sl, r6 + bne .L1029 + cmp r8, #0 + ldr r6, [sp, #20] + beq .L1030 + mov r0, r6 + bl update_multiplier_value + bl FtlBbmTblFlush +.L1030: + ldrb r2, [r5, #7] @ zero_extendqisi2 + ldr r3, .L1044 + cmp r2, #0 + bne .L1031 + ldr r3, [r4, #2256] + mvn r2, #0 + ldr sl, [sp, #16] + mov r0, r6 + strh r2, [r3, sl] @ movhi + bl INSERT_DATA_LIST + b .L1041 +.L1031: + ldrh r1, [r3, #72] + strh r6, [r5, #0] @ movhi + mul r2, r1, r2 + mov r1, #0 + strh r1, [r5, #2] @ movhi + strb r1, [r5, #6] + ldr r1, [r3, #2476] + uxth r2, r2 + strh r2, [r5, #4] @ movhi + str r1, [r5, #12] + add r1, r1, #1 + str r1, [r3, #2476] + ldrh r0, [r5, #0] + ldr r1, [r3, #2256] + mov r3, r0, asl #1 + strh r2, [r1, r3] @ movhi + ldrh r3, [r5, #4] + cmp r3, #0 + beq .L1032 + ldrb r3, [r5, #7] @ zero_extendqisi2 + cmp r3, #0 + bne .L1033 +.L1032: + ldr r0, .L1044+4 + movw r2, #2677 + ldr r1, .L1044+8 + bl printk +.L1033: + mov r0, #0 + add sp, sp, #28 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} +.L1045: + .align 2 +.L1044: + .word .LANCHOR0 + .word .LC1 + .word .LANCHOR1+459 + .word .LANCHOR0+2372 + .word .LANCHOR0+2268 + .word .LANCHOR3 + .word .LANCHOR0+2276 + .word .LANCHOR4 + .fnend + .size allocate_data_superblock, .-allocate_data_superblock + .align 2 + .global FtlWriteDump_data + .type FtlWriteDump_data, %function +FtlWriteDump_data: + .fnstart + @ args = 0, pretend = 0, frame = 24 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, r7, r8, sl, lr} + .save {r4, r5, r6, r7, r8, sl, lr} + movw r3, #2280 + ldr r5, .L1055 + .pad #28 + sub sp, sp, #28 + ldrh r3, [r5, r3] + mov r2, r5 + cmp r3, #0 + beq .L1047 + ldrb r1, [r5, #2284] @ zero_extendqisi2 + cmp r1, #0 + bne .L1047 + ldrb r1, [r5, #2283] @ zero_extendqisi2 + ldrh r0, [r5, #72] + mul r1, r0, r1 + cmp r3, r1 + beq .L1047 + ldrb r8, [r5, #2286] @ zero_extendqisi2 + ldr r7, [r5, #2440] + cmp r8, #0 + ldrh r6, [r5, #4] + bne .L1046 + sub r7, r7, #1 + mov r2, r8 + mov r1, sp + mov r0, r7 + bl log2phys + ldr r2, .L1055+4 + ldr r3, [sp, #0] + ldr r0, [r5, #2240] + ldr r4, [r2, #-836] + cmn r3, #1 + str r3, [sp, #8] + str r7, [sp, #20] + str r0, [sp, #12] + str r4, [sp, #16] + str r8, [r4, #4] + beq .L1049 + add r0, sp, #4 + mov r1, #1 + mov r2, r8 + bl FlashReadPages + b .L1050 +.L1049: + mov r1, #255 + ldrh r2, [r5, #82] + bl ftl_memset +.L1050: + ldr r3, .L1055+8 + mov r6, r6, asl #2 + ldr r5, .L1055 + movw sl, #2280 + movw r8, #2276 + strh r3, [r4, #0] @ movhi + b .L1051 +.L1054: + ldrh r3, [r5, sl] + cmp r3, #0 + beq .L1052 + ldr r3, [sp, #8] + sub r6, r6, #1 + str r7, [r4, #8] + ldr r0, .L1055+12 + str r3, [r4, #12] + ldrh r3, [r5, r8] + strh r3, [r4, #2] @ movhi + bl get_new_active_ppa + ldr r3, [r5, #2480] + mov r2, #0 + mov r1, #1 + str r0, [sp, #8] + add r0, sp, #4 + str r3, [r4, #4] + add r3, r3, #1 + cmn r3, #1 + str r3, [r5, #2480] + moveq r3, #0 + streq r3, [r5, #2480] + mov r3, r2 + bl FlashProgPages + ldrh r0, [r5, r8] + bl decrement_vpc_count +.L1051: + cmp r6, #0 + bne .L1054 +.L1052: + ldr r3, .L1055 + mov r2, #1 + strb r2, [r3, #2286] + b .L1046 +.L1047: + mov r3, #0 + strb r3, [r2, #2286] +.L1046: + add sp, sp, #28 + ldmfd sp!, {r4, r5, r6, r7, r8, sl, pc} +.L1056: + .align 2 +.L1055: + .word .LANCHOR0 + .word .LANCHOR3 + .word -3947 + .word .LANCHOR0+2276 + .fnend + .size FtlWriteDump_data, .-FtlWriteDump_data + .align 2 + .global l2p_flush + .type l2p_flush, %function +l2p_flush: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, lr} + .save {r4, r5, r6, lr} + bl FtlWriteDump_data + mov r4, #0 + ldr r5, .L1061 + mov r6, #12 + b .L1058 +.L1060: + ldr r3, [r5, #2420] + mla r3, r6, r4, r3 + ldr r3, [r3, #4] + cmp r3, #0 + bge .L1059 + mov r0, r4 + bl flush_l2p_region +.L1059: + add r4, r4, #1 + uxth r4, r4 +.L1058: + ldrh r3, [r5, #110] + cmp r3, r4 + bhi .L1060 + mov r0, #0 + ldmfd sp!, {r4, r5, r6, pc} +.L1062: + .align 2 +.L1061: + .word .LANCHOR0 + .fnend + .size l2p_flush, .-l2p_flush + .align 2 + .global allocate_new_data_superblock + .type allocate_new_data_superblock, %function +allocate_new_data_superblock: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, lr} + .save {r4, r5, r6, lr} + mov r5, r0 + ldr r6, .L1070 + ldrh r4, [r0, #0] + ldrh r3, [r6, #12] + cmp r3, r4 + bcs .L1064 + ldr r0, .L1070+4 + movw r2, #2684 + ldr r1, .L1070+8 + bl printk +.L1064: + movw r3, #65535 + cmp r4, r3 + beq .L1065 + ldr r2, [r6, #2256] + mov r3, r4, asl #1 + mov r0, r4 + ldrh r3, [r2, r3] + cmp r3, #0 + beq .L1066 + bl INSERT_DATA_LIST + b .L1065 +.L1066: + bl INSERT_FREE_LIST +.L1065: + ldr r2, .L1070+12 + mov r3, #1 + strb r3, [r5, #8] + movw r3, #3948 + ldrh r0, [r2, r3] + movw r3, #65535 + cmp r0, r3 + beq .L1067 + cmp r4, r0 + bne .L1068 + ldr r3, .L1070 + ldr r2, [r3, #2256] + mov r3, r0, asl #1 + ldrh r3, [r2, r3] + cmp r3, #0 + beq .L1069 +.L1068: + bl update_vpc_list +.L1069: + ldr r2, .L1070+12 + movw r3, #3948 + mvn r1, #0 + strh r1, [r2, r3] @ movhi +.L1067: + mov r0, r5 + bl allocate_data_superblock + bl l2p_flush + mov r0, #0 + bl FtlEctTblFlush + bl FtlVpcTblFlush + mov r0, #0 + ldmfd sp!, {r4, r5, r6, pc} +.L1071: + .align 2 +.L1070: + .word .LANCHOR0 + .word .LC1 + .word .LANCHOR1+484 + .word .LANCHOR4 + .fnend + .size allocate_new_data_superblock, .-allocate_new_data_superblock + .align 2 + .global FtlProgPages + .type FtlProgPages, %function +FtlProgPages: + .fnstart + @ args = 0, pretend = 0, frame = 8 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r0, r1, r2, r4, r5, r6, r7, r8, sl, lr} + .save {r0, r1, r2, r4, r5, r6, r7, r8, sl, lr} + mov r4, r3 + mov r2, #0 + ldrb r3, [r3, #9] @ zero_extendqisi2 + mov r5, r0 + mov sl, r1 + mov r7, #0 + bl FlashProgPages + ldr r6, .L1085 + b .L1073 +.L1076: + ldr r0, [r5, #4] + ubfx r0, r0, #10, #16 + bl P2V_block_in_plane + ldrh r3, [r4, #0] + cmp r3, r0 + bne .L1074 + ldr r2, [r6, #2256] + mov r3, r3, asl #1 + ldrh r1, [r4, #4] + ldrh r0, [r2, r3] + rsb r1, r1, r0 + strh r1, [r2, r3] @ movhi + ldrh r3, [r6, #72] + strb r8, [r4, #6] + strh r8, [r4, #4] @ movhi + strh r3, [r4, #2] @ movhi +.L1074: + ldrh r3, [r4, #4] + cmp r3, #0 + bne .L1075 + mov r0, r4 + bl allocate_new_data_superblock +.L1075: + ldr r3, [r6, #2720] + add r3, r3, #1 + str r3, [r6, #2720] + ldr r0, [r5, #4] + ubfx r0, r0, #10, #16 + bl FtlGcMarkBadPhyBlk + mov r0, r4 + bl get_new_active_ppa + mov r1, #1 + mov r2, #0 + str r0, [r5, #4] + str r0, [sp, #4] + mov r0, r5 + ldrb r3, [r4, #9] @ zero_extendqisi2 + bl FlashProgPages + b .L1083 +.L1084: + mov r8, #0 +.L1083: + ldr r3, [r5, #0] + cmn r3, #1 + beq .L1076 + ldrb r2, [r4, #6] @ zero_extendqisi2 + ldrh r3, [r6, #4] + cmp r2, r3 + bcc .L1077 + ldr r0, .L1085+4 + movw r2, #994 + ldr r1, .L1085+8 + bl printk +.L1077: + ldr r3, [r5, #4] + add r1, sp, #4 + ldr r0, [r5, #16] + mov r2, #1 + str r3, [sp, #4] + bl log2phys + ldr r3, [r5, #12] + ldr r0, [r3, #12] + cmn r0, #1 + beq .L1078 + ubfx r0, r0, #10, #16 + bl P2V_block_in_plane + ldr r2, [r6, #2256] + mov r3, r0, asl #1 + mov r8, r0 + ldrh r2, [r2, r3] + cmp r2, #0 + bne .L1079 + ldr r0, .L1085+12 + mov r1, r8 + bl printk +.L1079: + mov r0, r8 + bl decrement_vpc_count +.L1078: + add r7, r7, #1 + add r5, r5, #20 +.L1073: + cmp r7, sl + bne .L1084 + ldr r3, .L1085 + ldrb r2, [r4, #6] @ zero_extendqisi2 + ldrh r3, [r3, #4] + cmp r2, r3 + bcc .L1072 + ldr r0, .L1085+4 + movw r2, #1009 + ldr r1, .L1085+8 + bl printk +.L1072: + ldmfd sp!, {r1, r2, r3, r4, r5, r6, r7, r8, sl, pc} +.L1086: + .align 2 +.L1085: + .word .LANCHOR0 + .word .LC1 + .word .LANCHOR1+513 + .word .LC100 + .fnend + .size FtlProgPages, .-FtlProgPages + .align 2 + .global FtlCacheWriteBack + .type FtlCacheWriteBack, %function +FtlCacheWriteBack: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, lr} + .save {r4, lr} + ldr r4, .L1089 + ldr r0, [r4, #3944] + cmp r0, #0 + beq .L1088 + ldr r3, .L1089+4 + mov r1, #1 + mov r2, #0 + ldr r3, [r3, #-4020] + bl FtlProgPages + mov r3, #0 + str r3, [r4, #3944] +.L1088: + mov r0, #0 + ldmfd sp!, {r4, pc} +.L1090: + .align 2 +.L1089: + .word .LANCHOR4 + .word .LANCHOR5 + .fnend + .size FtlCacheWriteBack, .-FtlCacheWriteBack + .align 2 + .global FtlGcFreeTempBlock + .type FtlGcFreeTempBlock, %function +FtlGcFreeTempBlock: + .fnstart + @ args = 0, pretend = 0, frame = 8 + @ frame_needed = 0, uses_anonymous_args = 0 + ldr r3, .L1114 + stmfd sp!, {r0, r1, r2, r4, r5, r6, r7, r8, sl, lr} + .save {r0, r1, r2, r4, r5, r6, r7, r8, sl, lr} + movw r2, #2372 + ldrh r4, [r3, r2] + movw r2, #65535 + ldrh r1, [r3, #72] + cmp r4, r2 + beq .L1092 + cmp r0, #0 + beq .L1093 + ldr r0, .L1114+4 + ldrh ip, [r0, #4] + cmp ip, r2 + movne r1, #2 + bne .L1093 + mov r2, #0 + strh r2, [r0, #4] @ movhi + mov r2, #2272 + ldrh r3, [r3, r2] + cmp r3, #17 + movhi r1, #2 +.L1093: + ldr r0, .L1114+8 + bl FtlGcScanTempBlk + cmn r0, #1 + str r0, [sp, #4] + beq .L1094 + ldr r3, .L1114 + mov r4, r4, asl #1 + ldr r3, [r3, #2244] + ldrh r2, [r3, r4] + cmp r2, #4 + bls .L1095 + sub r2, r2, #5 + mov r0, #1 + strh r2, [r3, r4] @ movhi + bl FtlEctTblFlush +.L1095: + ldr r3, .L1114+12 + ldr r3, [r3, #3800] + cmp r3, #0 + bne .L1096 + ldr r3, .L1114 + ldr r0, [sp, #4] + ldr r2, [r3, #2720] + ubfx r0, r0, #10, #16 + add r2, r2, #1 + str r2, [r3, #2720] + bl FtlBbmMapBadBlock + bl FtlBbmTblFlush +.L1096: + ldr r3, .L1114+12 + mov r2, #0 + str r2, [r3, #3800] + b .L1109 +.L1094: + ldr r3, .L1114+4 + ldrh r2, [r3, #4] + movw r3, #65535 + cmp r2, r3 + bne .L1109 +.L1092: + ldr r3, .L1114+12 + mov r0, #0 + ldr r4, .L1114 + str r0, [r3, #3800] + movw r3, #2372 + ldrh r2, [r4, r3] + movw r3, #65535 + cmp r2, r3 + beq .L1097 + bl FtlCacheWriteBack + movw r3, #3188 + ldrh r2, [r4, r3] + ldrh r1, [r4, #72] + ldrb r3, [r4, #2379] @ zero_extendqisi2 + mul r3, r1, r3 + cmp r2, r3 + beq .L1098 + ldr r0, .L1114+16 + mov r2, #163 + ldr r1, .L1114+20 + bl printk +.L1098: + ldr r5, .L1114 + movw r3, #2372 + movw sl, #3188 + mov r6, #0 + ldrb r1, [r5, #2379] @ zero_extendqisi2 + ldrh r0, [r5, #72] + ldrh r3, [r5, r3] + ldr r2, [r5, #2256] + mul r1, r0, r1 + mov r3, r3, asl #1 + strh r1, [r2, r3] @ movhi + ldr r3, [r5, #2464] + ldrh r2, [r5, sl] + add r3, r2, r3 + str r3, [r5, #2464] + b .L1099 +.L1103: + mov r7, #12 + ldr r8, [r5, #3184] + mul r7, r7, r6 + ldr r3, [r5, #2440] + add r4, r8, r7 + ldr r2, [r4, #8] + cmp r2, r3 + bcc .L1100 + ldr r0, .L1114+16 + mov r2, #169 + ldr r1, .L1114+20 + bl printk +.L1100: + ldr r0, [r4, #8] + add r1, sp, #4 + mov r2, #0 + bl log2phys + ldr r0, [sp, #4] + ldr r3, [r8, r7] + cmp r0, r3 + bne .L1101 + ubfx r0, r0, #10, #16 + bl P2V_block_in_plane + add r1, r4, #4 + mov r2, #1 + mov r7, r0 + ldr r0, [r4, #8] + bl log2phys + mov r0, r7 + b .L1112 +.L1101: + ldr r3, [r4, #4] + cmp r0, r3 + beq .L1102 + movw r3, #2372 + ldrh r0, [r5, r3] +.L1112: + bl decrement_vpc_count +.L1102: + add r6, r6, #1 + uxth r6, r6 +.L1099: + ldrh r3, [r5, sl] + ldr r4, .L1114 + cmp r3, r6 + bhi .L1103 + movw r0, #65535 + movw r5, #2372 + bl decrement_vpc_count + ldrh r0, [r4, r5] + ldr r2, [r4, #2256] + mov r3, r0, asl #1 + ldrh r3, [r2, r3] + cmp r3, #0 + beq .L1104 + bl INSERT_DATA_LIST + b .L1105 +.L1104: + bl INSERT_FREE_LIST +.L1105: + ldr r4, .L1114 + movw r2, #3188 + mvn r3, #0 + strh r3, [r4, r5] @ movhi + mov r3, #0 + strh r3, [r4, r2] @ movhi + movw r2, #3176 + strh r3, [r4, r2] @ movhi + bl l2p_flush + bl FtlVpcTblFlush + ldr r3, [r4, #2436] + mov r1, r4 + movw r2, #2556 + cmp r3, #0 + beq .L1106 + ldr r3, [r4, #2504] + cmp r3, #29 + bhi .L1106 + ldrh r3, [r4, r2] + mov r2, #2272 + ldrh r2, [r4, r2] + mvn r1, #0 + cmp r2, r3 + movcc r3, r3, asl #1 + movcc r2, #3136 + strcch r3, [r4, r2] @ movhi + movw r3, #2572 + ldr r2, .L1114 + b .L1113 +.L1106: + ldrh r2, [r1, r2] + mov r0, #2272 + ldrh r0, [r1, r0] + ldr r3, .L1114 + add r2, r2, r2, asl #1 + cmp r0, r2, lsr #2 + ble .L1111 + movw r2, #2572 + mvn r1, #0 + strh r1, [r3, r2] @ movhi + mov r1, #20 + mov r2, #3136 +.L1113: + strh r1, [r3, r2] @ movhi + b .L1111 +.L1109: + mov r0, #1 + b .L1097 +.L1111: + mov r0, #0 +.L1097: + ldmfd sp!, {r1, r2, r3, r4, r5, r6, r7, r8, sl, pc} +.L1115: + .align 2 +.L1114: + .word .LANCHOR0 + .word .LANCHOR2 + .word .LANCHOR0+2372 + .word .LANCHOR3 + .word .LC1 + .word .LANCHOR1+526 + .fnend + .size FtlGcFreeTempBlock, .-FtlGcFreeTempBlock + .align 2 + .global Ftl_gc_temp_data_write_back + .type Ftl_gc_temp_data_write_back, %function +Ftl_gc_temp_data_write_back: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, r7, r8, lr} + .save {r4, r5, r6, r7, r8, lr} + mov r2, #0 + ldr r4, .L1122 + mov r3, r2 + ldr r5, .L1122+4 + mov r6, #0 + mov r7, #20 + ldr r0, [r4, #3988] + ldr r1, [r5, #3152] + bl FlashProgPages + b .L1117 +.L1120: + mul r3, r7, r6 + ldr r1, [r4, #3988] + add r2, r1, r3 + ldr r1, [r1, r3] + cmn r1, #1 + bne .L1118 + movw r2, #2372 + ldr lr, [r8, #2256] + ldrh ip, [r8, r2] + mov r4, #0 + mov ip, ip, asl #1 + strh r4, [lr, ip] @ movhi + strh r1, [r8, r2] @ movhi + ldr r2, [r8, #2720] + add r2, r2, #1 + str r2, [r8, #2720] + ldr r2, [r0, #3988] + add r3, r2, r3 + ldr r0, [r3, #4] + ubfx r0, r0, #10, #16 + bl FtlBbmMapBadBlock + bl FtlBbmTblFlush + bl FtlGcPageVarInit + mov r0, #1 + ldmfd sp!, {r4, r5, r6, r7, r8, pc} +.L1118: + ldr r3, [r2, #12] + add r6, r6, #1 + ldr r1, [r2, #4] + uxth r6, r6 + ldr r0, [r3, #12] + ldr r2, [r3, #8] + bl FtlGcUpdatePage +.L1117: + ldr r1, [r5, #3152] + ldr r8, .L1122+4 + cmp r6, r1 + ldr r0, .L1122 + bcc .L1120 + ldr r0, [r0, #3988] + bl FtlGcBufFree + movw r3, #2376 + ldrh r3, [r8, r3] + mov r0, #0 + str r0, [r8, #3152] + cmp r3, r0 + ldmnefd sp!, {r4, r5, r6, r7, r8, pc} + mov r0, #1 + bl FtlGcFreeTempBlock + mov r0, #1 + ldmfd sp!, {r4, r5, r6, r7, r8, pc} +.L1123: + .align 2 +.L1122: + .word .LANCHOR4 + .word .LANCHOR0 + .fnend + .size Ftl_gc_temp_data_write_back, .-Ftl_gc_temp_data_write_back + .align 2 + .global FtlGcPageRecovery + .type FtlGcPageRecovery, %function +FtlGcPageRecovery: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, lr} + .save {r4, lr} + ldr r4, .L1126 + ldr r0, .L1126+4 + ldrh r1, [r4, #72] + bl FtlGcScanTempBlk + movw r3, #2374 + ldrh r2, [r4, r3] + ldrh r3, [r4, #72] + cmp r2, r3 + ldmccfd sp!, {r4, pc} + ldr r0, .L1126+8 + bl FtlMapBlkWriteDump_data + mov r0, #0 + bl FtlGcFreeTempBlock + ldr r3, .L1126+12 + mov r2, #0 + str r2, [r3, #3800] + ldmfd sp!, {r4, pc} +.L1127: + .align 2 +.L1126: + .word .LANCHOR0 + .word .LANCHOR0+2372 + .word .LANCHOR3+3812 + .word .LANCHOR3 + .fnend + .size FtlGcPageRecovery, .-FtlGcPageRecovery + .align 2 + .global FtlPowerLostRecovery + .type FtlPowerLostRecovery, %function +FtlPowerLostRecovery: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, lr} + .save {r3, r4, r5, lr} + mov r4, #0 + ldr r3, .L1129 + ldr r5, .L1129+4 + str r4, [r3, #4032] + mov r0, r5 + bl FtlRecoverySuperblock + mov r0, r5 + add r5, r5, #48 + bl FtlSlcSuperblockCheck + mov r0, r5 + bl FtlRecoverySuperblock + mov r0, r5 + bl FtlSlcSuperblockCheck + bl FtlGcPageRecovery + movw r0, #65535 + bl decrement_vpc_count + mov r0, r4 + ldmfd sp!, {r3, r4, r5, pc} +.L1130: + .align 2 +.L1129: + .word .LANCHOR4 + .word .LANCHOR0+2276 + .fnend + .size FtlPowerLostRecovery, .-FtlPowerLostRecovery + .align 2 + .global Ftl_get_new_temp_ppa + .type Ftl_get_new_temp_ppa, %function +Ftl_get_new_temp_ppa: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, lr} + .save {r3, r4, r5, lr} + movw r3, #2372 + ldr r5, .L1134 + ldrh r2, [r5, r3] + movw r3, #65535 + cmp r2, r3 + beq .L1132 + movw r3, #2376 + ldrh r3, [r5, r3] + cmp r3, #0 + bne .L1133 +.L1132: + bl FtlCacheWriteBack + mov r0, #0 + bl FtlGcFreeTempBlock + ldr r0, .L1134+4 + mov r4, #0 + strb r4, [r5, #2380] + bl allocate_data_superblock + movw r3, #3176 + strh r4, [r5, r3] @ movhi + add r3, r3, #12 + strh r4, [r5, r3] @ movhi + bl l2p_flush + mov r0, r4 + bl FtlEctTblFlush + bl FtlVpcTblFlush +.L1133: + ldr r0, .L1134+4 + ldmfd sp!, {r3, r4, r5, lr} + b get_new_active_ppa +.L1135: + .align 2 +.L1134: + .word .LANCHOR0 + .word .LANCHOR0+2372 + .fnend + .size Ftl_get_new_temp_ppa, .-Ftl_get_new_temp_ppa + .align 2 + .type rk_ftl_garbage_collect.part.12, %function +rk_ftl_garbage_collect.part.12: + .fnstart + @ args = 0, pretend = 0, frame = 24 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r4, r5, r6, r7, r8, r9, sl, fp, lr} + movw r3, #3192 + ldr r4, .L1223 + mov r7, r1 + mov r5, r0 + movw r0, #65535 + .pad #36 + sub sp, sp, #36 + ldrh r1, [r4, r3] + cmp r1, r0 + beq .L1137 + movw r2, #3190 + ldrh ip, [r4, r2] + cmp ip, r0 + streqh r1, [r4, r2] @ movhi + mvneq r2, #0 + streqh r2, [r4, r3] @ movhi +.L1137: + bl FtlReadRefresh + ldr r1, [r4, #3140] + movw r3, #2572 + ldr r8, .L1223 + ldrh r2, [r4, r3] + add r1, r1, #1 + add r1, r1, r5, asl #7 + str r1, [r4, #3140] + movw r4, #65535 + cmp r2, r4 + bne .L1138 + movw r3, #2372 + ldrh r3, [r8, r3] + cmp r3, r2 + movne r4, r2 + bne .L1138 + movw r2, #3190 + ldrh sl, [r8, r2] + cmp sl, r3 + movne r4, r3 + bne .L1138 + mov r9, #2272 + ldrh r3, [r8, r9] + cmp r3, #23 + movhi r3, #1024 + movls r3, #5120 + cmp r1, r3 + movls r4, sl + bls .L1138 + ldr r2, .L1223+4 + mov r3, #0 + ldr r1, .L1223+8 + mov r6, r8 + str r3, [r8, #3140] + strh r3, [r1, r2] @ movhi + bl GetSwlReplaceBlock + cmp r0, sl + mov r4, r0 + bne .L1140 + movw sl, #3138 + ldrh r2, [r8, r9] + ldrh r3, [r8, sl] + cmp r2, r3 + movcs r3, #80 + strcsh r3, [r8, sl] @ movhi + bcs .L1150 + mov r0, #64 + bl List_get_gc_head_node + uxth r0, r0 + cmp r0, r4 + beq .L1150 + ldr r3, .L1223+12 + ldr r3, [r3, #3964] + cmp r3, #0 + bne .L1143 + ldr r3, [r8, #2620] + cmp r3, #0 + beq .L1144 +.L1143: + ldr r3, .L1223 + mov r0, r0, asl #1 + ldr r2, [r3, #2256] + ldrh ip, [r3, #24] + ldrh r1, [r2, r0] + cmp ip, #3 + ldrh r2, [r3, #74] + ldrh r0, [r3, #4] + mul r0, r0, r2 + moveq r2, r2, lsr #1 + movne r2, #0 + add r2, r0, r2 + cmp r1, r2 + bgt .L1146 + mov r0, #0 + bl List_get_gc_head_node + ldr r3, .L1223 + ldr r2, [r3, #2440] + ldr r1, [r3, #2428] + add r2, r2, r2, asl #1 + cmp r1, r2, lsr #2 + movw r2, #3138 + movhi r1, #128 + movls r1, #160 + strh r1, [r3, r2] @ movhi + uxth r4, r0 + b .L1148 +.L1146: + movw r2, #3138 + mov r1, #128 + strh r1, [r3, r2] @ movhi + b .L1150 +.L1144: + ldr r3, [r8, #2256] + mov r0, r0, asl #1 + ldrh r3, [r3, r0] + cmp r3, #7 + movhi r3, #64 + strhih r3, [r8, sl] @ movhi + bhi .L1150 + mov r0, #0 + bl List_get_gc_head_node + mov r3, #128 + strh r3, [r8, sl] @ movhi + uxth r4, r0 +.L1148: + movw r3, #65535 + cmp r4, r3 + beq .L1150 +.L1140: + ldr r1, .L1223 + mov r3, #2272 + mov r0, r4, asl #1 + ldrh r2, [r1, r3] + ldr ip, [r1, #2244] + ldr r3, [r1, #2256] + ldrh r3, [r3, r0] + ldrh r0, [ip, r0] + str r0, [sp, #0] + mov r0, #3136 + ldrh r1, [r1, r0] + ldr r0, .L1223+16 + str r1, [sp, #4] + mov r1, r4 + bl printk +.L1150: + bl FtlGcReFreshBadBlk +.L1138: + movw r1, #65535 + rsb r0, r1, r4 + rsbs r2, r0, #0 + ldr r8, .L1223 + adc r2, r2, r0 + cmp r5, #0 + movne r5, #0 + andeq r5, r2, #1 + cmp r5, #0 + beq .L1151 + mov r3, #2272 + ldrh r2, [r8, r3] + cmp r2, #24 + movhi r6, #1 + bhi .L1152 + ldrh r6, [r8, #72] + cmp r2, #16 + movhi r6, r6, lsr #5 + bhi .L1152 + cmp r2, #12 + movhi r6, r6, lsr #4 + bhi .L1152 + cmp r2, #8 + movhi r6, r6, lsr #2 +.L1152: + mov r1, #3136 + ldr r3, .L1223 + ldrh r0, [r8, r1] + cmp r0, r2 + bcs .L1156 + movw r2, #2372 + movw r0, #65535 + ldrh r2, [r3, r2] + cmp r2, r0 + bne .L1157 + movw r0, #3190 + ldrh r0, [r3, r0] + cmp r0, r2 + bne .L1157 + ldr r2, .L1223+4 + ldr r0, .L1223+8 + ldrh r0, [r0, r2] + cmp r0, #0 + bne .L1158 + ldr r2, [r3, #2440] + ldr ip, [r3, #2428] + add r2, r2, r2, asl #1 + cmp ip, r2, lsr #2 + movcs r2, #18 + bcs .L1221 +.L1158: + ldr r3, .L1223 + movw r2, #2556 + mov r1, #3136 + ldrh r2, [r3, r2] + add r2, r2, r2, asl #1 + mov r2, r2, asr #2 +.L1221: + strh r2, [r3, r1] @ movhi + mov r2, #0 + ldr r3, .L1223 + str r2, [r3, #3148] + b .L1161 +.L1157: + ldr r3, .L1223 + movw r2, #2556 + mov r1, #3136 + ldrh r2, [r3, r2] + add r2, r2, r2, asl #1 + mov r2, r2, asr #2 + strh r2, [r3, r1] @ movhi +.L1156: + ldr r3, .L1223 + cmp r7, #2 + movw r4, #65535 + movhi r7, #0 + movls r7, #1 + ldr r3, [r3, #2436] + cmp r3, #0 + moveq r7, #0 + cmp r7, #0 + addne r6, r6, #1 + uxthne r6, r6 + b .L1162 +.L1151: + movw r3, #2372 + ldrh r3, [r8, r3] + cmp r3, r1 + bne .L1163 + movw r1, #3190 + ldrh r1, [r8, r1] + cmp r1, r3 + movne r2, #0 + andeq r2, r2, #1 + cmp r2, #0 + beq .L1163 + movw r2, #2572 + ldrh r4, [r8, r2] + cmp r4, r3 + movne r4, r3 + bne .L1163 + mov r3, #2272 + str r5, [r8, #3148] + ldrh r7, [r8, r3] + mov r3, #3136 + ldrh r2, [r8, r3] + ldr r6, .L1223+8 + cmp r2, r7 + ldr r5, .L1223+4 + bcs .L1164 + ldrh r2, [r6, r5] + cmp r2, #0 + bne .L1165 + ldr r2, [r8, #2440] + ldr r1, [r8, #2428] + add r2, r2, r2, asl #1 + cmp r1, r2, lsr #2 + movcs r2, #18 + strcsh r2, [r8, r3] @ movhi + bcs .L1167 +.L1165: + ldr r3, .L1223 + movw r2, #2556 + mov r1, #3136 + ldrh r2, [r3, r2] + add r2, r2, r2, asl #1 + mov r2, r2, asr #2 + strh r2, [r3, r1] @ movhi +.L1167: + bl FtlReadRefresh + b .L1222 +.L1164: + ldrh r0, [r6, r5] + cmp r0, #0 + bne .L1163 + movw r2, #2556 + ldrh r4, [r8, r2] + add r2, r4, r4, asl #1 + mov r2, r2, asr #2 + strh r2, [r8, r3] @ movhi + bl List_get_gc_head_node + ldrh r2, [r8, #74] + ldrh r1, [r8, #4] + ldr r3, [r8, #2256] + mul r2, r1, r2 + add r2, r2, r2, lsr #31 + uxth r0, r0 + mov r0, r0, asl #1 + ldrh r3, [r3, r0] + cmp r3, r2, asr #1 + ble .L1168 + sub r4, r4, #1 + cmp r7, r4 + blt .L1168 + bl FtlReadRefresh + ldrh r0, [r6, r5] + b .L1161 +.L1168: + cmp r3, #0 + movwne r4, #65535 + bne .L1163 + movw r0, #65535 + bl decrement_vpc_count + ldr r2, .L1223 + mov r3, #2272 + ldrh r0, [r2, r3] + add r0, r0, #1 + b .L1161 +.L1163: + ldr r3, .L1223 + ldr r6, [r3, #2436] + cmp r6, #0 + movne r6, #2 + moveq r6, #1 +.L1162: + ldr r3, .L1223 + movw r2, #2572 + movw r0, #65535 + ldrh r1, [r3, r2] + cmp r1, r0 + bne .L1169 + cmp r4, r1 + strneh r4, [r3, r2] @ movhi + bne .L1171 + movw r2, #3190 + ldrh r1, [r3, r2] + cmp r1, r4 + beq .L1171 + ldr r0, [r3, #2256] + mov r1, r1, asl #1 + ldrh r1, [r0, r1] + cmp r1, #0 + mvneq r1, #0 + streqh r1, [r3, r2] @ movhi + ldr r3, .L1223 + movw r1, #2572 + ldrh r0, [r3, r2] + strh r0, [r3, r1] @ movhi + mvn r1, #0 + strh r1, [r3, r2] @ movhi +.L1171: + ldr r8, .L1223 + movw r7, #2572 + mov r3, #0 + ldrh r0, [r8, r7] + strb r3, [r8, #2580] + movw r3, #65535 + cmp r0, r3 + beq .L1169 + bl IsBlkInGcList + ldr r5, .L1223 + cmp r0, #0 + mvnne r3, #0 + strneh r3, [r8, r7] @ movhi + ldrh r2, [r8, r7] + movw r3, #65535 + cmp r2, r3 + beq .L1169 + ldr r0, .L1223+20 + bl make_superblock + movw r1, #2574 + mov r3, #0 + ldr r2, .L1223+8 + strh r3, [r5, r1] @ movhi + ldr r1, .L1223+24 + strb r3, [r5, #2578] + strh r3, [r2, r1] @ movhi + movw r3, #2572 + ldrh r3, [r5, r3] + ldr r1, [r5, #2256] + mov r3, r3, asl #1 + ldrh r1, [r1, r3] + ldr r3, .L1223+28 + strh r1, [r2, r3] @ movhi +.L1169: + ldr r3, .L1223 + movw r1, #2572 + movw r0, #2276 + ldrh r2, [r3, r1] + ldrh r0, [r3, r0] + cmp r0, r2 + beq .L1174 + movw r0, #2324 + ldrh r0, [r3, r0] + cmp r0, r2 + bne .L1204 +.L1174: + mvn r2, #0 + strh r2, [r3, r1] @ movhi +.L1204: + mov fp, r4 +.L1219: + ldr r4, .L1223 + movw sl, #2572 + movw r1, #65535 + ldrh r3, [r4, sl] + cmp r3, r1 + bne .L1176 + movw r5, #3144 + mov r3, #0 + str r3, [r4, #3148] +.L1218: + ldrh r8, [r4, r5] + mov r0, r8 + bl List_get_gc_head_node + movw r2, #65535 + uxth r7, r0 + strh r7, [r4, sl] @ movhi + cmp r7, r2 + bne .L1178 + ldr r2, .L1223 + movw r3, #3144 + mov r1, #0 + mov r0, #8 + strh r1, [r2, r3] @ movhi + b .L1161 +.L1178: + mov r0, r7 + add r8, r8, #1 + bl IsBlkInGcList + cmp r0, #0 + strneh r8, [r4, r5] @ movhi + bne .L1218 + ldrh r1, [r4, #72] + mov r7, r7, asl #1 + ldrh r0, [r4, #4] + uxth r8, r8 + ldr r3, [r4, #2256] + strh r8, [r4, r5] @ movhi + mul r0, r0, r1 + ldrh r2, [r3, r7] + add r1, r0, r0, lsr #31 + cmp r2, r1, asr #1 + bgt .L1181 + cmp r8, #48 + bls .L1182 + cmp r2, #8 + bls .L1182 + movw r2, #3176 + ldrh r2, [r4, r2] + cmp r2, #35 + bhi .L1182 +.L1181: + mov r2, #0 + strh r2, [r4, r5] @ movhi +.L1182: + ldrh r2, [r3, r7] + movw r3, #65535 + movw r1, #2572 + cmp r2, r0 + cmpge fp, r3 + ldr r3, .L1223 + movne r0, #0 + moveq r0, #1 + bne .L1183 + mvn r2, #0 + strh r2, [r3, r1] @ movhi + movw r2, #3144 + mov r1, #0 + strh r1, [r3, r2] @ movhi +.L1222: + ldr r3, .L1223+4 + ldr r2, .L1223+8 + ldrh r0, [r2, r3] + b .L1161 +.L1183: + cmp r2, #0 + bne .L1184 + movw r0, #65535 + bl decrement_vpc_count + ldrh r3, [r4, r5] + add r3, r3, #1 + strh r3, [r4, r5] @ movhi + b .L1218 +.L1184: + ldrh r2, [r3, r1] + movw r1, #2276 + strb r0, [r3, #2580] + ldrh r3, [r3, r1] + cmp r2, r3 + bne .L1185 + ldr r0, .L1223+32 + movw r2, #719 + ldr r1, .L1223+36 + bl printk +.L1185: + ldr r4, .L1223 + movw r5, #2572 + movw r3, #2324 + ldrh r2, [r4, r5] + ldrh r3, [r4, r3] + cmp r2, r3 + bne .L1186 + ldr r0, .L1223+32 + mov r2, #720 + ldr r1, .L1223+36 + bl printk +.L1186: + movw r3, #2372 + ldrh r2, [r4, r5] + ldrh r3, [r4, r3] + cmp r2, r3 + bne .L1187 + ldr r0, .L1223+32 + movw r2, #721 + ldr r1, .L1223+36 + bl printk +.L1187: + ldr r0, .L1223+20 + bl make_superblock + ldr r2, .L1223+8 + ldr r0, .L1223+24 + mov r3, #0 + ldr r4, .L1223 + strh r3, [r2, r0] @ movhi + movw r0, #2572 + ldrh r0, [r4, r0] + ldr ip, [r4, #2256] + mov r0, r0, asl #1 + ldrh ip, [ip, r0] + ldr r0, .L1223+28 + strb r3, [r4, #2578] + strh ip, [r2, r0] @ movhi + movw r2, #2574 + strh r3, [r4, r2] @ movhi +.L1176: + ldr r3, .L1223+12 + mov r2, #1 + mov r9, #0 + ldr r4, .L1223 + str fp, [sp, #20] + str r2, [r3, #3968] + movw r2, #2574 + ldr r3, .L1223 + ldrh r7, [r3, #72] + ldrh r3, [r3, r2] + add r2, r3, r6 + str r7, [sp, #16] + cmp r2, r7 + rsbgt r6, r3, r7 + uxthgt r6, r6 + mov sl, r6 + b .L1189 +.L1191: + ldrh r1, [r2, #2]! + movw r7, #65535 + add r3, r3, #1 + cmp r1, r7 + uxth r3, r3 + orrne r1, ip, r1, asl #10 + mlane r7, r0, r6, lr + addne r6, r6, #1 + uxthne r6, r6 + strne r1, [r7, #4] +.L1198: + cmp r3, r5 + bne .L1191 + ldr r0, [r4, #3168] + mov r1, r6 + ldrb r2, [r4, #2580] @ zero_extendqisi2 + mov r5, #0 + bl FlashReadPages + mov fp, r5 + b .L1192 +.L1196: + ldr r3, [r4, #3168] + add r2, r3, r5 + ldr r3, [r3, r5] + ldr r7, [r2, #12] + cmn r3, #1 + beq .L1193 + ldrh r3, [r7, #0] + movw r1, #61589 + cmp r3, r1 + bne .L1193 + ldr r8, [r7, #8] + cmn r8, #1 + bne .L1194 + ldr r0, .L1223+32 + movw r2, #753 + ldr r1, .L1223+36 + bl printk +.L1194: + add r1, sp, #28 + mov r2, #0 + mov r0, r8 + bl log2phys + ldr r1, [r4, #3168] + ldr r2, [sp, #28] + add r1, r1, r5 + ldr r3, [r1, #4] + cmp r2, r3 + bne .L1193 + ldr r2, .L1223+8 + mov r8, #20 + ldr r3, .L1223+24 + ldr r1, [r1, #16] + ldrh r0, [r2, r3] + add r0, r0, #1 + strh r0, [r2, r3] @ movhi + ldr r3, .L1223+12 + ldr r0, [r4, #3152] + ldr r2, [r3, #3988] + mla r2, r8, r0, r2 + str r1, [r2, #16] + str r2, [sp, #12] + str r3, [sp, #8] + bl Ftl_get_new_temp_ppa + ldr r2, [sp, #12] + mov r1, #1 + str r0, [r2, #4] + ldr r3, [sp, #8] + ldr r2, [r4, #3152] + ldr r3, [r3, #3988] + mla r8, r8, r2, r3 + ldr r3, [r4, #3168] + add r3, r3, r5 + ldr r2, [r3, #8] + str r2, [r8, #8] + ldr r3, [r3, #12] + str r3, [r8, #12] + ldr r3, [sp, #28] + str r3, [r7, #12] + movw r3, #2372 + ldrh r3, [r4, r3] + strh r3, [r7, #2] @ movhi + ldr r3, [r4, #2480] + ldr r0, [r4, #3168] + str r3, [r7, #4] + add r0, r0, r5 + ldr r3, [r4, #3152] + add r3, r3, #1 + str r3, [r4, #3152] + bl FtlGcBufAlloc + ldrb r3, [r4, #2379] @ zero_extendqisi2 + ldr r2, [r4, #3152] + cmp r2, r3 + beq .L1195 + movw r3, #2376 + ldrh r3, [r4, r3] + cmp r3, #0 + bne .L1193 +.L1195: + bl Ftl_gc_temp_data_write_back + cmp r0, #0 + ldrne r3, .L1223+12 + movne r2, #0 + strne r2, [r3, #3968] + bne .L1222 +.L1193: + add fp, fp, #1 + add r5, r5, #20 + uxth fp, fp +.L1192: + cmp fp, r6 + bne .L1196 + add r9, r9, #1 +.L1189: + uxth r3, r9 + ldr r2, .L1223 + cmp r3, sl + movw r3, #2574 + bcs .L1197 + ldrh ip, [r4, r3] + mov r6, #0 + ldrh r5, [r4, #4] + mov r3, r6 + ldr lr, [r4, #3168] + add ip, ip, r9 + ldr r2, .L1223+40 + mov r0, #20 + b .L1198 +.L1197: + ldrh r1, [r2, r3] + ldr fp, [sp, #20] + add r6, sl, r1 + uxth r6, r6 + strh r6, [r2, r3] @ movhi + ldr r3, [sp, #16] + cmp r6, r3 + bcs .L1199 + ldr r3, .L1223+8 + ldr r2, .L1223+24 + ldr r1, .L1223+28 + ldrh r2, [r3, r2] + ldrh r3, [r3, r1] + cmp r2, r3 + bne .L1200 +.L1199: + ldr r3, .L1223 + ldr r5, .L1223+8 + ldr r3, [r3, #3152] + cmp r3, #0 + beq .L1201 + bl Ftl_gc_temp_data_write_back + cmp r0, #0 + beq .L1201 + ldr r3, .L1223+12 + mov r2, #0 + str r2, [r3, #3968] + ldr r3, .L1223+4 + ldrh r0, [r5, r3] + b .L1161 +.L1201: + ldr r3, .L1223+24 + ldrh ip, [r5, r3] + cmp ip, #0 + bne .L1202 + ldr r3, .L1223 + movw r2, #2572 + ldrh r1, [r3, r2] + ldr r0, [r3, #2256] + mov r1, r1, asl #1 + ldrh r4, [r0, r1] + cmp r4, #0 + beq .L1202 + strh ip, [r0, r1] @ movhi + ldrh r0, [r3, r2] + bl update_vpc_list + bl FtlCacheWriteBack + bl l2p_flush + bl FtlVpcTblFlush +.L1202: + ldr r2, .L1223 + movw r3, #2572 + mvn r1, #0 + strh r1, [r2, r3] @ movhi +.L1200: + ldr r3, .L1223+12 + mov r2, #0 + str r2, [r3, #3968] + mov r3, #2272 + ldr r2, .L1223 + ldrh r3, [r2, r3] + cmp r3, #2 + ldrlsh r6, [r2, #72] + bls .L1219 +.L1203: + ldr r2, .L1223+4 + ldr r1, .L1223+8 + ldrh r0, [r1, r2] + cmp r0, #0 + addeq r0, r3, #1 +.L1161: + add sp, sp, #36 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} +.L1224: + .align 2 +.L1223: + .word .LANCHOR0 + .word -4016 + .word .LANCHOR5 + .word .LANCHOR4 + .word .LC101 + .word .LANCHOR0+2572 + .word -4014 + .word -4012 + .word .LC1 + .word .LANCHOR1+545 + .word .LANCHOR0+2586 + .fnend + .size rk_ftl_garbage_collect.part.12, .-rk_ftl_garbage_collect.part.12 + .align 2 + .global rk_ftl_garbage_collect + .type rk_ftl_garbage_collect, %function +rk_ftl_garbage_collect: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, lr} + .save {r3, r4, r5, lr} + mov r4, r0 + ldr r3, .L1231 + mov r5, r1 + ldr r0, [r3, #3968] + cmp r0, #0 + movne r0, #0 + ldmnefd sp!, {r3, r4, r5, pc} + ldr r2, .L1231+4 + movw r3, #2264 + ldrh r3, [r2, r3] + cmp r3, #47 + ldmlsfd sp!, {r3, r4, r5, pc} + ldr r3, .L1231+8 + ldrh r1, [r3, #4] + movw r3, #65535 + cmp r1, r3 + beq .L1227 + movw r1, #2372 + ldrh r2, [r2, r1] + cmp r2, r3 + beq .L1227 + mov r0, #1 + bl FtlGcFreeTempBlock + cmp r0, #0 + bne .L1230 +.L1227: + mov r0, r4 + mov r1, r5 + ldmfd sp!, {r3, r4, r5, lr} + b rk_ftl_garbage_collect.part.12 +.L1230: + mov r0, #1 + ldmfd sp!, {r3, r4, r5, pc} +.L1232: + .align 2 +.L1231: + .word .LANCHOR4 + .word .LANCHOR0 + .word .LANCHOR2 + .fnend + .size rk_ftl_garbage_collect, .-rk_ftl_garbage_collect + .align 2 + .global sftl_gc + .type sftl_gc, %function +sftl_gc: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + mov r0, #1 + mov r1, r0 + b rk_ftl_garbage_collect + .fnend + .size sftl_gc, .-sftl_gc + .align 2 + .global FtlDiscard + .type FtlDiscard, %function +FtlDiscard: + .fnstart + @ args = 0, pretend = 0, frame = 8 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r0, r1, r2, r4, r5, r6, r7, lr} + .save {r0, r1, r2, r4, r5, r6, r7, lr} + add r2, r1, r0 + ldr r5, .L1243 + mov r7, r0 + mov r4, r1 + ldr r3, [r5, #112] + cmp r2, r3 + mvnhi r0, #0 + bhi .L1235 + cmp r1, #31 + movls r0, #0 + bls .L1235 + bl FtlCacheWriteBack + ldrh r6, [r5, #78] + mov r0, r7 + mov r1, r6 + bl __aeabi_uidiv + mls r7, r0, r6, r7 + mov r5, r0 + uxth r7, r7 + cmp r7, #0 + beq .L1236 + rsb r6, r7, r6 + add r5, r0, #1 + cmp r6, r4 + movcs r6, r4 + uxth r6, r6 + rsb r4, r6, r4 +.L1236: + mvn r3, #0 + ldr r6, .L1243 + str r3, [sp, #4] + ldr r7, .L1243+4 + b .L1237 +.L1239: + mov r0, r5 + mov r1, sp + mov r2, #0 + bl log2phys + ldr r3, [sp, #0] + cmn r3, #1 + beq .L1238 + ldr r3, [r7, #-4008] + add r1, sp, #4 + mov r2, #1 + mov r0, r5 + add r3, r3, #1 + str r3, [r7, #-4008] + ldr r3, [r6, #2448] + add r3, r3, #1 + str r3, [r6, #2448] + bl log2phys + ldr r0, [sp, #0] + ubfx r0, r0, #10, #16 + bl P2V_block_in_plane + bl decrement_vpc_count +.L1238: + ldrh r3, [r6, #78] + add r5, r5, #1 + rsb r4, r3, r4 +.L1237: + ldrh r3, [r6, #78] + cmp r4, r3 + bcs .L1239 + ldr r3, .L1243+4 + mov r4, #0 + ldr r2, [r3, #-4008] + cmp r2, #32 + bls .L1242 + str r4, [r3, #-4008] + bl l2p_flush + bl FtlVpcTblFlush +.L1242: + mov r0, r4 +.L1235: + ldmfd sp!, {r1, r2, r3, r4, r5, r6, r7, pc} +.L1244: + .align 2 +.L1243: + .word .LANCHOR0 + .word .LANCHOR5 + .fnend + .size FtlDiscard, .-FtlDiscard + .align 2 + .global FtlSysFlush + .type FtlSysFlush, %function +FtlSysFlush: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, lr} + .save {r3, lr} + bl FtlCacheWriteBack + bl l2p_flush + mov r0, #1 + bl FtlEctTblFlush + bl FtlVpcTblFlush + mov r0, #0 + ldmfd sp!, {r3, pc} + .fnend + .size FtlSysFlush, .-FtlSysFlush + .align 2 + .global sftl_deinit + .type sftl_deinit, %function +sftl_deinit: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, lr} + .save {r3, lr} + ldr r3, .L1248 + ldr r3, [r3, #0] + cmp r3, #1 + bne .L1247 + bl FtlSysFlush +.L1247: + mov r0, #0 + ldmfd sp!, {r3, pc} +.L1249: + .align 2 +.L1248: + .word .LANCHOR2 + .fnend + .size sftl_deinit, .-sftl_deinit + .align 2 + .global FtlVpcCheckAndModify + .type FtlVpcCheckAndModify, %function +FtlVpcCheckAndModify: + .fnstart + @ args = 0, pretend = 0, frame = 8 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r0, r1, r4, r5, r6, r7, r8, lr} + .save {r0, r1, r4, r5, r6, r7, r8, lr} + mov r4, #0 + ldr r6, .L1257 + ldr r1, .L1257+4 + ldr r0, .L1257+8 + bl printk + ldr r5, .L1257+12 + ldrh r2, [r6, #14] + mov r1, #0 + ldr r0, [r5, #4020] + mov r2, r2, asl #1 + bl ftl_memset + b .L1251 +.L1253: + mov r0, r4 + add r1, sp, #4 + mov r2, #0 + bl log2phys + ldr r0, [sp, #4] + cmn r0, #1 + beq .L1252 + ubfx r0, r0, #10, #16 + bl P2V_block_in_plane + ldr r3, [r5, #4020] + mov r0, r0, asl #1 + ldrh r2, [r3, r0] + add r2, r2, #1 + strh r2, [r3, r0] @ movhi +.L1252: + add r4, r4, #1 +.L1251: + ldr r3, [r6, #2440] + cmp r4, r3 + bcc .L1253 + mov r4, #0 + ldr r5, .L1257 + ldr r7, .L1257+12 + movw r8, #65535 + b .L1254 +.L1256: + ldr r3, [r5, #2256] + mov r6, r4, asl #1 + ldrh r2, [r3, r6] + ldr r3, [r7, #4020] + ldrh r3, [r3, r6] + cmp r2, r3 + beq .L1255 + cmp r2, r8 + beq .L1255 + ldr r0, .L1257+16 + mov r1, r4 + bl printk + movw r3, #2276 + ldrh r3, [r5, r3] + cmp r3, r4 + beq .L1255 + movw r3, #2372 + ldrh r3, [r5, r3] + cmp r3, r4 + beq .L1255 + movw r3, #2324 + ldrh r3, [r5, r3] + cmp r3, r4 + beq .L1255 + ldr r3, [r7, #4020] + mov r0, r4 + ldrh r2, [r3, r6] + ldr r3, [r5, #2256] + strh r2, [r3, r6] @ movhi + bl update_vpc_list + bl l2p_flush + bl FtlVpcTblFlush +.L1255: + add r4, r4, #1 + uxth r4, r4 +.L1254: + ldrh r3, [r5, #12] + cmp r3, r4 + bhi .L1256 + ldmfd sp!, {r2, r3, r4, r5, r6, r7, r8, pc} +.L1258: + .align 2 +.L1257: + .word .LANCHOR0 + .word .LANCHOR1+568 + .word .LC87 + .word .LANCHOR4 + .word .LC102 + .fnend + .size FtlVpcCheckAndModify, .-FtlVpcCheckAndModify + .align 2 + .global FtlSysBlkInit + .type FtlSysBlkInit, %function +FtlSysBlkInit: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, lr} + .save {r3, r4, r5, lr} + movw r3, #4030 + ldr r2, .L1270 + mov r1, #0 + ldr r4, .L1270+4 + strh r1, [r2, r3] @ movhi + ldrh r0, [r4, #8] + bl FtlFreeSysBlkQueueInit + bl FtlScanSysBlk + mov r3, #2560 + ldrh r2, [r4, r3] + movw r3, #65535 + cmp r2, r3 + beq .L1268 + bl FtlLoadSysInfo + subs r5, r0, #0 + bne .L1268 + bl FtlLoadMapInfo + bl FtlLoadVonderInfo + bl Ftl_load_ext_data + bl FtlLoadEctTbl + bl FtlFreeSysBLkSort + bl SupperBlkListInit + bl FtlPowerLostRecovery + mov r0, #1 + bl FtlUpdateVaildLpn + ldrh r2, [r4, #110] + ldr r1, [r4, #2420] + mov r3, r5 + b .L1261 +.L1263: + add r0, r1, r5 + add r5, r5, #12 + ldr r0, [r0, #4] + cmp r0, #0 + blt .L1262 + add r3, r3, #1 +.L1261: + cmp r3, r2 + blt .L1263 +.L1262: + ldr r4, .L1270+4 + movw r1, #2536 + cmp r3, r2 + ldrh r0, [r4, r1] + add r0, r0, #1 + strh r0, [r4, r1] @ movhi + blt .L1264 + ldr r2, .L1270 + movw r3, #4030 + ldrh r3, [r2, r3] + cmp r3, #0 + beq .L1265 +.L1264: + ldr r0, .L1270+8 + bl FtlSuperblockPowerLostFix + ldr r0, .L1270+12 + bl FtlSuperblockPowerLostFix + movw r3, #2276 + ldrh r3, [r4, r3] + movw r2, #2280 + ldr r1, [r4, #2256] + ldrh r0, [r4, r2] + mov r3, r3, asl #1 + ldrh ip, [r1, r3] + rsb r0, r0, ip + strh r0, [r1, r3] @ movhi + ldrh r1, [r4, #72] + movw r3, #2278 + ldr r0, [r4, #2256] + strh r1, [r4, r3] @ movhi + mov r3, #0 + strh r3, [r4, r2] @ movhi + add r2, r2, #44 + strb r3, [r4, #2282] + ldrh r1, [r4, r2] + add r2, r2, #4 + ldrh ip, [r4, r2] + mov r1, r1, asl #1 + ldrh lr, [r0, r1] + rsb ip, ip, lr + strh ip, [r0, r1] @ movhi + ldrh r0, [r4, #72] + movw r1, #2326 + strh r3, [r4, r2] @ movhi + strb r3, [r4, #2330] + strh r0, [r4, r1] @ movhi + ldr r0, .L1270+16 + bl FtlMapBlkWriteDump_data + ldr r0, .L1270+20 + bl FtlMapBlkWriteDump_data + movw r3, #2538 + ldrh r2, [r4, r3] + add r2, r2, #1 + strh r2, [r4, r3] @ movhi + bl l2p_flush + bl FtlVpcTblFlush + bl FtlVpcTblFlush +.L1265: + ldr r4, .L1270+4 + movw r3, #2276 + ldrh r0, [r4, r3] + movw r3, #65535 + cmp r0, r3 + beq .L1266 + movw r3, #2280 + ldrh r3, [r4, r3] + cmp r3, #0 + bne .L1266 + movw r3, #2328 + ldrh r3, [r4, r3] + cmp r3, #0 + bne .L1266 + bl FtlGcRefreshBlock + movw r3, #2324 + ldrh r0, [r4, r3] + bl FtlGcRefreshBlock + ldr r0, .L1270+8 + bl allocate_new_data_superblock + ldr r0, .L1270+12 + bl allocate_new_data_superblock +.L1266: + ldr r2, .L1270+4 + movw r3, #2536 + ldrh r0, [r2, r3] + ands r4, r0, #31 + bne .L1269 + bl FtlVpcCheckAndModify + mov r0, r4 + ldmfd sp!, {r3, r4, r5, pc} +.L1268: + mvn r0, #0 + ldmfd sp!, {r3, r4, r5, pc} +.L1269: + mov r0, #0 + ldmfd sp!, {r3, r4, r5, pc} +.L1271: + .align 2 +.L1270: + .word .LANCHOR4 + .word .LANCHOR0 + .word .LANCHOR0+2276 + .word .LANCHOR0+2324 + .word .LANCHOR3+3812 + .word .LANCHOR3+3876 + .fnend + .size FtlSysBlkInit, .-FtlSysBlkInit + .align 2 + .global sftl_init + .type sftl_init, %function +sftl_init: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 +.L1273: + stmfd sp!, {r3, r4, r5, lr} + .save {r3, r4, r5, lr} + mvn r3, #0 + ldr r4, .L1277 + ldr r5, .L1277+4 + ldr r1, .L1277+8 + str r3, [r4, #0] + ldr r0, .L1277+12 + bl printk + ldr r0, .L1277+16 + bl FtlConstantsInit + bl FtlMemInit + bl FtlVariablesInit + ldrh r0, [r5, #8] + bl FtlFreeSysBlkQueueInit + bl FtlLoadBbt + cmp r0, #0 + bne .L1274 + bl FtlSysBlkInit + cmp r0, #0 + bne .L1274 + mov r3, #1 + str r3, [r4, #0] + mov r3, #2272 + ldrh r3, [r5, r3] + cmp r3, #15 + bhi .L1274 + movw r4, #8129 +.L1275: + mov r0, #0 + mov r1, #1 + bl rk_ftl_garbage_collect + subs r4, r4, #1 + bne .L1275 +.L1274: + mov r0, #0 + ldmfd sp!, {r3, r4, r5, pc} +.L1278: + .align 2 +.L1277: + .word .LANCHOR2 + .word .LANCHOR0 + .word .LC71 + .word .LC70 + .word g_nand_phy_info + .fnend + .size sftl_init, .-sftl_init + .align 2 + .global FtlMakeBbt + .type FtlMakeBbt, %function +FtlMakeBbt: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r3, r4, r5, r6, r7, r8, r9, sl, fp, lr} + bl FtlBbtMemInit + mov r6, #0 + ldr r7, .L1296 + bl FtlLoadFactoryBbt + ldr r4, .L1296+4 + add sl, r7, #12 + sub r5, r7, #124 + b .L1280 +.L1286: + ldrh r3, [sl], #2 + movw r2, #65535 + ldr r0, [r5, #2240] + ldr r9, [r4, #-836] + cmp r3, r2 + str r0, [r4, #-848] + str r9, [r4, #-844] + beq .L1281 + ldrh r8, [r5, #68] + mov r1, #1 + mov r2, r1 + ldr r0, .L1296+8 + mla r8, r8, r6, r3 + mov r3, r8, asl #10 + str r3, [r4, #-852] + bl FlashReadPages + ldrh r2, [r5, #68] + ldr r0, [r7, #28] + add r2, r2, #7 + ldr r1, [r4, #-848] + mov r2, r2, lsr #3 + bl memcpy + b .L1282 +.L1281: + mov r1, r6 + bl FlashGetBadBlockList + ldr r0, [r4, #-848] + ldr r1, [r7, #28] + bl FtlBbt2Bitmap + ldrh fp, [r5, #68] +.L1284: + sub fp, fp, #1 + uxth fp, fp +.L1295: + ldrh r0, [r5, #68] + mla r0, r0, r6, fp + uxth r0, r0 + bl FtlBbmIsBadBlock + cmp r0, #1 + beq .L1284 + mov r1, #0 + mov r2, #16 + strh fp, [sl, #-2] @ movhi + ldr r0, [r4, #-836] + bl ftl_memset + mov r1, #0 + mov r2, #4096 + ldr r0, [r5, #2240] + bl ftl_memset + ldr r3, .L1296+12 + ldr r2, .L1296+16 + strh r3, [r9, #0] @ movhi + mov r3, #0 + str r3, [r9, #4] + ldrh r3, [sl, #-2] + ldrh r8, [r5, #68] + strh r3, [r9, #2] @ movhi + ldrh r3, [sl, #-2] + ldr r1, [r7, #28] + ldr r0, [r4, #-848] + mla r8, r8, r6, r3 + mov r3, r8, asl #10 + str r3, [r4, #-852] + movw r3, #3940 + ldrh r2, [r2, r3] + mov r2, r2, asl #2 + bl memcpy + mov r1, #1 + mov r2, r1 + ldr r0, .L1296+8 + bl FlashEraseBlocks + mov r1, #1 + mov r3, r1 + ldr r0, .L1296+8 + mov r2, r1 + bl FlashProgPages + ldr r3, [r4, #-856] + cmn r3, #1 + bne .L1282 + uxth r0, r8 + bl FtlBbmMapBadBlock + b .L1295 +.L1282: + uxth r0, r8 + add r6, r6, #1 + bl FtlBbmMapBadBlock + add r7, r7, #4 +.L1280: + ldrh r3, [r5, #26] + cmp r6, r3 + bcc .L1286 + mov r4, #0 + ldr r6, .L1296+20 + b .L1287 +.L1288: + mov r0, r4 + add r4, r4, #1 + bl FtlBbmMapBadBlock + uxth r4, r4 +.L1287: + ldrh r3, [r6, #86] + ldr r5, .L1296+20 + cmp r3, r4 + bhi .L1288 + ldrh r4, [r5, #136] + movw r6, #65535 + sub r4, r4, #1 + uxth r4, r4 + b .L1289 +.L1294: + mov r0, r4 + bl FtlBbmIsBadBlock + cmp r0, #1 + beq .L1290 + mov r0, r4 + bl FlashTestBlk + cmp r0, #0 + beq .L1291 + mov r0, r4 + bl FtlBbmMapBadBlock + b .L1290 +.L1291: + ldrh r3, [r5, #124] + cmp r3, r6 + streqh r4, [r5, #124] @ movhi +.L1292: + ldrne r3, .L1296+20 + strneh r4, [r3, #128] @ movhi + bne .L1293 +.L1290: + sub r4, r4, #1 + uxth r4, r4 +.L1289: + ldrh r3, [r5, #136] + sub r3, r3, #48 + cmp r4, r3 + bgt .L1294 +.L1293: + ldr r4, .L1296+20 + mov r5, #0 + ldr r3, .L1296+4 + mov r1, #1 + mov r2, #2 + str r5, [r4, #132] + ldr r0, [r3, #3776] + ldrh r3, [r4, #124] + strh r5, [r4, #126] @ movhi + mov r3, r3, asl #10 + str r3, [r0, #4] + ldrh r3, [r4, #128] + mov r3, r3, asl #10 + str r3, [r0, #24] + bl FlashEraseBlocks + ldrh r0, [r4, #124] + bl FtlBbmMapBadBlock + ldrh r0, [r4, #128] + bl FtlBbmMapBadBlock + bl FtlBbmTblFlush + ldr r3, [r4, #132] + ldrh r2, [r4, #128] + add r3, r3, #1 + str r3, [r4, #132] + ldrh r3, [r4, #124] + strh r5, [r4, #126] @ movhi + strh r2, [r4, #124] @ movhi + strh r3, [r4, #128] @ movhi + bl FtlBbmTblFlush + mov r0, r5 + ldmfd sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, pc} +.L1297: + .align 2 +.L1296: + .word .LANCHOR0+124 + .word .LANCHOR3 + .word .LANCHOR3-856 + .word -3872 + .word .LANCHOR4 + .word .LANCHOR0 + .fnend + .size FtlMakeBbt, .-FtlMakeBbt + .align 2 + .global ftl_low_format + .type ftl_low_format, %function +ftl_low_format: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + ldr r3, .L1318 + mov r2, #0 + stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + .save {r4, r5, r6, r7, r8, r9, sl, lr} + str r2, [r3, #2476] + str r2, [r3, #2480] + ldrh r0, [r3, #8] + bl FtlFreeSysBlkQueueInit + bl FtlLoadBbt + cmp r0, #0 + beq .L1299 + bl FtlMakeBbt +.L1299: + mov r3, #0 + ldr r0, .L1318 + ldr r2, .L1318+4 + ldr r1, .L1318+8 + b .L1300 +.L1301: + ldr ip, [r2, #3792] + mvn lr, r3 + orr lr, r3, lr, asl #16 + str lr, [ip, r3, asl #2] + ldr ip, [r2, #3784] + str r1, [ip, r3, asl #2] + add r3, r3, #1 + uxth r3, r3 +.L1300: + ldrh ip, [r0, #78] + ldr r7, .L1318 + cmp r3, ip, asl #7 + blt .L1301 + ldrh r6, [r7, #12] + mov r5, #0 + b .L1302 +.L1303: + mov r0, r6 + mov r1, #1 + bl FtlLowFormatEraseBlock + add r6, r6, #1 + uxth r6, r6 + add r5, r5, r0 + uxth r5, r5 +.L1302: + ldrh r3, [r7, #14] + ldr r4, .L1318 + cmp r3, r6 + bhi .L1303 + ldrh r1, [r4, #4] + sub r3, r5, #3 + cmp r3, r1, asl #1 + bge .L1304 +.L1308: + mov r4, #0 + ldr r7, .L1318 + mov r6, r4 + b .L1305 +.L1304: + mov r0, r5 + bl __aeabi_uidiv + ldr r3, [r4, #104] + add r0, r0, r3 + uxth r0, r0 + bl FtlSysBlkNumInit + ldrh r0, [r4, #8] + bl FtlFreeSysBlkQueueInit + ldrh r5, [r4, #12] + b .L1306 +.L1307: + mov r0, r5 + mov r1, #1 + bl FtlLowFormatEraseBlock + add r5, r5, #1 + uxth r5, r5 +.L1306: + ldrh r3, [r4, #14] + cmp r3, r5 + bhi .L1307 + b .L1308 +.L1309: + mov r0, r6 + mov r1, #0 + bl FtlLowFormatEraseBlock + add r6, r6, #1 + uxth r6, r6 + add r4, r4, r0 + uxth r4, r4 +.L1305: + ldrh r3, [r7, #12] + ldr r5, .L1318 + cmp r3, r6 + bhi .L1309 + ldr r3, .L1318+4 + movw sl, #2556 + ldrh r2, [r5, #14] + ldrh r6, [r5, #4] + ldr r9, [r5, #16] + str r2, [r3, #3780] + mov r1, r6 + mov r0, r9 + bl __aeabi_uidiv + ubfx r8, r0, #5, #16 + mov r7, r0 + add r3, r8, #36 + strh r3, [r5, sl] @ movhi + mov r3, #24 + str r0, [r5, #2440] + mul r3, r3, r6 + cmp r4, r3 + ble .L1310 + rsb r0, r4, r9 + mov r1, r6 + bl __aeabi_uidiv + str r0, [r5, #2440] + mov r0, r0, lsr #5 + add r0, r0, #24 + strh r0, [r5, sl] @ movhi +.L1310: + ldr r5, .L1318 + ldr r3, [r5, #2436] + cmp r3, #1 + bne .L1311 + mov r0, r4 + mov r1, r6 + bl __aeabi_uidiv + movw sl, #2556 + ldrh r9, [r5, sl] + uxtah r0, r9, r0 + add r9, r9, r0, lsr #2 + strh r9, [r5, sl] @ movhi +.L1311: + ldr r3, .L1318 + ldrh r2, [r3, #64] + cmp r2, #0 + beq .L1312 + movw r1, #2556 + ldrh r0, [r3, r1] + add r0, r0, r2, lsr #1 + strh r0, [r3, r1] @ movhi + mul r0, r6, r2 + cmp r0, r4 + strgt r7, [r3, #2440] + addgt r2, r2, #32 + addgt r8, r8, r2 + strgth r8, [r3, r1] @ movhi +.L1312: + ldr r4, .L1318 + movw r3, #2556 + mvn r5, #0 + ldr r2, [r4, #2440] + ldrh r3, [r4, r3] + rsb r3, r3, r2 + mul r6, r6, r3 + ldr r3, .L1318+12 + str r6, [r3, #4024] + ldrh r3, [r4, #72] + mul r6, r3, r6 + ldrh r3, [r4, #78] + str r6, [r4, #2440] + mul r6, r3, r6 + str r6, [r4, #112] + movw r6, #2276 + bl FtlBbmTblFlush + ldrh r2, [r4, #14] + mov r1, #0 + ldr r0, [r4, #2256] + mov r2, r2, asl #1 + bl ftl_memset + movw r2, #2572 + movw r1, #2574 + strh r5, [r4, r2] @ movhi + ldrh r2, [r4, #12] + mov r3, #0 + strh r3, [r4, r1] @ movhi + sub r1, r1, #296 + str r3, [r4, #2428] + strh r3, [r4, r1] @ movhi + mov r2, r2, lsr #3 + strb r3, [r4, #2578] + mov r1, #255 + strb r3, [r4, #2580] + strb r3, [r4, #2282] + strh r3, [r4, r6] @ movhi + mov r3, #1 + ldr r0, [r4, #2432] + strb r3, [r4, #2284] + bl ftl_memset +.L1313: + ldr r0, .L1318+16 + bl make_superblock + ldrb r3, [r4, #2283] @ zero_extendqisi2 + ldr r7, .L1318 + cmp r3, #0 + movw r3, #2276 + bne .L1314 + ldrh r3, [r4, r6] + ldr r2, [r4, #2256] + mov r3, r3, asl #1 + strh r5, [r2, r3] @ movhi + ldrh r3, [r4, r6] + add r3, r3, #1 + strh r3, [r4, r6] @ movhi + b .L1313 +.L1314: + ldr r2, [r7, #2476] + movw r5, #2324 + ldr r1, [r7, #2256] + mvn r6, #0 + str r2, [r7, #2288] + add r2, r2, #1 + str r2, [r7, #2476] + movw r2, #2280 + ldrh r0, [r7, r2] + ldrh r2, [r7, r3] + mov r2, r2, asl #1 + strh r0, [r1, r2] @ movhi + movw r0, #2326 + ldrh r3, [r7, r3] + mov r2, #0 + strh r2, [r7, r0] @ movhi + add r3, r3, #1 + strb r2, [r7, #2330] + strh r3, [r7, r5] @ movhi + mov r3, #1 + strb r3, [r7, #2332] +.L1315: + ldr r0, .L1318+20 + bl make_superblock + ldrb r3, [r7, #2331] @ zero_extendqisi2 + ldr r4, .L1318 + cmp r3, #0 + bne .L1316 + ldrh r3, [r7, r5] + ldr r2, [r7, #2256] + mov r3, r3, asl #1 + strh r6, [r2, r3] @ movhi + ldrh r3, [r7, r5] + add r3, r3, #1 + strh r3, [r7, r5] @ movhi + b .L1315 +.L1316: + ldr r3, [r4, #2476] + mvn r5, #0 + ldr r2, [r4, #2256] + str r3, [r4, #2336] + add r3, r3, #1 + str r3, [r4, #2476] + movw r3, #2328 + ldrh r1, [r4, r3] + movw r3, #2324 + ldrh r3, [r4, r3] + mov r3, r3, asl #1 + strh r1, [r2, r3] @ movhi + movw r3, #2372 + strh r5, [r4, r3] @ movhi + bl FtlFreeSysBlkQueueOut + mov r3, #2560 + mov r2, #0 + strh r0, [r4, r3] @ movhi + add r3, r3, #2 + strh r2, [r4, r3] @ movhi + add r3, r3, #2 + strh r5, [r4, r3] @ movhi + ldr r3, .L1318+12 + ldr r2, [r3, #4024] + movw r3, #2566 + strh r2, [r4, r3] @ movhi + ldr r3, [r4, #2476] + str r3, [r4, #2568] + add r3, r3, #1 + str r3, [r4, #2476] + bl FtlVpcTblFlush + bl FtlSysBlkInit + cmp r0, #0 + mov r0, #0 + ldreq r3, .L1318+24 + moveq r2, #1 + streq r2, [r3, #0] + ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, pc} +.L1319: + .align 2 +.L1318: + .word .LANCHOR0 + .word .LANCHOR3 + .word 168778952 + .word .LANCHOR4 + .word .LANCHOR0+2276 + .word .LANCHOR0+2324 + .word .LANCHOR2 + .fnend + .size ftl_low_format, .-ftl_low_format + .align 2 + .global FtlWrite + .type FtlWrite, %function +FtlWrite: + .fnstart + @ args = 0, pretend = 0, frame = 72 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r4, r5, r6, r7, r8, r9, sl, fp, lr} + cmp r0, #16 + .pad #76 + sub sp, sp, #76 + mov r7, r1 + mov r9, r3 + str r2, [sp, #16] + bne .L1321 + add r0, r1, #256 + mov r1, r2 + mov r2, r3 + bl FtlVendorPartWrite + b .L1322 +.L1321: + ldr r6, .L1374 + ldr ip, [sp, #16] + ldr r3, [r6, #112] + add r8, ip, r1 + cmp r8, r3 + mvnhi r0, #0 + bhi .L1322 + ldr r3, .L1374+4 + ldr r0, [r3, #0] + cmn r0, #1 + beq .L1322 + ldr r3, .L1374+8 + mov r2, #2048 + ldrh r5, [r6, #78] + mov r0, r1 + str r2, [r3, #-4004] + mov r1, r5 + bl __aeabi_uidiv + mov r1, r5 + str r0, [sp, #12] + sub r0, r8, #1 + bl __aeabi_uidiv + ldr ip, [sp, #12] + ldr r3, [r6, #2452] + rsb r4, ip, r0 + str r0, [sp, #32] + add ip, r4, #1 + str ip, [sp, #4] + add r3, ip, r3 + str r3, [r6, #2452] + ldr r3, .L1374+12 + ldr r8, [r3, #3944] + cmp r8, #0 + beq .L1323 + ldr r3, [r8, #16] + ldr ip, [sp, #12] + cmp ip, r3 + beq .L1324 + bl FtlCacheWriteBack + b .L1323 +.L1324: + ldr r3, [r6, #2456] + mov r1, r5 + mov r0, r7 + add r3, r3, #1 + str r3, [r6, #2456] + bl __aeabi_uidivmod + ldr ip, [sp, #16] + ldr r0, [r8, #8] + rsb r5, r1, r5 + add r0, r0, r1, asl #9 + cmp r5, ip + movcs r5, ip + mov r1, r9 + mov r6, r5, asl #9 + mov r2, r6 + bl memcpy + cmp r4, #0 + moveq r0, r4 + beq .L1322 + ldr ip, [sp, #16] + add r7, r7, r5 + add r9, r9, r6 + rsb ip, r5, ip + str ip, [sp, #16] + ldr ip, [sp, #12] + add ip, ip, #1 + str ip, [sp, #12] + bl FtlCacheWriteBack + str r4, [sp, #4] +.L1323: + ldr r3, .L1374+4 + ldr r3, [r3, #8] + cmp r3, #0 + ldreq r4, .L1374+16 + beq .L1325 + ldr r2, .L1374 + movw r3, #2280 + ldrh r4, [r2, r3] + ldr r3, .L1374+16 + ldr r2, .L1374+20 + cmp r4, #0 + movne r4, r3 + moveq r4, r2 +.L1325: + mov fp, #0 + ldr r6, [sp, #12] + str fp, [sp, #28] + mov sl, r7 + ldr r5, .L1374 + b .L1326 +.L1355: + ldrb r2, [r4, #6] @ zero_extendqisi2 + ldrh r3, [r5, #4] + cmp r2, r3 + bcc .L1327 + ldr r0, .L1374+24 + mov r2, #1072 + ldr r1, .L1374+28 + bl printk +.L1327: + ldrh r7, [r4, #4] + cmp r7, #0 + bne .L1328 + bl FtlCacheWriteBack + ldr r3, .L1374+16 + cmp r4, r3 + bne .L1329 + movw r3, #2328 + ldrh r7, [r5, r3] + cmp r7, #0 + bne .L1330 + add r0, r4, #48 + bl allocate_new_data_superblock + ldr r3, .L1374+4 + str r7, [r3, #8] +.L1330: + ldr r0, .L1374+16 + bl allocate_new_data_superblock + ldr r3, .L1374+4 + ldr r2, [r3, #8] + ldr r3, .L1374+20 + cmp r2, #0 + movne r4, r3 + b .L1331 +.L1329: + ldr r2, .L1374+4 + str r7, [r2, #8] + movw r2, #2280 + ldrh r2, [r5, r2] + cmp r2, #0 + movne r4, r3 + bne .L1331 + mov r0, r4 + bl allocate_new_data_superblock +.L1331: + ldrh r3, [r4, #4] + cmp r3, #0 + bne .L1328 + mov r0, r4 + bl allocate_new_data_superblock +.L1328: + ldrb r3, [r4, #7] @ zero_extendqisi2 + ldrh r2, [r4, #4] + ldr ip, [sp, #4] + mov r3, r3, asl #2 + cmp r3, r2 + movcs r3, r2 + ldrb r2, [r4, #6] @ zero_extendqisi2 + cmp r3, ip + movcc ip, r3 + ldrh r3, [r5, #4] + str ip, [sp, #8] + cmp r2, r3 + bcc .L1332 + ldr r0, .L1374+24 + movw r2, #1105 + ldr r1, .L1374+28 + bl printk +.L1332: + mov r3, #0 + b .L1373 +.L1351: + ldrh r3, [r4, #4] + cmp r3, #0 + beq .L1365 + add r1, sp, #48 + mov r2, #0 + mov r0, r6 + mov r7, #20 + bl log2phys + mov r0, r4 + bl get_new_active_ppa + ldr ip, [sp, #20] + ldr r3, .L1374+12 + ldrh r2, [r5, #84] + mul r7, r7, ip + ldr r1, [r3, #3992] + add r1, r1, r7 + str r6, [r1, #16] + str r0, [r1, #4] + mul r0, r2, ip + bic r0, r0, #3 + str r0, [sp, #40] + ldr r0, .L1374+32 + ldr ip, [sp, #40] + ldr r0, [r0, #3788] + add r8, r0, ip + str r8, [r1, #12] + str r0, [sp, #44] + mov r1, #0 + mov r0, r8 + str r3, [sp, #0] + bl ftl_memset + ldr ip, [sp, #12] + rsb lr, ip, r6 + rsbs ip, lr, #0 + adc ip, ip, lr + str ip, [sp, #24] + ldr ip, [sp, #32] + ldr r0, [sp, #24] + rsb r3, ip, r6 + rsbs ip, r3, #0 + adc ip, ip, r3 + str ip, [sp, #36] + orrs ip, ip, r0 + ldr r3, [sp, #0] + beq .L1335 + cmp r0, #0 + beq .L1336 + ldrh fp, [r5, #78] + mov r0, sl + mov r1, fp + bl __aeabi_uidivmod + ldr ip, [sp, #16] + rsb fp, r1, fp + str r1, [sp, #28] + cmp fp, ip + movcs fp, ip + b .L1337 +.L1336: + ldr r3, [sp, #36] + cmp r3, #0 + beq .L1337 + ldr ip, [sp, #16] + ldrh r3, [r5, #78] + add fp, ip, sl + mls fp, r3, r6, fp + ldr r3, [sp, #24] + str r3, [sp, #28] + uxth fp, fp +.L1337: + ldrh r3, [r5, #78] + ldr ip, [sp, #24] + cmp fp, r3 + ldr r3, .L1374+12 + ldr r3, [r3, #3992] + bne .L1338 + add r7, r3, r7 + cmp ip, #0 + strne r9, [r7, #8] + muleq r3, fp, r6 + beq .L1372 + b .L1340 +.L1338: + ldr r2, .L1374+32 + cmp ip, #0 + add r3, r3, r7 + ldrne r2, [r2, #3792] + ldreq r2, [r2, #3784] + str r2, [r3, #8] + ldr r2, [sp, #48] + ldr r3, .L1374+12 + cmn r2, #1 + beq .L1343 + ldr r3, [r3, #3992] + add r0, sp, #52 + str r6, [sp, #68] + mov r1, #1 + add r3, r3, r7 + str r2, [sp, #56] + ldr r2, [r3, #8] + ldr r3, [r3, #12] + str r2, [sp, #60] + mov r2, #0 + str r3, [sp, #64] + bl FlashReadPages + ldr r3, [sp, #52] + cmn r3, #1 + ldreq r3, [r5, #2696] + addeq r3, r3, #1 + streq r3, [r5, #2696] + beq .L1345 + ldr r3, [r8, #8] + cmp r3, r6 + beq .L1346 + ldr r3, [r5, #2696] + mov r2, r6 + ldr r0, .L1374+36 + add r3, r3, #1 + str r3, [r5, #2696] + ldr r1, [r8, #8] + bl printk +.L1346: + ldr r3, [r8, #8] + cmp r3, r6 + beq .L1345 + ldr r1, .L1374+28 + movw r2, #1158 + ldr r0, .L1374+24 + bl printk + b .L1345 +.L1343: + ldr r3, [r3, #3992] + mov r1, #0 + ldrh r2, [r5, #82] + add r3, r3, r7 + ldr r0, [r3, #8] + bl ftl_memset +.L1345: + ldr r3, [sp, #24] + mov r2, fp, asl #9 + cmp r3, #0 + ldr r3, .L1374+12 + ldreqh r1, [r5, #78] + movne r1, r9 + ldr r3, [r3, #3992] + ldrne ip, [sp, #28] + muleq r1, r1, r6 + add r3, r3, r7 + ldrne r0, [r3, #8] + rsbeq r1, sl, r1 + ldreq r0, [r3, #8] + addne r0, r0, ip, asl #9 + addeq r1, r9, r1, asl #9 + bl memcpy + ldr r3, [sp, #36] + cmp r3, #0 + beq .L1340 + ldrh r3, [r4, #4] + cmp r3, #0 + beq .L1340 + ldr r3, .L1374+12 + ldr r2, [r3, #3992] + add r7, r2, r7 + str r7, [r3, #3944] + ldr r3, .L1374+8 + str r4, [r3, #-4020] + b .L1340 +.L1335: + ldr r3, [r3, #3992] + add r7, r3, r7 + ldrh r3, [r5, #78] + mul r3, r3, r6 +.L1372: + rsb r3, sl, r3 + add r3, r9, r3, asl #9 + str r3, [r7, #8] +.L1340: + ldrb r2, [r4, #6] @ zero_extendqisi2 + ldrh r3, [r5, #4] + cmp r2, r3 + bcc .L1349 + ldr r0, .L1374+24 + movw r2, #1179 + ldr r1, .L1374+28 + bl printk +.L1349: + ldr r3, .L1374+40 + ldr r1, .L1374 + ldr r0, [sp, #44] + ldr ip, [sp, #40] + strh r3, [r0, ip] @ movhi + ldr r3, [r1, #2480] + str r6, [r8, #8] + add r6, r6, #1 + str r3, [r8, #4] + add r3, r3, #1 + cmn r3, #1 + str r3, [r1, #2480] + moveq r3, #0 + streq r3, [r5, #2480] + ldr r3, [sp, #48] + str r3, [r8, #12] + ldrh r3, [r4, #0] + strh r3, [r8, #2] @ movhi + ldr r3, [sp, #20] + add r3, r3, #1 +.L1373: + str r3, [sp, #20] + ldr ip, [sp, #20] + ldr r0, [sp, #8] + cmp ip, r0 + bne .L1351 + b .L1334 +.L1365: + ldr r3, [sp, #20] + str r3, [sp, #8] +.L1334: + ldr r3, .L1374+12 + ldr r2, [r3, #3944] + cmp r2, #0 + beq .L1352 + ldr ip, [sp, #8] + subs ip, ip, #1 + str ip, [sp, #8] + beq .L1353 + ldr ip, [sp, #4] + sub ip, ip, #1 + str ip, [sp, #4] +.L1352: + ldr r0, [r3, #3992] + mov r2, #0 + ldr r1, [sp, #8] + mov r3, r4 + bl FtlProgPages + ldr ip, [sp, #4] + ldr r0, [sp, #8] + cmp ip, r0 + bcs .L1354 + ldr r0, .L1374+24 + movw r2, #1194 + ldr r1, .L1374+28 + bl printk +.L1354: + ldr ip, [sp, #4] + ldr r0, [sp, #8] + rsb ip, r0, ip + str ip, [sp, #4] +.L1326: + ldr ip, [sp, #4] + cmp ip, #0 + bne .L1355 +.L1353: + ldr ip, [sp, #32] + mov r0, #0 + ldr r2, [sp, #12] + ldr r5, .L1374 + rsb r1, r2, ip + bl rk_ftl_garbage_collect + mov r3, #2272 + ldrh r3, [r5, r3] + cmp r3, #15 + bhi .L1367 + movw r6, #2572 + mov r4, r5 +.L1368: + ldrh r3, [r5, r6] + movw r2, #65535 + cmp r3, r2 + bne .L1356 + movw r2, #3190 + ldrh r2, [r5, r2] + cmp r2, r3 + bne .L1356 + mov r0, #0 + bl List_get_gc_head_node + uxth r0, r0 + bl FtlGcRefreshBlock +.L1356: + movw r2, #3138 + mov r3, #128 + mov r0, #1 + strh r3, [r4, r2] @ movhi + mov r2, #3136 + mov r1, r0 + strh r3, [r4, r2] @ movhi + bl rk_ftl_garbage_collect + mov r0, #0 + mov r1, #1 + bl rk_ftl_garbage_collect + mov r3, #2272 + ldrh r3, [r4, r3] + cmp r3, #8 + bls .L1368 +.L1367: + mov r0, #0 +.L1322: + add sp, sp, #76 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} +.L1375: + .align 2 +.L1374: + .word .LANCHOR0 + .word .LANCHOR2 + .word .LANCHOR5 + .word .LANCHOR4 + .word .LANCHOR0+2276 + .word .LANCHOR0+2324 + .word .LC1 + .word .LANCHOR1+589 + .word .LANCHOR3 + .word .LC103 + .word -3947 + .fnend + .size FtlWrite, .-FtlWrite + .align 2 + .global sftl_write + .type sftl_write, %function +sftl_write: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + mov ip, r1 + mov r3, r2 + stmfd sp!, {r4, lr} + .save {r4, lr} + mov r4, r0 + mov r1, r4 + mov r0, #0 + mov r2, ip + ldmfd sp!, {r4, lr} + b FtlWrite + .fnend + .size sftl_write, .-sftl_write + .align 2 + .global FtlRead + .type FtlRead, %function +FtlRead: + .fnstart + @ args = 0, pretend = 0, frame = 64 + @ frame_needed = 0, uses_anonymous_args = 0 + stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + .save {r4, r5, r6, r7, r8, r9, sl, fp, lr} + cmp r0, #16 + .pad #68 + sub sp, sp, #68 + mov r4, r1 + mov r8, r3 + str r2, [sp, #36] + bne .L1378 + add r0, r1, #256 + mov r1, r2 + mov r2, r3 + bl FtlVendorPartRead + str r0, [sp, #8] + b .L1379 +.L1378: + ldr r3, [sp, #36] + ldr r5, .L1408 + add r3, r3, r1 + str r3, [sp, #12] + ldr r1, [sp, #12] + ldr r3, [r5, #112] + cmp r1, r3 + bhi .L1397 + ldr r3, .L1408+4 + ldr r3, [r3, #0] + cmn r3, #1 + beq .L1398 + bl FtlCacheWriteBack + ldrh r6, [r5, #78] + mov r0, r4 + mov r9, #0 + mov r1, r6 + bl __aeabi_uidiv + ldr r3, [sp, #12] + mov r1, r6 + mov r6, r9 + str r0, [sp, #16] + sub r0, r3, #1 + bl __aeabi_uidiv + ldr r3, [sp, #16] + ldr r7, [sp, #16] + rsb fp, r3, #1 + ldr r3, [r5, #2444] + str r9, [sp, #32] + str r9, [sp, #28] + str r9, [sp, #8] + add fp, fp, r0 + str r0, [sp, #20] + add r3, fp, r3 + str r3, [r5, #2444] + b .L1403 +.L1396: + mov r2, #0 + mov r0, r7 + add r1, sp, #60 + bl log2phys + ldr r2, [sp, #60] + cmn r2, #1 + bne .L1404 + b .L1407 +.L1384: + mla r0, r0, r7, sl + cmp r0, r4 + bcc .L1383 + ldr r3, [sp, #12] + cmp r0, r3 + bcs .L1383 + rsb r0, r4, r0 + mov r1, #0 + mov r2, #512 + add r0, r8, r0, asl #9 + bl ftl_memset +.L1383: + add sl, sl, #1 + b .L1381 +.L1407: + mov sl, #0 +.L1381: + ldrh r0, [r5, #78] + cmp sl, r0 + bcc .L1384 + b .L1385 +.L1404: + ldr r3, .L1408+8 + mov sl, #20 + ldr r1, [r3, #3796] + mla sl, sl, r6, r1 + ldr r1, [sp, #16] + cmp r7, r1 + str r2, [sl, #4] + bne .L1386 + ldr r3, [r3, #3792] + mov r0, r4 + str r3, [sl, #8] + ldrh r3, [r5, #78] + mov r1, r3 + str r3, [sp, #4] + bl __aeabi_uidivmod + ldr r3, [sp, #4] + str r1, [sp, #28] + rsb r2, r1, r3 + ldr r1, [sp, #36] + cmp r2, r1 + movcc r1, r2 + str r1, [sp, #32] + cmp r1, r3 + streq r8, [sl, #8] + b .L1387 +.L1386: + ldr r2, [sp, #20] + cmp r7, r2 + ldrneh r3, [r5, #78] + mulne r3, r3, r7 + bne .L1405 + ldr r3, [r3, #3784] + ldrh r2, [r5, #78] + ldr r1, [sp, #12] + str r3, [sl, #8] + mul r3, r2, r7 + rsb r9, r3, r1 + cmp r9, r2 + bne .L1387 +.L1405: + rsb r3, r4, r3 + add r3, r8, r3, asl #9 + str r3, [sl, #8] +.L1387: + ldrh r3, [r5, #84] + ldr r2, .L1408+8 + str r7, [sl, #16] + mul r3, r3, r6 + ldr r2, [r2, #3788] + add r6, r6, #1 + bic r3, r3, #3 + add r3, r2, r3 + str r3, [sl, #12] +.L1385: + subs fp, fp, #1 + add r7, r7, #1 + beq .L1389 + ldrh r3, [r5, #4] + cmp r6, r3, asl #2 + bne .L1403 +.L1389: + cmp r6, #0 + beq .L1403 + ldr sl, .L1408+8 + mov r1, r6 + mov r2, #0 + ldr r0, [sl, #3796] + bl FlashReadPages + ldr r3, [sp, #28] + str r7, [sp, #52] + mov r3, r3, asl #9 + str r3, [sp, #40] + ldr r3, [sp, #32] + mov r3, r3, asl #9 + str r3, [sp, #44] + mov r3, r9, asl #9 + str r3, [sp, #48] + mov r3, #0 + str r3, [sp, #24] +.L1395: + ldr r3, [sp, #24] + mov r1, #20 + mul r7, r1, r3 + ldr r3, [sl, #3796] + ldr r1, [sp, #16] + add r3, r3, r7 + ldr r2, [r3, #16] + cmp r2, r1 + bne .L1391 + ldr r1, [r3, #8] + ldr r3, [sl, #3792] + cmp r1, r3 + bne .L1392 + ldr r3, [sp, #40] + mov r0, r8 + ldr r2, [sp, #44] + add r1, r1, r3 + b .L1406 +.L1391: + ldr r1, [sp, #20] + cmp r2, r1 + bne .L1392 + ldr r1, [r3, #8] + ldr r3, [sl, #3784] + cmp r1, r3 + bne .L1392 + ldrh r0, [r5, #78] + ldr r3, [sp, #20] + ldr r2, [sp, #48] + mul r0, r0, r3 + rsb r0, r4, r0 + add r0, r8, r0, asl #9 +.L1406: + bl memcpy +.L1392: + ldr r3, [sl, #3796] + add r0, r3, r7 + ldr r2, [r3, r7] + cmn r2, #1 + streq r2, [sp, #8] + ldreq r1, [r5, #2696] + addeq r1, r1, #1 + streq r1, [r5, #2696] + ldr r3, [r3, r7] + cmp r3, #256 + bne .L1394 + ldr r0, [r0, #4] + ubfx r0, r0, #10, #16 + bl P2V_block_in_plane + bl FtlGcRefreshBlock +.L1394: + ldr r3, [sp, #24] + add r3, r3, #1 + str r3, [sp, #24] + cmp r3, r6 + bne .L1395 + ldr r7, [sp, #52] + mov r6, #0 +.L1403: + cmp fp, #0 + bne .L1396 + ldr r2, .L1408 + movw r3, #3194 + ldrh r3, [r2, r3] + cmp r3, #0 + beq .L1379 + mov r0, fp + mov r1, #1 + bl rk_ftl_garbage_collect + b .L1379 +.L1397: + mvn r3, #0 +.L1398: + str r3, [sp, #8] +.L1379: + ldr r0, [sp, #8] + add sp, sp, #68 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} +.L1409: + .align 2 +.L1408: + .word .LANCHOR0 + .word .LANCHOR2 + .word .LANCHOR3 + .fnend + .size FtlRead, .-FtlRead + .align 2 + .global sftl_read + .type sftl_read, %function +sftl_read: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + mov ip, r1 + mov r3, r2 + stmfd sp!, {r4, lr} + .save {r4, lr} + mov r4, r0 + mov r1, r4 + mov r0, #0 + mov r2, ip + ldmfd sp!, {r4, lr} + b FtlRead + .fnend + .size sftl_read, .-sftl_read + .align 2 + .global ftl_memcpy + .type ftl_memcpy, %function +ftl_memcpy: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + b memcpy + .fnend + .size ftl_memcpy, .-ftl_memcpy + .align 2 + .global ftl_memcmp + .type ftl_memcmp, %function +ftl_memcmp: + .fnstart + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + b memcmp + .fnend + .size ftl_memcmp, .-ftl_memcmp + .global ftl_temp_buf + .global gc_ink_free_return_value + .global check_vpc_table + .global FtlUpdateVaildLpnCount + .global g_ect_tbl_power_up_flush + .global power_up_flag + .global gFtlInitStatus + .global DeviceCapacity + .global g_power_lost_recovery_flag + .global c_mlc_erase_count_value + .global g_recovery_ppa_tbl + .global g_recovery_page_min_ver + .global g_recovery_page_num + .global g_cur_erase_blk + .global g_gc_skip_write_count + .global g_gc_head_data_block_count + .global g_gc_head_data_block + .global g_ftl_nand_free_count + .global g_in_swl_replace + .global g_in_gc_progress + .global g_all_blk_used_slc_mode + .global g_max_erase_count + .global g_totle_sys_slc_erase_count + .global g_totle_slc_erase_count + .global g_min_erase_count + .global g_totle_avg_erase_count + .global g_totle_mlc_erase_count + .global g_totle_l2p_write_count + .global g_totle_cache_write_count + .global g_tmp_data_superblock_id + .global g_totle_read_page_count + .global g_totle_discard_page_count + .global g_totle_read_sector + .global g_totle_write_sector + .global g_totle_write_page_count + .global g_totle_gc_page_count + .global g_gc_blk_index + .global g_gc_merge_free_blk_threshold + .global g_gc_free_blk_threshold + .global g_gc_bad_block_temp_tbl + .global g_gc_bad_block_gc_index + .global g_gc_bad_block_temp_num + .global g_gc_next_blk_1 + .global g_gc_next_blk + .global g_gc_cur_blk_max_valid_pages + .global g_gc_cur_blk_valid_pages + .global g_gc_page_offset + .global g_gc_blk_num + .global p_gc_blk_tbl + .global p_gc_page_info + .global g_sys_ext_data + .global g_sys_save_data + .global gp_last_act_superblock + .global g_gc_superblock + .global g_gc_temp_superblock + .global g_buffer_superblock + .global g_active_superblock + .global g_num_data_superblocks + .global g_num_free_superblocks + .global p_data_block_list_tail + .global p_data_block_list_head + .global p_free_data_block_list_head + .global p_data_block_list_table + .global g_l2p_last_update_region_id + .global p_l2p_map_buf + .global p_l2p_ram_map + .global g_totle_vendor_block + .global p_vendor_region_ppn_table + .global p_vendor_block_ver_table + .global p_vendor_block_valid_page_count + .global p_vendor_block_table + .global g_totle_map_block + .global p_map_region_ppn_table + .global p_map_block_ver_table + .global p_map_block_valid_page_count + .global p_map_block_table + .global p_blk_mode_table + .global p_valid_page_count_check_table + .global p_valid_page_count_table + .global g_totle_swl_count + .global p_swl_mul_table + .global p_erase_count_table + .global g_ect_tbl_info_size + .global gp_ect_tbl_info + .global g_gc_num_req + .global c_gc_page_buf_num + .global gp_gc_page_buf_info + .global p_gc_data_buf + .global p_gc_spare_buf + .global p_io_spare_buf + .global p_io_data_buf_1 + .global p_io_data_buf_0 + .global p_sys_spare_buf + .global p_vendor_data_buf + .global p_sys_data_buf_1 + .global p_sys_data_buf + .global g_wr_page_num + .global req_wr_io + .global c_wr_page_buf_num + .global p_wr_io_data_buf + .global p_wr_io_spare_buf + .global p_plane_order_table + .global g_req_cache + .global req_gc_dst + .global req_gc + .global req_erase + .global req_prgm + .global req_read + .global req_sys + .global gVendorBlkInfo + .global gL2pMapInfo + .global gSysFreeQueue + .global gSysInfo + .global gBbtInfo + .global g_inkDie_check_enable + .global g_SlcPartLbaEndSector + .global g_MaxLbn + .global g_VaildLpn + .global g_MaxLpn + .global g_MaxLbaSector + .global g_GlobalDataVersion + .global g_GlobalSysVersion + .global ftl_gc_temp_power_lost_recovery_flag + .global c_ftl_nand_max_data_blks + .global c_ftl_nand_data_op_blks_per_plane + .global c_ftl_nand_data_blks_per_plane + .global c_ftl_nand_max_sys_blks + .global c_ftl_nand_init_sys_blks_per_plane + .global c_ftl_nand_sys_blks_per_plane + .global c_ftl_vendor_part_size + .global c_ftl_nand_max_vendor_blks + .global c_ftl_nand_max_map_blks + .global c_ftl_nand_map_blks_per_plane + .global c_ftl_nand_vendor_region_num + .global c_ftl_nand_l2pmap_ram_region_num + .global c_ftl_nand_map_region_num + .global c_ftl_nand_totle_phy_blks + .global c_ftl_nand_reserved_blks + .global c_ftl_nand_byte_pre_oob + .global c_ftl_nand_byte_pre_page + .global c_ftl_nand_sec_pre_page_shift + .global c_ftl_nand_sec_pre_page + .global c_ftl_nand_page_pre_super_blk + .global c_ftl_nand_page_pre_slc_blk + .global c_ftl_nand_page_pre_blk + .global c_ftl_nand_bbm_buf_size + .global c_ftl_nand_ext_blk_pre_plane + .global c_ftl_nand_blk_pre_plane + .global c_ftl_nand_planes_num + .global c_ftl_nand_blks_per_die_shift + .global c_ftl_nand_blks_per_die + .global c_ftl_nand_planes_per_die + .global c_ftl_nand_die_num + .global c_ftl_nand_type + .section .rodata + .set .LANCHOR1,. + 0 + .type __func__.3657, %object + .size __func__.3657, 17 +__func__.3657: + .ascii "INSERT_DATA_LIST\000" + .type __func__.3652, %object + .size __func__.3652, 17 +__func__.3652: + .ascii "INSERT_FREE_LIST\000" + .type __func__.3687, %object + .size __func__.3687, 17 +__func__.3687: + .ascii "List_remove_node\000" + .type __func__.3719, %object + .size __func__.3719, 22 +__func__.3719: + .ascii "List_update_data_list\000" + .type __func__.3760, %object + .size __func__.3760, 26 +__func__.3760: + .ascii "ftl_map_blk_alloc_new_blk\000" + .type __func__.3824, %object + .size __func__.3824, 22 +__func__.3824: + .ascii "select_l2p_ram_region\000" + .type __func__.4147, %object + .size __func__.4147, 16 +__func__.4147: + .ascii "make_superblock\000" + .type __func__.4321, %object + .size __func__.4321, 19 +__func__.4321: + .ascii "get_new_active_ppa\000" + .type __func__.4560, %object + .size __func__.4560, 15 +__func__.4560: + .ascii "FlashReadPages\000" + .type __func__.4577, %object + .size __func__.4577, 15 +__func__.4577: + .ascii "FlashProgPages\000" + .type __func__.4168, %object + .size __func__.4168, 18 +__func__.4168: + .ascii "SupperBlkListInit\000" + .type __func__.3936, %object + .size __func__.3936, 14 +__func__.3936: + .ascii "FtlScanSysBlk\000" + .type __func__.3785, %object + .size __func__.3785, 31 +__func__.3785: + .ascii "Ftl_write_map_blk_to_last_page\000" + .type __func__.3799, %object + .size __func__.3799, 16 +__func__.3799: + .ascii "FtlMapWritePage\000" + .type __func__.3771, %object + .size __func__.3771, 15 +__func__.3771: + .ascii "ftl_map_blk_gc\000" + .type __func__.3728, %object + .size __func__.3728, 16 +__func__.3728: + .ascii "load_l2p_region\000" + .type __func__.3841, %object + .size __func__.3841, 9 +__func__.3841: + .ascii "log2phys\000" + .type __func__.4056, %object + .size __func__.4056, 16 +__func__.4056: + .ascii "FtlReUsePrevPpa\000" + .type __func__.4209, %object + .size __func__.4209, 14 +__func__.4209: + .ascii "ftl_check_vpc\000" + .type __func__.3529, %object + .size __func__.3529, 11 +__func__.3529: + .ascii "FtlLoadBbt\000" + .type __func__.3486, %object + .size __func__.3486, 14 +__func__.3486: + .ascii "FtlBbt2Bitmap\000" + .type __func__.3270, %object + .size __func__.3270, 11 +__func__.3270: + .ascii "FtlMemInit\000" + .type __func__.3993, %object + .size __func__.3993, 15 +__func__.3993: + .ascii "FtlLoadSysInfo\000" + .type __func__.3914, %object + .size __func__.3914, 15 +__func__.3914: + .ascii "FtlVpcTblFlush\000" + .type __func__.4334, %object + .size __func__.4334, 16 +__func__.4334: + .ascii "update_vpc_list\000" + .type __func__.4341, %object + .size __func__.4341, 20 +__func__.4341: + .ascii "decrement_vpc_count\000" + .type __func__.4090, %object + .size __func__.4090, 22 +__func__.4090: + .ascii "FtlRecoverySuperblock\000" + .type __func__.4293, %object + .size __func__.4293, 25 +__func__.4293: + .ascii "allocate_data_superblock\000" + .type __func__.4314, %object + .size __func__.4314, 29 +__func__.4314: + .ascii "allocate_new_data_superblock\000" + .type __func__.3394, %object + .size __func__.3394, 13 +__func__.3394: + .ascii "FtlProgPages\000" + .type __func__.4411, %object + .size __func__.4411, 19 +__func__.4411: + .ascii "FtlGcFreeTempBlock\000" + .type __func__.4517, %object + .size __func__.4517, 23 +__func__.4517: + .ascii "rk_ftl_garbage_collect\000" + .type __func__.4193, %object + .size __func__.4193, 21 +__func__.4193: + .ascii "FtlVpcCheckAndModify\000" + .type __func__.3422, %object + .size __func__.3422, 9 +__func__.3422: + .ascii "FtlWrite\000" + .section .rodata.str1.1,"aMS",%progbits,1 +.LC0: + .ascii "phyBlk = 0x%x die = %d block_in_die = 0x%x 0x%8x\012" + .ascii "\000" +.LC1: + .ascii "\012!!!!! error @ func:%s - line:%d\012\000" +.LC2: + .ascii "FLASH INFO:\012\000" +.LC3: + .ascii "Device Capacity: %d MB\012\000" +.LC4: + .ascii "FTL INFO:\012\000" +.LC5: + .ascii "g_MaxLpn = 0x%x\012\000" +.LC6: + .ascii "g_VaildLpn = 0x%x\012\000" +.LC7: + .ascii "read_page_count = 0x%x\012\000" +.LC8: + .ascii "discard_page_count = 0x%x\012\000" +.LC9: + .ascii "write_page_count = 0x%x\012\000" +.LC10: + .ascii "cache_write_count = 0x%x\012\000" +.LC11: + .ascii "l2p_write_count = 0x%x\012\000" +.LC12: + .ascii "gc_page_count = 0x%x\012\000" +.LC13: + .ascii "totle_write = %d MB\012\000" +.LC14: + .ascii "totle_read = %d MB\012\000" +.LC15: + .ascii "GSV = 0x%x\012\000" +.LC16: + .ascii "GDV = 0x%x\012\000" +.LC17: + .ascii "bad blk num = %d\012\000" +.LC18: + .ascii "free_superblocks = 0x%x\012\000" +.LC19: + .ascii "mlc_EC = 0x%x\012\000" +.LC20: + .ascii "slc_EC = 0x%x\012\000" +.LC21: + .ascii "avg_EC = 0x%x\012\000" +.LC22: + .ascii "sys_EC = 0x%x\012\000" +.LC23: + .ascii "max_EC = 0x%x\012\000" +.LC24: + .ascii "min_EC = 0x%x\012\000" +.LC25: + .ascii "PLT = 0x%x\012\000" +.LC26: + .ascii "POT = 0x%x\012\000" +.LC27: + .ascii "MaxSector = 0x%x\012\000" +.LC28: + .ascii "init_sys_blks_pp = 0x%x\012\000" +.LC29: + .ascii "sys_blks_pp = 0x%x\012\000" +.LC30: + .ascii "free sysblock = 0x%x\012\000" +.LC31: + .ascii "data_blks_pp = 0x%x\012\000" +.LC32: + .ascii "data_op_blks_pp = 0x%x\012\000" +.LC33: + .ascii "max_data_blks = 0x%x\012\000" +.LC34: + .ascii "Sys.id = 0x%x\012\000" +.LC35: + .ascii "Bbt.id = 0x%x\012\000" +.LC36: + .ascii "ACT.page = 0x%x\012\000" +.LC37: + .ascii "ACT.plane = 0x%x\012\000" +.LC38: + .ascii "ACT.id = 0x%x\012\000" +.LC39: + .ascii "ACT.mode = 0x%x\012\000" +.LC40: + .ascii "ACT.a_pages = 0x%x\012\000" +.LC41: + .ascii "ACT VPC = 0x%x\012\000" +.LC42: + .ascii "BUF.page = 0x%x\012\000" +.LC43: + .ascii "BUF.plane = 0x%x\012\000" +.LC44: + .ascii "BUF.id = 0x%x\012\000" +.LC45: + .ascii "BUF.mode = 0x%x\012\000" +.LC46: + .ascii "BUF.a_pages = 0x%x\012\000" +.LC47: + .ascii "BUF VPC = 0x%x\012\000" +.LC48: + .ascii "TMP.page = 0x%x\012\000" +.LC49: + .ascii "TMP.plane = 0x%x\012\000" +.LC50: + .ascii "TMP.id = 0x%x\012\000" +.LC51: + .ascii "TMP.mode = 0x%x\012\000" +.LC52: + .ascii "TMP.a_pages = 0x%x\012\000" +.LC53: + .ascii "GC.page = 0x%x\012\000" +.LC54: + .ascii "GC.plane = 0x%x\012\000" +.LC55: + .ascii "GC.id = 0x%x\012\000" +.LC56: + .ascii "GC.mode = 0x%x\012\000" +.LC57: + .ascii "GC.a_pages = 0x%x\012\000" +.LC58: + .ascii "WR_CHK = 0x%x %x %x %x\012\000" +.LC59: + .ascii "Read Err Cnt = 0x%x\012\000" +.LC60: + .ascii "Prog Err Cnt = 0x%x\012\000" +.LC61: + .ascii "gc_free_blk_th= 0x%x\012\000" +.LC62: + .ascii "gc_merge_free_blk_th= 0x%x\012\000" +.LC63: + .ascii "gc_skip_write_count= 0x%x\012\000" +.LC64: + .ascii "gc_blk_index= 0x%x\012\000" +.LC65: + .ascii "free min EC= 0x%x\012\000" +.LC66: + .ascii "free max EC= 0x%x\012\000" +.LC67: + .ascii "GC__SB VPC = 0x%x\012\000" +.LC68: + .ascii "%d. [0x%x]=0x%x 0x%x 0x%x\012\000" +.LC69: + .ascii "free %d. [0x%x] 0x%x 0x%x\012\000" +.LC70: + .ascii "%s\012\000" +.LC71: + .ascii "FTL version: 5.0.41 20170928\000" +.LC72: + .ascii "GetSwlReplaceBlock min_ec_id =%x %x\012\000" +.LC73: + .ascii "swblk %x ,avg = %x max= %x vpc= %x,ec=%x ,max ec=%x" + .ascii "\012\000" +.LC74: + .ascii "FtlGcRefreshBlock 0x%x\012\000" +.LC75: + .ascii "FtlGcMarkBadPhyBlk %d 0x%x\012\000" +.LC76: + .ascii "prog read error: = %x\012\000" +.LC77: + .ascii "prog read s error: = %x %x %x\012\000" +.LC78: + .ascii "prog read d error: = %x %x %x\012\000" +.LC79: + .ascii "FtlMapWritePage error = %x \012\000" +.LC80: + .ascii "FtlMapWritePage error = %x error count = %d\012\000" +.LC81: + .ascii "region_id = %x phyAddr = %x\012\000" +.LC82: + .ascii "spare:\000" +.LC83: + .ascii "map_ppn:\000" +.LC84: + .ascii "ftl_scan_all_data = %x\012\000" +.LC85: + .ascii "scan lpa = %x ppa= %x\012\000" +.LC86: + .ascii "lba = %x,addr= %x,spare= %x %x %x %x data=%x %x\012" + .ascii "\000" +.LC87: + .ascii "...%s enter...\012\000" +.LC88: + .ascii "FtlCheckVpc2 %x = %x %x\012\000" +.LC89: + .ascii "free blk vpc error %x = %x %x\012\000" +.LC90: + .ascii "%s error allocating memory. return -1\012\000" +.LC91: + .ascii "FtlVpcTblFlush error = %x error count = %d\012\000" +.LC92: + .ascii "slc mode\000" +.LC93: + .ascii "no ect\000" +.LC94: + .ascii "FtlBbmTblFlush id=%x,page=%x,previd=%x cnt=%d\012\000" +.LC95: + .ascii "FtlBbmTblFlush error:%x\012\000" +.LC96: + .ascii "FtlBbmTblFlush error = %x error count = %d\012\000" +.LC97: + .ascii "FtlGcFreeBadSuperBlk 0x%x\012\000" +.LC98: + .ascii "decrement_vpc_count %x = %d\012\000" +.LC99: + .ascii "spuer block %x vpn is 0\012 \000" +.LC100: + .ascii "Ftlwrite decrement_vpc_count %x = %d\012\000" +.LC101: + .ascii "SWL %x, FSB = %x vpc= %x,ec=%x th=%x\012\000" +.LC102: + .ascii "FtlCheckVpc %x = %x %x\012\000" +.LC103: + .ascii "FtlWrite: lpa error:%x %x\012\000" + .data + .align 2 + .set .LANCHOR2,. + 0 + .type gFtlInitStatus, %object + .size gFtlInitStatus, 4 +gFtlInitStatus: + .word -1 + .type ftl_gc_temp_block_bops_scan_page_addr, %object + .size ftl_gc_temp_block_bops_scan_page_addr, 2 +ftl_gc_temp_block_bops_scan_page_addr: + .short -1 + .space 2 + .type power_up_flag, %object + .size power_up_flag, 4 +power_up_flag: + .word 1 + .bss + .align 2 + .set .LANCHOR0,. + 0 + .set .LANCHOR3,. + 8184 + .set .LANCHOR4,. + 24552 + .set .LANCHOR5,. + 32736 + .type c_ftl_nand_sys_blks_per_plane, %object + .size c_ftl_nand_sys_blks_per_plane, 4 +c_ftl_nand_sys_blks_per_plane: + .space 4 + .type c_ftl_nand_planes_num, %object + .size c_ftl_nand_planes_num, 2 +c_ftl_nand_planes_num: + .space 2 + .space 2 + .type c_ftl_nand_max_sys_blks, %object + .size c_ftl_nand_max_sys_blks, 4 +c_ftl_nand_max_sys_blks: + .space 4 + .type c_ftl_nand_data_blks_per_plane, %object + .size c_ftl_nand_data_blks_per_plane, 2 +c_ftl_nand_data_blks_per_plane: + .space 2 + .type c_ftl_nand_blk_pre_plane, %object + .size c_ftl_nand_blk_pre_plane, 2 +c_ftl_nand_blk_pre_plane: + .space 2 + .type c_ftl_nand_max_data_blks, %object + .size c_ftl_nand_max_data_blks, 4 +c_ftl_nand_max_data_blks: + .space 4 + .type c_ftl_nand_totle_phy_blks, %object + .size c_ftl_nand_totle_phy_blks, 4 +c_ftl_nand_totle_phy_blks: + .space 4 + .type c_ftl_nand_type, %object + .size c_ftl_nand_type, 2 +c_ftl_nand_type: + .space 2 + .type c_ftl_nand_die_num, %object + .size c_ftl_nand_die_num, 2 +c_ftl_nand_die_num: + .space 2 + .type c_ftl_nand_planes_per_die, %object + .size c_ftl_nand_planes_per_die, 2 +c_ftl_nand_planes_per_die: + .space 2 + .type p_plane_order_table, %object + .size p_plane_order_table, 32 +p_plane_order_table: + .space 32 + .type c_mlc_erase_count_value, %object + .size c_mlc_erase_count_value, 2 +c_mlc_erase_count_value: + .space 2 + .type c_ftl_nand_ext_blk_pre_plane, %object + .size c_ftl_nand_ext_blk_pre_plane, 2 +c_ftl_nand_ext_blk_pre_plane: + .space 2 + .type c_ftl_vendor_part_size, %object + .size c_ftl_vendor_part_size, 2 +c_ftl_vendor_part_size: + .space 2 + .type c_ftl_nand_blks_per_die, %object + .size c_ftl_nand_blks_per_die, 2 +c_ftl_nand_blks_per_die: + .space 2 + .type c_ftl_nand_blks_per_die_shift, %object + .size c_ftl_nand_blks_per_die_shift, 2 +c_ftl_nand_blks_per_die_shift: + .space 2 + .type c_ftl_nand_page_pre_blk, %object + .size c_ftl_nand_page_pre_blk, 2 +c_ftl_nand_page_pre_blk: + .space 2 + .type c_ftl_nand_page_pre_slc_blk, %object + .size c_ftl_nand_page_pre_slc_blk, 2 +c_ftl_nand_page_pre_slc_blk: + .space 2 + .type c_ftl_nand_page_pre_super_blk, %object + .size c_ftl_nand_page_pre_super_blk, 2 +c_ftl_nand_page_pre_super_blk: + .space 2 + .type c_ftl_nand_sec_pre_page, %object + .size c_ftl_nand_sec_pre_page, 2 +c_ftl_nand_sec_pre_page: + .space 2 + .type c_ftl_nand_sec_pre_page_shift, %object + .size c_ftl_nand_sec_pre_page_shift, 2 +c_ftl_nand_sec_pre_page_shift: + .space 2 + .type c_ftl_nand_byte_pre_page, %object + .size c_ftl_nand_byte_pre_page, 2 +c_ftl_nand_byte_pre_page: + .space 2 + .type c_ftl_nand_byte_pre_oob, %object + .size c_ftl_nand_byte_pre_oob, 2 +c_ftl_nand_byte_pre_oob: + .space 2 + .type c_ftl_nand_reserved_blks, %object + .size c_ftl_nand_reserved_blks, 2 +c_ftl_nand_reserved_blks: + .space 2 + .type DeviceCapacity, %object + .size DeviceCapacity, 4 +DeviceCapacity: + .space 4 + .type c_ftl_nand_max_vendor_blks, %object + .size c_ftl_nand_max_vendor_blks, 2 +c_ftl_nand_max_vendor_blks: + .space 2 + .type c_ftl_nand_vendor_region_num, %object + .size c_ftl_nand_vendor_region_num, 2 +c_ftl_nand_vendor_region_num: + .space 2 + .type c_ftl_nand_map_blks_per_plane, %object + .size c_ftl_nand_map_blks_per_plane, 2 +c_ftl_nand_map_blks_per_plane: + .space 2 + .space 2 + .type c_ftl_nand_max_map_blks, %object + .size c_ftl_nand_max_map_blks, 4 +c_ftl_nand_max_map_blks: + .space 4 + .type c_ftl_nand_init_sys_blks_per_plane, %object + .size c_ftl_nand_init_sys_blks_per_plane, 4 +c_ftl_nand_init_sys_blks_per_plane: + .space 4 + .type c_ftl_nand_map_region_num, %object + .size c_ftl_nand_map_region_num, 2 +c_ftl_nand_map_region_num: + .space 2 + .type c_ftl_nand_l2pmap_ram_region_num, %object + .size c_ftl_nand_l2pmap_ram_region_num, 2 +c_ftl_nand_l2pmap_ram_region_num: + .space 2 + .type g_MaxLbaSector, %object + .size g_MaxLbaSector, 4 +g_MaxLbaSector: + .space 4 + .type g_totle_vendor_block, %object + .size g_totle_vendor_block, 2 +g_totle_vendor_block: + .space 2 + .space 2 + .type p_vendor_block_table, %object + .size p_vendor_block_table, 4 +p_vendor_block_table: + .space 4 + .type gBbtInfo, %object + .size gBbtInfo, 60 +gBbtInfo: + .space 60 + .type gSysFreeQueue, %object + .size gSysFreeQueue, 2056 +gSysFreeQueue: + .space 2056 + .type p_sys_data_buf, %object + .size p_sys_data_buf, 4 +p_sys_data_buf: + .space 4 + .type p_erase_count_table, %object + .size p_erase_count_table, 4 +p_erase_count_table: + .space 4 + .type p_data_block_list_table, %object + .size p_data_block_list_table, 4 +p_data_block_list_table: + .space 4 + .type p_data_block_list_head, %object + .size p_data_block_list_head, 4 +p_data_block_list_head: + .space 4 + .type p_valid_page_count_table, %object + .size p_valid_page_count_table, 4 +p_valid_page_count_table: + .space 4 + .type p_data_block_list_tail, %object + .size p_data_block_list_tail, 4 +p_data_block_list_tail: + .space 4 + .type g_num_data_superblocks, %object + .size g_num_data_superblocks, 2 +g_num_data_superblocks: + .space 2 + .space 2 + .type p_free_data_block_list_head, %object + .size p_free_data_block_list_head, 4 +p_free_data_block_list_head: + .space 4 + .type g_num_free_superblocks, %object + .size g_num_free_superblocks, 2 +g_num_free_superblocks: + .space 2 + .space 2 + .type g_active_superblock, %object + .size g_active_superblock, 48 +g_active_superblock: + .space 48 + .type g_buffer_superblock, %object + .size g_buffer_superblock, 48 +g_buffer_superblock: + .space 48 + .type g_gc_temp_superblock, %object + .size g_gc_temp_superblock, 48 +g_gc_temp_superblock: + .space 48 + .type p_l2p_ram_map, %object + .size p_l2p_ram_map, 4 +p_l2p_ram_map: + .space 4 + .type g_l2p_last_update_region_id, %object + .size g_l2p_last_update_region_id, 2 +g_l2p_last_update_region_id: + .space 2 + .type FtlUpdateVaildLpnCount, %object + .size FtlUpdateVaildLpnCount, 2 +FtlUpdateVaildLpnCount: + .space 2 + .type g_VaildLpn, %object + .size g_VaildLpn, 4 +g_VaildLpn: + .space 4 + .type p_blk_mode_table, %object + .size p_blk_mode_table, 4 +p_blk_mode_table: + .space 4 + .type g_inkDie_check_enable, %object + .size g_inkDie_check_enable, 4 +g_inkDie_check_enable: + .space 4 + .type g_MaxLpn, %object + .size g_MaxLpn, 4 +g_MaxLpn: + .space 4 + .type g_totle_read_page_count, %object + .size g_totle_read_page_count, 4 +g_totle_read_page_count: + .space 4 + .type g_totle_discard_page_count, %object + .size g_totle_discard_page_count, 4 +g_totle_discard_page_count: + .space 4 + .type g_totle_write_page_count, %object + .size g_totle_write_page_count, 4 +g_totle_write_page_count: + .space 4 + .type g_totle_cache_write_count, %object + .size g_totle_cache_write_count, 4 +g_totle_cache_write_count: + .space 4 + .type g_totle_l2p_write_count, %object + .size g_totle_l2p_write_count, 4 +g_totle_l2p_write_count: + .space 4 + .type g_totle_gc_page_count, %object + .size g_totle_gc_page_count, 4 +g_totle_gc_page_count: + .space 4 + .type g_totle_write_sector, %object + .size g_totle_write_sector, 4 +g_totle_write_sector: + .space 4 + .type g_totle_read_sector, %object + .size g_totle_read_sector, 4 +g_totle_read_sector: + .space 4 + .type g_GlobalSysVersion, %object + .size g_GlobalSysVersion, 4 +g_GlobalSysVersion: + .space 4 + .type g_GlobalDataVersion, %object + .size g_GlobalDataVersion, 4 +g_GlobalDataVersion: + .space 4 + .type g_totle_mlc_erase_count, %object + .size g_totle_mlc_erase_count, 4 +g_totle_mlc_erase_count: + .space 4 + .type g_totle_slc_erase_count, %object + .size g_totle_slc_erase_count, 4 +g_totle_slc_erase_count: + .space 4 + .type g_totle_avg_erase_count, %object + .size g_totle_avg_erase_count, 4 +g_totle_avg_erase_count: + .space 4 + .type g_totle_sys_slc_erase_count, %object + .size g_totle_sys_slc_erase_count, 4 +g_totle_sys_slc_erase_count: + .space 4 + .type g_max_erase_count, %object + .size g_max_erase_count, 4 +g_max_erase_count: + .space 4 + .type g_min_erase_count, %object + .size g_min_erase_count, 4 +g_min_erase_count: + .space 4 + .type g_sys_save_data, %object + .size g_sys_save_data, 48 +g_sys_save_data: + .space 48 + .type c_ftl_nand_data_op_blks_per_plane, %object + .size c_ftl_nand_data_op_blks_per_plane, 2 +c_ftl_nand_data_op_blks_per_plane: + .space 2 + .space 2 + .type gSysInfo, %object + .size gSysInfo, 12 +gSysInfo: + .space 12 + .type g_gc_superblock, %object + .size g_gc_superblock, 48 +g_gc_superblock: + .space 48 + .type g_all_blk_used_slc_mode, %object + .size g_all_blk_used_slc_mode, 4 +g_all_blk_used_slc_mode: + .space 4 + .type g_sys_ext_data, %object + .size g_sys_ext_data, 512 +g_sys_ext_data: + .space 512 + .type g_gc_free_blk_threshold, %object + .size g_gc_free_blk_threshold, 2 +g_gc_free_blk_threshold: + .space 2 + .type g_gc_merge_free_blk_threshold, %object + .size g_gc_merge_free_blk_threshold, 2 +g_gc_merge_free_blk_threshold: + .space 2 + .type g_gc_skip_write_count, %object + .size g_gc_skip_write_count, 4 +g_gc_skip_write_count: + .space 4 + .type g_gc_blk_index, %object + .size g_gc_blk_index, 2 +g_gc_blk_index: + .space 2 + .space 2 + .type g_in_swl_replace, %object + .size g_in_swl_replace, 4 +g_in_swl_replace: + .space 4 + .type g_gc_num_req, %object + .size g_gc_num_req, 4 +g_gc_num_req: + .space 4 + .type gp_gc_page_buf_info, %object + .size gp_gc_page_buf_info, 4 +gp_gc_page_buf_info: + .space 4 + .type p_gc_data_buf, %object + .size p_gc_data_buf, 4 +p_gc_data_buf: + .space 4 + .type p_gc_spare_buf, %object + .size p_gc_spare_buf, 4 +p_gc_spare_buf: + .space 4 + .type req_gc, %object + .size req_gc, 4 +req_gc: + .space 4 + .type c_gc_page_buf_num, %object + .size c_gc_page_buf_num, 4 +c_gc_page_buf_num: + .space 4 + .type g_gc_blk_num, %object + .size g_gc_blk_num, 2 +g_gc_blk_num: + .space 2 + .space 2 + .type p_gc_blk_tbl, %object + .size p_gc_blk_tbl, 4 +p_gc_blk_tbl: + .space 4 + .type p_gc_page_info, %object + .size p_gc_page_info, 4 +p_gc_page_info: + .space 4 + .type g_gc_page_offset, %object + .size g_gc_page_offset, 2 +g_gc_page_offset: + .space 2 + .type g_gc_next_blk, %object + .size g_gc_next_blk, 2 +g_gc_next_blk: + .space 2 + .type g_gc_next_blk_1, %object + .size g_gc_next_blk_1, 2 +g_gc_next_blk_1: + .space 2 + .type g_gc_bad_block_temp_num, %object + .size g_gc_bad_block_temp_num, 2 +g_gc_bad_block_temp_num: + .space 2 + .type g_gc_bad_block_temp_tbl, %object + .size g_gc_bad_block_temp_tbl, 34 +g_gc_bad_block_temp_tbl: + .space 34 + .type g_gc_bad_block_gc_index, %object + .size g_gc_bad_block_gc_index, 2 +g_gc_bad_block_gc_index: + .space 2 + .type ftl_temp_buf, %object + .size ftl_temp_buf, 4096 +ftl_temp_buf: + .space 4096 + .type req_sys, %object + .size req_sys, 20 +req_sys: + .space 20 + .type p_sys_spare_buf, %object + .size p_sys_spare_buf, 4 +p_sys_spare_buf: + .space 4 + .type check_buf, %object + .size check_buf, 4096 +check_buf: + .space 4096 + .type check_spare_buf, %object + .size check_spare_buf, 512 +check_spare_buf: + .space 512 + .type req_erase, %object + .size req_erase, 4 +req_erase: + .space 4 + .type g_cur_erase_blk, %object + .size g_cur_erase_blk, 4 +g_cur_erase_blk: + .space 4 + .type p_io_data_buf_1, %object + .size p_io_data_buf_1, 4 +p_io_data_buf_1: + .space 4 + .type p_io_spare_buf, %object + .size p_io_spare_buf, 4 +p_io_spare_buf: + .space 4 + .type p_io_data_buf_0, %object + .size p_io_data_buf_0, 4 +p_io_data_buf_0: + .space 4 + .type req_read, %object + .size req_read, 4 +req_read: + .space 4 + .type ftl_gc_temp_power_lost_recovery_flag, %object + .size ftl_gc_temp_power_lost_recovery_flag, 4 +ftl_gc_temp_power_lost_recovery_flag: + .space 4 + .type p_map_block_valid_page_count, %object + .size p_map_block_valid_page_count, 4 +p_map_block_valid_page_count: + .space 4 + .type p_l2p_map_buf, %object + .size p_l2p_map_buf, 4 +p_l2p_map_buf: + .space 4 + .type gL2pMapInfo, %object + .size gL2pMapInfo, 40 +gL2pMapInfo: + .space 40 + .type g_totle_map_block, %object + .size g_totle_map_block, 2 +g_totle_map_block: + .space 2 + .space 2 + .type p_map_block_table, %object + .size p_map_block_table, 4 +p_map_block_table: + .space 4 + .type p_map_block_ver_table, %object + .size p_map_block_ver_table, 4 +p_map_block_ver_table: + .space 4 + .type p_map_region_ppn_table, %object + .size p_map_region_ppn_table, 4 +p_map_region_ppn_table: + .space 4 + .type p_vendor_block_ver_table, %object + .size p_vendor_block_ver_table, 4 +p_vendor_block_ver_table: + .space 4 + .type p_sys_data_buf_1, %object + .size p_sys_data_buf_1, 4 +p_sys_data_buf_1: + .space 4 + .type gVendorBlkInfo, %object + .size gVendorBlkInfo, 40 +gVendorBlkInfo: + .space 40 + .type p_vendor_block_valid_page_count, %object + .size p_vendor_block_valid_page_count, 4 +p_vendor_block_valid_page_count: + .space 4 + .type p_vendor_region_ppn_table, %object + .size p_vendor_region_ppn_table, 4 +p_vendor_region_ppn_table: + .space 4 + .type check_vpc_table, %object + .size check_vpc_table, 16384 +check_vpc_table: + .space 16384 + .type c_ftl_nand_bbm_buf_size, %object + .size c_ftl_nand_bbm_buf_size, 2 +c_ftl_nand_bbm_buf_size: + .space 2 + .space 2 + .type g_req_cache, %object + .size g_req_cache, 4 +g_req_cache: + .space 4 + .type g_tmp_data_superblock_id, %object + .size g_tmp_data_superblock_id, 2 +g_tmp_data_superblock_id: + .space 2 + .space 2 + .type g_totle_swl_count, %object + .size g_totle_swl_count, 4 +g_totle_swl_count: + .space 4 + .type g_recovery_page_min_ver, %object + .size g_recovery_page_min_ver, 4 +g_recovery_page_min_ver: + .space 4 + .type p_swl_mul_table, %object + .size p_swl_mul_table, 4 +p_swl_mul_table: + .space 4 + .type g_SlcPartLbaEndSector, %object + .size g_SlcPartLbaEndSector, 4 +g_SlcPartLbaEndSector: + .space 4 + .type g_in_gc_progress, %object + .size g_in_gc_progress, 4 +g_in_gc_progress: + .space 4 + .type g_gc_head_data_block, %object + .size g_gc_head_data_block, 4 +g_gc_head_data_block: + .space 4 + .type g_gc_head_data_block_count, %object + .size g_gc_head_data_block_count, 4 +g_gc_head_data_block_count: + .space 4 + .type c_wr_page_buf_num, %object + .size c_wr_page_buf_num, 4 +c_wr_page_buf_num: + .space 4 + .type g_wr_page_num, %object + .size g_wr_page_num, 4 +g_wr_page_num: + .space 4 + .type req_gc_dst, %object + .size req_gc_dst, 4 +req_gc_dst: + .space 4 + .type req_prgm, %object + .size req_prgm, 4 +req_prgm: + .space 4 + .type req_wr_io, %object + .size req_wr_io, 4 +req_wr_io: + .space 4 + .type p_vendor_data_buf, %object + .size p_vendor_data_buf, 4 +p_vendor_data_buf: + .space 4 + .type p_wr_io_data_buf, %object + .size p_wr_io_data_buf, 4 +p_wr_io_data_buf: + .space 4 + .type p_wr_io_spare_buf, %object + .size p_wr_io_spare_buf, 4 +p_wr_io_spare_buf: + .space 4 + .type g_ect_tbl_info_size, %object + .size g_ect_tbl_info_size, 2 +g_ect_tbl_info_size: + .space 2 + .space 2 + .type gp_ect_tbl_info, %object + .size gp_ect_tbl_info, 4 +gp_ect_tbl_info: + .space 4 + .type p_valid_page_count_check_table, %object + .size p_valid_page_count_check_table, 4 +p_valid_page_count_check_table: + .space 4 + .type g_MaxLbn, %object + .size g_MaxLbn, 4 +g_MaxLbn: + .space 4 + .type g_ect_tbl_power_up_flush, %object + .size g_ect_tbl_power_up_flush, 2 +g_ect_tbl_power_up_flush: + .space 2 + .type g_power_lost_recovery_flag, %object + .size g_power_lost_recovery_flag, 2 +g_power_lost_recovery_flag: + .space 2 + .type g_recovery_page_num, %object + .size g_recovery_page_num, 4 +g_recovery_page_num: + .space 4 + .type g_recovery_ppa_tbl, %object + .size g_recovery_ppa_tbl, 128 +g_recovery_ppa_tbl: + .space 128 + .type gp_last_act_superblock, %object + .size gp_last_act_superblock, 4 +gp_last_act_superblock: + .space 4 + .type gc_ink_free_return_value, %object + .size gc_ink_free_return_value, 2 +gc_ink_free_return_value: + .space 2 + .type g_gc_cur_blk_valid_pages, %object + .size g_gc_cur_blk_valid_pages, 2 +g_gc_cur_blk_valid_pages: + .space 2 + .type g_gc_cur_blk_max_valid_pages, %object + .size g_gc_cur_blk_max_valid_pages, 2 +g_gc_cur_blk_max_valid_pages: + .space 2 + .space 2 + .type gc_discard_updated, %object + .size gc_discard_updated, 4 +gc_discard_updated: + .space 4 + .type g_ftl_nand_free_count, %object + .size g_ftl_nand_free_count, 4 +g_ftl_nand_free_count: + .space 4 diff --git a/drivers/rkflash/rk_sftl.h b/drivers/rkflash/rk_sftl.h new file mode 100644 index 000000000000..7412fd49db78 --- /dev/null +++ b/drivers/rkflash/rk_sftl.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#ifndef __RK_SFTL_H +#define __RK_SFTL_H + +u32 ftl_low_format(void); +int sftl_init(void); +int sftl_deinit(void); +int sftl_read(u32 index, u32 count, u8 *buf); +int sftl_write(u32 index, u32 count, u8 *buf); +u32 sftl_get_density(void); +s32 sftl_gc(void); + +#endif diff --git a/drivers/rkflash/rkflash_api.h b/drivers/rkflash/rkflash_api.h new file mode 100644 index 000000000000..dffd43e3c6b3 --- /dev/null +++ b/drivers/rkflash/rkflash_api.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#ifndef __RK_FLASH_API_H +#define __RK_FLASH_API_H + +#ifdef CONFIG_RK_NANDC_NAND +#include "nand_boot.h" +#endif + +#ifdef CONFIG_RK_SFC_NOR +#include "sfc_nor_boot.h" +#endif + +#ifdef CONFIG_RK_SFC_NAND +#include "sfc_nand_boot.h" +#endif + +#endif diff --git a/drivers/rkflash/rkflash_blk.c b/drivers/rkflash/rkflash_blk.c new file mode 100644 index 000000000000..e3131309ddfd --- /dev/null +++ b/drivers/rkflash/rkflash_blk.c @@ -0,0 +1,704 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rkflash_api.h" +#include "rkflash_blk.h" + +#include "../soc/rockchip/flash_vendor_storage.h" + +static struct flash_boot_ops nandc_nand_ops = { +#ifdef CONFIG_RK_NANDC_NAND + FLASH_TYPE_NANDC_NAND, + sftl_flash_init, + sftl_flash_read, + sftl_flash_write, + sftl_flash_get_capacity, + sftl_flash_deinit, + sftl_flash_resume, + sftl_flash_read, + sftl_flash_write, +#else + -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +#endif +}; + +static struct flash_boot_ops sfc_nor_ops = { +#ifdef CONFIG_RK_SFC_NOR + FLASH_TYPE_SFC_NOR, + spi_flash_init, + snor_read_lba, + snor_write_lba, + snor_capacity, + snor_deinit, + snor_resume, + snor_vendor_read, + snor_vendor_write, +#else + -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +#endif +}; + +static struct flash_boot_ops sfc_nand_ops = { +#ifdef CONFIG_RK_SFC_NAND + FLASH_TYPE_SFC_NAND, + snand_init, + snand_read, + snand_write, + snand_get_capacity, + snand_deinit, + snand_resume, + snand_read, + snand_write, +#else + -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +#endif +}; + +static struct flash_boot_ops *g_boot_ops[] = { + &nandc_nand_ops, + &sfc_nor_ops, + &sfc_nand_ops, +}; + +static int g_flash_type = -1; + +static struct flash_part disk_array[MAX_PART_COUNT]; +static int g_max_part_num = 4; +#define FW_HRADER_PT_NAME ("fw_header_p") +static struct flash_part fw_header_p; + +#define PART_READONLY 0x85 +#define PART_WRITEONLY 0x86 +#define PART_NO_ACCESS 0x87 + +static unsigned long totle_read_data; +static unsigned long totle_write_data; +static unsigned long totle_read_count; +static unsigned long totle_write_count; +static int rkflash_dev_initialised; + +static char *mtd_read_temp_buffer; +#define MTD_RW_SECTORS (512) +static DEFINE_MUTEX(g_flash_ops_mutex); + +static unsigned int rk_partition_init(struct flash_part *part) +{ + int i, part_num = 0; + int desity; + struct STRUCT_PART_INFO *g_part; /* size 2KB */ + + g_part = kmalloc(sizeof(*g_part), GFP_KERNEL | GFP_DMA); + if (!g_part) + return 0; + + if (g_boot_ops[g_flash_type]->read(0, 4, g_part) == 0) { + if (g_part->hdr.ui_fw_tag == RK_PARTITION_TAG) { + part_num = g_part->hdr.ui_part_entry_count; + desity = g_boot_ops[g_flash_type]->get_capacity(); + for (i = 0; i < part_num; i++) { + memcpy(part[i].name, + g_part->part[i].sz_name, + 32); + part[i].offset = g_part->part[i].ui_pt_off; + part[i].size = g_part->part[i].ui_pt_sz; + part[i].type = 0; + if (part[i].size == UINT_MAX) + part[i].size = desity - part[i].offset; + } + } + } + kfree(g_part); + + memset(&fw_header_p, 0x0, sizeof(fw_header_p)); + memcpy(fw_header_p.name, FW_HRADER_PT_NAME, strlen(FW_HRADER_PT_NAME)); + fw_header_p.offset = 0x0; + fw_header_p.size = 0x4; + fw_header_p.type = 0; + + return part_num; +} + +static int rkflash_proc_show(struct seq_file *m, void *v) +{ + seq_printf(m, "Totle Read %ld KB\n", totle_read_data >> 1); + seq_printf(m, "Totle Write %ld KB\n", totle_write_data >> 1); + seq_printf(m, "totle_write_count %ld\n", totle_write_count); + seq_printf(m, "totle_read_count %ld\n", totle_read_count); + return 0; +} + +static int rkflash_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, rkflash_proc_show, PDE_DATA(inode)); +} + +static const struct file_operations rkflash_proc_fops = { + .owner = THIS_MODULE, + .open = rkflash_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int rkflash_create_procfs(void) +{ + struct proc_dir_entry *ent; + + ent = proc_create_data("rkflash", 0x664, NULL, &rkflash_proc_fops, + (void *)0); + if (!ent) + return -1; + + return 0; +} + +static int rkflash_xfer(struct flash_blk_dev *dev, + unsigned long start, + unsigned long nsector, + char *buf, + int cmd, + int totle_nsec) +{ + int ret; + + if (dev->disable_access || + (cmd == WRITE && dev->readonly) || + (cmd == READ && dev->writeonly)) { + return -EIO; + } + + start += dev->off_size; + + switch (cmd) { + case READ: + totle_read_data += nsector; + totle_read_count++; + mutex_lock(&g_flash_ops_mutex); + ret = g_boot_ops[g_flash_type]->read(start, nsector, buf); + mutex_unlock(&g_flash_ops_mutex); + if (ret) + ret = -EIO; + break; + + case WRITE: + totle_write_data += nsector; + totle_write_count++; + mutex_lock(&g_flash_ops_mutex); + ret = g_boot_ops[g_flash_type]->write(start, nsector, buf); + mutex_unlock(&g_flash_ops_mutex); + if (ret) + ret = -EIO; + break; + + default: + ret = -EIO; + break; + } + + return ret; +} + +static DECLARE_WAIT_QUEUE_HEAD(rkflash_thread_wait); +static unsigned long rkflash_req_jiffies; +static unsigned int rknand_req_do; + +static int req_check_buffer_align(struct request *req, char **pbuf) +{ + int nr_vec = 0; + struct bio_vec bvec; + struct req_iterator iter; + char *buffer; + void *firstbuf = 0; + char *nextbuffer = 0; + + rq_for_each_segment(bvec, req, iter) { + buffer = page_address(bvec.bv_page) + bvec.bv_offset; + if (!firstbuf) + firstbuf = buffer; + nr_vec++; + if (nextbuffer && nextbuffer != buffer) + return 0; + nextbuffer = buffer + bvec.bv_len; + } + *pbuf = firstbuf; + return 1; +} + +static int rkflash_blktrans_thread(void *arg) +{ + struct flash_blk_ops *blk_ops = arg; + struct request_queue *rq = blk_ops->rq; + struct request *req = NULL; + char *buf; + struct req_iterator rq_iter; + struct bio_vec bvec; + unsigned long long sector_index = ULLONG_MAX; + unsigned long totle_nsect; + unsigned long rq_len = 0; + int rw_flag = 0; + + spin_lock_irq(rq->queue_lock); + while (!blk_ops->quit) { + int res; + struct flash_blk_dev *dev; + DECLARE_WAITQUEUE(wait, current); + + if (!req) + req = blk_fetch_request(rq); + if (!req) { + add_wait_queue(&blk_ops->thread_wq, &wait); + set_current_state(TASK_INTERRUPTIBLE); + spin_unlock_irq(rq->queue_lock); + rkflash_req_jiffies = HZ / 10; + wait_event_timeout(blk_ops->thread_wq, + blk_ops->quit || rknand_req_do, + rkflash_req_jiffies); + rknand_req_do = 0; + spin_lock_irq(rq->queue_lock); + remove_wait_queue(&blk_ops->thread_wq, &wait); + continue; + } else { + rkflash_req_jiffies = 1 * HZ; + } + + dev = req->rq_disk->private_data; + totle_nsect = (req->__data_len) >> 9; + sector_index = blk_rq_pos(req); + rq_len = 0; + buf = 0; + res = 0; + + if (req->cmd_flags & REQ_DISCARD) { + if (!__blk_end_request_cur(req, res)) + req = NULL; + continue; + } else if (req->cmd_flags & REQ_FLUSH) { + if (!__blk_end_request_cur(req, res)) + req = NULL; + continue; + } + + rw_flag = req->cmd_flags & REQ_WRITE; + if (rw_flag == READ && mtd_read_temp_buffer) { + buf = mtd_read_temp_buffer; + req_check_buffer_align(req, &buf); + spin_unlock_irq(rq->queue_lock); + res = rkflash_xfer(dev, + sector_index, + totle_nsect, + buf, + rw_flag, + totle_nsect); + spin_lock_irq(rq->queue_lock); + if (buf == mtd_read_temp_buffer) { + char *p = buf; + + rq_for_each_segment(bvec, req, rq_iter) { + memcpy(page_address(bvec.bv_page) + + bvec.bv_offset, + p, + bvec.bv_len); + p += bvec.bv_len; + } + } + } else { + rq_for_each_segment(bvec, req, rq_iter) { + if ((page_address(bvec.bv_page) + + bvec.bv_offset) + == (buf + rq_len)) { + rq_len += bvec.bv_len; + } else { + if (rq_len) { + spin_unlock_irq(rq->queue_lock); + res = rkflash_xfer(dev, + sector_index, + rq_len >> 9, + buf, + rw_flag, + totle_nsect); + spin_lock_irq(rq->queue_lock); + } + sector_index += rq_len >> 9; + buf = (page_address(bvec.bv_page) + + bvec.bv_offset); + rq_len = bvec.bv_len; + } + } + if (rq_len) { + spin_unlock_irq(rq->queue_lock); + res = rkflash_xfer(dev, + sector_index, + rq_len >> 9, + buf, + rw_flag, + totle_nsect); + spin_lock_irq(rq->queue_lock); + } + } + __blk_end_request_all(req, res); + req = NULL; + } + pr_info("flash th quited\n"); + blk_ops->flash_th_quited = 1; + if (req) + __blk_end_request_all(req, -EIO); + while ((req = blk_fetch_request(rq)) != NULL) + __blk_end_request_all(req, -ENODEV); + spin_unlock_irq(rq->queue_lock); + complete_and_exit(&blk_ops->thread_exit, 0); + return 0; +} + +static void rkflash_blk_request(struct request_queue *rq) +{ + struct flash_blk_ops *blk_ops = rq->queuedata; + struct request *req = NULL; + + if (blk_ops->flash_th_quited) { + while ((req = blk_fetch_request(rq)) != NULL) + __blk_end_request_all(req, -ENODEV); + return; + } + rknand_req_do = 1; + wake_up(&blk_ops->thread_wq); +} + +static int rkflash_open(struct block_device *bdev, fmode_t mode) +{ + return 0; +} + +static void rkflash_release(struct gendisk *disk, fmode_t mode) +{ +}; + +#define DISABLE_WRITE _IO('V', 0) +#define ENABLE_WRITE _IO('V', 1) +#define DISABLE_READ _IO('V', 2) +#define ENABLE_READ _IO('V', 3) +static int rkflash_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, + unsigned long arg) +{ + struct flash_blk_dev *dev = bdev->bd_disk->private_data; + + switch (cmd) { + case ENABLE_WRITE: + dev->disable_access = 0; + dev->readonly = 0; + set_disk_ro(dev->blkcore_priv, 0); + return 0; + + case DISABLE_WRITE: + dev->readonly = 1; + set_disk_ro(dev->blkcore_priv, 1); + return 0; + + case ENABLE_READ: + dev->disable_access = 0; + dev->writeonly = 0; + return 0; + + case DISABLE_READ: + dev->writeonly = 1; + return 0; + default: + return -ENOTTY; + } +} + +const struct block_device_operations rkflash_blktrans_ops = { + .owner = THIS_MODULE, + .open = rkflash_open, + .release = rkflash_release, + .ioctl = rkflash_ioctl, +}; + +static struct flash_blk_ops mytr = { + .name = "rkflash", + .major = 31, + .minorbits = 0, + .owner = THIS_MODULE, +}; + +static int rkflash_add_dev(struct flash_blk_ops *blk_ops, + struct flash_part *part) +{ + struct flash_blk_dev *dev; + struct gendisk *gd; + + if (part->size == 0) + return -1; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + + gd = alloc_disk(1 << blk_ops->minorbits); + if (!gd) { + kfree(dev); + return -ENOMEM; + } + + dev->blk_ops = blk_ops; + dev->size = part->size; + dev->off_size = part->offset; + dev->devnum = blk_ops->last_dev_index; + list_add_tail(&dev->list, &blk_ops->devs); + blk_ops->last_dev_index++; + + gd->major = blk_ops->major; + gd->first_minor = (dev->devnum) << blk_ops->minorbits; + gd->fops = &rkflash_blktrans_ops; + + if (part->name[0]) { + snprintf(gd->disk_name, + sizeof(gd->disk_name), + "%s", + part->name); + } else { + gd->flags = GENHD_FL_EXT_DEVT; + gd->minors = 255; + snprintf(gd->disk_name, + sizeof(gd->disk_name), + "%s%d", + blk_ops->name, + dev->devnum); + } + + set_capacity(gd, dev->size); + + gd->private_data = dev; + dev->blkcore_priv = gd; + gd->queue = blk_ops->rq; + gd->queue->bypass_depth = 1; + + if (part->type == PART_NO_ACCESS) + dev->disable_access = 1; + + if (part->type == PART_READONLY) + dev->readonly = 1; + + if (part->type == PART_WRITEONLY) + dev->writeonly = 1; + + if (dev->readonly) + set_disk_ro(gd, 1); + + add_disk(gd); + + return 0; +} + +static int rkflash_remove_dev(struct flash_blk_dev *dev) +{ + struct gendisk *gd; + + gd = dev->blkcore_priv; + list_del(&dev->list); + gd->queue = NULL; + del_gendisk(gd); + put_disk(gd); + kfree(dev); + return 0; +} + +static int rkflash_blk_register(struct flash_blk_ops *blk_ops) +{ + int i, ret; + u64 offset; + + rknand_req_do = 0; + blk_ops->quit = 0; + blk_ops->flash_th_quited = 0; + + mtd_read_temp_buffer = kmalloc(MTD_RW_SECTORS * 512, + GFP_KERNEL | GFP_DMA); + + ret = register_blkdev(blk_ops->major, blk_ops->name); + if (ret) + return -1; + + spin_lock_init(&blk_ops->queue_lock); + init_completion(&blk_ops->thread_exit); + init_waitqueue_head(&blk_ops->thread_wq); + + blk_ops->rq = blk_init_queue(rkflash_blk_request, &blk_ops->queue_lock); + if (!blk_ops->rq) { + unregister_blkdev(blk_ops->major, blk_ops->name); + return -1; + } + + blk_queue_max_hw_sectors(blk_ops->rq, MTD_RW_SECTORS); + blk_queue_max_segments(blk_ops->rq, MTD_RW_SECTORS); + + queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, blk_ops->rq); + blk_queue_max_discard_sectors(blk_ops->rq, UINT_MAX >> 9); + + blk_ops->rq->queuedata = blk_ops; + INIT_LIST_HEAD(&blk_ops->devs); + kthread_run(rkflash_blktrans_thread, (void *)blk_ops, "rkflash"); + g_max_part_num = rk_partition_init(disk_array); + if (g_max_part_num) { + /* partition 0 is save vendor data, need hidden */ + blk_ops->last_dev_index = 0; + for (i = 1; i < g_max_part_num; i++) { + offset = (u64)disk_array[i].offset; + pr_info("%10s: 0x%09llx -- 0x%09llx (%llu MB)\n", + disk_array[i].name, + offset * 512, + (u64)(offset + disk_array[i].size) * 512, + (u64)disk_array[i].size / 2048); + rkflash_add_dev(blk_ops, &disk_array[i]); + } + rkflash_add_dev(blk_ops, &fw_header_p); + } else { + struct flash_part part; + + part.offset = 0; + part.size = g_boot_ops[g_flash_type]->get_capacity(); + part.type = 0; + part.name[0] = 0; + rkflash_add_dev(&mytr, &part); + } + rkflash_create_procfs(); + + return 0; +} + +static void rkflash_blk_unregister(struct flash_blk_ops *blk_ops) +{ + struct list_head *this, *next; + + blk_ops->quit = 1; + wake_up(&blk_ops->thread_wq); + wait_for_completion(&blk_ops->thread_exit); + list_for_each_safe(this, next, &blk_ops->devs) { + struct flash_blk_dev *dev = + list_entry(this, struct flash_blk_dev, list); + + rkflash_remove_dev(dev); + } + blk_cleanup_queue(blk_ops->rq); + unregister_blkdev(blk_ops->major, blk_ops->name); +} + +int rkflash_dev_init(void __iomem *reg_addr, enum flash_con_type con_type) +{ + int ret; + int tmp_id, start_id, end_id; + + pr_err("%s\n", __func__); + if (rkflash_dev_initialised) { + pr_err("rkflash has already inited as id[%d]\n", g_flash_type); + return -1; + } + + if (con_type == FLASH_CON_TYPE_NANDC) { + start_id = FLASH_TYPE_NANDC_NAND; + end_id = FLASH_TYPE_NANDC_NAND; + } else { + start_id = FLASH_TYPE_SFC_NOR; + end_id = FLASH_TYPE_SFC_NAND; + } + for (tmp_id = start_id; tmp_id <= end_id; tmp_id++) { + pr_info("init rkflash[%d]\n", tmp_id); + if (g_boot_ops[tmp_id]->id == -1) { + pr_err("rkflash[%d] is invalid\n", tmp_id); + if (tmp_id == end_id) + return -1; + continue; + } + ret = g_boot_ops[tmp_id]->init(reg_addr); + if (ret) { + pr_err("rkflash[%d] init fail\n", tmp_id); + if (tmp_id == end_id) + return -1; + continue; + } else { + break; + } + } + pr_info("rkflash[%d] init success\n", tmp_id); + g_flash_type = tmp_id; + mytr.quit = 1; + flash_vendor_dev_ops_register(g_boot_ops[g_flash_type]->vendor_read, + g_boot_ops[g_flash_type]->vendor_write); +#ifdef CONFIG_RK_SFC_NOR_MTD + if (g_flash_type == FLASH_TYPE_SFC_NOR) { + pr_info("sfc_nor flash registered as a mtd device\n"); + rkflash_dev_initialised = 1; + return 0; + } +#endif + ret = rkflash_blk_register(&mytr); + if (ret) { + pr_err("rkflash_blk_register fail\n"); + g_flash_type = -1; + return -1; + } + rkflash_dev_initialised = 1; + + return ret; +} + +int rkflash_dev_exit(void) +{ + if (rkflash_dev_initialised) { + g_flash_type = -1; + rkflash_dev_initialised = 0; + rkflash_blk_unregister(&mytr); + pr_info("%s:OK\n", __func__); + } + return 0; +} + +int rkflash_dev_suspend(void) +{ + mutex_lock(&g_flash_ops_mutex); + return 0; +} + +int rkflash_dev_resume(void __iomem *reg_addr) +{ + g_boot_ops[g_flash_type]->resume(reg_addr); + mutex_unlock(&g_flash_ops_mutex); + return 0; +} + +void rkflash_dev_shutdown(void) +{ + pr_info("rkflash_shutdown...\n"); + if (mytr.quit == 0) { + mytr.quit = 1; + wake_up(&mytr.thread_wq); + wait_for_completion(&mytr.thread_exit); + } + g_boot_ops[g_flash_type]->deinit(); + pr_info("rkflash_shutdown:OK\n"); +} diff --git a/drivers/rkflash/rkflash_blk.h b/drivers/rkflash/rkflash_blk.h new file mode 100644 index 000000000000..7735910ec2f2 --- /dev/null +++ b/drivers/rkflash/rkflash_blk.h @@ -0,0 +1,126 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#ifndef __RKFLASH_BLK_H +#define __RKFLASH_BLK_H + +#include + +#define MAX_PART_COUNT 32 +#define RK_PARTITION_TAG 0x50464B52 + +enum flash_con_type { + FLASH_CON_TYPE_NANDC = 0, + FLASH_CON_TYPE_SFC, + FLASH_CON_TYPE_MAX, +}; + +enum flash_type { + FLASH_TYPE_NANDC_NAND = 0, + FLASH_TYPE_SFC_NOR, + FLASH_TYPE_SFC_NAND, + FLASH_TYPE_MAX, +}; + +struct flash_boot_ops { + int id; + int (*init)(void __iomem *reg_addr); + int (*read)(u32 sec, u32 n_sec, void *p_data); + int (*write)(u32 sec, u32 n_sec, void *p_data); + u32 (*get_capacity)(void); + void (*deinit)(void); + int (*resume)(void __iomem *reg_addr); + int (*vendor_read)(u32 sec, u32 n_sec, void *p_data); + int (*vendor_write)(u32 sec, u32 n_sec, void *p_data); +}; + +struct flash_part { + unsigned char name[32]; + unsigned int offset; + unsigned int size; + unsigned char type; +}; + +struct flash_blk_ops { + char *name; + int major; + int minorbits; + int last_dev_index; + struct completion thread_exit; + int quit; + int flash_th_quited; + wait_queue_head_t thread_wq; /* thread wait queue */ + struct request_queue *rq; + spinlock_t queue_lock; /* queue lock */ + struct list_head devs; + struct module *owner; +}; + +struct flash_blk_dev { + struct flash_blk_ops *blk_ops; + struct list_head list; + int devnum; + unsigned int size; + unsigned int off_size; + int readonly; + int writeonly; + int disable_access; + void *blkcore_priv; +}; + +enum ENUM_PARTITION_TYPE { + PART_VENDOR = 1 << 0, + PART_IDBLOCK = 1 << 1, + PART_KERNEL = 1 << 2, + PART_BOOT = 1 << 3, + PART_USER = 1 << 31 +}; + +struct STRUCT_DATETIME { + unsigned short year; + unsigned char month; + unsigned char day; + unsigned char hour; + unsigned char min; + unsigned char sec; + unsigned char reserve; +}; + +struct STRUCT_FW_HEADER { + unsigned int ui_fw_tag; /* "RKFP" */ + struct STRUCT_DATETIME dt_release_data_time; + unsigned int ui_fw_ver; + unsigned int ui_size; /* size of sturct,unit of u8 */ + unsigned int ui_part_entry_offset; /* unit of sector */ + unsigned int ui_backup_part_entry_offset; + unsigned int ui_part_entry_size; /* unit of u8 */ + unsigned int ui_part_entry_count; + unsigned int ui_fw_size; /* unit of u8 */ + unsigned char reserved[464]; + unsigned int ui_part_entry_crc; + unsigned int ui_header_crc; +}; + +struct STRUCT_PART_ENTRY { + unsigned char sz_name[32]; + enum ENUM_PARTITION_TYPE em_part_type; + unsigned int ui_pt_off; /* unit of sector */ + unsigned int ui_pt_sz; /* unit of sector */ + unsigned int ui_data_length; /* unit of u8 */ + unsigned int ui_part_property; + unsigned char reserved[76]; +}; + +struct STRUCT_PART_INFO { + struct STRUCT_FW_HEADER hdr; /* 0.5KB */ + struct STRUCT_PART_ENTRY part[12]; /* 1.5KB */ +} __packed; + +int rkflash_dev_suspend(void); +int rkflash_dev_resume(void __iomem *reg_addr); +void rkflash_dev_shutdown(void); +void rkflash_dev_flush(void); +int rkflash_dev_init(void __iomem *reg_addr, enum flash_con_type type); +int rkflash_dev_exit(void); +#endif diff --git a/drivers/rkflash/rkflash_debug.c b/drivers/rkflash/rkflash_debug.c new file mode 100644 index 000000000000..fcff32d098e9 --- /dev/null +++ b/drivers/rkflash/rkflash_debug.c @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#include + +#include "rkflash_debug.h" +#include "sfc_nor.h" + +void rkflash_print_hex(char *s, void *buf, u32 width, u32 len) +{ + print_hex_dump(KERN_WARNING, s, DUMP_PREFIX_OFFSET, + 16, width, buf, len * width, 0); +} + diff --git a/drivers/rkflash/rkflash_debug.h b/drivers/rkflash/rkflash_debug.h new file mode 100644 index 000000000000..a844df814681 --- /dev/null +++ b/drivers/rkflash/rkflash_debug.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#ifndef _RKFLASH_DEBUG_H +#define _RKFLASH_DEBUG_H + +/* + * Print switch, set to 1 if needed + * I - info + * E - error + * HEX - multiline print + */ + +#define PRINT_SWI_SFC_I 0 +#define PRINT_SWI_SFC_E 1 +#define PRINT_SWI_SFC_HEX 1 + +/* + * Test switch + */ + +#if (PRINT_SWI_SFC_I) +#define PRINT_SFC_I(...) pr_info(__VA_ARGS__) +#else +#define PRINT_SFC_I(...) +#endif + +#if (PRINT_SWI_SFC_E) +#define PRINT_SFC_E(...) pr_err(__VA_ARGS__) +#else +#define PRINT_SFC_E(...) +#endif + +#if (PRINT_SWI_SFC_HEX) +#define PRINT_SFC_HEX(s, buf, width, len)\ + rkflash_print_hex(s, buf, width, len) +#else +#define PRINT_SFC_HEX(s, buf, width, len) +#endif + +void rkflash_print_hex(char *s, void *buf, u32 width, u32 len); + +#endif diff --git a/drivers/rkflash/rknandc_base.c b/drivers/rkflash/rknandc_base.c new file mode 100644 index 000000000000..997016caa5e5 --- /dev/null +++ b/drivers/rkflash/rknandc_base.c @@ -0,0 +1,193 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_OF +#include +#endif + +#include "nandc.h" +#include "rkflash_api.h" +#include "rkflash_blk.h" + +#define RKNANDC_VERSION_AND_DATE "rknandc_base v1.1 2017-01-11" +#define RKNANDC_CLK_SET_RATE (150 * 1000 * 1000) + +struct rknandc_info { + void __iomem *reg_base; + int irq; + int clk_rate; + struct clk *clk; /* controller's clk*/ + struct clk *ahb_clk; /* ahb clk gate*/ + struct clk *g_clk; /* clk_src_en gate*/ +}; + +static struct rknandc_info g_nandc_info; +static struct device *g_nandc_dev; +static struct completion nandc_irq_complete; + +unsigned long rknandc_dma_map_single(unsigned long ptr, int size, int dir) +{ +#ifdef CONFIG_ARM64 + __dma_map_area((void *)ptr, size, dir); + return ((unsigned long)virt_to_phys((void *)ptr)); +#else + return dma_map_single(NULL, (void *)ptr, size + , dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); +#endif +} + +void rknandc_dma_unmap_single(unsigned long ptr, int size, int dir) +{ +#ifdef CONFIG_ARM64 + __dma_unmap_area(phys_to_virt(ptr), size, dir); +#else + dma_unmap_single(NULL, (dma_addr_t)ptr, size + , dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); +#endif +} + +static irqreturn_t rknandc_interrupt(int irq, void *dev_id) +{ + nandc_clean_irq(); + complete(&nandc_irq_complete); + return IRQ_HANDLED; +} + +static int rknandc_irq_config(int mode, void *pfun) +{ + int ret = 0; + int irq = g_nandc_info.irq; + + if (mode) + ret = request_irq(irq, pfun, 0, "rknandc", + g_nandc_info.reg_base); + else + free_irq(irq, NULL); + return ret; +} + +static int rknandc_irq_init(void) +{ + init_completion(&nandc_irq_complete); + rknandc_irq_config(1, rknandc_interrupt); + return 0; +} + +static int rknandc_irq_deinit(void) +{ + rknandc_irq_config(0, rknandc_interrupt); + return 0; +} + +static int rknandc_probe(struct platform_device *pdev) +{ + int irq; + struct resource *mem; + void __iomem *membase; + int ret; + + g_nandc_dev = &pdev->dev; + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + membase = devm_ioremap_resource(&pdev->dev, mem); + if (!membase) { + dev_err(&pdev->dev, "no reg resource?\n"); + return -1; + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "no irq resource?\n"); + return irq; + } + + g_nandc_info.irq = irq; + g_nandc_info.reg_base = membase; + g_nandc_info.ahb_clk = devm_clk_get(&pdev->dev, "hclk_nandc"); + g_nandc_info.clk = devm_clk_get(&pdev->dev, "clk_nandc"); + g_nandc_info.g_clk = devm_clk_get(&pdev->dev, "g_clk_nandc"); + if (unlikely(IS_ERR(g_nandc_info.clk)) || + unlikely(IS_ERR(g_nandc_info.ahb_clk))) { + dev_err(&pdev->dev, "%s get clk error\n", __func__); + return -1; + } + clk_prepare_enable(g_nandc_info.g_clk); + clk_prepare_enable(g_nandc_info.ahb_clk); + clk_set_rate(g_nandc_info.clk, RKNANDC_CLK_SET_RATE); + g_nandc_info.clk_rate = clk_get_rate(g_nandc_info.clk); + clk_prepare_enable(g_nandc_info.clk); + dev_info(&pdev->dev, + "%s clk rate = %d\n", + __func__, + g_nandc_info.clk_rate); + rknandc_irq_init(); + ret = rkflash_dev_init(g_nandc_info.reg_base, FLASH_CON_TYPE_NANDC); + + return ret; +} + +static int rknandc_suspend(struct platform_device *pdev, pm_message_t state) +{ + return rkflash_dev_suspend(); +} + +static int rknandc_resume(struct platform_device *pdev) +{ + return rkflash_dev_resume(g_nandc_info.reg_base); +} + +static void rknandc_shutdown(struct platform_device *pdev) +{ + rkflash_dev_shutdown(); +} + +#ifdef CONFIG_OF +static const struct of_device_id of_rknandc_match[] = { + {.compatible = "rockchip,nandc"}, + {} +}; +#endif + +static struct platform_driver rknandc_driver = { + .probe = rknandc_probe, + .suspend = rknandc_suspend, + .resume = rknandc_resume, + .shutdown = rknandc_shutdown, + .driver = { + .name = "rknandc", +#ifdef CONFIG_OF + .of_match_table = of_rknandc_match, +#endif + }, +}; + +static void __exit rknandc_driver_exit(void) +{ + rkflash_dev_exit(); + rknandc_irq_deinit(); + platform_driver_unregister(&rknandc_driver); +} + +static int __init rknandc_driver_init(void) +{ + int ret = 0; + + pr_err("%s\n", RKNANDC_VERSION_AND_DATE); + ret = platform_driver_register(&rknandc_driver); + return ret; +} + +module_init(rknandc_driver_init); +module_exit(rknandc_driver_exit); +MODULE_ALIAS(DRIVER_NAME); diff --git a/drivers/rkflash/rksfc_base.c b/drivers/rkflash/rksfc_base.c new file mode 100644 index 000000000000..68394638e2ad --- /dev/null +++ b/drivers/rkflash/rksfc_base.c @@ -0,0 +1,207 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_OF +#include +#endif + +#include "sfc.h" +#include "rkflash_api.h" +#include "rkflash_blk.h" + +#define RKSFC_VERSION_AND_DATE "rksfc_base v1.1 2016-01-08" +#define RKSFC_CLK_SET_RATE (100 * 1000 * 1000) + +struct rksfc_info { + void __iomem *reg_base; + int irq; + int clk_rate; + struct clk *clk; /* sfc clk*/ + struct clk *ahb_clk; /* ahb clk gate*/ +}; + +static struct rksfc_info g_sfc_info; +static struct device *g_sfc_dev; +static struct completion sfc_irq_complete; + +unsigned long rksfc_dma_map_single(unsigned long ptr, int size, int dir) +{ +#ifdef CONFIG_ARM64 + __dma_map_area((void *)ptr, size, dir); + return ((unsigned long)virt_to_phys((void *)ptr)); +#else + return dma_map_single(NULL, (void *)ptr, size + , dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); +#endif +} + +void rksfc_dma_unmap_single(unsigned long ptr, int size, int dir) +{ +#ifdef CONFIG_ARM64 + __dma_unmap_area(phys_to_virt(ptr), size, dir); +#else + dma_unmap_single(NULL, (dma_addr_t)ptr, size + , dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); +#endif +} + +int rksfc_get_reg_addr(unsigned long *p_sfc_addr) +{ + *p_sfc_addr = (unsigned long)g_sfc_info.reg_base; + return 0; +} + +static irqreturn_t rksfc_interrupt(int irq, void *dev_id) +{ + sfc_clean_irq(); + complete(&sfc_irq_complete); + return IRQ_HANDLED; +} + +void rksfc_irq_flag_init(void) +{ + init_completion(&sfc_irq_complete); +} + +void rksfc_wait_for_irq_completed(void) +{ + wait_for_completion_timeout(&sfc_irq_complete, + msecs_to_jiffies(10)); +} + +static int rksfc_irq_config(int mode, void *pfun) +{ + int ret = 0; + int irq = g_sfc_info.irq; + + if (mode) + ret = request_irq(irq, pfun, 0, "rksfc", + g_sfc_info.reg_base); + else + free_irq(irq, NULL); + return ret; +} + +static int rksfc_irq_init(void) +{ + init_completion(&sfc_irq_complete); + rksfc_irq_config(1, rksfc_interrupt); + return 0; +} + +static int rksfc_irq_deinit(void) +{ + rksfc_irq_config(0, rksfc_interrupt); + return 0; +} + +static int rksfc_probe(struct platform_device *pdev) +{ + int irq; + struct resource *mem; + void __iomem *membase; + int ret; + + g_sfc_dev = &pdev->dev; + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + membase = devm_ioremap_resource(&pdev->dev, mem); + if (!membase) { + dev_err(&pdev->dev, "no reg resource?\n"); + return -1; + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "no irq resource?\n"); + return irq; + } + + g_sfc_info.irq = irq; + g_sfc_info.reg_base = membase; + g_sfc_info.ahb_clk = devm_clk_get(&pdev->dev, "hclk_sfc"); + g_sfc_info.clk = devm_clk_get(&pdev->dev, "clk_sfc"); + if (unlikely(IS_ERR(g_sfc_info.clk)) || + unlikely(IS_ERR(g_sfc_info.ahb_clk))) { + dev_err(&pdev->dev, "%s get clk error\n", __func__); + return -1; + } + clk_prepare_enable(g_sfc_info.ahb_clk); + clk_set_rate(g_sfc_info.clk, RKSFC_CLK_SET_RATE); + g_sfc_info.clk_rate = clk_get_rate(g_sfc_info.clk); + clk_prepare_enable(g_sfc_info.clk); + dev_info(&pdev->dev, + "%s clk rate = %d\n", + __func__, + g_sfc_info.clk_rate); + rksfc_irq_init(); + ret = rkflash_dev_init(g_sfc_info.reg_base, FLASH_CON_TYPE_SFC); + + return ret; +} + +static int rksfc_suspend(struct platform_device *pdev, pm_message_t state) +{ + return rkflash_dev_suspend(); +} + +static int rksfc_resume(struct platform_device *pdev) +{ + return rkflash_dev_resume(g_sfc_info.reg_base); +} + +static void rksfc_shutdown(struct platform_device *pdev) +{ + rkflash_dev_shutdown(); +} + +#ifdef CONFIG_OF +static const struct of_device_id of_rksfc_match[] = { + {.compatible = "rockchip,sfc"}, + {} +}; +#endif + +static struct platform_driver rksfc_driver = { + .probe = rksfc_probe, + .suspend = rksfc_suspend, + .resume = rksfc_resume, + .shutdown = rksfc_shutdown, + .driver = { + .name = "rksfc", +#ifdef CONFIG_OF + .of_match_table = of_rksfc_match, +#endif + }, +}; + +static void __exit rksfc_driver_exit(void) +{ + rkflash_dev_exit(); + rksfc_irq_deinit(); + platform_driver_unregister(&rksfc_driver); +} + +static int __init rksfc_driver_init(void) +{ + int ret = 0; + + pr_err("%s\n", RKSFC_VERSION_AND_DATE); + ret = platform_driver_register(&rksfc_driver); + return ret; +} + +module_init(rksfc_driver_init); +module_exit(rksfc_driver_exit); +MODULE_ALIAS(DRIVER_NAME); diff --git a/drivers/rkflash/sfc.c b/drivers/rkflash/sfc.c new file mode 100644 index 000000000000..1b9fc71cdfab --- /dev/null +++ b/drivers/rkflash/sfc.c @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#include +#include +#include + +#include "sfc.h" + +static void __iomem *g_sfc_reg; + +static void sfc_reset(void) +{ + int timeout = 10000; + + writel(SFC_RESET, g_sfc_reg + SFC_RCVR); + while ((readl(g_sfc_reg + SFC_RCVR) == SFC_RESET) && (timeout > 0)) { + sfc_delay(1); + timeout--; + } + writel(0xFFFFFFFF, g_sfc_reg + SFC_ICLR); +} + +u16 sfc_get_version(void) +{ + return (u32)(readl(g_sfc_reg + SFC_VER) & 0xffff); +} + +int sfc_init(void __iomem *reg_addr) +{ + g_sfc_reg = reg_addr; + sfc_reset(); + writel(0, g_sfc_reg + SFC_CTRL); + + return SFC_OK; +} + +void sfc_clean_irq(void) +{ + writel(0xFFFFFFFF, g_sfc_reg + SFC_ICLR); + writel(0xFFFFFFFF, g_sfc_reg + SFC_IMR); +} + +int sfc_request(u32 sfcmd, u32 sfctrl, u32 addr, void *data) +{ + int ret = SFC_OK; + union SFCCMD_DATA cmd; + int reg; + int timeout = 0; + + reg = readl(g_sfc_reg + SFC_FSR); + if (!(reg & SFC_TXEMPTY) || !(reg & SFC_RXEMPTY) || + (readl(g_sfc_reg + SFC_SR) & SFC_BUSY)) + sfc_reset(); + + cmd.d32 = sfcmd; + if (cmd.b.addrbits == SFC_ADDR_XBITS) { + union SFCCTRL_DATA ctrl; + + ctrl.d32 = sfctrl; + if (!ctrl.b.addrbits) + return SFC_PARAM_ERR; + /* Controller plus 1 automatically */ + writel(ctrl.b.addrbits - 1, g_sfc_reg + SFC_ABIT); + } + /* shift in the data at negedge sclk_out */ + sfctrl |= 0x2; + + writel(sfctrl, g_sfc_reg + SFC_CTRL); + writel(sfcmd, g_sfc_reg + SFC_CMD); + if (cmd.b.addrbits) + writel(addr, g_sfc_reg + SFC_ADDR); + if (!cmd.b.datasize) + goto exit_wait; + if (SFC_ENABLE_DMA & sfctrl) { + unsigned long dma_addr; + u8 direction = (cmd.b.rw == SFC_WRITE) ? 1 : 0; + + dma_addr = rksfc_dma_map_single((unsigned long)data, + cmd.b.datasize, + direction); + rksfc_irq_flag_init(); + writel(0xFFFFFFFF, g_sfc_reg + SFC_ICLR); + writel(~(FINISH_INT), g_sfc_reg + SFC_IMR); + writel((u32)dma_addr, g_sfc_reg + SFC_DMA_ADDR); + writel(SFC_DMA_START, g_sfc_reg + SFC_DMA_TRIGGER); + + timeout = cmd.b.datasize * 10; + rksfc_wait_for_irq_completed(); + while ((readl(g_sfc_reg + SFC_SR) & SFC_BUSY) && + (timeout-- > 0)) + sfc_delay(1); + writel(0xFFFFFFFF, g_sfc_reg + SFC_ICLR); + if (timeout <= 0) + ret = SFC_WAIT_TIMEOUT; + direction = (cmd.b.rw == SFC_WRITE) ? 1 : 0; + rksfc_dma_unmap_single(dma_addr, + cmd.b.datasize, + direction); + } else { + u32 i, words, count, bytes; + union SFCFSR_DATA fifostat; + u32 *p_data = (u32 *)data; + + if (cmd.b.rw == SFC_WRITE) { + words = (cmd.b.datasize + 3) >> 2; + while (words) { + fifostat.d32 = readl(g_sfc_reg + SFC_FSR); + if (fifostat.b.txlevel > 0) { + count = words < fifostat.b.txlevel ? + words : fifostat.b.txlevel; + for (i = 0; i < count; i++) { + writel(*p_data++, + g_sfc_reg + SFC_DATA); + words--; + } + if (words == 0) + break; + timeout = 0; + } else { + sfc_delay(1); + if (timeout++ > 10000) { + ret = SFC_TX_TIMEOUT; + break; + } + } + } + } else { + /* SFC_READ == cmd.b.rw */ + bytes = cmd.b.datasize & 0x3; + words = cmd.b.datasize >> 2; + while (words) { + fifostat.d32 = readl(g_sfc_reg + SFC_FSR); + if (fifostat.b.rxlevel > 0) { + u32 count; + + count = words < fifostat.b.rxlevel ? + words : fifostat.b.rxlevel; + + for (i = 0; i < count; i++) { + *p_data++ = readl(g_sfc_reg + + SFC_DATA); + words--; + } + if (words == 0) + break; + timeout = 0; + } else { + sfc_delay(1); + if (timeout++ > 10000) { + ret = SFC_RX_TIMEOUT; + break; + } + } + } + + timeout = 0; + while (bytes) { + fifostat.d32 = readl(g_sfc_reg + SFC_FSR); + if (fifostat.b.rxlevel > 0) { + u8 *p_data1 = (u8 *)p_data; + + words = readl(g_sfc_reg + SFC_DATA); + for (i = 0; i < bytes; i++) + p_data1[i] = + (u8)((words >> (i * 8)) & 0xFF); + break; + } + + sfc_delay(1); + if (timeout++ > 10000) { + ret = SFC_RX_TIMEOUT; + break; + } + } + } + } + +exit_wait: + timeout = 0; /* wait cmd or data send complete */ + while (!(readl(g_sfc_reg + SFC_FSR) & SFC_TXEMPTY)) { + sfc_delay(1); + if (timeout++ > 100000) { /* wait 100ms */ + ret = SFC_TX_TIMEOUT; + break; + } + } + sfc_delay(1); /* CS# High Time (read/write) >100ns */ + return ret; +} diff --git a/drivers/rkflash/sfc.h b/drivers/rkflash/sfc.h new file mode 100644 index 000000000000..3b84046d64c9 --- /dev/null +++ b/drivers/rkflash/sfc.h @@ -0,0 +1,179 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#ifndef _SFC_H +#define _SFC_H + +#define SFC_VER_3 0x3 /* ver 3, else ver 1 */ + +#define SFC_MAX_IOSIZE (1024 * 8) /* 8K byte */ +#define SFC_EN_INT (0) /* enable interrupt */ +#define SFC_EN_DMA (1) /* enable dma */ +#define SFC_FIFO_DEPTH (0x10) /* 16 words */ + +/* FIFO watermark */ +#define SFC_RX_WMARK (SFC_FIFO_DEPTH) /* RX watermark level */ +#define SFC_TX_WMARK (SFC_FIFO_DEPTH) /* TX watermark level */ +#define SFC_RX_WMARK_SHIFT (8) +#define SFC_TX_WMARK_SHIFT (0) + +/*return value*/ +#define SFC_OK (0) +#define SFC_ERROR (-1) +#define SFC_PARAM_ERR (-2) +#define SFC_TX_TIMEOUT (-3) +#define SFC_RX_TIMEOUT (-4) +#define SFC_WAIT_TIMEOUT (-5) +#define SFC_BUSY_TIMEOUT (-6) +#define SFC_ECC_FAIL (-7) +#define SFC_PROG_FAIL (-8) +#define SFC_ERASE_FAIL (-9) + +/* SFC_CMD Register */ +#define SFC_ADDR_0BITS (0) +#define SFC_ADDR_24BITS (1) +#define SFC_ADDR_32BITS (2) +#define SFC_ADDR_XBITS (3) + +#define SFC_WRITE (1) +#define SFC_READ (0) + +/* SFC_CTRL Register */ +#define SFC_1BITS_LINE (0) +#define SFC_2BITS_LINE (1) +#define SFC_4BITS_LINE (2) + +#define SFC_ENABLE_DMA BIT(14) +#define sfc_delay(us) udelay(us) + +#define DMA_INT BIT(7) /* dma interrupt */ +#define NSPIERR_INT BIT(6) /* Nspi error interrupt */ +#define AHBERR_INT BIT(5) /* Ahb bus error interrupt */ +#define FINISH_INT BIT(4) /* Transfer finish interrupt */ +#define TXEMPTY_INT BIT(3) /* Tx fifo empty interrupt */ +#define TXOF_INT BIT(2) /* Tx fifo overflow interrupt */ +#define RXUF_INT BIT(1) /* Rx fifo underflow interrupt */ +#define RXFULL_INT BIT(0) /* Rx fifo full interrupt */ + +/* SFC_FSR Register*/ +#define SFC_RXFULL BIT(3) /* rx fifo full */ +#define SFC_RXEMPTY BIT(2) /* rx fifo empty */ +#define SFC_TXEMPTY BIT(1) /* tx fifo empty */ +#define SFC_TXFULL BIT(0) /* tx fifo full */ + +/* SFC_RCVR Register */ +#define SFC_RESET BIT(0) /* controller reset */ + +/* SFC_SR Register */ +/* sfc busy flag. When busy, don't try to set the control register */ +#define SFC_BUSY BIT(0) + +/* SFC_DMA_TRIGGER Register */ +/* Dma start trigger signal. Auto cleared after write */ +#define SFC_DMA_START BIT(0) + +#define SFC_CTRL 0x00 +#define SFC_IMR 0x04 +#define SFC_ICLR 0x08 +#define SFC_FTLR 0x0C +#define SFC_RCVR 0x10 +#define SFC_AX 0x14 +#define SFC_ABIT 0x18 +#define SFC_MASKISR 0x1C +#define SFC_FSR 0x20 +#define SFC_SR 0x24 +#define SFC_RAWISR 0x28 +#define SFC_VER 0x2C +#define SFC_QOP 0x30 +#define SFC_DMA_TRIGGER 0x80 +#define SFC_DMA_ADDR 0x84 +#define SFC_CMD 0x100 +#define SFC_ADDR 0x104 +#define SFC_DATA 0x108 + +union SFCFSR_DATA { + u32 d32; + struct { + unsigned txempty : 1; + unsigned txfull : 1; + unsigned rxempty : 1; + unsigned rxfull : 1; + unsigned reserved7_4 : 4; + unsigned txlevel : 5; + unsigned reserved15_13 : 3; + unsigned rxlevel : 5; + unsigned reserved31_21 : 11; + } b; +}; + +/*------------------------------ Global Typedefs -----------------------------*/ +enum SFC_DATA_LINES { + DATA_LINES_X1 = 0, + DATA_LINES_X2, + DATA_LINES_X4 +}; + +union SFCCTRL_DATA { + /* raw register data */ + u32 d32; + /* register bits */ + struct { + /* spi mode select */ + unsigned mode : 1; + /* + * Shift in phase selection + * 0: shift in the flash data at posedge sclk_out + * 1: shift in the flash data at negedge sclk_out + */ + unsigned sps : 1; + unsigned reserved3_2 : 2; + /* sclk_idle_level_cycles */ + unsigned scic : 4; + /* Cmd bits number */ + unsigned cmdlines : 2; + /* Address bits number */ + unsigned addrlines : 2; + /* Data bits number */ + unsigned datalines : 2; + /* this bit is not exit in regiseter, just use for code param */ + unsigned enbledma : 1; + unsigned reserved15 : 1; + unsigned addrbits : 5; + unsigned reserved31_21 : 11; + } b; +}; + +union SFCCMD_DATA { + /* raw register data */ + u32 d32; + /* register bits */ + struct { + /* Command that will send to Serial Flash */ + unsigned cmd : 8; + /* Dummy bits number */ + unsigned dummybits : 4; + /* 0: read, 1: write */ + unsigned rw : 1; + /* Continuous read mode */ + unsigned readmode : 1; + /* Address bits number */ + unsigned addrbits : 2; + /* Transferred bytes number */ + unsigned datasize : 14; + /* Chip select */ + unsigned cs : 2; + } b; +}; + +int sfc_init(void __iomem *reg_addr); +int sfc_request(u32 sfcmd, u32 sfctrl, u32 addr, void *data); +u16 sfc_get_version(void); +void sfc_clean_irq(void); +int rksfc_get_reg_addr(unsigned long *p_sfc_addr); +void sfc_handle_irq(void); +unsigned long rksfc_dma_map_single(unsigned long ptr, int size, int dir); +void rksfc_dma_unmap_single(unsigned long ptr, int size, int dir); +void rksfc_irq_flag_init(void); +void rksfc_wait_for_irq_completed(void); +#endif diff --git a/drivers/rkflash/sfc_nand.c b/drivers/rkflash/sfc_nand.c new file mode 100644 index 000000000000..c237f54ad4e3 --- /dev/null +++ b/drivers/rkflash/sfc_nand.c @@ -0,0 +1,584 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#include +#include +#include + +#include "flash.h" +#include "flash_com.h" +#include "sfc.h" +#include "sfc_nand.h" + +#define SFC_NAND_STRESS_TEST_EN 0 + +#define SFC_NAND_PROG_ERASE_ERROR -2 +#define SFC_NAND_HW_ERROR -1 +#define SFC_NAND_ECC_ERROR NAND_ERROR +#define SFC_NAND_ECC_REFRESH NAND_STS_REFRESH +#define SFC_NAND_ECC_OK NAND_STS_OK + +#define SFC_NAND_PAGE_MAX_SIZE 2112 + +#define FEA_READ_STATUE_MASK (0x3 << 0) +#define FEA_STATUE_MODE1 0 +#define FEA_STATUE_MODE2 1 +#define FEA_4BIT_READ BIT(2) +#define FEA_4BIT_PROG BIT(3) +#define FEA_4BYTE_ADDR BIT(4) +#define FEA_4BYTE_ADDR_MODE BIT(5) + +struct SFC_NAND_DEV_T { + u32 capacity; + u32 block_size; + u16 page_size; + u8 manufacturer; + u8 mem_type; + u8 read_lines; + u8 prog_lines; + u8 page_read_cmd; + u8 page_prog_cmd; +}; + +struct nand_info { + u32 id; + + u16 sec_per_page; + u16 page_per_blk; + u16 plane_per_die; + u16 blk_per_plane; + + u8 page_read_cmd; + u8 page_prog_cmd; + u8 read_cache_cmd_1; + u8 prog_cache_cmd_1; + + u8 read_cache_cmd_4; + u8 prog_cache_cmd_4; + u8 block_erase_cmd; + u8 feature; + + u8 density; /* (1 << density) sectors*/ + u8 max_ecc_bits; + u8 QE_address; + u8 QE_bits; + + u8 spare_offs_1; + u8 spare_offs_2; +}; + +static struct nand_info spi_nand_tbl[] = { + /* TC58CVG0S0HxAIx */ + {0x98C2, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x02, 0xD8, 0x00, 18, 8, 0xB0, 0XFF, 4, 8}, + /* TC58CVG1S0HxAIx */ + {0x98CB, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x02, 0xD8, 0x00, 19, 8, 0xB0, 0XFF, 4, 8}, + /* MX35LF1GE4AB */ + {0xC212, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 1, 0xB0, 0, 4, 8}, + /* MX35LF2GE4AB */ + {0xC222, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 19, 1, 0xB0, 0, 4, 8}, + /* GD5F1GQ4UAYIG */ + {0xC8F1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 1, 0xB0, 0, 4, 8}, + /* GD5F2GQ40BY2GR */ + {0xC8D2, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 1, 0xB0, 0, 4, 8}, + /* MT29F1G01ZAC */ + {0x2C12, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x00, 18, 1, 0xB0, 0, 4, 8}, + /* GD5F1GQ4U */ + {0xC8B1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 1, 0xB0, 0, 4, 8}, + /* GD5F2GQ4U */ + {0xC8B2, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 19, 1, 0xB0, 0, 4, 8}, + /* GD5F1GQ4U */ + {0xC8D1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 1, 0xB0, 0, 4, 8}, + /* IS37SML01G1 */ + {0xC821, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x00, 18, 1, 0xB0, 0XFF, 8, 12}, + /* W25N01GV */ + {0xEFAA, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 1, 0xFF, 0XFF, 4, 20}, +}; + +static u8 id_byte[8]; +static struct nand_info *p_nand_info; +static u32 gp_page_buf[SFC_NAND_PAGE_MAX_SIZE / 4]; +static struct SFC_NAND_DEV_T sfc_nand_dev; + +static struct nand_info *spi_nand_get_info(u8 *nand_id) +{ + u32 i; + u32 id = (nand_id[0] << 8) | (nand_id[1] << 0); + + for (i = 0; i < ARRAY_SIZE(spi_nand_tbl); i++) { + if (spi_nand_tbl[i].id == id) + return &spi_nand_tbl[i]; + } + return NULL; +} + +static int sfc_nand_write_en(void) +{ + int ret; + union SFCCMD_DATA sfcmd; + + sfcmd.d32 = 0; + sfcmd.b.cmd = CMD_WRITE_EN; + ret = sfc_request(sfcmd.d32, 0, 0, NULL); + return ret; +} + +static int sfc_nand_rw_preset(void) +{ + int ret; + union SFCCTRL_DATA sfctrl; + union SFCCMD_DATA sfcmd; + u8 status = 0xFF; + + sfcmd.d32 = 0; + sfcmd.b.cmd = 0; + sfcmd.b.datasize = 1; + sfcmd.b.rw = SFC_WRITE; + + sfctrl.b.datalines = 2; + ret = sfc_request(sfcmd.d32, sfctrl.d32, 0, &status); + return ret; +} + +static int sfc_nand_read_feature(u8 addr, u8 *data) +{ + int ret; + union SFCCMD_DATA sfcmd; + + sfcmd.d32 = 0; + sfcmd.b.cmd = 0x0F; + sfcmd.b.datasize = 1; + sfcmd.b.addrbits = SFC_ADDR_XBITS; + *data = 0; + + ret = sfc_request(sfcmd.d32, 0x8 << 16, addr, data); + if (ret != SFC_OK) + return ret; + return SFC_OK; +} + +static int sfc_nand_write_feature(u32 addr, u8 status) +{ + int ret; + union SFCCMD_DATA sfcmd; + + sfc_nand_write_en(); + + sfcmd.d32 = 0; + sfcmd.b.cmd = 0x1F; + sfcmd.b.datasize = 1; + sfcmd.b.addrbits = SFC_ADDR_XBITS; + sfcmd.b.rw = SFC_WRITE; + + ret = sfc_request(sfcmd.d32, 0x8 << 16, addr, &status); + if (ret != SFC_OK) + return ret; + return ret; +} + +static int sfc_nand_wait_busy(u8 *data, int timeout) +{ + int ret; + int i; + u8 status; + + *data = 0; + for (i = 0; i < timeout; i++) { + ret = sfc_nand_read_feature(0xC0, &status); + if (ret != SFC_OK) + return ret; + *data = status; + if (!(status & (1 << 0))) + return SFC_OK; + sfc_delay(1); + } + return -1; +} + +static u32 sfc_nand_erase_block(u8 cs, u32 addr) +{ + int ret; + union SFCCMD_DATA sfcmd; + u8 status; + + sfcmd.d32 = 0; + sfcmd.b.cmd = p_nand_info->block_erase_cmd; + sfcmd.b.addrbits = SFC_ADDR_24BITS; + sfc_nand_write_en(); + ret = sfc_request(sfcmd.d32, 0, addr, NULL); + if (ret != SFC_OK) + return ret; + ret = sfc_nand_wait_busy(&status, 1000 * 1000); + if (status & (1 << 2)) + return SFC_NAND_PROG_ERASE_ERROR; + return ret; +} + +static u32 sfc_nand_prog_page(u8 cs, u32 addr, u32 *p_data, u32 *p_spare) +{ + int ret; + union SFCCMD_DATA sfcmd; + union SFCCTRL_DATA sfctrl; + u8 status; + u32 data_sz = 2048; + u32 spare_offs_1 = p_nand_info->spare_offs_1; + u32 spare_offs_2 = p_nand_info->spare_offs_2; + + memcpy(gp_page_buf, p_data, data_sz); + gp_page_buf[(data_sz + spare_offs_1) / 4] = p_spare[0]; + gp_page_buf[(data_sz + spare_offs_2) / 4] = p_spare[1]; + + sfc_nand_write_en(); + if (sfc_nand_dev.prog_lines == DATA_LINES_X4 && + p_nand_info->QE_address == 0xFF && + sfc_get_version() != SFC_VER_3) + sfc_nand_rw_preset(); + + sfcmd.d32 = 0; + sfcmd.b.cmd = sfc_nand_dev.page_prog_cmd; + sfcmd.b.addrbits = SFC_ADDR_XBITS; + sfcmd.b.datasize = SFC_NAND_PAGE_MAX_SIZE; + sfcmd.b.rw = SFC_WRITE; + + sfctrl.d32 = 0; + sfctrl.b.datalines = sfc_nand_dev.prog_lines; + sfctrl.b.addrbits = 16; + ret = sfc_request(sfcmd.d32, sfctrl.d32, 0, gp_page_buf); + + sfcmd.d32 = 0; + sfcmd.b.cmd = p_nand_info->page_prog_cmd; + sfcmd.b.addrbits = SFC_ADDR_24BITS; + sfcmd.b.datasize = 0; + sfcmd.b.rw = SFC_WRITE; + ret = sfc_request(sfcmd.d32, 0, addr, p_data); + if (ret != SFC_OK) + return ret; + ret = sfc_nand_wait_busy(&status, 1000 * 1000); + if (status & (1 << 3)) + return SFC_NAND_PROG_ERASE_ERROR; + return ret; +} + +static u32 sfc_nand_read_page(u8 cs, u32 addr, u32 *p_data, u32 *p_spare) +{ + int ret; + union SFCCMD_DATA sfcmd; + union SFCCTRL_DATA sfctrl; + u8 status; + u8 ecc; + u32 data_sz = 2048; + u32 spare_offs_1 = p_nand_info->spare_offs_1; + u32 spare_offs_2 = p_nand_info->spare_offs_2; + + sfcmd.d32 = 0; + sfcmd.b.cmd = p_nand_info->page_read_cmd; + sfcmd.b.datasize = 0; + sfcmd.b.addrbits = SFC_ADDR_24BITS; + ret = sfc_request(sfcmd.d32, 0, addr, p_data); + + ret = sfc_nand_wait_busy(&status, 1000 * 1000); + ecc = (status >> 4) & 0x03; + if (sfc_nand_dev.read_lines == DATA_LINES_X4 && + p_nand_info->QE_address == 0xFF && + sfc_get_version() != SFC_VER_3) + sfc_nand_rw_preset(); + + sfcmd.d32 = 0; + sfcmd.b.cmd = sfc_nand_dev.page_read_cmd; + sfcmd.b.datasize = SFC_NAND_PAGE_MAX_SIZE; + sfcmd.b.addrbits = SFC_ADDR_24BITS; + sfctrl.d32 = 0; + sfctrl.b.datalines = sfc_nand_dev.read_lines; + + memset(gp_page_buf, 0, SFC_NAND_PAGE_MAX_SIZE); + ret = sfc_request(sfcmd.d32, sfctrl.d32, 0, gp_page_buf); + + memcpy(p_data, gp_page_buf, data_sz); + p_spare[0] = gp_page_buf[(data_sz + spare_offs_1) / 4]; + p_spare[1] = gp_page_buf[(data_sz + spare_offs_2) / 4]; + if (ret != SFC_OK) + return SFC_NAND_ECC_ERROR; + + /* + * ecc status: + * 0, No bit errors were detected + * 1, Bit errors were detected and corrected. If max_ecc_bits equals 1, + * Bit error count exceed the bit flip detection threshold. + * 2, Multiple bit errors were detected and not corrected. + * 3, If max_ecc_bits equals 1, reserved, else bit errors were detected + * and corrected, bit error count exceed the bit flip detection + * threshold + */ + + if (ecc == 0) { + ret = SFC_NAND_ECC_OK; + } else if (ecc == 1) { + if (p_nand_info->max_ecc_bits == 1) + ret = SFC_NAND_ECC_REFRESH; + else + ret = SFC_NAND_ECC_OK; + } else if (ecc == 2) { + ret = SFC_NAND_ECC_ERROR; + } else { + if (p_nand_info->max_ecc_bits == 1) + ret = SFC_NAND_ECC_ERROR; + else + ret = SFC_NAND_ECC_REFRESH; + } + + if (ret != SFC_NAND_ECC_OK) { + PRINT_E("%s[0x%x], ret=0x%x\n", __func__, addr, ret); + if (p_data) + rknand_print_hex("data:", p_data, 4, 8); + if (p_spare) + rknand_print_hex("spare:", p_spare, 4, 2); + } + return ret; +} + +static int sfc_nand_read_id_raw(u8 *data) +{ + int ret; + union SFCCMD_DATA sfcmd; + + sfcmd.d32 = 0; + sfcmd.b.cmd = CMD_READ_JEDECID; + sfcmd.b.datasize = 3; + sfcmd.b.addrbits = SFC_ADDR_XBITS; + + ret = sfc_request(sfcmd.d32, 0x8 << 16, 0, data); + + return ret; +} + +/* + * Read the 1st page's 1st byte of a phy_blk + * If not FF, it's bad blk + */ +static int sfc_nand_get_bad_block_list(u16 *table, u32 die) +{ + u16 blk; + u32 bad_cnt, page; + u32 blk_per_die; + u32 *pread; + u32 *pspare_read; + + PRINT_E("%s\n", __func__); + pread = ftl_malloc(2048); + pspare_read = ftl_malloc(8); + bad_cnt = 0; + blk_per_die = p_nand_info->plane_per_die * + p_nand_info->blk_per_plane; + for (blk = 0; blk < blk_per_die; blk++) { + page = (blk + blk_per_die * die) * + p_nand_info->page_per_blk; + sfc_nand_read_page(0, page, pread, pspare_read); + + if (pread[0] != 0xFFFFFFFF || + pspare_read[0] != 0xFFFFFFFF) { + table[bad_cnt++] = blk; + PRINT_E("die[%d], bad_blk[%d]\n", die, blk); + } + } + ftl_free(pread); + ftl_free(pspare_read); + return (int)bad_cnt; +} + +#if SFC_NAND_STRESS_TEST_EN + +#define SFC_NAND_PAGE_SIZE 2048 +#define SFC_NAND_SPARE_SIZE 8 + +static u16 bad_blk_list[1024]; +static u32 pwrite[SFC_NAND_PAGE_SIZE / 4]; +static u32 pread[SFC_NAND_PAGE_SIZE / 4]; +static u32 pspare_write[SFC_NAND_SPARE_SIZE / 4]; +static u32 pspare_read[SFC_NAND_SPARE_SIZE / 4]; +static u32 bad_blk_num; +static u32 bad_page_num; + +static void sfc_nand_test(void) +{ + u32 i, blk, page, bad_cnt, page_addr; + int ret; + u32 pages_num = 64; + u32 blk_addr = 64; + u32 is_bad_blk = 0; + + PRINT_E("%s\n", __func__); + + bad_blk_num = 0; + bad_page_num = 0; + bad_cnt = sfc_nand_get_bad_block_list(bad_blk_list, 0); + + for (blk = 0; blk < 1024; blk++) { + for (i = 0; i < bad_cnt; i++) { + if (bad_blk_list[i] == blk) + break; + } + if (i < bad_cnt) + continue; + is_bad_blk = 0; + PRINT_E("Flash prog block: %x\n", blk); + sfc_nand_erase_block(0, blk * blk_addr); + for (page = 0; page < pages_num; page++) { + page_addr = blk * blk_addr + page; + for (i = 0; i < 512; i++) + pwrite[i] = (page_addr << 16) + i; + pspare_write[0] = pwrite[0] + 0x5AF0; + pspare_write[1] = pspare_write[0] + 1; + sfc_nand_prog_page(0, page_addr, pwrite, pspare_write); + memset(pread, 0, 2048); + memset(pspare_read, 0, 8); + ret = sfc_nand_read_page(0, page_addr, pread, + pspare_read); + if (ret != SFC_NAND_ECC_OK) + is_bad_blk = 1; + for (i = 0; i < 512; i++) { + if (pwrite[i] != pread[i]) { + is_bad_blk = 1; + break; + } + } + for (i = 0; i < 2; i++) { + if (pspare_write[i] != pspare_read[i]) { + is_bad_blk = 1; + break; + } + } + if (is_bad_blk) { + bad_page_num++; + PRINT_E("ERR:page%x, ret=%x\n", page_addr, ret); + rknand_print_hex("data:", pread, 4, 8); + rknand_print_hex("spare:", pspare_read, 4, 2); + } + } + sfc_nand_erase_block(0, blk * blk_addr); + if (is_bad_blk) + bad_blk_num++; + } + PRINT_E("bad_blk_num = %d, bad_page_num = %d\n", + bad_blk_num, bad_page_num); + + PRINT_E("Flash Test Finish!!!\n"); + while (1) + ; +} +#endif + +static void ftl_flash_init(void) +{ + /* para init */ + g_nand_phy_info.nand_type = 1; + g_nand_phy_info.die_num = 1; + g_nand_phy_info.plane_per_die = p_nand_info->plane_per_die; + g_nand_phy_info.blk_per_plane = p_nand_info->blk_per_plane; + g_nand_phy_info.page_per_blk = p_nand_info->page_per_blk; + g_nand_phy_info.page_per_slc_blk = p_nand_info->page_per_blk; + g_nand_phy_info.byte_per_sec = 512; + g_nand_phy_info.sec_per_page = p_nand_info->sec_per_page; + g_nand_phy_info.sec_per_blk = p_nand_info->sec_per_page * + p_nand_info->page_per_blk; + g_nand_phy_info.reserved_blk = 8; + g_nand_phy_info.blk_per_die = p_nand_info->plane_per_die * + p_nand_info->blk_per_plane; + g_nand_phy_info.ecc_bits = p_nand_info->max_ecc_bits; + + /* driver register */ + g_nand_ops.get_bad_blk_list = sfc_nand_get_bad_block_list; + g_nand_ops.erase_blk = sfc_nand_erase_block; + g_nand_ops.prog_page = sfc_nand_prog_page; + g_nand_ops.read_page = sfc_nand_read_page; +} + +static int spi_nand_enable_QE(void) +{ + int ret = SFC_OK; + u8 status; + int bit_offset = p_nand_info->QE_bits; + + if (bit_offset == 0xFF) + return SFC_OK; + + ret = sfc_nand_read_feature(p_nand_info->QE_address, &status); + if (ret != SFC_OK) + return ret; + + if (status & (1 << bit_offset)) /* is QE bit set */ + return SFC_OK; + + status |= (1 << bit_offset); + return sfc_nand_write_feature(p_nand_info->QE_address, status); + + return ret; +} + +u32 sfc_nand_init(void __iomem *sfc_addr) +{ + PRINT_E("%s\n", __func__); + sfc_init(sfc_addr); + sfc_nand_read_id_raw(id_byte); + PRINT_E("sfc_nand id: %x %x %x\n", id_byte[0], id_byte[1], id_byte[2]); + if (id_byte[0] == 0xFF || id_byte[0] == 0x00) + return FTL_NO_FLASH; + + p_nand_info = spi_nand_get_info(id_byte); + if (!p_nand_info) + return FTL_UNSUPPORTED_FLASH; + + sfc_nand_dev.manufacturer = id_byte[0]; + sfc_nand_dev.mem_type = id_byte[1]; + + /* disable block lock */ + sfc_nand_write_feature(0xA0, 0); + sfc_nand_dev.read_lines = DATA_LINES_X1; + sfc_nand_dev.prog_lines = DATA_LINES_X1; + sfc_nand_dev.page_read_cmd = p_nand_info->read_cache_cmd_1; + sfc_nand_dev.page_prog_cmd = p_nand_info->prog_cache_cmd_1; + if (p_nand_info->feature & FEA_4BIT_READ) { + if (spi_nand_enable_QE() == SFC_OK) { + sfc_nand_dev.read_lines = DATA_LINES_X4; + sfc_nand_dev.page_read_cmd = + p_nand_info->read_cache_cmd_4; + } + } + + if (p_nand_info->feature & FEA_4BIT_PROG && + sfc_nand_dev.read_lines == DATA_LINES_X4) { + sfc_nand_dev.prog_lines = DATA_LINES_X4; + sfc_nand_dev.page_prog_cmd = p_nand_info->prog_cache_cmd_4; + } + + if (1) { + u8 status; + + sfc_nand_read_feature(0xA0, &status); + PRINT_E("sfc_nand A0 = 0x%x\n", status); + sfc_nand_read_feature(0xB0, &status); + PRINT_E("sfc_nand B0 = 0x%x\n", status); + sfc_nand_read_feature(0xC0, &status); + PRINT_E("sfc_nand C0 = 0x%x\n", status); + PRINT_E("read_lines = %x\n", sfc_nand_dev.read_lines); + PRINT_E("prog_lines = %x\n", sfc_nand_dev.prog_lines); + PRINT_E("page_read_cmd = %x\n", sfc_nand_dev.page_read_cmd); + PRINT_E("page_prog_cmd = %x\n", sfc_nand_dev.page_prog_cmd); + } + ftl_flash_init(); + + #if SFC_NAND_STRESS_TEST_EN + sfc_nand_test(); + #endif + + return SFC_OK; +} + +void sfc_nand_deinit(void) +{ +} + +int sfc_nand_read_id(u8 *data) +{ + memcpy(data, id_byte, 3); + return 0; +} diff --git a/drivers/rkflash/sfc_nand.h b/drivers/rkflash/sfc_nand.h new file mode 100644 index 000000000000..151687ab1075 --- /dev/null +++ b/drivers/rkflash/sfc_nand.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#ifndef __SFC_NAND_H +#define __SFC_NAND_H + +/* Manufactory ID */ +#define MID_WINBOND 0xEF +#define MID_GIGADEV 0xC8 +#define MID_MICRON 0x2C +#define MID_MACRONIX 0xC2 +#define MID_SPANSION 0x01 +#define MID_EON 0x1C +#define MID_ST 0x20 + +/* Command Set */ +#define CMD_READ_JEDECID (0x9F) +#define CMD_READ_DATA (0x03) +#define CMD_READ_STATUS (0x05) +#define CMD_WRITE_STATUS (0x01) +#define CMD_PAGE_PROG (0x02) +#define CMD_SECTOR_ERASE (0x20) +#define CMD_BLK64K_ERASE (0xD8) +#define CMD_BLK32K_ERASE (0x52) +#define CMD_CHIP_ERASE (0xC7) +#define CMD_WRITE_EN (0x06) +#define CMD_WRITE_DIS (0x04) +#define CMD_PAGE_READ (0x13) +#define CMD_GET_FEATURE (0x0F) +#define CMD_SET_FEATURE (0x1F) +#define CMD_PROG_LOAD (0x02) +#define CMD_PROG_EXEC (0x10) +#define CMD_BLOCK_ERASE (0xD8) +#define CMD_READ_DATA_X2 (0x3B) +#define CMD_READ_DATA_X4 (0x6B) +#define CMD_PROG_LOAD_X4 (0x32) +#define CMD_READ_STATUS2 (0x35) +#define CMD_READ_STATUS3 (0x15) +#define CMD_WRITE_STATUS2 (0x31) +#define CMD_WRITE_STATUS3 (0x11) +#define CMD_FAST_READ_X1 (0x0B) /* X1 cmd, X1 addr, X1 data */ +#define CMD_FAST_READ_X2 (0x3B) /* X1 cmd, X1 addr, X2 data */ +/* X1 cmd, X1 addr, X4 data SUPPORT GD MARCONIX WINBOND */ +#define CMD_FAST_READ_X4 (0x6B) +/* X1 cmd, X1 addr, X4 data SUPPORT GD MARCONIX WINBOND */ +#define CMD_FAST_4READ_X4 (0x6C) +/* X1 cmd, X4 addr, X4 data SUPPORT EON GD MARCONIX WINBOND */ +#define CMD_FAST_READ_A4 (0xEB) +/* X1 cmd, X1 addr, X4 data, SUPPORT GD WINBOND */ +#define CMD_PAGE_PROG_X4 (0x32) +/* X1 cmd, X4 addr, X4 data, SUPPORT MARCONIX */ +#define CMD_PAGE_PROG_A4 (0x38) +#define CMD_RESET_NAND (0xFF) + +#define CMD_ENTER_4BYTE_MODE (0xB7) +#define CMD_EXIT_4BYTE_MODE (0xE9) +#define CMD_ENABLE_RESER (0x66) +#define CMD_RESET_DEVICE (0x99) + +u32 sfc_nand_init(void __iomem *sfc_addr); +void sfc_nand_deinit(void); +int sfc_nand_read_id(u8 *buf); + +#endif diff --git a/drivers/rkflash/sfc_nand_boot.c b/drivers/rkflash/sfc_nand_boot.c new file mode 100644 index 000000000000..2cc8a8c77472 --- /dev/null +++ b/drivers/rkflash/sfc_nand_boot.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#include +#include + +#include "rk_sftl.h" +#include "sfc_nand.h" +#include "sfc_nand_boot.h" +#include "typedef.h" + +int snand_init(void __iomem *reg_addr) +{ + int ret; + + ret = sfc_nand_init(reg_addr); + if (ret == 0) + ret = sftl_init(); + + return ret; +} +EXPORT_SYMBOL_GPL(snand_init); + +unsigned int snand_get_capacity(void) +{ + return sftl_get_density(); +} + +int snand_write(u32 sec, u32 n_sec, void *p_data) +{ + return sftl_write(sec, n_sec, p_data); +} + +int snand_read(u32 sec, u32 n_sec, void *p_data) +{ + return sftl_read(sec, n_sec, p_data); +} + +void snand_deinit(void) +{ + sftl_deinit(); + sfc_nand_deinit(); +} + +int snand_resume(void __iomem *reg_addr) +{ + return sfc_nand_init(reg_addr); +} diff --git a/drivers/rkflash/sfc_nand_boot.h b/drivers/rkflash/sfc_nand_boot.h new file mode 100644 index 000000000000..747de0e816af --- /dev/null +++ b/drivers/rkflash/sfc_nand_boot.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#ifndef _SFC_NOR_BOOT_H +#define _SFC_NOR_BOOT_H + +int snand_init(void __iomem *reg_addr); +int snand_read(unsigned int sec, unsigned int n_sec, void *p_data); +int snand_write(unsigned int sec, unsigned int n_sec, void *p_data); +unsigned int snand_get_capacity(void); +void snand_deinit(void); +int snand_resume(void __iomem *reg_addr); +void sfc_clean_irq(void); + +#endif diff --git a/drivers/rkflash/sfc_nor.c b/drivers/rkflash/sfc_nor.c new file mode 100644 index 000000000000..d8b061892da6 --- /dev/null +++ b/drivers/rkflash/sfc_nor.c @@ -0,0 +1,656 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#include +#include +#include + +#include "sfc_nor.h" +#include "rkflash_debug.h" + +static struct flash_info spi_flash_tbl[] = { + /* GD25Q32B */ + {0xc84016, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 13, 9, 0}, + /* GD25Q64B */ + {0xc84017, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0D, 14, 9, 0}, + /* GD25Q127C and GD25Q128C*/ + {0xc84018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 9, 0}, + /* GD25Q256B */ + {0xc84019, 128, 8, 0x13, 0x12, 0x6C, 0x3E, 0x21, 0xDC, 0x1C, 16, 6, 0}, + /* GD25Q512MC */ + {0xc84020, 128, 8, 0x13, 0x12, 0x6C, 0x3E, 0x21, 0xDC, 0x1C, 17, 6, 0}, + /* 25Q128FV */ + {0xef4018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x0C, 15, 9, 0}, + /* 25Q256FV */ + {0xef4019, 128, 8, 0x13, 0x02, 0x6C, 0x32, 0x20, 0xD8, 0x3C, 16, 9, 0}, + /* XT25F128A */ + {0x207018, 128, 8, 0x03, 0x02, 0x6B, 0x32, 0x20, 0xD8, 0x00, 15, 0, 0}, + /* MX25L25635E/F */ + {0xc22019, 128, 8, 0x03, 0x02, 0x6B, 0x38, 0x20, 0xD8, 0x30, 16, 6, 0}, +}; + +static const u8 sfnor_dev_code[] = { + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19 +}; + +static const u32 sfnor_capacity[] = { + 0x20000, /* 128k-byte */ + 0x40000, /* 256k-byte */ + 0x80000, /* 512k-byte */ + 0x100000, /* 1M-byte */ + 0x200000, /* 2M-byte */ + 0x400000, /* 4M-byte */ + 0x800000, /* 8M-byte */ + 0x1000000, /* 16M-byte */ + 0x2000000 /* 32M-byte */ +}; + +struct SFNOR_DEV sfnor_dev; +struct flash_info *g_spi_flash_info; + +static int snor_write_en(void) +{ + int ret; + union SFCCMD_DATA sfcmd; + + sfcmd.d32 = 0; + sfcmd.b.cmd = CMD_WRITE_EN; + + ret = sfc_request(sfcmd.d32, 0, 0, NULL); + + return ret; +} + +int snor_reset_device(void) +{ + int ret; + union SFCCMD_DATA sfcmd; + + sfcmd.d32 = 0; + sfcmd.b.cmd = CMD_ENABLE_RESER; + sfc_request(sfcmd.d32, 0, 0, NULL); + + sfcmd.d32 = 0; + sfcmd.b.cmd = CMD_RESET_DEVICE; + ret = sfc_request(sfcmd.d32, 0, 0, NULL); + /* tRST=30us , delay 1ms here */ + mdelay(1); + return ret; +} + +static int snor_enter_4byte_mode(void) +{ + int ret; + union SFCCMD_DATA sfcmd; + + sfcmd.d32 = 0; + sfcmd.b.cmd = CMD_ENTER_4BYTE_MODE; + + ret = sfc_request(sfcmd.d32, 0, 0, NULL); + return ret; +} + +static int snor_read_status(u32 reg_index, u8 *status) +{ + int ret; + union SFCCMD_DATA sfcmd; + u8 read_stat_cmd[] = {CMD_READ_STATUS, + CMD_READ_STATUS2, CMD_READ_STATUS3}; + sfcmd.d32 = 0; + sfcmd.b.cmd = read_stat_cmd[reg_index]; + sfcmd.b.datasize = 1; + + ret = sfc_request(sfcmd.d32, 0, 0, status); + + return ret; +} + +static int snor_wait_busy(int timeout) +{ + int ret; + union SFCCMD_DATA sfcmd; + int i; + u32 status; + + sfcmd.d32 = 0; + sfcmd.b.cmd = CMD_READ_STATUS; + sfcmd.b.datasize = 1; + + for (i = 0; i < timeout; i++) { + ret = sfc_request(sfcmd.d32, 0, 0, &status); + if (ret != SFC_OK) + return ret; + + if ((status & 0x01) == 0) + return SFC_OK; + + sfc_delay(1); + } + PRINT_SFC_E("%s error %x\n", __func__, timeout); + + return SFC_BUSY_TIMEOUT; +} + +static int snor_write_status2(u32 reg_index, u8 status) +{ + int ret; + union SFCCMD_DATA sfcmd; + u8 status2[2]; + u8 read_index; + + status2[reg_index] = status; + read_index = (reg_index == 0) ? 1 : 0; + ret = snor_read_status(read_index, &status2[read_index]); + if (ret != SFC_OK) + return ret; + + snor_write_en(); + + sfcmd.d32 = 0; + sfcmd.b.cmd = CMD_WRITE_STATUS; + sfcmd.b.datasize = 2; + sfcmd.b.rw = SFC_WRITE; + + ret = sfc_request(sfcmd.d32, 0, 0, &status2[0]); + if (ret != SFC_OK) + return ret; + + ret = snor_wait_busy(10000); /* 10ms */ + + return ret; +} + +static int snor_write_status(u32 reg_index, u8 status) +{ + int ret; + union SFCCMD_DATA sfcmd; + u8 write_stat_cmd[] = {CMD_WRITE_STATUS, + CMD_WRITE_STATUS2, CMD_WRITE_STATUS3}; + snor_write_en(); + sfcmd.d32 = 0; + sfcmd.b.cmd = write_stat_cmd[reg_index]; + sfcmd.b.datasize = 1; + sfcmd.b.rw = SFC_WRITE; + + ret = sfc_request(sfcmd.d32, 0, 0, &status); + if (ret != SFC_OK) + return ret; + + ret = snor_wait_busy(10000); /* 10ms */ + + return ret; +} + +int snor_erase(struct SFNOR_DEV *p_dev, + u32 addr, + enum NOR_ERASE_TYPE erase_type) +{ + int ret; + union SFCCMD_DATA sfcmd; + int timeout[] = {400, 2000, 40000}; /* ms */ + + if (erase_type > ERASE_CHIP) + return SFC_PARAM_ERR; + + sfcmd.d32 = 0; + if (erase_type == ERASE_BLOCK64K) + sfcmd.b.cmd = p_dev->blk_erase_cmd; + else if (erase_type == ERASE_SECTOR) + sfcmd.b.cmd = p_dev->sec_erase_cmd; + else + sfcmd.b.cmd = CMD_CHIP_ERASE; + + sfcmd.b.addrbits = (erase_type != ERASE_CHIP) ? + SFC_ADDR_24BITS : SFC_ADDR_0BITS; + if (p_dev->addr_mode == ADDR_MODE_4BYTE && erase_type != ERASE_CHIP) + sfcmd.b.addrbits = SFC_ADDR_32BITS; + + snor_write_en(); + + ret = sfc_request(sfcmd.d32, 0, addr, NULL); + if (ret != SFC_OK) + return ret; + + ret = snor_wait_busy(timeout[erase_type] * 1000); + return ret; +} + +int snor_prog_page(struct SFNOR_DEV *p_dev, + u32 addr, + void *p_data, + u32 size) +{ + int ret; + union SFCCMD_DATA sfcmd; + union SFCCTRL_DATA sfctrl; + + sfcmd.d32 = 0; + sfcmd.b.cmd = p_dev->prog_cmd; + sfcmd.b.addrbits = SFC_ADDR_24BITS; + sfcmd.b.datasize = size; + sfcmd.b.rw = SFC_WRITE; + + sfctrl.d32 = 0; + sfctrl.b.datalines = p_dev->prog_lines; + sfctrl.b.enbledma = 0; + if (p_dev->prog_cmd == CMD_PAGE_PROG_A4) + sfctrl.b.addrlines = SFC_4BITS_LINE; + + if (p_dev->addr_mode == ADDR_MODE_4BYTE) + sfcmd.b.addrbits = SFC_ADDR_32BITS; + + snor_write_en(); + + ret = sfc_request(sfcmd.d32, sfctrl.d32, addr, p_data); + if (ret != SFC_OK) + return ret; + + ret = snor_wait_busy(10000); + + return ret; +} + +static int snor_prog(struct SFNOR_DEV *p_dev, u32 addr, void *p_data, u32 size) +{ + int ret = SFC_OK; + u32 page_size, len; + u8 *p_buf = (u8 *)p_data; + + page_size = NOR_PAGE_SIZE; + while (size) { + len = page_size < size ? page_size : size; + ret = snor_prog_page(p_dev, addr, p_buf, len); + if (ret != SFC_OK) + return ret; + + size -= len; + addr += len; + p_buf += len; + } + + return ret; +} + +static int snor_enable_QE(struct SFNOR_DEV *p_dev) +{ + int ret = SFC_OK; + int reg_index; + int bit_offset; + u8 status; + + if (p_dev->manufacturer == MID_GIGADEV || + p_dev->manufacturer == MID_WINBOND) { + reg_index = p_dev->QE_bits >> 3; + bit_offset = p_dev->QE_bits & 0x7; + ret = snor_read_status(reg_index, &status); + if (ret != SFC_OK) + return ret; + + if (status & (1 << bit_offset)) /* is QE bit set */ + return SFC_OK; + + status |= (1 << bit_offset); + return p_dev->write_status(reg_index, status); + } + + return ret; +} + +int snor_disable_QE(struct SFNOR_DEV *p_dev) +{ + int ret = SFC_OK; + int reg_index; + int bit_offset; + u8 status; + + if (p_dev->manufacturer == MID_GIGADEV || + p_dev->manufacturer == MID_WINBOND) { + reg_index = p_dev->QE_bits >> 3; + bit_offset = p_dev->QE_bits & 0x7; + ret = snor_read_status(reg_index, &status); + if (ret != SFC_OK) + return ret; + + if (!(status & (1 << bit_offset))) + return SFC_OK; + + status &= ~(1 << bit_offset); + return p_dev->write_status(reg_index, status); + } + + return ret; +} + +#if (SNOR_4BIT_DATA_DETECT_EN) +static int snor_set_dlines(struct SFNOR_DEV *p_dev, enum SFC_DATA_LINES lines) +{ + int ret; + u8 read_cmd[] = {CMD_FAST_READ_X1, CMD_FAST_READ_X2, CMD_FAST_READ_X4}; + + if (lines == DATA_LINES_X4) { + ret = snor_enable_QE(p_dev); + if (ret != SFC_OK) + return ret; + } + + p_dev->read_lines = lines; + p_dev->read_cmd = read_cmd[lines]; + + if (p_dev->manufacturer == MID_GIGADEV || + p_dev->manufacturer == MID_WINBOND || + p_dev->manufacturer == MID_MACRONIX) { + p_dev->prog_lines = (lines != DATA_LINES_X2) ? + lines : DATA_LINES_X1; + if (lines == DATA_LINES_X1) { + p_dev->prog_cmd = CMD_PAGE_PROG; + } else { + if (p_dev->manufacturer == MID_GIGADEV || + p_dev->manufacturer == MID_WINBOND) + p_dev->prog_cmd = CMD_PAGE_PROG_X4; + else + p_dev->prog_cmd = CMD_PAGE_PROG_A4; + } + } + + return SFC_OK; +} +#endif + +int snor_read_data(struct SFNOR_DEV *p_dev, + u32 addr, + void *p_data, + u32 size) +{ + int ret; + union SFCCMD_DATA sfcmd; + union SFCCTRL_DATA sfctrl; + + sfcmd.d32 = 0; + sfcmd.b.cmd = p_dev->read_cmd; + sfcmd.b.datasize = size; + sfcmd.b.addrbits = SFC_ADDR_24BITS; + + sfctrl.d32 = 0; + sfctrl.b.datalines = p_dev->read_lines; + if (!(size & 0x3) && size >= 4) + sfctrl.b.enbledma = 0; + + if (p_dev->read_cmd == CMD_FAST_READ_X1 || + p_dev->read_cmd == CMD_FAST_READ_X4 || + p_dev->read_cmd == CMD_FAST_READ_X2 || + p_dev->read_cmd == CMD_FAST_4READ_X4) { + sfcmd.b.dummybits = 8; + } else if (p_dev->read_cmd == CMD_FAST_READ_A4) { + sfcmd.b.addrbits = SFC_ADDR_32BITS; + addr = (addr << 8) | 0xFF; /* Set M[7:0] = 0xFF */ + sfcmd.b.dummybits = 4; + sfctrl.b.addrlines = SFC_4BITS_LINE; + } + + if (p_dev->addr_mode == ADDR_MODE_4BYTE) + sfcmd.b.addrbits = SFC_ADDR_32BITS; + + ret = sfc_request(sfcmd.d32, sfctrl.d32, addr, p_data); + + return ret; +} + +int snor_read(struct SFNOR_DEV *p_dev, u32 sec, u32 n_sec, void *p_data) +{ + int ret = SFC_OK; + u32 addr, size, len; + u8 *p_buf = (u8 *)p_data; + + if ((sec + n_sec) > p_dev->capacity) + return SFC_PARAM_ERR; + + mutex_lock(&p_dev->lock); + addr = sec << 9; + size = n_sec << 9; + while (size) { + len = size < SFC_MAX_IOSIZE ? size : SFC_MAX_IOSIZE; + ret = snor_read_data(p_dev, addr, p_buf, len); + if (ret != SFC_OK) { + PRINT_SFC_E("snor_read_data %x ret= %x\n", + addr >> 9, ret); + goto out; + } + + size -= len; + addr += len; + p_buf += len; + } +out: + mutex_unlock(&p_dev->lock); + if (!ret) + ret = n_sec; + + return ret; +} + +int snor_write(struct SFNOR_DEV *p_dev, u32 sec, u32 n_sec, void *p_data) +{ + int ret = SFC_OK; + u32 len, blk_size, offset; + u8 *p_buf = (u8 *)p_data; + + if ((sec + n_sec) > p_dev->capacity) + return SFC_PARAM_ERR; + + mutex_lock(&p_dev->lock); + while (n_sec) { + if (sec < 512 || sec >= p_dev->capacity - 512) + blk_size = 8; + else + blk_size = p_dev->blk_size; + + offset = (sec & (blk_size - 1)); + if (!offset) { + ret = snor_erase(p_dev, sec << 9, (blk_size == 8) ? + ERASE_SECTOR : ERASE_BLOCK64K); + if (ret != SFC_OK) { + PRINT_SFC_E("snor_erase %x ret= %x\n", + sec, ret); + goto out; + } + } + len = (blk_size - offset) < n_sec ? + (blk_size - offset) : n_sec; + ret = snor_prog(p_dev, sec << 9, p_buf, len << 9); + if (ret != SFC_OK) { + PRINT_SFC_E("snor_prog %x ret= %x\n", sec, ret); + goto out; + } + n_sec -= len; + sec += len; + p_buf += len << 9; + } +out: + mutex_unlock(&p_dev->lock); + if (!ret) + ret = n_sec; + + return ret; +} + +int snor_read_id(u8 *data) +{ + int ret; + union SFCCMD_DATA sfcmd; + + sfcmd.d32 = 0; + sfcmd.b.cmd = CMD_READ_JEDECID; + sfcmd.b.datasize = 3; + + ret = sfc_request(sfcmd.d32, 0, 0, data); + + return ret; +} + +static int snor_read_parameter(u32 addr, u8 *data) +{ + int ret; + union SFCCMD_DATA sfcmd; + + sfcmd.d32 = 0; + sfcmd.b.cmd = CMD_READ_PARAMETER; + sfcmd.b.datasize = 1; + sfcmd.b.addrbits = SFC_ADDR_24BITS; + sfcmd.b.dummybits = 8; + + ret = sfc_request(sfcmd.d32, 0, addr, data); + + return ret; +} + +u32 snor_get_capacity(struct SFNOR_DEV *p_dev) +{ + return p_dev->capacity; +} + +static void snor_print_spi_chip_info(struct SFNOR_DEV *p_dev) +{ + PRINT_SFC_I("addr_mode: %x\n", p_dev->addr_mode); + PRINT_SFC_I("read_lines: %x\n", p_dev->read_lines); + PRINT_SFC_I("prog_lines: %x\n", p_dev->prog_lines); + PRINT_SFC_I("read_cmd: %x\n", p_dev->read_cmd); + PRINT_SFC_I("prog_cmd: %x\n", p_dev->prog_cmd); + PRINT_SFC_I("blk_erase_cmd: %x\n", p_dev->blk_erase_cmd); + PRINT_SFC_I("sec_erase_cmd: %x\n", p_dev->sec_erase_cmd); +} + +static struct flash_info *snor_get_flash_info(u8 *flash_id) +{ + u32 i; + u32 id = (flash_id[0] << 16) | (flash_id[1] << 8) | (flash_id[2] << 0); + + for (i = 0; i < ARRAY_SIZE(spi_flash_tbl); i++) { + if (spi_flash_tbl[i].id == id) + return &spi_flash_tbl[i]; + } + return NULL; +} + +/* Adjust flash info in ram base on parameter */ +static void *snor_flash_info_adjust(struct flash_info *spi_flash_info) +{ + u32 addr; + u8 para_version; + + if (spi_flash_info->id == 0xc84019) { + addr = 0x09; + snor_read_parameter(addr, ¶_version); + if (para_version == 0x06) { + spi_flash_info->QE_bits = 9; + spi_flash_info->prog_cmd_4 = 0x34; + } + } + return 0; +} + +int snor_init(struct SFNOR_DEV *p_dev) +{ + u32 i; + u8 id_byte[5]; + int err; + + memset(p_dev, 0, sizeof(struct SFNOR_DEV)); + snor_read_id(id_byte); + PRINT_SFC_E("sfc nor id: %x %x %x\n", + id_byte[0], id_byte[1], id_byte[2]); + if (0xFF == id_byte[0] || 0x00 == id_byte[0]) { + err = SFC_ERROR; + goto err_out; + } + + p_dev->manufacturer = id_byte[0]; + p_dev->mem_type = id_byte[1]; + + mutex_init(&p_dev->lock); + g_spi_flash_info = snor_get_flash_info(id_byte); + if (g_spi_flash_info) { + snor_flash_info_adjust(g_spi_flash_info); + p_dev->capacity = 1 << g_spi_flash_info->density; + p_dev->blk_size = g_spi_flash_info->block_size; + p_dev->page_size = NOR_SECS_PAGE; + p_dev->read_cmd = g_spi_flash_info->read_cmd; + p_dev->prog_cmd = g_spi_flash_info->prog_cmd; + p_dev->sec_erase_cmd = g_spi_flash_info->sector_erase_cmd; + p_dev->blk_erase_cmd = g_spi_flash_info->block_erase_cmd; + p_dev->prog_lines = DATA_LINES_X1; + p_dev->read_lines = DATA_LINES_X1; + p_dev->QE_bits = g_spi_flash_info->QE_bits; + + i = g_spi_flash_info->feature & FEA_READ_STATUE_MASK; + if (i == 0) + p_dev->write_status = snor_write_status; + else + p_dev->write_status = snor_write_status2; + if (g_spi_flash_info->feature & FEA_4BIT_READ) { + if (snor_enable_QE(p_dev) == SFC_OK) { + p_dev->read_lines = DATA_LINES_X4; + p_dev->read_cmd = g_spi_flash_info->read_cmd_4; + } + } + if (g_spi_flash_info->feature & FEA_4BIT_PROG && + p_dev->read_lines == DATA_LINES_X4) { + p_dev->prog_lines = DATA_LINES_X4; + p_dev->prog_cmd = g_spi_flash_info->prog_cmd_4; + } + + if (g_spi_flash_info->feature & FEA_4BYTE_ADDR) + p_dev->addr_mode = ADDR_MODE_4BYTE; + + if ((g_spi_flash_info->feature & FEA_4BYTE_ADDR_MODE)) + snor_enter_4byte_mode(); +#ifdef CONFIG_RK_SFC_NOR_MTD + err = sfc_nor_mtd_init(p_dev); + if (err) + goto err_out; +#endif + + goto normal_out; + } + + for (i = 0; i < sizeof(sfnor_dev_code); i++) { + if (id_byte[2] == sfnor_dev_code[i]) { + p_dev->capacity = sfnor_capacity[i] >> 9; + break; + } + } + + if (i >= sizeof(sfnor_dev_code)) { + err = SFC_ERROR; + goto err_out; + } + + p_dev->QE_bits = 9; + p_dev->blk_size = NOR_SECS_BLK; + p_dev->page_size = NOR_SECS_PAGE; + p_dev->read_cmd = CMD_READ_DATA; + p_dev->prog_cmd = CMD_PAGE_PROG; + p_dev->sec_erase_cmd = CMD_SECTOR_ERASE; + p_dev->blk_erase_cmd = CMD_BLOCK_ERASE; + p_dev->write_status = snor_write_status2; + #if (SNOR_4BIT_DATA_DETECT_EN) + snor_set_dlines(p_dev, DATA_LINES_X4); + #endif + +normal_out: + snor_print_spi_chip_info(p_dev); + + return SFC_OK; + +err_out: + return err; +} + diff --git a/drivers/rkflash/sfc_nor.h b/drivers/rkflash/sfc_nor.h new file mode 100644 index 000000000000..f001a64c08bb --- /dev/null +++ b/drivers/rkflash/sfc_nor.h @@ -0,0 +1,171 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#ifndef _SFNOR_H +#define _SFNOR_H + +#include +#include + +#include "sfc.h" + +/* Four line data transmission detection */ +#define SNOR_4BIT_DATA_DETECT_EN 0 + +#define NOR_PAGE_SIZE 256 +#define NOR_BLOCK_SIZE (64 * 1024) +#define NOR_SECS_BLK (NOR_BLOCK_SIZE / 512) +#define NOR_SECS_PAGE 4 + +#define FEA_READ_STATUE_MASK (0x3 << 0) +#define FEA_STATUE_MODE1 0 +#define FEA_STATUE_MODE2 1 +#define FEA_4BIT_READ BIT(2) +#define FEA_4BIT_PROG BIT(3) +#define FEA_4BYTE_ADDR BIT(4) +#define FEA_4BYTE_ADDR_MODE BIT(5) + +/*Manufactory ID*/ +#define MID_WINBOND 0xEF +#define MID_GIGADEV 0xC8 +#define MID_MICRON 0x2C +#define MID_MACRONIX 0xC2 +#define MID_SPANSION 0x01 +#define MID_EON 0x1C +#define MID_ST 0x20 + +/*Command Set*/ +#define CMD_READ_JEDECID (0x9F) +#define CMD_READ_DATA (0x03) +#define CMD_READ_STATUS (0x05) +#define CMD_WRITE_STATUS (0x01) +#define CMD_PAGE_PROG (0x02) +#define CMD_SECTOR_ERASE (0x20) +#define CMD_BLK64K_ERASE (0xD8) +#define CMD_BLK32K_ERASE (0x52) +#define CMD_CHIP_ERASE (0xC7) +#define CMD_WRITE_EN (0x06) +#define CMD_WRITE_DIS (0x04) +#define CMD_PAGE_READ (0x13) +#define CMD_GET_FEATURE (0x0F) +#define CMD_SET_FEATURE (0x1F) +#define CMD_PROG_LOAD (0x02) +#define CMD_PROG_EXEC (0x10) +#define CMD_BLOCK_ERASE (0xD8) +#define CMD_READ_DATA_X2 (0x3B) +#define CMD_READ_DATA_X4 (0x6B) +#define CMD_PROG_LOAD_X4 (0x32) +#define CMD_READ_STATUS2 (0x35) +#define CMD_READ_STATUS3 (0x15) +#define CMD_WRITE_STATUS2 (0x31) +#define CMD_WRITE_STATUS3 (0x11) +/* X1 cmd, X1 addr, X1 data */ +#define CMD_FAST_READ_X1 (0x0B) +/* X1 cmd, X1 addr, X2 data */ +#define CMD_FAST_READ_X2 (0x3B) +/* X1 cmd, X1 addr, X4 data SUPPORT GD MARCONIX WINBOND */ +#define CMD_FAST_READ_X4 (0x6B) +/* X1 cmd, X1 addr, X4 data SUPPORT GD MARCONIX WINBOND */ +#define CMD_FAST_4READ_X4 (0x6C) +/* X1 cmd, X4 addr, X4 data SUPPORT EON GD MARCONIX WINBOND */ +#define CMD_FAST_READ_A4 (0xEB) +/* X1 cmd, X1 addr, X4 data, SUPPORT GD WINBOND */ +#define CMD_PAGE_PROG_X4 (0x32) +/* X1 cmd, X4 addr, X4 data, SUPPORT MARCONIX */ +#define CMD_PAGE_PROG_A4 (0x38) +#define CMD_RESET_NAND (0xFF) +#define CMD_ENTER_4BYTE_MODE (0xB7) +#define CMD_EXIT_4BYTE_MODE (0xE9) +#define CMD_ENABLE_RESER (0x66) +#define CMD_RESET_DEVICE (0x99) +#define CMD_READ_PARAMETER (0x5A) + +enum NOR_ERASE_TYPE { + ERASE_SECTOR = 0, + ERASE_BLOCK64K, + ERASE_CHIP +}; + +enum SNOR_IO_MODE { + IO_MODE_SPI = 0, + IO_MODE_QPI +}; + +enum SNOR_READ_MODE { + READ_MODE_NOMAL = 0, + READ_MODE_FAST +}; + +enum SNOR_ADDR_MODE { + ADDR_MODE_3BYTE = 0, + ADDR_MODE_4BYTE +}; + +typedef int (*SNOR_WRITE_STATUS)(u32 reg_index, u8 status); + +struct SFNOR_DEV { + u32 capacity; + u8 manufacturer; + u8 mem_type; + u16 page_size; + u32 blk_size; + + u8 read_cmd; + u8 prog_cmd; + u8 sec_erase_cmd; + u8 blk_erase_cmd; + u8 QE_bits; + + enum SNOR_READ_MODE read_mode; + enum SNOR_ADDR_MODE addr_mode; + enum SNOR_IO_MODE io_mode; + + enum SFC_DATA_LINES read_lines; + enum SFC_DATA_LINES prog_lines; + + SNOR_WRITE_STATUS write_status; + struct mutex lock; /* to lock this object */ +#ifdef CONFIG_RK_SFC_NOR_MTD + struct mtd_info mtd; + u8 *dma_buf; +#endif +}; + +struct flash_info { + u32 id; + + u8 block_size; + u8 sector_size; + u8 read_cmd; + u8 prog_cmd; + + u8 read_cmd_4; + u8 prog_cmd_4; + u8 sector_erase_cmd; + u8 block_erase_cmd; + + u8 feature; + u8 density; /* (1 << density) sectors*/ + u8 QE_bits; + u8 reserved2; +}; + +int snor_init(struct SFNOR_DEV *p_dev); +u32 snor_get_capacity(struct SFNOR_DEV *p_dev); +int snor_read(struct SFNOR_DEV *p_dev, u32 sec, u32 n_sec, void *p_data); +int snor_write(struct SFNOR_DEV *p_dev, u32 sec, u32 n_sec, void *p_data); +int snor_erase(struct SFNOR_DEV *p_dev, + u32 addr, + enum NOR_ERASE_TYPE erase_type); +int snor_read_id(u8 *data); +int snor_prog_page(struct SFNOR_DEV *p_dev, u32 addr, void *p_data, u32 size); +int snor_read_data(struct SFNOR_DEV *p_dev, u32 addr, void *p_data, u32 size); +int snor_reset_device(void); +int snor_disable_QE(struct SFNOR_DEV *p_dev); +extern struct flash_info *g_spi_flash_info; +extern struct SFNOR_DEV sfnor_dev; + +int sfc_nor_mtd_init(struct SFNOR_DEV *p_dev); + +#endif diff --git a/drivers/rkflash/sfc_nor_boot.c b/drivers/rkflash/sfc_nor_boot.c new file mode 100644 index 000000000000..9077d23ecaae --- /dev/null +++ b/drivers/rkflash/sfc_nor_boot.c @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#include +#include + +#include "sfc.h" +#include "sfc_nor.h" +#include "sfc_nor_boot.h" +#include "typedef.h" + +#define VENDOR_PART_NUM 4 + +#define FLASH_VENDOR_PART_START 8 +#define FLASH_VENDOR_PART_SIZE 8 +#define FLASH_VENDOR_ITEM_NUM 62 +#define FLASH_VENDOR_PART_END \ + (FLASH_VENDOR_PART_START +\ + FLASH_VENDOR_PART_SIZE * VENDOR_PART_NUM - 1) + +/* SFNOR_DEV sfnor_dev is in the sfc_nor.h */ +int spi_flash_init(void __iomem *reg_addr) +{ + int ret; + + sfc_init(reg_addr); + ret = snor_init(&sfnor_dev); + + return ret; +} +EXPORT_SYMBOL_GPL(spi_flash_init); + +void spi_flash_read_id(u8 chip_sel, void *buf) +{ + snor_read_id(buf); +} +EXPORT_SYMBOL_GPL(spi_flash_read_id); + +int snor_read_lba(u32 sec, u32 n_sec, void *p_data) +{ + int ret = 0; + u32 count, offset; + char *buf; + + if (sec + n_sec - 1 < FLASH_VENDOR_PART_START || + sec > FLASH_VENDOR_PART_END) { + ret = snor_read(&sfnor_dev, sec, n_sec, p_data); + } else { + memset(p_data, 0, 512 * n_sec); + if (sec < FLASH_VENDOR_PART_START) { + count = FLASH_VENDOR_PART_START - sec; + buf = p_data; + ret = snor_read(&sfnor_dev, sec, count, buf); + } + if ((sec + n_sec - 1) > FLASH_VENDOR_PART_END) { + count = sec + n_sec - 1 - FLASH_VENDOR_PART_END; + offset = FLASH_VENDOR_PART_END - sec + 1; + buf = p_data + offset * 512; + ret = snor_read(&sfnor_dev, + FLASH_VENDOR_PART_END + 1, + count, buf); + } + } + + return (u32)ret == n_sec ? 0 : ret; +} + +int snor_write_lba(u32 sec, u32 n_sec, void *p_data) +{ + int ret = 0; + + ret = snor_write(&sfnor_dev, sec, n_sec, p_data); + + return (u32)ret == n_sec ? 0 : ret; +} + +int snor_vendor_read(u32 sec, u32 n_sec, void *p_data) +{ + int ret = 0; + + ret = snor_read(&sfnor_dev, sec, n_sec, p_data); + + return (u32)ret == n_sec ? 0 : ret; +} + +int snor_vendor_write(u32 sec, u32 n_sec, void *p_data) +{ + int ret = 0; + + ret = snor_write(&sfnor_dev, sec, n_sec, p_data); + + return (u32)ret == n_sec ? 0 : ret; +} + +unsigned int snor_capacity(void) +{ + return snor_get_capacity(&sfnor_dev); +} + +void snor_deinit(void) +{ + snor_disable_QE(&sfnor_dev); + snor_reset_device(); +} + +int snor_resume(void __iomem *reg_addr) +{ + return snor_init(&sfnor_dev); +} diff --git a/drivers/rkflash/sfc_nor_boot.h b/drivers/rkflash/sfc_nor_boot.h new file mode 100644 index 000000000000..a06dcd5c4dc1 --- /dev/null +++ b/drivers/rkflash/sfc_nor_boot.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#ifndef _SFC_NOR_BOOT_H +#define _SFC_NOR_BOOT_H + +int spi_flash_init(void __iomem *reg_addr); +void spi_flash_read_id(u8 chip_sel, void *buf); +int snor_read_lba(unsigned int sec, unsigned int n_sec, void *p_data); +int snor_write_lba(unsigned int sec, unsigned int n_sec, void *p_data); +unsigned int snor_capacity(void); +void snor_deinit(void); +int snor_resume(void __iomem *reg_addr); +int snor_vendor_read(unsigned int sec, unsigned int n_sec, void *p_data); +int snor_vendor_write(unsigned int sec, unsigned int n_sec, void *p_data); + +#endif + diff --git a/drivers/rkflash/sfc_nor_mtd.c b/drivers/rkflash/sfc_nor_mtd.c new file mode 100644 index 000000000000..aefb2923ae56 --- /dev/null +++ b/drivers/rkflash/sfc_nor_mtd.c @@ -0,0 +1,224 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#include +#include +#include +#include +#include + +#include "sfc_nor.h" +#include "rkflash_blk.h" +#include "rkflash_debug.h" + +static struct mtd_partition nor_parts[MAX_PART_COUNT]; + +static inline struct SFNOR_DEV *mtd_to_sfc(struct mtd_info *ptr_mtd) +{ + return (struct SFNOR_DEV *)((char *)ptr_mtd - + offsetof(struct SFNOR_DEV, mtd)); +} + +static int sfc_erase_mtd(struct mtd_info *mtd, struct erase_info *instr) +{ + int ret; + struct SFNOR_DEV *p_dev = mtd_to_sfc(mtd); + u32 addr, len; + u32 rem; + + if ((instr->addr + instr->len) > p_dev->capacity << 9) + return -EINVAL; + + div_u64_rem(instr->len, mtd->erasesize, &rem); + if (rem) + return -EINVAL; + + mutex_lock(&p_dev->lock); + + addr = instr->addr; + len = instr->len; + + if (len == p_dev->mtd.size) { + ret = snor_erase(p_dev, 0, CMD_CHIP_ERASE); + if (ret) { + PRINT_SFC_E("snor_erase CHIP 0x%x ret=%d\n", + addr, ret); + instr->state = MTD_ERASE_FAILED; + mutex_unlock(&p_dev->lock); + return -EIO; + } + } else { + while (len > 0) { + ret = snor_erase(p_dev, addr, ERASE_BLOCK64K); + if (ret) { + PRINT_SFC_E("snor_erase 0x%x ret=%d\n", + addr, ret); + instr->state = MTD_ERASE_FAILED; + mutex_unlock(&p_dev->lock); + return -EIO; + } + addr += mtd->erasesize; + len -= mtd->erasesize; + } + } + + mutex_unlock(&p_dev->lock); + + instr->state = MTD_ERASE_DONE; + mtd_erase_callback(instr); + + return 0; +} + +static int sfc_write_mtd(struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) +{ + int status; + u32 addr, size, chunk, padding; + u32 page_align; + struct SFNOR_DEV *p_dev = mtd_to_sfc(mtd); + + if ((to + len) > p_dev->capacity << 9) + return -EINVAL; + + mutex_lock(&p_dev->lock); + + addr = to; + size = len; + + while (size > 0) { + page_align = addr & (NOR_PAGE_SIZE - 1); + chunk = size; + if (chunk > (NOR_PAGE_SIZE - page_align)) + chunk = NOR_PAGE_SIZE - page_align; + memcpy(p_dev->dma_buf, buf, chunk); + padding = 0; + if (chunk < NOR_PAGE_SIZE) { + /* 4 bytes algin */ + padding = ((chunk + 3) & 0xFFFC) - chunk; + memset(p_dev->dma_buf + chunk, 0xFF, padding); + } + status = snor_prog_page(p_dev, addr, p_dev->dma_buf, + chunk + padding); + if (status != SFC_OK) { + PRINT_SFC_E("snor_prog_page %x ret= %d\n", + addr, status); + *retlen = len - size; + mutex_unlock(&p_dev->lock); + return status; + } + + size -= chunk; + addr += chunk; + buf += chunk; + } + *retlen = len; + mutex_unlock(&p_dev->lock); + + return 0; +} + +static int sfc_read_mtd(struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) +{ + u32 addr, size, chunk; + u8 *p_buf = (u8 *)buf; + int ret = SFC_OK; + + struct SFNOR_DEV *p_dev = mtd_to_sfc(mtd); + + if ((from + len) > p_dev->capacity << 9) + return -EINVAL; + + mutex_lock(&p_dev->lock); + + addr = from; + size = len; + + while (size > 0) { + chunk = (size < NOR_PAGE_SIZE) ? size : NOR_PAGE_SIZE; + ret = snor_read_data(p_dev, addr, p_dev->dma_buf, chunk); + if (ret != SFC_OK) { + PRINT_SFC_E("snor_read_data %x ret=%d\n", addr, ret); + *retlen = len - size; + mutex_unlock(&p_dev->lock); + return ret; + } + memcpy(p_buf, p_dev->dma_buf, chunk); + size -= chunk; + addr += chunk; + p_buf += chunk; + } + + *retlen = len; + mutex_unlock(&p_dev->lock); + return 0; +} + +int sfc_nor_mtd_init(struct SFNOR_DEV *p_dev) +{ + int ret, i, part_num = 0; + int capacity; + struct STRUCT_PART_INFO *g_part; /* size 2KB */ + + capacity = p_dev->capacity; + p_dev->mtd.name = "sfc_nor"; + p_dev->mtd.type = MTD_NORFLASH; + p_dev->mtd.writesize = 1; + p_dev->mtd.flags = MTD_CAP_NORFLASH; + /* see snor_write */ + p_dev->mtd.size = capacity << 9; + p_dev->mtd._erase = sfc_erase_mtd; + p_dev->mtd._read = sfc_read_mtd; + p_dev->mtd._write = sfc_write_mtd; + p_dev->mtd.erasesize = g_spi_flash_info->block_size << 9; + p_dev->mtd.writebufsize = NOR_PAGE_SIZE; + + p_dev->dma_buf = kmalloc(NOR_PAGE_SIZE, GFP_KERNEL | GFP_DMA); + if (!p_dev->dma_buf) { + PRINT_SFC_E("kmalloc size=0x%x failed\n", NOR_PAGE_SIZE); + ret = -ENOMEM; + goto out; + } + + g_part = kmalloc(sizeof(*g_part), GFP_KERNEL | GFP_DMA); + if (!g_part) { + ret = -ENOMEM; + goto free_dma_buf; + } + part_num = 0; + if (snor_read(p_dev, 0, 4, g_part) == 0) { + if (g_part->hdr.ui_fw_tag == RK_PARTITION_TAG) { + part_num = g_part->hdr.ui_part_entry_count; + for (i = 0; i < part_num; i++) { + nor_parts[i].name = + kstrdup(g_part->part[i].sz_name, + GFP_KERNEL); + if (g_part->part[i].ui_pt_sz == 0xFFFFFFFF) + g_part->part[i].ui_pt_sz = capacity - + g_part->part[i].ui_pt_off; + nor_parts[i].offset = + (u64)g_part->part[i].ui_pt_off << 9; + nor_parts[i].size = + (u64)g_part->part[i].ui_pt_sz << 9; + nor_parts[i].mask_flags = 0; + } + } + } + kfree(g_part); + if (part_num == 0) { + ret = -1; + goto free_dma_buf; + } + ret = mtd_device_register(&p_dev->mtd, nor_parts, part_num); + if (ret != 0) + goto free_dma_buf; + return ret; + +free_dma_buf: + kfree(p_dev->dma_buf); +out: + return ret; +} + diff --git a/drivers/rkflash/typedef.h b/drivers/rkflash/typedef.h new file mode 100644 index 000000000000..3ec5da308980 --- /dev/null +++ b/drivers/rkflash/typedef.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */ + +#ifndef __TYPE_DEF_H +#define __TYPE_DEF_H + +#include + +#ifndef NULL +#define NULL 0 +#endif + +#define OK 0 +#define ERROR (-1) + +#define FTL_ERROR ERROR +#define FTL_OK OK +#define FTL_NO_FLASH -2 +#define FTL_NO_IDB -3 +#define FTL_UNSUPPORTED_FLASH -4 + +#define FALSE 0 +#define TRUE (!FALSE) + +#define INVALID_UINT8 ((u8)0xFF) +#define INVALID_UINT16 ((u16)0xFFFF) +#define INVALID_UINT32 ((u32)0xFFFFFFFFL) + +#define PRINT_E pr_info +#define PRINT_I pr_info + +void *ftl_malloc(int n_size); +void *ftl_memset(void *s, int c, unsigned int n); +void *ftl_memcpy(void *pv_to, + const void *pv_from, + unsigned int size); +void ftl_free(void *p, int size); +void rknand_print_hex(char *s, void *buf, int width, int len); + +#endif /*__TYPEDEF_H */