summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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