diff options
author | Dino Li <Dino.Li@ite.com.tw> | 2022-06-06 15:59:08 +0800 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-06-20 03:53:42 +0000 |
commit | a33c1207ce871b24d39b9b7da89b50ca605107d5 (patch) | |
tree | f7cb9b4d999e2de625d1cb9825e91023aa706c1a | |
parent | 7df328dc8ab9d5cd424a8e16f09177e4cd5a46d5 (diff) | |
download | chrome-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.h | 7 | ||||
-rw-r--r-- | chip/it83xx/config_chip_it8xxx2.h | 7 | ||||
-rw-r--r-- | core/riscv-rv32i/__it8xxx2_arithmetic.S | 45 | ||||
-rw-r--r-- | core/riscv-rv32i/build.mk | 1 | ||||
-rw-r--r-- | include/config.h | 6 | ||||
-rw-r--r-- | util/config_allowed.txt | 1 |
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 |