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-20 03:53:42 +0000
commita33c1207ce871b24d39b9b7da89b50ca605107d5 (patch)
treef7cb9b4d999e2de625d1cb9825e91023aa706c1a
parent7df328dc8ab9d5cd424a8e16f09177e4cd5a46d5 (diff)
downloadchrome-ec-a33c1207ce871b24d39b9b7da89b50ca605107d5.tar.gz
it8xxx2: The "M" extension is disabled by default
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/+/3707071 Tested-by: Tommy Chung <tommy.chung@quanta.corp-partner.google.com> Commit-Queue: Eric Yilun Lin <yllin@google.com> Auto-Submit: Tommy Chung <tommy.chung@quanta.corp-partner.google.com>
-rw-r--r--board/drawcia_riscv/board.h7
-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
6 files changed, 67 insertions, 0 deletions
diff --git a/board/drawcia_riscv/board.h b/board/drawcia_riscv/board.h
index 529b8fccdc..5dd3c916de 100644
--- a/board/drawcia_riscv/board.h
+++ b/board/drawcia_riscv/board.h
@@ -19,6 +19,13 @@
#define CONFIG_LTO
+/*
+ * The workaround can be enabled on a chip variant with 1MB flash.
+ * (There is relocation truncated to fit error when building this board)
+ */
+#define CONFIG_RISCV_EXTENSION_M
+#undef CONFIG_IT8XXX2_MUL_WORKAROUND
+
#undef GPIO_VOLUME_UP_L
#define GPIO_VOLUME_UP_L GPIO_VOLUP_BTN_ODL_HDMI_HPD
diff --git a/chip/it83xx/config_chip_it8xxx2.h b/chip/it83xx/config_chip_it8xxx2.h
index 8716380f29..0bbfe89b59 100644
--- a/chip/it83xx/config_chip_it8xxx2.h
+++ b/chip/it83xx/config_chip_it8xxx2.h
@@ -87,6 +87,13 @@
|| defined(CHIP_VARIANT_IT81302BX_512) \
|| defined(CHIP_VARIANT_IT81202BX_1024)
+/*
+ * 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
+
#if defined(CHIP_VARIANT_IT81302BX_512)
#define CONFIG_FLASH_SIZE_BYTES 0x00080000
#define CONFIG_RAM_BASE 0x80080000
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 244ab4c57c..41bf31fe93 100644
--- a/include/config.h
+++ b/include/config.h
@@ -2833,6 +2833,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 90648e81b5..bb9843409d 100644
--- a/util/config_allowed.txt
+++ b/util/config_allowed.txt
@@ -585,6 +585,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