pub struct ChainedPics {
pub master: Pic,
pub slave: Pic,
/* private fields */
}Expand description
A x86 setup of Chained PICs.
In most PCs there are one master and one slave PIC configuration, each having 8 inputs servicing 16 interrupts. This structure allows to easily initialize and control the x86 configuration of PICs and configure all 16 interrupts for further handling.
Provides a minimal set of functions required to properly handle interrupts based on the currently used mode for each PIC.
Fields§
§master: Pic§slave: PicImplementations§
Source§impl ChainedPics
impl ChainedPics
Sourcepub const fn new(master_offset: u8, slave_offset: u8) -> Self
pub const fn new(master_offset: u8, slave_offset: u8) -> Self
Creates a new instance of Chained Pics.
The master offset and slave offset are two offsets that are pointing to the first interrupt vector of each 8259 chip.
§Panics
This function will panic if the provided offsets will overlap with each other or collide with CPU exceptions.
Sourcepub const fn new_contiguous(primary_offset: u8) -> Self
pub const fn new_contiguous(primary_offset: u8) -> Self
Creates a new instance of a Chained Pics.
The offset must point to the the chosen 16 entries from the IDT that will be used for the software interrupts.
This is a convenience function that maps the PIC1 and PIC2 to a
contiguous set of interrupts. This function is equivalent to
Self::new(primary_offset, primary_offset + 8).
§Panics
This function will panic if the provided offset will overlap with cpu exceptions. It will always prevent the overlapping between master and slave chips though
Sourcepub fn is_initialized(&self) -> bool
pub fn is_initialized(&self) -> bool
Returns true if initialized at least once.
Sourcepub fn initialize(&mut self)
pub fn initialize(&mut self)
Initializes the PICs.
This performs an initialization that is compatible with most x86 PC devices. Some archaic devices may use only one PIC. For such possibilities a manual initialization of PIC structure must be performed.
Sourcepub fn operation_mode_change(&mut self, new_op_mode: PicOperationMode)
pub fn operation_mode_change(&mut self, new_op_mode: PicOperationMode)
Changes the operation mode for both master and slave PICs.
This sends the OCW2 command and configures the current operation mode of the PIC logic.
Refer to PicOperationMode enum for more details. This function only checks the mode of
the master PIC, assuming that slave was not changed manually to something else.
§Note
The IRQ mask must be changed after switching from PicOperationMode::PolledMode.
Sourcepub unsafe fn is_spurious(&mut self, vec_id: u8) -> bool
pub unsafe fn is_spurious(&mut self, vec_id: u8) -> bool
Checks if the provided interrupt vector was caused by PIC properly.
When an IRQ occurs, the PIC chip tells the CPU (via. the PIC’s INTR line) that there’s an interrupt, and the CPU acknowledges this and waits for the PIC to send the interrupt vector. This creates a race condition: if the IRQ disappears after the PIC has told the CPU there’s an interrupt but before the PIC has sent the interrupt vector to the CPU, then the CPU will be waiting for the PIC to tell it which interrupt vector but the PIC won’t have a valid interrupt vector to tell the CPU.
Here we read if the interrupt is written within the ISR register, to be sure that we are dealing with real interrupt. If a spurious interrupt was also sent from the slave PIC, the master shall clear this flag, because he also thinks that it was a legit IRQ.
§Important
This is also the reason why sometimes an unimplemented handler functions are causing general protection faults. PIC will cause an interrupt on the lowest priority IRQ, and the interrupt service routine for something like hard disk controller is most likely not implemented in the stage of configuring PICs.
§Note (Fully Nested Mode)
Spurious interrupts can only happen when the lowest priority IRQ are called. The fake interrupt number is the lowest priority interrupt number for the corresponding PIC chip (IRQ 7 for the master PIC, and IRQ 15 for the slave PIC).
Basically this means that you shall only check for spurious IRQs when it is a parallel port interrupt (IRQ7) or secondary ATA channel interrupt (IRQ15)
§Note (Rotations)
When modes with rotations are used: PicOperationMode::AutomaticRotation,
PicOperationMode::SpecialMask, the spurious interrupt can still only be found on IRQ7
for the master PIC or IRQ15 for the slave PIC.
§Note (Polled Mode)
Makes no sense in polled mode. Note also that in polled mode the ISR is always zero, so this function will always mark proper IRQs as spurious.
§Unsafe
This function is unsafe only because it shall be used within the interrupt handler function at the very start, to make sure that we are not handling a spurious interrupt. It is completely forbidden to send an end of interrupt after this function.
Sourcepub unsafe fn notify_end_of_interrupt(&mut self, vec_id: u8)
pub unsafe fn notify_end_of_interrupt(&mut self, vec_id: u8)
Notify a proper PIC chip that the interrupt was successfully handled and shall be cleared within the ISR register.
§Important
To prevent spurious interrupts on lowest priority IRQs, use ChainedPics::is_spurious
and jump to the end of interrupt handler function if it returns true. If some interrupt was
caused by a hardware|software error, it should not be handled.
PIC must not receive a EOI command, when it is a spurious interrupts. It can clear other interrupt’s flag, which is a bigger trouble.
Lower priority interrupts vary based on the current mode. The function mentioned above handles all logic required for each.
§Unsafe
This command must be used at the end of every interrupt that was issued by any of two PICs. Make sure that this is a last command withon the interrupt service routine.
Sourcepub fn disable(&mut self)
pub fn disable(&mut self)
Disable both PICs interrupts.
§Note
This must be used when switching to APIC controller for handling interrupts.
Sourcepub fn enable(&mut self)
pub fn enable(&mut self)
Enables both PICs interrupts.
They are enabled by default after the initialization.
§Warn
This is not the initialization. Please see ChainedPics::initialize
Sourcepub fn disable_slave(&mut self)
pub fn disable_slave(&mut self)
Disables the slave PIC fully, i.e IRQ8 … IRQ15.
Sourcepub fn enable_slave(&mut self)
pub fn enable_slave(&mut self)
Enables the slave PIC, i.e IRQ8 … IRQ15.
Sourcepub unsafe fn write_mask(&mut self, mask: IrqMask)
pub unsafe fn write_mask(&mut self, mask: IrqMask)
Masks the IRQ lines of chained PICs.
§Unsafe
Even though masking just disabled some interrupt lines, this function is marked as unsafe due to undefined behavior that might happen when the OCW1 command is not right.
Sourcepub fn with_master<F>(&mut self, f: F)where
F: FnOnce(&mut Pic),
pub fn with_master<F>(&mut self, f: F)where
F: FnOnce(&mut Pic),
Perform something on the master PIC.
Sourcepub fn with_slave<F>(&mut self, f: F)where
F: FnOnce(&mut Pic),
pub fn with_slave<F>(&mut self, f: F)where
F: FnOnce(&mut Pic),
Perform something on the slave PIC.
Sourcepub const unsafe fn new_unchecked(master_offset: u8, slave_offset: u8) -> Self
pub const unsafe fn new_unchecked(master_offset: u8, slave_offset: u8) -> Self
Creates a new instance of PIC controller.
The master offset and slave offset are two offsets that are pointing to the first interrupt vector of each 8259 chip.
§Unsafe
This function will not check if the chosen offsets overlap with each other or do they overlap with CPU exceptions.