From 16ba0c0686134262131f8cc7017c0b5875572b54 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Sat, 23 Sep 2023 15:29:31 -0700 Subject: [PATCH 1/2] Add HandlerFuncType trait --- Changelog.md | 4 +++ src/structures/idt.rs | 57 ++++++++++++++++++++++++++----------------- 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/Changelog.md b/Changelog.md index 96bb5bd8..947e1d09 100644 --- a/Changelog.md +++ b/Changelog.md @@ -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 diff --git a/src/structures/idt.rs b/src/structures/idt.rs index 75923f37..6eac9404 100644 --- a/src/structures/idt.rs +++ b/src/structures/idt.rs @@ -779,34 +779,47 @@ impl Entry { } } -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 Entry { + /// 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()) } + } +} + +/// The trait for all function types that can be used as a handler function in `Entry`. +pub trait HandlerFuncType { + /// Get the virtual memory address of the 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)] From faea2730fec1f25b19d8ba318debe68cdeabb917 Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Sat, 23 Sep 2023 18:47:52 -0700 Subject: [PATCH 2/2] Update HandlerFuncType documentation Signed-off-by: Joe Richey --- src/structures/idt.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/structures/idt.rs b/src/structures/idt.rs index 6eac9404..1f7381b6 100644 --- a/src/structures/idt.rs +++ b/src/structures/idt.rs @@ -797,9 +797,9 @@ impl Entry { } } -/// The trait for all function types that can be used as a handler function in `Entry`. +/// A common trait for all handler functions usable in [`Entry`]. pub trait HandlerFuncType { - /// Get the virtual memory address of the function + /// Get the virtual address of the handler function. fn to_virt_addr(self) -> VirtAddr; }