diff options
author | Dino Li <Dino.Li@ite.com.tw> | 2018-12-07 10:49:57 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-12-10 12:34:28 -0800 |
commit | 080075c076d9c3daabb050abfe9d71b55b585656 (patch) | |
tree | d59bbbe3570b322259be40e33c9f6459fe70ad9d | |
parent | c8f2c6b13fda5f2e943c1f978b2da63182891ac5 (diff) | |
download | chrome-ec-080075c076d9c3daabb050abfe9d71b55b585656.tar.gz |
it83xx: force filling cache if the last two 4KB blocks of 512KB flash are modified
After immu reset, we will fill the immu cache with 8KB data
that are outside address 0x7e000 ~ 0x7ffff.
When CPU tries to fetch contents from address 0x7e000 ~ 0x7ffff,
immu will re-fetch the missing contents inside 0x7e000 ~ 0x7ffff.
BUG=b:111808417, b:119799561
BRANCH=none
TEST=use console "flasherase" and "flashwrite" commands to erase/write
last two 4KB blocks(0x7e000 ~ 0x7ffff), no error message occurred.
Change-Id: Ia97c814f20d602c591c39040b964b122edd50205
Signed-off-by: Dino Li <Dino.Li@ite.com.tw>
Reviewed-on: https://chromium-review.googlesource.com/1365372
Reviewed-by: Diana Z <dzigterman@chromium.org>
-rw-r--r-- | chip/it83xx/flash.c | 37 | ||||
-rw-r--r-- | chip/it83xx/flash_chip.h | 3 | ||||
-rw-r--r-- | core/nds32/ec.lds.S | 1 |
3 files changed, 38 insertions, 3 deletions
diff --git a/chip/it83xx/flash.c b/chip/it83xx/flash.c index 40fa0d1925..dd50dc3803 100644 --- a/chip/it83xx/flash.c +++ b/chip/it83xx/flash.c @@ -34,6 +34,17 @@ /* Auto address increment programming */ #define FLASH_CMD_AAI_WORD 0xAD +#define FLASH_TEXT_START ((uint32_t) &__flash_text_start) +/* The default tag index of immu. */ +#define IMMU_TAG_INDEX_BY_DEFAULT 0x7E000 +/* immu cache size is 8K bytes. */ +#define IMMU_SIZE 0x2000 + +#if CONFIG_FLASH_SIZE == 0x80000 +/* Apply workaround of the issue (b:111808417) */ +#define IMMU_CACHE_TAG_INVALID +#endif + static int stuck_locked; static int inconsistent_locked; static int all_protected; @@ -79,7 +90,7 @@ enum dlm_address_view { SCAR12_ILM12_DLM12 = 0x8C000, /* DLM ~ 0x8CFFF immu cache */ }; -void FLASH_DMA_CODE dma_reset_immu(void) +void FLASH_DMA_CODE dma_reset_immu(int fill_immu) { /* Immu tag sram reset */ IT83XX_GCTRL_MCCR |= 0x10; @@ -87,6 +98,26 @@ void FLASH_DMA_CODE dma_reset_immu(void) asm volatile ("dsb"); IT83XX_GCTRL_MCCR &= ~0x10; asm volatile ("dsb"); + +#ifdef IMMU_CACHE_TAG_INVALID + /* + * Workaround for (b:111808417): + * After immu reset, we will fill the immu cache with 8KB data + * that are outside address 0x7e000 ~ 0x7ffff. + * When CPU tries to fetch contents from address 0x7e000 ~ 0x7ffff, + * immu will re-fetch the missing contents inside 0x7e000 ~ 0x7ffff. + */ + if (fill_immu) { + volatile int immu __unused; + const uint32_t *ptr = (uint32_t *)FLASH_TEXT_START; + int i = 0; + + while (i < IMMU_SIZE) { + immu = *ptr++; + i += sizeof(*ptr); + } + } +#endif } void FLASH_DMA_CODE dma_flash_follow_mode(void) @@ -367,7 +398,7 @@ int FLASH_DMA_CODE flash_physical_write(int offset, int size, const char *data) interrupt_disable(); dma_flash_aai_write(offset, size, data); - dma_reset_immu(); + dma_reset_immu((offset + size) >= IMMU_TAG_INDEX_BY_DEFAULT); ret = dma_flash_verify(offset, size, data); interrupt_enable(); @@ -405,7 +436,7 @@ int FLASH_DMA_CODE flash_physical_erase(int offset, int size) dma_flash_erase(offset, FLASH_CMD_SECTOR_ERASE); offset += FLASH_SECTOR_ERASE_SIZE; } - dma_reset_immu(); + dma_reset_immu((v_addr + v_size) >= IMMU_TAG_INDEX_BY_DEFAULT); ret = dma_flash_verify(v_addr, v_size, NULL); interrupt_enable(); diff --git a/chip/it83xx/flash_chip.h b/chip/it83xx/flash_chip.h index 558db82c27..4a604ed7f7 100644 --- a/chip/it83xx/flash_chip.h +++ b/chip/it83xx/flash_chip.h @@ -13,4 +13,7 @@ */ extern const char __flash_dma_start; +/* This symbol is the begin address of the text section. */ +extern const char __flash_text_start; + #endif /* __CROS_EC_FLASH_CHIP_H */ diff --git a/core/nds32/ec.lds.S b/core/nds32/ec.lds.S index 7048fe0cfd..926be4f788 100644 --- a/core/nds32/ec.lds.S +++ b/core/nds32/ec.lds.S @@ -48,6 +48,7 @@ SECTIONS ASSERT((__flash_dma_size < IT83XX_ILM_BLOCK_SIZE), "__flash_dma_size < IT83XX_ILM_BLOCK_SIZE"); . = ALIGN(IT83XX_ILM_BLOCK_SIZE); + __flash_text_start = .; *(.text*) } > FLASH . = ALIGN(4); |