Skip to content

Commit

Permalink
Merge pull request #439 from brandonchinn178/handler-func-type
Browse files Browse the repository at this point in the history
Add HandlerFuncType trait
  • Loading branch information
josephlr committed Sep 24, 2023
2 parents 56c949b + faea273 commit d486e86
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 22 deletions.
4 changes: 4 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Unreleased

## New Features

- [Add `HandlerFuncType` trait](https://github.com/rust-osdev/x86_64/pull/439)

# 0.14.11 – 2022-09-15

## New Features
Expand Down
57 changes: 35 additions & 22 deletions src/structures/idt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -779,34 +779,47 @@ impl<F> Entry<F> {
}
}

macro_rules! impl_set_handler_fn {
($h:ty) => {
#[cfg(all(feature = "instructions", feature = "abi_x86_interrupt"))]
impl Entry<$h> {
/// Set the handler function for the IDT entry and sets the present bit.
///
/// For the code selector field, this function uses the code segment selector currently
/// active in the CPU.
///
/// The function returns a mutable reference to the entry's options that allows
/// further customization.
///
/// This method is only usable with the `abi_x86_interrupt` feature enabled. Without it, the
/// unsafe [`Entry::set_handler_addr`] method has to be used instead.
#[cfg(feature = "instructions")]
impl<F: HandlerFuncType> Entry<F> {
/// Set the handler function for the IDT entry and sets the present bit.
///
/// For the code selector field, this function uses the code segment selector currently
/// active in the CPU.
///
/// The function returns a mutable reference to the entry's options that allows
/// further customization.
///
/// This method is only usable with the `abi_x86_interrupt` feature enabled. Without it, the
/// unsafe [`Entry::set_handler_addr`] method has to be used instead.
#[inline]
pub fn set_handler_fn(&mut self, handler: F) -> &mut EntryOptions {
unsafe { self.set_handler_addr(handler.to_virt_addr()) }
}
}

/// A common trait for all handler functions usable in [`Entry`].
pub trait HandlerFuncType {
/// Get the virtual address of the handler function.
fn to_virt_addr(self) -> VirtAddr;
}

macro_rules! impl_handler_func_type {
($f:ty) => {
#[cfg(feature = "abi_x86_interrupt")]
impl HandlerFuncType for $f {
#[inline]
pub fn set_handler_fn(&mut self, handler: $h) -> &mut EntryOptions {
let handler = VirtAddr::new(handler as u64);
unsafe { self.set_handler_addr(handler) }
fn to_virt_addr(self) -> VirtAddr {
VirtAddr::new(self as u64)
}
}
};
}

impl_set_handler_fn!(HandlerFunc);
impl_set_handler_fn!(HandlerFuncWithErrCode);
impl_set_handler_fn!(PageFaultHandlerFunc);
impl_set_handler_fn!(DivergingHandlerFunc);
impl_set_handler_fn!(DivergingHandlerFuncWithErrCode);
impl_handler_func_type!(HandlerFunc);
impl_handler_func_type!(HandlerFuncWithErrCode);
impl_handler_func_type!(PageFaultHandlerFunc);
impl_handler_func_type!(DivergingHandlerFunc);
impl_handler_func_type!(DivergingHandlerFuncWithErrCode);

/// Represents the options field of an IDT entry.
#[repr(transparent)]
Expand Down

0 comments on commit d486e86

Please sign in to comment.