Skip to content

Commit eaff145

Browse files
stephan-ghTravMurav
authored andcommitted
platform: msm_shared: qpic_nand: Skip writing trailing 0xFF pages for EFS
At the moment, attempting to restore a backup of the EFS2 partitions for the modem corrupts it, e.g. $ fastboot fetch efs2 efs2.img $ fasbtoot flash efs2 efs2.img $ fastboot reboot qcom-q6v5-mss 4080000.remoteproc: fatal error received: fs_logr.c:114:Ran out of good blocks in log-rgn XY It looks like the mdoem relies on having erased ("good") blocks to write to. The current flash_write() routine blindly writes all pages, so if there was an erased page with all 0xFF in the input, it is still explicitly written rather than leaving the page erased. To write these pages, the modem would need to erase the whole block (consisting of multiple pages) and re-write all pages in the beginning. We can't reliably distinguish between an explicitly written all-0xFF page and an erased page in the image, so let's just assume that all trailing 0xFF pages at the end of a block were erased and leave them that way when flashing. Apply this behavior only for the "efs2" partition, since most other partitions (e.g. "boot", "aboot", "sbl1" etc) contain actual file images were explicitly writing all-0xFF pages makes more sense. This is similar to the "nandwrite --skip-all-ffs" option on Linux, except that we only consider trailing all-0xFF pages in a block. This is unlikely to make much difference in practice, but it seems to be closer to how the modem firmware is managing the EFS partition.
1 parent f08af0c commit eaff145

1 file changed

Lines changed: 38 additions & 1 deletion

File tree

platform/msm_shared/qpic_nand.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2105,18 +2105,37 @@ flash_ecc_bch_enabled(void)
21052105
return (flash.ecc_width == NAND_WITH_4_BIT_ECC)? 0 : 1;
21062106
}
21072107

2108+
static uint32_t find_num_pages_to_write(const uint8_t *data, uint32_t num_pages, uint32_t wsize)
2109+
{
2110+
data += num_pages * wsize; /* Go to end of block */
2111+
2112+
/* Scan backward page-by-page, checking if any byte is not 0xFF */
2113+
while (num_pages > 0) {
2114+
data -= wsize; /* Go back one page */
2115+
for (uint32_t i = 0; i < wsize; i++)
2116+
if (data[i] != 0xff)
2117+
return num_pages;
2118+
--num_pages;
2119+
}
2120+
return 0; /* Entire block is empty 0xFF, write 0 pages */
2121+
}
2122+
21082123
int
21092124
flash_write(struct ptentry *ptn,
21102125
unsigned write_extra_bytes,
21112126
const void *data,
21122127
unsigned bytes)
21132128
{
2129+
/* EFS2 expects empty 0xFF pages to remain erased */
2130+
bool skip_trailing_0xff = strcmp(ptn->name, "efs2") == 0;
21142131
uint32_t page = ptn->start * flash.num_pages_per_blk;
21152132
uint32_t lastpage = (ptn->start + ptn->length) * flash.num_pages_per_blk;
2133+
uint32_t num_pages_to_write = flash.num_pages_per_blk;
21162134
uint32_t *spare = (unsigned *)flash_spare_bytes;
21172135
const unsigned char *image = data;
21182136
uint32_t wsize;
21192137
uint32_t spare_byte_count = 0;
2138+
uint32_t pages_avail = 0;
21202139
int r;
21212140

21222141
spare_byte_count = ((flash.cw_size * flash.cws_per_page)- flash.page_size);
@@ -2130,6 +2149,8 @@ flash_write(struct ptentry *ptn,
21302149

21312150
while (bytes > 0)
21322151
{
2152+
uint32_t page_in_blk;
2153+
21332154
if (bytes < wsize)
21342155
{
21352156
dprintf(CRITICAL,
@@ -2145,7 +2166,8 @@ flash_write(struct ptentry *ptn,
21452166
return -1;
21462167
}
21472168

2148-
if ((page & flash.num_pages_per_blk_mask) == 0)
2169+
page_in_blk = page & flash.num_pages_per_blk_mask;
2170+
if (page_in_blk == 0)
21492171
{
21502172
if (qpic_nand_blk_erase(page))
21512173
{
@@ -2156,6 +2178,21 @@ flash_write(struct ptentry *ptn,
21562178
page += flash.num_pages_per_blk;
21572179
continue;
21582180
}
2181+
2182+
pages_avail = MIN(bytes / wsize, flash.num_pages_per_blk);
2183+
if (skip_trailing_0xff)
2184+
num_pages_to_write = find_num_pages_to_write(image, pages_avail, wsize);
2185+
}
2186+
2187+
if (page_in_blk >= num_pages_to_write)
2188+
{
2189+
uint32_t skip = pages_avail - page_in_blk;
2190+
dprintf(INFO, "flash_write_image: Block %u: wrote %u pages, skipping %u trailing 0xFF pages (%u-%u)\n",
2191+
page / flash.num_pages_per_blk, page_in_blk, skip, page, page + skip - 1);
2192+
page += skip;
2193+
image += skip * wsize;
2194+
bytes -= skip * wsize;
2195+
continue;
21592196
}
21602197

21612198
memcpy(rdwr_buf, image, flash.page_size);

0 commit comments

Comments
 (0)