summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDino Li <Dino.Li@ite.com.tw>2018-12-07 10:49:57 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-12-10 12:34:28 -0800
commit080075c076d9c3daabb050abfe9d71b55b585656 (patch)
treed59bbbe3570b322259be40e33c9f6459fe70ad9d
parentc8f2c6b13fda5f2e943c1f978b2da63182891ac5 (diff)
downloadchrome-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.c37
-rw-r--r--chip/it83xx/flash_chip.h3
-rw-r--r--core/nds32/ec.lds.S1
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);