Skip to content

Commit 6d9d9cd

Browse files
committed
qemu: Emit Zcmt opcodes by default for RV32 boards.
This commit updates the configuration for RISC-V 32-bit boards to always emit Zcmt opcodes when it comes to natively compiled functions. QEMU's CPU configuration was changed accordingly, with Zcmt opcodes also sharing opcode space with the Zcd instructions (just like Zcmp ones). The entry point for the port will also perform the necessary initialisation steps to create a suitable function table in RAM that can be used for Zcmt opcodes, and also sets up the appropriate CPU registers in order to make jump opcodes read the correct address. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
1 parent 3a8de5d commit 6d9d9cd

3 files changed

Lines changed: 19 additions & 2 deletions

File tree

ports/qemu/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,14 @@ GCC_VERSION = $(word 1, $(subst ., , $(shell $(CC) -dumpversion)))
105105

106106
RV32_ABI = ilp32
107107

108-
QEMU_ARGS += -bios none -cpu rv32,zcd=off,zcmp=on
108+
QEMU_ARGS += -bios none -cpu rv32,zcd=off,zcmp=on,zcmt=on
109109

110110
# GCC 10 and lower do not recognise the Zicsr extension in the architecture name.
111111
ifeq ($(shell test $(GCC_VERSION) -le 10; echo $$?),0)
112112
RV32_ARCH ?= rv32imac
113113
else
114114
# Recent GCC versions explicitly require to declare extensions.
115-
RV32_ARCH ?= rv32imac_zicsr
115+
RV32_ARCH ?= rv32imac_zicsr_zifencei
116116
endif
117117

118118
AFLAGS += -mabi=$(RV32_ABI) -march=$(RV32_ARCH)

ports/qemu/mcu/rv32/startup.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,28 @@
2929
#include <stdlib.h>
3030

3131
#include "uart.h"
32+
#include "mpconfigport.h"
3233

3334
extern void set_interrupt_table(void);
3435
extern int main(int argc, char **argv);
36+
extern const uintptr_t mp_fun_table;
3537

3638
void _entry_point(void) {
3739
// Set interrupt table
3840
set_interrupt_table();
41+
#if MICROPY_EMIT_RV32_ZCMT
42+
// Relocate the table address to always perform a jump and link (index has
43+
// to be between 32 and 255), so that calling function index #32 will perform
44+
// a jump-and-link to the real function at index #0 (see §28.14.5).
45+
__asm volatile (
46+
// Use the JVT CSR index directly for compatibility.
47+
"csrw 0x017, %0 \n"
48+
"fence.i \n"
49+
:
50+
: "r" ((ptrdiff_t)&mp_fun_table - (ptrdiff_t)(32 * sizeof(uintptr_t)))
51+
: "memory"
52+
);
53+
#endif
3954
// Enable UART
4055
uart_init();
4156
// Now that we have a basic system up and running we can call main

ports/qemu/mpconfigport.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
#define MICROPY_EMIT_RV32 (1)
4545
#define MICROPY_EMIT_RV32_ZBA (1)
4646
#define MICROPY_EMIT_RV32_ZCMP (1)
47+
#define MICROPY_EMIT_RV32_ZCMT (1)
48+
#define MICROPY_NATIVE_FUN_TABLE_ALIGNMENT (64)
4749
#define MICROPY_EMIT_INLINE_RV32 (1)
4850
#elif (__riscv_xlen == 64)
4951
#define MICROPY_PERSISTENT_CODE_LOAD_NATIVE (1)

0 commit comments

Comments
 (0)