summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDino Li <Dino.Li@ite.com.tw>2022-06-06 15:59:08 +0800
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-06-14 10:16:42 +0000
commit689870d95ca5318942bb6e653ebd2375ace32ab1 (patch)
treea41b9be58abbde49c3fdb8353b2bec4172de5a62
parent7453254050089ab085eda60c6d21c387fc29414a (diff)
downloadchrome-ec-firmware-icarus-12574.B.tar.gz
it8xxx2: The "M" extension is disabled by defaultfirmware-icarus-12574.B
There is a mul instruction bug. The bug may cause instructions of writing back CPU GPR (e.g mv a0,s2) which following the mul instruction to fail. This patch disables the 'M' extension and overwrite integer multiplication and division arithmetic library routines with using hardware multiplication and division and nop instructions. This will ensure that there is no write back GPR instruction to follow mul instruction to avoid the bug. BUG=b:235297478 BRANCH=asurada,cherry,icarus TEST=- buildall - The "M" extension is disabled on cherry image (-march=rv32iac) Signed-off-by: Dino Li <Dino.Li@ite.com.tw> Change-Id: I39b34a91dd77d975b78b6756494691c6b28dc42d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3690042 Reviewed-by: Eric Yilun Lin <yllin@google.com> (cherry picked from commit 4a2e334030cf936cc5bc59b034b8bbbb6aa55caa) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3705076
-rw-r--r--chip/it83xx/config_chip_it8xxx2.h7
-rw-r--r--core/riscv-rv32i/__it8xxx2_arithmetic.S45
-rw-r--r--core/riscv-rv32i/build.mk1
-rw-r--r--include/config.h6
-rw-r--r--util/config_allowed.txt1
5 files changed, 60 insertions, 0 deletions
diff --git a/chip/it83xx/config_chip_it8xxx2.h b/chip/it83xx/config_chip_it8xxx2.h
index 3f715380ac..345a248867 100644
--- a/chip/it83xx/config_chip_it8xxx2.h
+++ b/chip/it83xx/config_chip_it8xxx2.h
@@ -86,6 +86,13 @@
#define CONFIG_RAM_BASE 0x80100000
#define CONFIG_RAM_SIZE 0x0000f000
+/*
+ * Workaround mul instruction bug, see:
+ * https://www.ite.com.tw/uploads/product_download/it81202-bx-chip-errata.pdf
+ */
+#undef CONFIG_RISCV_EXTENSION_M
+#define CONFIG_IT8XXX2_MUL_WORKAROUND
+
/* Embedded flash is KGD */
#define IT83XX_CHIP_FLASH_IS_KGD
/* Set ILM (instruction local memory) size up to 1M bytes */
diff --git a/core/riscv-rv32i/__it8xxx2_arithmetic.S b/core/riscv-rv32i/__it8xxx2_arithmetic.S
new file mode 100644
index 0000000000..8e477863fc
--- /dev/null
+++ b/core/riscv-rv32i/__it8xxx2_arithmetic.S
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2022 The ChromiumOS Authors.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * When the 'M' extension is disabled, compiler can not recognize div/mul
+ * instructions. So mul/div instructions in the below integer arithmetic
+ * routines are hard coded by opcodes.
+ *
+ * IMPORTANT:
+ * The workaround requires the nop instruction, please don't optimize it.
+ */
+
+.macro __int_arithmetic func opcode
+.section .ram_code_ilm0
+.align 2
+.globl \func
+.type \func, @function
+\func:
+.word \opcode
+nop
+ret
+.size \func, .-\func
+.endm
+
+/* signed 32 bit multiplication. opcode of mul a0,a0,a1 is 0x02b50533 */
+__int_arithmetic __mulsi3 0x02b50533
+
+/* signed 32 bit division. opcode of div a0,a0,a1 is 0x02b54533 */
+__int_arithmetic __divsi3 0x02b54533
+
+/* unsigned 32 bit division. opcode of divu a0,a0,a1 is 0x02b55533 */
+__int_arithmetic __udivsi3 0x02b55533
+
+/*
+ * This function return the remainder of the signed division.
+ * opcode of rem a0,a0,a1 is 0x02b56533
+ */
+__int_arithmetic __modsi3 0x02b56533
+
+/*
+ * This function return the remainder of the unsigned division.
+ * opcode of remu a0,a0,a1 is 0x02b57533
+ */
+__int_arithmetic __umodsi3 0x02b57533
diff --git a/core/riscv-rv32i/build.mk b/core/riscv-rv32i/build.mk
index 376bd2c093..7e5ce0e8a7 100644
--- a/core/riscv-rv32i/build.mk
+++ b/core/riscv-rv32i/build.mk
@@ -30,3 +30,4 @@ LDFLAGS_EXTRA+=-flto
endif
core-y=cpu.o init.o panic.o task.o switch.o __builtin.o math.o
+core-$(CONFIG_IT8XXX2_MUL_WORKAROUND)+=__it8xxx2_arithmetic.o
diff --git a/include/config.h b/include/config.h
index ee84db0291..cb364d5516 100644
--- a/include/config.h
+++ b/include/config.h
@@ -2643,6 +2643,12 @@
#undef CONFIG_IT83XX_VCC_3P3V
/*
+ * Overwrite integer multiplication and division arithmetic library routines
+ * with using hardware multiplication and division and nop instructions.
+ */
+#undef CONFIG_IT8XXX2_MUL_WORKAROUND
+
+/*
* Support the standard integer multiplication and division instruction
* extension.
*/
diff --git a/util/config_allowed.txt b/util/config_allowed.txt
index e28bd5f39c..3405570a72 100644
--- a/util/config_allowed.txt
+++ b/util/config_allowed.txt
@@ -609,6 +609,7 @@ CONFIG_IT83XX_SMCLK2_ON_GPC7
CONFIG_IT83XX_TUNE_CC_PHY
CONFIG_IT83XX_VCC_1P8V
CONFIG_IT83XX_VCC_3P3V
+CONFIG_IT8XXX2_MUL_WORKAROUND
CONFIG_ITE_FLASH_SUPPORT
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT
CONFIG_KEYBOARD_ASSISTANT_KEY