Skip to content

Add #[entry], #[irq] and #[exception(...)] macros. #33

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

Merged
merged 13 commits into from
May 19, 2025

Conversation

thejpster
Copy link
Contributor

@thejpster thejpster commented May 4, 2025

Adds:

  • #[entry]
  • #[exception(Undefined)]
  • #[exception(SupervisorCall)]
  • #[exception(PrefetchAbort)]
  • #[exception(DataAbort)]
  • #[irq] (or #[exception(Irq)])

You previously had to write:

#[unsafe(no_mangle)]
unsafe extern "C" fn _irq_handler() {
    todo!()
}

Now you can write:

#[irq]
fn irq_handler() {
    todo!()
}

@thejpster
Copy link
Contributor Author

OK, I guess we can't set a default target for the whole repository. rebased without that.

@thejpster
Copy link
Contributor Author

Uh, my re-entrant interrupt test is failing in CI, so I dropped that commit. It was unrelated to these changes anyway, so I'll fix it here and add it in another PR.

@robamu
Copy link
Contributor

robamu commented May 4, 2025

Maybe exception(IrqHandler) would be better as interrupt or interrupt_handler ?
It is technically an exception, but I associate exception with unexpected error cases.

@thejpster
Copy link
Contributor Author

Yeah, I take your point. But Arm doesn't distinguish between handling an IRQ and handling an Abort. They are all just jumps from the vector table, and they have the same banked register state.

Is it worth creating a whole new macro just for the interrupt handler?

@thejpster
Copy link
Contributor Author

I fixed the re-entrant interrupt handling. We need to preserve LR across the call to _irq_handler.

@thejpster
Copy link
Contributor Author

I added #[interrupt] as an alias for #[exception(IrqHandler)]

@thejpster
Copy link
Contributor Author

Force pushed with formatting fixed

@robamu
Copy link
Contributor

robamu commented May 8, 2025

I tested the interrupt macro on the Zynq7000, seems to work fine.

One more question:
The function signature(s) looks like this according to docs:

#[cortex_a_rt::exception(UndefinedHandler)]
fn my_handler(addr: usize) -> ! {
    todo!();
}

Is it possibly problematic to return the address like in the extern C function signature?

@thejpster
Copy link
Contributor Author

Uh, the interrupt handler doesn't take an argument and also returns nothing - unlike the exception handlers (which take and return an address) and the SVCall handler (which takes the SVCall number and returns an empty tuple).

I should check the documentation is clear on this.

thejpster added 6 commits May 10, 2025 13:11
It provides the #[entry] and #[exception(FooHandler)] macros.
It can now handle a hi-prio SGI whilst in the middle of handling a low-prio SGI. This shows we got the asm interrupt handler's stacking code right (probably).
Now the re-entrant test works correctly.
* AbortHandler is now DataAbort
* PrefetchHandler is now PrefetchAbort
* UndefinedHandler is now Undefined
* SvcHandler is now SupervisorCall

I also renamed the asm handlers for abort and prefetch to data_abort and prefetch_abort, which makes it clearer that both are aborts and both are handled in abort mode. I also added links to the relevant part of the Arm Armv7 ARM.

This patch also causes `#[exception(Nonsense)` to correctly identify 'Nonense' as the thing that is wrong, rather than the function that comes after the attribute.
@thejpster thejpster changed the title Add #[entry] and #[exception] macros. Add #[entry], #[irq] and #[exception(...)] macros. May 10, 2025
@thejpster
Copy link
Contributor Author

Rebased, and then revised again - hopefully adding clarity and readability. In particular, I now make clear there are "Prefetch Aborts" and "Data Aborts", both handled in ABT mode.

I've left the handlers as safe functions, but I could be persuaded that the handlers that fn handler(usize) -> usize should be unsafe because returning a weird integer here will cause undefined behaviour. Basically the only sound thing you can do is return the argument, or the argument + 4.

@thejpster
Copy link
Contributor Author

OK, here's what it's like if you require unsafe.

I think I prefer it this way?

You shouldn't call them, so don't list them. Now the exception handlers match the main function.
@thejpster
Copy link
Contributor Author

Good to go?

@robamu
Copy link
Contributor

robamu commented May 19, 2025

Yes, LGTM 👍

@jonathanpallant jonathanpallant merged commit fc1eb78 into rust-embedded:main May 19, 2025
57 checks passed
@thejpster thejpster deleted the add-macros branch May 22, 2025 19:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants