Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PIC: Masks #7

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 30 additions & 6 deletions crates/pic8259_simple/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ impl Pic {
unsafe fn end_of_interrupt(&mut self) {
self.command.write(CMD_END_OF_INTERRUPT);
}

/// Reads the interrupt mask of this PIC.
unsafe fn read_mask(&mut self) -> u8 {
self.data.read()
}

/// Writes the interrupt mask of this PIC.
unsafe fn write_mask(&mut self, mask: u8) {
self.data.write(mask)
}
}

/// A pair of chained PIC controllers. This is the standard setup on x86.
Expand All @@ -81,7 +91,7 @@ impl ChainedPics {
command: cpuio::UnsafePort::new(0xA0),
data: cpuio::UnsafePort::new(0xA1),
},
]
],
}
}

Expand All @@ -97,13 +107,12 @@ impl ChainedPics {
// allegedly takes long enough to make everything work on most
// hardware. Here, `wait` is a closure.
let mut wait_port: cpuio::Port<u8> = cpuio::Port::new(0x80);
let mut wait = || { wait_port.write(0) };
let mut wait = || wait_port.write(0);

// Save our original interrupt masks, because I'm too lazy to
// figure out reasonable values. We'll restore these when we're
// done.
let saved_mask1 = self.pics[0].data.read();
let saved_mask2 = self.pics[1].data.read();
let saved_masks = self.read_masks();

// Tell each PIC that we're going to send it a three-byte
// initialization sequence on its data port.
Expand Down Expand Up @@ -131,8 +140,23 @@ impl ChainedPics {
wait();

// Restore our saved masks.
self.pics[0].data.write(saved_mask1);
self.pics[1].data.write(saved_mask2);
self.write_masks(saved_masks[0], saved_masks[1])
}

/// Reads the interrupt masks of both PICs.
pub unsafe fn read_masks(&mut self) -> [u8; 2] {
[self.pics[0].read_mask(), self.pics[1].read_mask()]
}

/// Writes the interrupt masks of both PICs.
pub unsafe fn write_masks(&mut self, mask1: u8, mask2: u8) {
self.pics[0].write_mask(mask1);
self.pics[1].write_mask(mask2);
}

/// Disables both PICs by masking all interrupts.
pub unsafe fn disable(&mut self) {
self.write_masks(u8::MAX, u8::MAX)
}

/// Do we handle this interrupt?
Expand Down