Skip to content

Commit d486e86

Browse files
authored
Merge pull request #439 from brandonchinn178/handler-func-type
Add HandlerFuncType trait
2 parents 56c949b + faea273 commit d486e86

File tree

2 files changed

+39
-22
lines changed

2 files changed

+39
-22
lines changed

Changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Unreleased
22

3+
## New Features
4+
5+
- [Add `HandlerFuncType` trait](https://github.com/rust-osdev/x86_64/pull/439)
6+
37
# 0.14.11 – 2022-09-15
48

59
## New Features

src/structures/idt.rs

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -779,34 +779,47 @@ impl<F> Entry<F> {
779779
}
780780
}
781781

782-
macro_rules! impl_set_handler_fn {
783-
($h:ty) => {
784-
#[cfg(all(feature = "instructions", feature = "abi_x86_interrupt"))]
785-
impl Entry<$h> {
786-
/// Set the handler function for the IDT entry and sets the present bit.
787-
///
788-
/// For the code selector field, this function uses the code segment selector currently
789-
/// active in the CPU.
790-
///
791-
/// The function returns a mutable reference to the entry's options that allows
792-
/// further customization.
793-
///
794-
/// This method is only usable with the `abi_x86_interrupt` feature enabled. Without it, the
795-
/// unsafe [`Entry::set_handler_addr`] method has to be used instead.
782+
#[cfg(feature = "instructions")]
783+
impl<F: HandlerFuncType> Entry<F> {
784+
/// Set the handler function for the IDT entry and sets the present bit.
785+
///
786+
/// For the code selector field, this function uses the code segment selector currently
787+
/// active in the CPU.
788+
///
789+
/// The function returns a mutable reference to the entry's options that allows
790+
/// further customization.
791+
///
792+
/// This method is only usable with the `abi_x86_interrupt` feature enabled. Without it, the
793+
/// unsafe [`Entry::set_handler_addr`] method has to be used instead.
794+
#[inline]
795+
pub fn set_handler_fn(&mut self, handler: F) -> &mut EntryOptions {
796+
unsafe { self.set_handler_addr(handler.to_virt_addr()) }
797+
}
798+
}
799+
800+
/// A common trait for all handler functions usable in [`Entry`].
801+
pub trait HandlerFuncType {
802+
/// Get the virtual address of the handler function.
803+
fn to_virt_addr(self) -> VirtAddr;
804+
}
805+
806+
macro_rules! impl_handler_func_type {
807+
($f:ty) => {
808+
#[cfg(feature = "abi_x86_interrupt")]
809+
impl HandlerFuncType for $f {
796810
#[inline]
797-
pub fn set_handler_fn(&mut self, handler: $h) -> &mut EntryOptions {
798-
let handler = VirtAddr::new(handler as u64);
799-
unsafe { self.set_handler_addr(handler) }
811+
fn to_virt_addr(self) -> VirtAddr {
812+
VirtAddr::new(self as u64)
800813
}
801814
}
802815
};
803816
}
804817

805-
impl_set_handler_fn!(HandlerFunc);
806-
impl_set_handler_fn!(HandlerFuncWithErrCode);
807-
impl_set_handler_fn!(PageFaultHandlerFunc);
808-
impl_set_handler_fn!(DivergingHandlerFunc);
809-
impl_set_handler_fn!(DivergingHandlerFuncWithErrCode);
818+
impl_handler_func_type!(HandlerFunc);
819+
impl_handler_func_type!(HandlerFuncWithErrCode);
820+
impl_handler_func_type!(PageFaultHandlerFunc);
821+
impl_handler_func_type!(DivergingHandlerFunc);
822+
impl_handler_func_type!(DivergingHandlerFuncWithErrCode);
810823

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

0 commit comments

Comments
 (0)