diff options
-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 |
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 |