-
-
Notifications
You must be signed in to change notification settings - Fork 7.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tests/run-tests, ports/qemu-riscv: Add QEMU RV32 port.
This adds a QEMU-based bare metal RISC-V 32 bits port. For the time being only QEMU's "virt" 32 bits board is supported, using the ilp32 ABI and the RV32IMC architecture. Tests run and pass, and the test generator framework was modified to remove hardcoded references to the "qemu-arm" port. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
- Loading branch information
Showing
18 changed files
with
1,072 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
include ../../py/mkenv.mk | ||
-include mpconfigport.mk | ||
|
||
# qstr definitions (must come before including py.mk) | ||
QSTR_DEFS = qstrdefsport.h | ||
|
||
# MicroPython feature configurations | ||
MICROPY_ROM_TEXT_COMPRESSION ?= 1 | ||
|
||
# include py core make definitions | ||
include $(TOP)/py/py.mk | ||
include $(TOP)/extmod/extmod.mk | ||
|
||
CROSS_COMPILE ?= riscv64-unknown-elf- | ||
|
||
BOARD ?= virt | ||
LDFLAGS = --gc-sections -Map=$(@:.elf=.map) | ||
LIBS = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) | ||
|
||
ifeq ($(BOARD),virt) | ||
ABI=ilp32 | ||
ARCH=rv32imc_zicsr | ||
AFLAGS = -mabi=$(ABI) -march=$(ARCH) | ||
CFLAGS += -mabi=$(ABI) -fPIC -mlittle-endian -march=$(ARCH) -mcmodel=medany | ||
CFLAGS += -DQEMU_SOC_VIRT | ||
LDSCRIPT = virt.ld | ||
LDFLAGS += -T $(LDSCRIPT) -m elf32lriscv | ||
SRC_BOARD_O = shared/runtime/gchelper_generic.o setjmp.o | ||
SRC_BOARD_O += entry.o | ||
endif | ||
|
||
INC += -I. | ||
INC += -I$(TOP) | ||
INC += -I$(BUILD) | ||
|
||
CFLAGS += $(INC) -Wall -Wpointer-arith -Wdouble-promotion -Wfloat-conversion -Werror -std=gnu99 $(COPT) \ | ||
-ffunction-sections -fdata-sections | ||
CFLAGS += $(CFLAGS_EXTRA) | ||
|
||
# Debugging/Optimization | ||
ifeq ($(DEBUG), 1) | ||
CFLAGS += -g | ||
COPT = -O0 | ||
else | ||
COPT += -Os -DNDEBUG | ||
endif | ||
|
||
SRC_COMMON_C = \ | ||
interrupts.c \ | ||
startup.c \ | ||
uart.c \ | ||
modmachine.c \ | ||
shared/libc/string0.c \ | ||
shared/runtime/sys_stdio_mphal.c \ | ||
|
||
SRC_RUN_C = \ | ||
main.c \ | ||
|
||
SRC_TEST_C = \ | ||
test_main.c \ | ||
lib/tinytest/tinytest.c \ | ||
|
||
LIB_SRC_C += $(addprefix lib/,\ | ||
libm/math.c \ | ||
libm/fmodf.c \ | ||
libm/nearbyintf.c \ | ||
libm/ef_sqrt.c \ | ||
libm/kf_rem_pio2.c \ | ||
libm/kf_sin.c \ | ||
libm/kf_cos.c \ | ||
libm/kf_tan.c \ | ||
libm/ef_rem_pio2.c \ | ||
libm/sf_sin.c \ | ||
libm/sf_cos.c \ | ||
libm/sf_tan.c \ | ||
libm/sf_frexp.c \ | ||
libm/sf_modf.c \ | ||
libm/sf_ldexp.c \ | ||
libm/asinfacosf.c \ | ||
libm/atanf.c \ | ||
libm/atan2f.c \ | ||
libm/roundf.c \ | ||
) | ||
|
||
OBJ_COMMON = | ||
OBJ_COMMON += $(PY_O) | ||
OBJ_COMMON += $(addprefix $(BUILD)/, $(SRC_COMMON_C:.c=.o)) | ||
OBJ_COMMON += $(addprefix $(BUILD)/, $(SRC_BOARD_O)) | ||
OBJ_COMMON += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o)) | ||
|
||
OBJ_RUN = | ||
OBJ_RUN += $(addprefix $(BUILD)/, $(SRC_RUN_C:.c=.o)) | ||
|
||
ALL_OBJ_RUN = $(OBJ_COMMON) $(OBJ_RUN) | ||
|
||
OBJ_TEST = | ||
OBJ_TEST += $(addprefix $(BUILD)/, $(SRC_TEST_C:.c=.o)) | ||
|
||
ALL_OBJ_TEST = $(OBJ_COMMON) $(OBJ_TEST) | ||
|
||
# All object files, needed to get dependencies correct | ||
OBJ = $(OBJ_COMMON) $(OBJ_RUN) $(OBJ_TEST) | ||
|
||
# List of sources for qstr extraction | ||
SRC_QSTR += $(SRC_COMMON_C) $(SRC_RUN_C) $(LIB_SRC_C) | ||
|
||
all: run | ||
|
||
debug: $(BUILD)/firmware.elf | ||
qemu-system-riscv32 -machine $(BOARD) -bios none $(QEMU_EXTRA) -nographic -monitor null -semihosting -serial mon:stdio -S -s -kernel $< | ||
|
||
run: $(BUILD)/firmware.elf | ||
qemu-system-riscv32 -machine $(BOARD) -bios none $(QEMU_EXTRA) -nographic -monitor null -semihosting -kernel $< | ||
|
||
## `$(LD)` doesn't seem to like `--specs` for some reason, but we can just use `$(CC)` here. | ||
$(BUILD)/firmware.elf: $(LDSCRIPT) $(ALL_OBJ_RUN) | ||
$(Q)$(LD) $(LDFLAGS) -o $@ $(ALL_OBJ_RUN) $(LIBS) | ||
$(Q)$(SIZE) $@ | ||
|
||
include $(TOP)/py/mkrules.mk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
LIB_SRC_C = shared/upytesthelper/upytesthelper.c | ||
|
||
include Makefile | ||
|
||
ifeq ($(BOARD),virt) | ||
TESTS_EXCLUDE = extmod/deflate_decompress.py | ||
endif | ||
|
||
CFLAGS += -DTEST | ||
|
||
.PHONY: $(BUILD)/genhdr/tests.h | ||
|
||
TESTS_PROFILE = $(dir $(abspath $(firstword $(MAKEFILE_LIST))))/tests_profile.txt | ||
|
||
$(BUILD)/test_main.o: $(BUILD)/genhdr/tests.h | ||
$(BUILD)/genhdr/tests.h: | ||
(cd $(TOP)/tests; ./run-tests.py --target=qemu-riscv --write-exp) | ||
$(Q)echo "Generating $@";(cd $(TOP)/tests; ../tools/tinytest-codegen.py --profile $(TESTS_PROFILE) $(addprefix --exclude ,$(TESTS_EXCLUDE))) > $@ | ||
|
||
$(BUILD)/lib/tinytest/tinytest.o: CFLAGS += -DNO_FORKING | ||
|
||
$(BUILD)/firmware-test.elf: $(LDSCRIPT) $(ALL_OBJ_TEST) | ||
$(Q)$(LD) $(LDFLAGS) -o $@ $(ALL_OBJ_TEST) $(LIBS) | ||
$(Q)$(SIZE) $@ | ||
|
||
# Note: Using timeout(1) to handle cases where qemu hangs (e.g. this can happen with alignment errors). | ||
test: $(BUILD)/firmware-test.elf | ||
timeout --foreground -k 5s 60s qemu-system-riscv32 -machine $(BOARD) -bios none $(QEMU_EXTRA) -nographic -monitor null -semihosting -kernel $< > $(BUILD)/console.out | ||
$(Q)tail -n2 $(BUILD)/console.out | ||
$(Q)tail -n1 $(BUILD)/console.out | grep -q "status: 0" | ||
|
||
debugtest: $(BUILD)/firmware-test.elf | ||
qemu-system-riscv32 -machine $(BOARD) -bios none $(QEMU_EXTRA) -nographic -monitor null -semihosting -serial mon:stdio -S -s -kernel $< | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
This is experimental, community-supported port for RISC-V RV32IM emulation as | ||
provided by QEMU (http://qemu.org). | ||
|
||
The purposes of this port are to enable: | ||
|
||
1. Continuous integration | ||
- run tests against architecture-specific parts of code base | ||
2. Experimentation | ||
- simulation & prototyping of anything that has architecture-specific | ||
code | ||
- exploring instruction set in terms of optimising some part of | ||
MicroPython or a module | ||
3. Streamlined debugging | ||
- no need for JTAG or even an MCU chip itself | ||
- no need to use OpenOCD or anything else that might slow down the | ||
process in terms of plugging things together, pressing buttons, etc. | ||
|
||
This port requires a newlib based bare metal/ELF RISC-V toolchain, either | ||
with multilib support or 32 bits specific (M, C, and Zicsr extensions must | ||
be supported, along with ilp32 ABI). Either musl-based or glibc-based | ||
toolchains are not tested or known to work. | ||
|
||
If your toolchain does not support the above requirements, either download | ||
a pre-built toolchain (and that's a hit or miss situation in its own right) | ||
or follow the instructions on [RISC-V's reference toolchain Github repo](https://github.com/riscv-collab/riscv-gnu-toolchain) | ||
to get a newlib-based multilib toolchain (the target will be | ||
`riscv64-unknown-elf` but said toolchain will be able to generate 32 bits | ||
code as well). | ||
|
||
That said, when in doubt, build your own toolchain - it's the fastest way to | ||
get things going for sure. | ||
|
||
To build and run image with builtin testsuite: | ||
|
||
make -f Makefile.test test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
Adapted from https://wiki.osdev.org/RISC-V_Bare_Bones#entry.S | ||
According to the page history, this content was added after 20110703, and | ||
following the text found at https://wiki.osdev.org/OSDev_Wiki:License the | ||
overall licence for this code is as follows: | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. | ||
*/ | ||
|
||
.section .init | ||
.option norvc | ||
.type start, @function | ||
.global start | ||
|
||
start: | ||
.cfi_startproc | ||
|
||
.option push | ||
.option norelax | ||
|
||
la gp, global_pointer | ||
|
||
.option pop | ||
|
||
csrw satp, zero | ||
la sp, stack_top | ||
la t5, bss_start | ||
la t6, bss_end | ||
|
||
bss_clear: | ||
sw zero, (t5) | ||
addi t5, t5, 4 | ||
bltu t5, t6, bss_clear | ||
|
||
la t0, _entry_point | ||
csrw mepc, t0 | ||
|
||
tail _entry_point | ||
|
||
.cfi_endproc | ||
.end | ||
|
Oops, something went wrong.