-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Merge qemu-riscv port functionality into qemu-arm port #15743
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
920e4c0
to
74b6a80
Compare
@agatti I would appreciate your comments/review of this, thanks! |
#define MICROPY_PY_SYS_PLATFORM "qemu-arm" | ||
#elif defined(__riscv) | ||
#define MICROPY_PY_SYS_PLATFORM "qemu-riscv32" | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably this would be replaced with simply "qemu"
when we rename the port.
Code size report:
|
74b6a80
to
a8d7fa0
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #15743 +/- ##
=======================================
Coverage 98.43% 98.43%
=======================================
Files 163 163
Lines 21294 21294
=======================================
Hits 20960 20960
Misses 334 334 ☔ View full report in Codecov by Sentry. |
71908ed
to
b39dbcb
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Besides a couple of minor Makefile things, that looks good to me!
ports/qemu-arm/Makefile
Outdated
# architecture name. "Make" unfortunately does not provide any simple way | ||
# to perform numeric comparisons, so to keep things simple we assume that | ||
# GCC is at least version 10 for the time being. | ||
ifeq ($(GCC_VERSION),10) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you may want to replace this bit with ifeq ($(shell test $(GCC_VERSION) -ge 10; echo $$?),0)
and remove the second sentence in the original comment. I found a solution about that issue long after the code was committed...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, done. But I changed -ge
to -le
because I think that's what you meant.
ports/qemu-arm/Makefile
Outdated
# `make debug` will block QEMU until a debugger is connected to port 1234. | ||
.PHONY: debug | ||
debug: $(BUILD)/firmware.elf | ||
$(QEMU_SYSTEM) $(QEMU_ARGS) -serial mon:stdio -S -s -kernel $< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about moving the -s
parameter to its own $(QEMU_DBG)
variable so it can be overridden with other things like https://www.qemu.org/docs/master/system/gdb.html#using-unix-sockets. If you do that, $(QEMU_ARGS)
should also pick up externally defined arguments and add to them rather than replacing its contents.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a $(QEMU_DEBUG_ARGS)
option, defaulting to -s
.
.PHONY: debug | ||
debug: $(BUILD)/firmware.elf | ||
$(QEMU_SYSTEM) $(QEMU_ARGS) -serial mon:stdio -S -s -kernel $< | ||
|
||
.PHONY: test | ||
test: $(BUILD)/firmware.elf |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd add a testdebug
target too. How would you be able to see things like #15589 in a debugger otherwise?
That issue was reproduced by running several tests in a row - with that debug target definition there would be no way to get that under gdb or lldb or anything else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not possible to used both -S
and the run-tests.py
infrastructure, because the latter consumes stdio of qemu-system-X and so you won't be able to start the emulator because the monitor is not accessible.
That issue was reproduced by running several tests in a row -
I think we could make this debug
target use -serial pty
and then you can run the tests manually as many times as you like against the exposed serial device, eg:
$ make debug
<in a separate terminal>
$ gdb ...
<in a separate terminal>
$ ./run-tests.py --target qemu-arm --device /dev/pts/123
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just tried the version I committed a few days ago as agatti@ce8a877, using -serial pty
, and it seems to work when running make testdebug
in the first terminal and when it's ready spawning another one and run gdb
attaching to the qemu instance. Unless something else changed there's no need to use three terminals :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I will test.
But what I'm also saying above is that it's possible to rerun the test suite over and over, or whatever combination of tests you like. That requires 3 terminals.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But what I'm also saying above is that it's possible to rerun the test suite over and over, or whatever combination of tests you like. That requires 3 terminals.
Oh, never figured that was a possibility. Almost every time I've had the need for this it turned out to be a fatal crash so there was no point in rerunning the test without restarting qemu as well. In that case then yes, you're absolutely right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, you can use -S -s
with the make test
target.
Instead of duplicating all targets with a debug version, I added an orthogonal option QEMU_DEBUG
which can be enabled for any qemu target, eg:
$ make QEMU_DEBUG=1 test
That will run the test suite with -S -s
.
I also added QEMU_DEBUG_EXTRA
, and updated the README with descriptions of these options.
ports/qemu-arm/Makefile
Outdated
|
||
.PHONY: test | ||
test: $(BUILD)/firmware.elf | ||
$(eval DIRNAME=ports/$(notdir $(CURDIR))) | ||
cd $(TOP)/tests && ./run-tests.py --target qemu-arm --device execpty:"qemu-system-arm $(QEMU_ARGS) -serial pty -kernel ../$(DIRNAME)/$<" $(TESTS_EXCLUDE) | ||
cd $(TOP)/tests && ./run-tests.py --target qemu-arm --device execpty:"$(QEMU_SYSTEM) $(QEMU_ARGS) -serial pty -kernel ../$(DIRNAME)/$<" $(TESTS_EXCLUDE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd add another argument to this for additional user arguments for run-tests.py
, or rename TESTS_EXCLUDE
into something else and have it kick in only if it's not defined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, how about adding $(RUN_TESTS_EXTRA)
? If it's not defined it won't do anything. The user can set it from the command line, eg to -d basics
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would work, too. Would it help if these extra arguments (along with the other targets) are documented or are niche enough that if you need them you'd have probably figured them out already?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can document the extra args, and the possible options for BOARD=
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added RUN_TEST_EXTRA
, and documented it in the README, along with a list of available boards.
08c330d
to
a513d83
Compare
@agatti this has been updated based on your feedback, if you'd like to take another look, thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changes LGTM! Have one question about CI, but that's all.
I support the idea of renaming the port to qemu
as a follow-up.
a513d83
to
6128328
Compare
@dpgeorge the new changes look good to me as well! Just one minor thing: given that picolibc for Arm is also an option on the CI machine, would it make sense to extract the libc selection bit that's currently in place for RV32 and make it available for all ports? I haven't tried to build qemu-arm with picolibc but it'd be an interesting experiment to try (@projectgus expressed some interest back then if memory serves). All the known libm incompatibilities should be already sorted out, or it wouldn't build the RV32 target at all, would it. |
6128328
to
f120acb
Compare
I have now applied this suggestion and moved the picolibc bit of the Makefile so that it's accessible by both ARM and RISC-V targets. As part of this I needed to make ARM use CC for linking instead of LD, to match RISC-V. That anyway makes things more consistent. |
And of course the CI fails now with picolibc... |
6632c07
to
8ccd74a
Compare
Interestingly, Arm targets with picolibc are ever so slightly larger than their newlib counterparts:
Not sure if that's due to some missing flags/ifdefs/whatever, but that's unexpected to say the least. |
@dpgeorge I was also wondering, given that there's no RV32 platform in the code size report then maybe adding the size of the qemu repl build there could be nice to have. The qemu build isn't influenced by too much third party code so it would reflect core code increase more accurately I think. If that's not in the scope for this PR, then if I can add that functionality myself I'll send one after this is merged (and the port gets renamed from qemu-arm to qemu). |
Huh, that's indeed interesting! I suppose MicroPython is pretty light-on with the libc features it uses, especially in these ports, so there may not be a lot of scope for size optimisation. |
8ccd74a
to
0484368
Compare
That's a good idea. But we need to be aware of the time that the code-size CI job takes to run, it's currently one of the slowest jobs, and adding more build to it will make it even slower. Feel free to open a PR for it. |
Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Damien George <damien@micropython.org>
Currently both the qemu-arm and qemu-riscv ports share a lot of code and functionality. This commit merges the qemu-riscv port into the qemu-arm port. The only real differences between the two are the toolchains used to build the code, and the initialisation/startup framework. Everything else is pretty much the same, so this brings the following benefits: - less code duplication - less burden on maintenance - generalised qemu port, could in the future support other architectures A new board `VIRT_RV32` has been added to the qemu-arm port which is the existing RISC-V board from the qemu-riscv port. To build it: $ make BOARD=VIRT_RV32 repl To cleanly separate the code for the different architectures, startup code has been moved to ports/qemu-arm/mcu/<arch>/. Signed-off-by: Damien George <damien@micropython.org>
0484368
to
0426934
Compare
See #15784 for the rename of the qemu-arm port to qemu. |
@dpgeorge you may want to increase the heap size for RV32, I just bumped into #12853 (comment) again. |
The tests are no longer embedded in the firmware, but rather run individually over the serial port. Can you please explain what the issue is that you see? Something I can reproduce? |
Sure, take a look at the test results of #15714: https://github.com/micropython/micropython/actions/runs/10700895755/job/29665631825?pr=15714 - I rebased the code to be compatible with the merged qemu port.
|
Hmm, that's strange the failure comes up there, with seemingly unrelated changes. All that PR does is enable inline-riscv-asm, and that shouldn't change the amount of GC heap available, or how the GC heap is used by that failing test. I guess you can just increase the qemu-arm GC heap size by a little bit in your PR, to get that test to pass. If that doesn't do it, it needs investigating. |
I can also reproduce the issue locally on an Ubuntu 22.04 VM when running tests through If a GC sweep is performed after each test, I wonder what's lingering in the GC heap when that test is scheduled to run. I'm not sure decompressing the zlib data from that failing test should take that much memory to begin with. If needed I can easily attach a debugger, reproduce the issue, and report back on what's happening - but I'd need a couple of pointers on what to look for and where to look. |
Summary
Currently both the
qemu-arm
andqemu-riscv
share a lot of code and functionality. In particular the recent improvement to running tests onqemu-arm
in #15624 would need to be duplicated in theqemu-riscv
port.This PR merges the
qemu-riscv
port into theqemu-arm
port. The only real differences between the two are the toolchains used to build the code, and the initialisation/startup framework. Everything else is pretty much the same, so this brings the following benefits:A new board
VIRT_RV32
has been added to theqemu-arm
port which is the existing RISC-V from theqemu-riscv
port. To build it is simply:To cleanly separate the code for the different architectures, startup code has been moved to
ports/qemu-arm/mcu/<arch>/
.Testing
The CI has been updated to run the
VIRT_RV32
board against the test suite.Trade-offs and Alternatives
We could keep the ports separate, but there's a lot of code duplication, and an extra burden on maintenance.
Eventually we would rename the
qemu-arm
port toqemu
, but I didn't do that in this PR.