Skip to content

Commit

Permalink
draw the rest of the syscall
Browse files Browse the repository at this point in the history
  • Loading branch information
hawkw committed Mar 15, 2024
1 parent bcd2e54 commit 107efb2
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 0 deletions.
40 changes: 40 additions & 0 deletions doc/syscalls.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -659,3 +659,43 @@ return registers 0 and 1 for future compatibility.
Like `REPLY`, this syscall just silently ignores replies to the wrong
generation, under the assumption that the task got restarted for some reason
while we were processing its request. (It can happen.)

[#sys_irq_status]
=== `IRQ_STATUS` (13)

Returns the current status of interrupts mapped to the calling task.

==== Arguments

- 0: notification bitmask corresponding to the interrupt(s) to query

==== Return values

- 0: an `IrqStatus` (see the `abi` crate) describing the status of the
interrupts in the notification mask. Currently, the following bits in
`IrqStatus` are significant:
** `0b0001`: set if any interrupt in the mask is enabled
** `0b0010`: set if an IRQ is pending for any interrupt in the mask
** `0b0100`: set if a notification has been posted to the caller but
not yet consumed

==== Faults

|===
| Condition | Fault taken

| The given notification bitmask is not mapped to an interrupt in this task.
| `NoIrq`

|===

==== Notes

As discussed in the notes for the <<sys_irq_control, IRQ_CONTROL>> syscall,
tasks refer to interrupts using their notification bits.

If the provided notification mask is zero, the syscall will return a `NoIrq`
fault. If the provided notification mask has multiple bits set, the returned
`IrqStatus` value will be the boolean OR of the status of all interrupts in the
map (e.g. if any interrupt in the mask is pending, the `PENDING` bit will be
set, and so on).
2 changes: 2 additions & 0 deletions sys/abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,8 @@ pub struct ImageVectors {
pub entry: u32,
}

/// A set of bitflags representing the status of the interrupts mapped to a
/// notification mask.
#[derive(Copy, Clone, Debug, FromBytes)]
#[repr(transparent)]
pub struct IrqStatus(pub u32);
Expand Down
86 changes: 86 additions & 0 deletions sys/userlib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1652,3 +1652,89 @@ unsafe extern "C" fn sys_reply_fault_stub(_tid: u32, _reason: u32) {
}
}
}

/// Returns the current status of any interrupts mapped to the provided
/// notification mask.
///
/// # Arguments
///
/// - `mask`: a notification mask for interrupts mapped to the current task.
///
/// # Returns
///
/// An [`IrqStatus`] (see the `abi` crate) describing the status of the
/// interrupts in the notification mask.
///
/// # Faults
///
/// This syscall faults the caller if the given notification bitmask is not
/// mapped to an interrupt in this task.
#[inline(always)]
pub fn sys_irq_status(mask: u32) -> abi::IrqStatus {
let status = unsafe {
sys_irq_status(mask);
};
abi::IrqStatus::from_bits_truncate(status)
}

/// Core implementation of the IRQ_STATUS syscall.
///
/// See the note on syscall stubs at the top of this module for rationale.
#[naked]
unsafe extern "C" fn sys_irq_status_stub(_mask: u32) {
cfg_if::cfg_if! {
if #[cfg(armv6m)] {
arch::asm!("
@ Spill the registers we're about to use to pass stuff.
push {{r4, lr}}
mov r4, r11
push {{r4}}
@ Load the constant syscall number.
eors r4, r4
adds r4, #{sysnum}
mov r11, r4
@ Move register arguments into place.
mov r4, r0
@ To the kernel!
svc #0
@ Move result into place.
mov r0, r4
@ Restore the registers we used and return.
pop {{r4}}
mov r11, r4
pop {{r4, r5, pc}}
",
sysnum = const Sysnum::IrqStatus as u32,
options(noreturn),
)
} else if #[cfg(any(armv7m, armv8m))] {
arch::asm!("
@ Spill the registers we're about to use to pass stuff.
push {{r4, r11, lr}}
@ Move register arguments into place.
mov r4, r0
@ Load the constant syscall number.
mov r11, {sysnum}
@ To the kernel!
svc #0
@ Move result into place.
mov r0, r4
@ Restore the registers we used and return.
pop {{r4, r11, pc}}
",
sysnum = const Sysnum::IrqStatus as u32,
options(noreturn),
)
} else {
compile_error!("missing sys_irq_status stub for ARM profile")
}
}
}

0 comments on commit 107efb2

Please sign in to comment.