modm-io / modm

modm: a C++23 library generator for AVR and ARM Cortex-M devices
https://modm.io
Mozilla Public License 2.0
733 stars 131 forks source link

[fiber] Add support for ARM64 targets #1113

Closed salkinium closed 7 months ago

salkinium commented 8 months ago

I've added a new key to the hosted device files: arch with arm64 and x86_64. Maybe it should be aarch64?

salkinium commented 7 months ago

I'll merge this tonight, we can check and fix the RPi ARM64 later. It's not our primary target anyways, but I'd like to have the unit tests pass on my machine again ;-P

rleh commented 7 months ago
  • [ ] Test on ARM64 Linux specifically RPi

It does not work 😢, because the x86_64 context switching (fiber/context_x86_64.cpp) is choosen for both the hosted-linux and hosted-linux-arm64 targets:

``` user@raspberrypi:~/modm $ (cd test && make run-hosted-linux) /home/user/.local/bin/lbuild -p ../build/generated-unittest/hosted -c config/hosted.xml -D":target=hosted-linux" -C ../build/generated-unittest/hosted build --no-log >> modm: Recomputing device cache... scons -j8 -C ../build/generated-unittest/hosted run scons: Entering directory `/home/user/modm/build/generated-unittest/hosted' scons: Reading SConscript files ... scons: done reading SConscript files. scons: Building targets ... Unittest······· unittest_runner.cpp ╭────Jinja2──── modm/modm_tools/info.c.in ╰───Template──> modm/src/info_git.c ╭────Jinja2──── modm/modm_tools/info.c.in ╰───Template──> modm/src/info_build.c Compiling C++·· scons-release/modm/src/modm/architecture/driver/atomic/flag.o Compiling C++·· scons-release/modm/src/modm/architecture/interface/can.o Compiling C++·· scons-release/modm/src/modm/communication/sab/interface.o Compiling C++·· scons-release/modm/src/modm/communication/sab/slave.o Compiling C++·· scons-release/modm/src/modm/communication/xpcc/backend/can/connector.o Compiling C···· scons-release/modm/src/info_git.o Compiling C···· scons-release/modm/src/info_build.o Compiling C++·· scons-release/unittest_runner.o Compiling C++·· scons-release/modm/src/modm/communication/xpcc/backend/header.o Compiling C++·· scons-release/modm/src/modm/communication/xpcc/communicator.o Compiling C++·· scons-release/modm/src/modm/communication/xpcc/dispatcher.o Compiling C++·· scons-release/modm/src/modm/communication/xpcc/postman/dynamic_postman/dynamic_postman.o Compiling C++·· scons-release/modm/src/modm/communication/xpcc/postman/postman.o Compiling C++·· scons-release/modm/src/modm/container/smart_pointer.o Compiling C++·· scons-release/modm/src/modm/debug/logger/hosted/default_style.o Compiling C++·· scons-release/modm/src/modm/driver/can/can_lawicel_formatter.o Compiling C++·· scons-release/modm/src/modm/driver/can/mcp2515.o Compiling C++·· scons-release/modm/src/modm/driver/io/terminal.o Compiling C++·· scons-release/modm/src/modm/driver/motor/drv832x_spi.o Compiling C++·· scons-release/modm/src/modm/driver/temperature/ltc2984.o Compiling C++·· scons-release/modm/src/modm/io/iostream.o Compiling C++·· scons-release/modm/src/modm/io/iostream_printf.o Compiling C++·· scons-release/modm/src/modm/math/geometry/angle.o Compiling C++·· scons-release/modm/src/modm/math/geometry/vector2.o Compiling C++·· scons-release/modm/src/modm/math/utils/bit_operation.o Compiling C++·· scons-release/modm/src/modm/math/utils/pc/operator.o Compiling C++·· scons-release/modm/src/modm/platform/core/assert.o Compiling C++·· scons-release/modm/src/modm/platform/core/clock.o Compiling C++·· scons-release/modm/src/modm/platform/core/memory.o Compiling C++·· scons-release/modm/src/modm/processing/fiber/context_x86_64.o modm/src/modm/processing/fiber/context_x86_64.cpp:51:20: warning: 'naked' attribute directive ignored [-Wattributes] 51 | modm_context_entry() | ^ modm/src/modm/processing/fiber/context_x86_64.cpp:152:51: warning: 'naked' attribute directive ignored [-Wattributes] 152 | modm_context_jump(modm_context_t*, modm_context_t*) | ^ /tmp/ccwrMUes.s: Assembler messages: /tmp/ccwrMUes.s:16: Error: operand 1 must be an integer register -- `mov (%rsp),%rdi' /tmp/ccwrMUes.s:17: Error: operand 1 must be an integer register -- `mov 8(%rsp),%rsi' /tmp/ccwrMUes.s:18: Error: unknown mnemonic `jmp' -- `jmp *%rsi' /tmp/ccwrMUes.s:89: Error: unknown mnemonic `stmxcsr' -- `stmxcsr 0xa0(x1)' /tmp/ccwrMUes.s:90: Error: unknown mnemonic `fnstcw' -- `fnstcw 0xa4(x1)' /tmp/ccwrMUes.s:278: Error: unknown mnemonic `leaq' -- `leaq -0xe8(%rsp),%rsp' /tmp/ccwrMUes.s:279: Error: unknown mnemonic `stmxcsr' -- `stmxcsr 0xa0(%rsp)' /tmp/ccwrMUes.s:280: Error: unknown mnemonic `fnstcw' -- `fnstcw 0xa4(%rsp)' /tmp/ccwrMUes.s:281: Error: unknown mnemonic `movq' -- `movq %r12,0xa8(%rsp)' /tmp/ccwrMUes.s:282: Error: unknown mnemonic `movq' -- `movq %r13,0xb0(%rsp)' /tmp/ccwrMUes.s:283: Error: unknown mnemonic `movq' -- `movq %r14,0xb8(%rsp)' /tmp/ccwrMUes.s:284: Error: unknown mnemonic `movq' -- `movq %r15,0xc0(%rsp)' /tmp/ccwrMUes.s:285: Error: unknown mnemonic `movq' -- `movq %rbx,0xd8(%rsp)' /tmp/ccwrMUes.s:286: Error: unknown mnemonic `movq' -- `movq %rbp,0xe0(%rsp)' /tmp/ccwrMUes.s:287: Error: unknown mnemonic `movq' -- `movq %rsp,(%rdi)' /tmp/ccwrMUes.s:288: Error: unknown mnemonic `movq' -- `movq (%rsi),%rsp' /tmp/ccwrMUes.s:289: Error: unknown mnemonic `ldmxcsr' -- `ldmxcsr 0xa0(%rsp)' /tmp/ccwrMUes.s:290: Error: unknown mnemonic `fldcw' -- `fldcw 0xa4(%rsp)' /tmp/ccwrMUes.s:291: Error: unknown mnemonic `movq' -- `movq 0xa8(%rsp),%r12' /tmp/ccwrMUes.s:292: Error: unknown mnemonic `movq' -- `movq 0xb0(%rsp),%r13' /tmp/ccwrMUes.s:293: Error: unknown mnemonic `movq' -- `movq 0xb8(%rsp),%r14' /tmp/ccwrMUes.s:294: Error: unknown mnemonic `movq' -- `movq 0xc0(%rsp),%r15' /tmp/ccwrMUes.s:295: Error: unknown mnemonic `movq' -- `movq 0xd8(%rsp),%rbx' /tmp/ccwrMUes.s:296: Error: unknown mnemonic `movq' -- `movq 0xe0(%rsp),%rbp' /tmp/ccwrMUes.s:297: Error: unknown mnemonic `leaq' -- `leaq 0xe8(%rsp),%rsp' scons: *** [scons-release/modm/src/modm/processing/fiber/context_x86_64.o] Error 1 scons: building terminated because of errors. make: *** [Makefile:29: run-hosted-linux] Error 2 ```

I'll investigate further later this day...

rleh commented 7 months ago
  • [x] hosted-rpi-arm64 (renamed from hosted-rpi)

What is the purpose of this "rpi" target? I don't see any difference, except that it includes the wiringpi GPIO module, which is deprected since 2019 and also broken on Debian bookworm-based Rpi Linux distibutions.

I would suggest simply removing the hosted-rpi/hosted-rpi-arm64 target (and maybe even the whole wiringpi module).

salkinium commented 7 months ago

because the x86_64 context switching (fiber/context_x86_64.cpp) is choosen for both the hosted-linux and hosted-linux-arm64 targets:

Because I'm stupid and I copied the x86_64 file without modifications. 🙈🙈🙈 OMG, I'm getting old… 👴

I would suggest simply removing the hosted-rpi/hosted-rpi-arm64 target.

Yeah, that make sense. We only had GPIO support anyways, so with that gone, there's no difference to hosted-linux-arm64. I'll remove the code.

salkinium commented 7 months ago

Could you try it again now? @rleh

rleh commented 7 months ago

Now it works on a Aarch64 linux system (Raspberry Pi 4 8GB running Raspbian OS 64-bit)!

image

@salkinium Could you check if it still works on ARM-based MacOS? 😆

salkinium commented 7 months ago

Will do. I also read that GitHub has ARM64 macOS runners, I'll check that out tonight.

salkinium commented 7 months ago

Ok, so.

GCC on macOS ignores __attribute__((naked)). Not sure why. That's why I moved the modm_context_entry function into assembly. I now found out that I can add asm statements into the .cpp file too, so I got rid of the .S file. I hope this also works on Linux GCC.

The macOS linker seems to require leading underscores. 🙄 This is also done in the boost asm files. I've added a template switch.

Could you test again on Linux?

rleh commented 7 months ago

Could you test again on Linux?

Yes, and it works fine!


The macOS linker seems to require leading underscores. 🙄 This is also done in the boost asm files. I've added a template switch.

GCC has a switch -fleading-underscore to control the prefix of the emitted objects, but I would rather not touch it.

Because there is a better option:

extern "C" void modm_context_entry() asm("_modm_context_entry");

I reverted the template file back to a normal C++ file and implemented the ASM labels instead (see 1e3643455), works (still) on arm64 linux. Could you test again on MacOS? (Otherwise just drop my commit.)

salkinium commented 7 months ago

Yup, that works! Thanks! I'll squash and merge it after the CI passes.

salkinium commented 7 months ago

Removing the underscores also works this way!