-
Notifications
You must be signed in to change notification settings - Fork 156
cortex_m: Enable fpu on startup #749
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
base: main
Are you sure you want to change the base?
Conversation
| } | ||
|
|
||
| microzig_main(); | ||
| @call(.never_inline, microzig_main, .{}); |
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.
NP: instead can we use the noinline from the microzig.zig ? it won't be that big of an issue for other chip ?
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.
Imo it's ok that calls inside microzig_main get inlined because the FPU is already enabled when execution gets there.
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.
this would bubble up the hf store to the startup function and you end up with the same issue IIUC.
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.
Sorry, I don't understand what you are referring to. Can you elaborate?
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.
Ah sorry I think I was not clear. I though of flagging the microzig_main as noinline for every CPU not only arm. Just to simplify this @call other arch could suffer the same issue. It might also deserve a small explanation why we don't want microzig_main not to be inlined ? Feel free to discard this comment if you don't think it worth the effort.
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.
Definitely worth a comment to explain.
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 though of flagging the microzig_main as noinline for every CPU not only arm.
How can this be achieved? Idk of a way to make calls to microzig_main never inline (since it's always referenced as extern). But I will mark this PR as draft for now. I want to do a bit of refactoring.
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 the comment. Is it ok?
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.
Great comment, I was unsure why this was an issue but that makes sense to me!
| /// the startup of other cores. | ||
| pub inline fn enable_fpu() void { | ||
| // Taken from the rust crate cortex-m-rt. | ||
| asm volatile ( |
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've implemented this using raw assembly since we might be missing some register definitions for FPU in some cortex-m variants and also it allows being embedded in naked functions.
| const mpu_present = @hasDecl(microzig.chip, "properties") and | ||
| @hasDecl(microzig.chip.properties, "cpu.mpuPresent") and | ||
| std.mem.eql(u8, microzig.chip.properties.@"cpu.mpuPresent", "true"); | ||
| const fpu_present = @hasDecl(microzig.chip, "properties") and |
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.
Sometimes code generated by regz doesn't include a properties declaration => if you used in the past fpu_present or mpu_present you got a compilation error.
mattnite
left a comment
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.
Looks good to me once that flag is done, and the conversation with @mathk is resolved.
| } | ||
|
|
||
| if (builtin.abi.float() == .hard) { | ||
| enable_fpu(); |
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 like that this change makes microzig have more "batteries included" by default, but let's allow the user to disable the FPU at build time, with a flag named disable_fpu.
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 add this but isn't it a footgun? You could achieve the same by switching to soft float in the rp2350_arm target in build.zig and you don't risk crashing.
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 the option
| pub const CPU_Options = struct { | ||
| /// If true, interrupt vectors are moved to RAM so handlers can be set at runtime. | ||
| /// | ||
| /// NOTE: Not supported on cortex_m0. | ||
| ram_vector_table: bool = false, | ||
|
|
||
| /// If true, the Cortex-M interrupts will be initialized with a more verbose variant | ||
| /// of the interrupt handlers which print the interrupt name. | ||
| /// | ||
| /// NOTE: This option is enabled in debug builds by default. | ||
| verbose_unhandled_irq: bool = (builtin.mode == .Debug), | ||
|
|
||
| /// If true, the FPU will be enabled in the startup code. | ||
| /// | ||
| /// NOTE: This option is enabled by default if hard float is enabled. | ||
| /// NOTE: Not supported on cortex_m0, cortex_m0plus and cortex_m3. | ||
| enable_fpu: bool = builtin.abi.float() == .hard, | ||
| }; |
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 made common CPU variant between cortex m flavours to be easier to add options. I also added compilation errors if for instance you try to use a ram vector table on cortex m0 or if you try to enable the FPU on the cortex ms that don't support it.
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.
Let me know what you think of this
|
Only one last thing remains: standardising fpu and mpu present chip properties (there is a long standing TODO about this in cortex_m.zig) |
| "caption", | ||
| }); | ||
|
|
||
| const property_name_map: std.StaticStringMap([]const u8) = .initComptime(.{ |
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.
Is it ok to hardcode these here? Same applies for svd
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 should probably be documented. Currently we just rename the properties. Another option which I like is to duplicate them with the microzig standard name (keep __MPU_PRESENT but also export mpu_present). But this makes set_device_property a bit weird. For this to work we should add some sort of property aliasing at least for the database (where if you change one, you change the other).
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'm fine with this for now, but honestly we should standardize these for regz/microzig soon. Similar to how we transform register schemas to a common structure, we can do the same for some specific properties, and leave the rest as they come.
Is this needed though? A different approach would be to check both fields (__FPU_PRESENT and @"cpu.fpuPresent") in cortex_m.zig when we assign fpu_present. |
|
@tacit1m4n3 I'm not sure where |
mattnite
left a comment
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.
Looks great to me, strong work! Let's let @Grazfather and @mathk chime in and then we can merge
I got a CI compile error from an atsam chip that it didn't have an fpu available. Except it did but the property was called |
No description provided.