43 lines
1.4 KiB
Rust
43 lines
1.4 KiB
Rust
|
use crate::{
|
||
|
interrupts::{self, EoiGuard},
|
||
|
println, TASKING,
|
||
|
};
|
||
|
use spin::Mutex;
|
||
|
use x86_64::instructions::port::{Port, PortWriteOnly};
|
||
|
|
||
|
static DATA: Mutex<Port<u8>> = Mutex::new(Port::new(0x40));
|
||
|
static CMD: Mutex<PortWriteOnly<u8>> = Mutex::new(PortWriteOnly::new(0x43));
|
||
|
|
||
|
const MAX_FREQ: u32 = 1_193_180;
|
||
|
|
||
|
pub fn init(mut freq: u32) {
|
||
|
interrupts::register_handler(0, handler).unwrap();
|
||
|
let mut div = MAX_FREQ / freq;
|
||
|
if div > 65535 {
|
||
|
println!("[PIT] Frequency of {}Hz too slow, min freq is 18 Hz", freq);
|
||
|
div = 65535;
|
||
|
freq = 18;
|
||
|
} else if div == 0 {
|
||
|
println!("[PIT] Frequency of {}Hz too fast, max freq is {} Hz", freq, MAX_FREQ);
|
||
|
div = 1;
|
||
|
freq = MAX_FREQ;
|
||
|
}
|
||
|
println!("[PIT] Setting PIT to {}Hz with divisor of {}", freq, div);
|
||
|
// Command breakdown (MSB to LSB):
|
||
|
// 00 - Channel 0
|
||
|
// 11 - lobyte/hibyte access mode - set both bytes in one command
|
||
|
// 011 - Mode 3, sqaure wave generator at frequency MAX_FREQ/div, generates interrupts at that
|
||
|
// frequency
|
||
|
// 0 - binary mode, always used
|
||
|
unsafe { CMD.lock().write(0b0011_0110_u8) };
|
||
|
unsafe { DATA.lock().write((div & 0xFF) as u8) };
|
||
|
unsafe { DATA.lock().write(((div >> 8) & 0xFF) as u8) };
|
||
|
}
|
||
|
|
||
|
fn handler(_irq: u8, eoi_guard: EoiGuard) {
|
||
|
drop(eoi_guard);
|
||
|
if let Some(mut tasking) = TASKING.try_lock() {
|
||
|
tasking.task_yield();
|
||
|
}
|
||
|
}
|