2021-10-09 06:11:52 +00:00
|
|
|
|
2021-10-09 18:00:32 +00:00
|
|
|
use std::iter;
|
|
|
|
|
2021-10-09 06:11:52 +00:00
|
|
|
use crate::error::Error;
|
2021-10-17 17:39:43 +00:00
|
|
|
use crate::devices::TransmutableBox;
|
2021-10-09 06:11:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
pub struct InterruptController {
|
2021-10-17 17:39:43 +00:00
|
|
|
pub target: Option<TransmutableBox>,
|
2021-10-30 05:02:29 +00:00
|
|
|
pub interrupts: Vec<(bool, u8)>,
|
|
|
|
pub highest: u8,
|
2021-10-09 06:11:52 +00:00
|
|
|
}
|
|
|
|
|
2021-10-09 18:00:32 +00:00
|
|
|
impl InterruptController {
|
|
|
|
pub fn new() -> InterruptController {
|
|
|
|
InterruptController {
|
|
|
|
target: None,
|
2021-10-30 05:02:29 +00:00
|
|
|
interrupts: vec![(false, 0); 7],
|
|
|
|
highest: 0,
|
2021-10-09 18:00:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-17 17:39:43 +00:00
|
|
|
pub fn set_target(&mut self, dev: TransmutableBox) -> Result<(), Error> {
|
2021-10-09 18:00:32 +00:00
|
|
|
if self.target.is_some() {
|
|
|
|
return Err(Error::new("Interruptable device already set, and interrupt controller only supports one receiver"));
|
|
|
|
}
|
|
|
|
|
|
|
|
self.target = Some(dev);
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set(&mut self, state: bool, priority: u8, number: u8) -> Result<(), Error> {
|
2021-10-30 05:02:29 +00:00
|
|
|
self.interrupts[priority as usize].0 = state;
|
|
|
|
self.interrupts[priority as usize].1 = number;
|
|
|
|
if state && priority > self.highest {
|
|
|
|
self.highest = priority;
|
2021-10-09 18:00:32 +00:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2021-10-30 05:02:29 +00:00
|
|
|
pub fn check(&mut self) -> (bool, u8) {
|
|
|
|
if self.highest > 0 {
|
|
|
|
(true, self.highest)
|
|
|
|
} else {
|
|
|
|
(false, 0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn acknowledge(&mut self, priority: u8) -> Result<u8, Error> {
|
|
|
|
let acknowledge = self.interrupts[priority as usize].1;
|
|
|
|
self.interrupts[priority as usize].0 = false;
|
|
|
|
while self.highest > 0 && !self.interrupts[self.highest as usize].0 {
|
|
|
|
self.highest -= 1;
|
2021-10-09 18:00:32 +00:00
|
|
|
}
|
2021-10-30 05:02:29 +00:00
|
|
|
Ok(acknowledge)
|
2021-10-09 18:00:32 +00:00
|
|
|
}
|
|
|
|
}
|
2021-10-09 06:11:52 +00:00
|
|
|
|