diff options
| author | Tianhao Wang <shrik3@mailbox.org> | 2024-06-11 15:06:33 +0200 |
|---|---|---|
| committer | Tianhao Wang <shrik3@mailbox.org> | 2024-06-11 15:17:15 +0200 |
| commit | 49fc3b6df25bea2aaccbe2b26735204e3ee4b809 (patch) | |
| tree | d16c76f6c62c6e268434efc4945135d431cb3fc2 | |
| parent | e148a5e329add10452d86ae8f2da97e545b7ecb2 (diff) | |
dev: add x86 PIT (programmable interrupt timer)
Signed-off-by: Tianhao Wang <shrik3@mailbox.org>
| -rw-r--r-- | src/arch/x86_64/interrupt/pit.rs | 26 | ||||
| -rw-r--r-- | src/lib.rs | 6 |
2 files changed, 31 insertions, 1 deletions
diff --git a/src/arch/x86_64/interrupt/pit.rs b/src/arch/x86_64/interrupt/pit.rs index 8b13789..c1b7c45 100644 --- a/src/arch/x86_64/interrupt/pit.rs +++ b/src/arch/x86_64/interrupt/pit.rs @@ -1 +1,27 @@ +// x86 programmable interrupt timer +// TODO there should be an machine level timer abstraction +use crate::machine::device_io::IOPort; +pub struct PIT {} +impl PIT { + const CTRL_PORT: IOPort = IOPort::new(0x43); + const DATA_PORT: IOPort = IOPort::new(0x40); + const PIT_BASE_FREQ: u64 = 1193182; + // 1193182 Hz is roughly 838 ns + const PIT_BASE_NS: u64 = 838; + // max is around 54918 us (54 ms) + pub fn set_interval(us: u64) -> u64 { + let mut divider = (us * 1000 + Self::PIT_BASE_NS / 2) / Self::PIT_BASE_NS; + if divider == 0 { + panic!("how on earth can you make a zero divider?") + } + if divider >= 65535 { + divider = 65535; + } + // TODO 65536 actually translates to 0 + Self::CTRL_PORT.outb(0x34); + Self::DATA_PORT.outb((divider & 0xff) as u8); + Self::DATA_PORT.outb(((divider & 0xff00) >> 8) as u8); + return divider * Self::PIT_BASE_NS; + } +} @@ -55,13 +55,16 @@ pub extern "C" fn _entry() -> ! { bss_start(), bss_end() ); + let interval = interrupt::pit::PIT::set_interval(500000); + println!("[init] timer interrupt set to {} ns", interval); // busy loop query keyboard interrupt::interrupt_enable(); pic_8259::allow(PicDeviceInt::KEYBOARD); let mut test_vec = Vec::<&str>::new(); + _test_proc_switch_to(); + // default test, should not reach test_vec.push("hello "); test_vec.push("world"); - _test_proc_switch_to(); for s in test_vec.iter() { println!("{s}"); } @@ -89,5 +92,6 @@ pub fn _test_proc_switch_to() { SCHEDULER.lock().insert_task(Task::create_dummy(3)); SCHEDULER.lock().insert_task(Task::create_dummy(4)); SCHEDULER.lock().insert_task(Task::create_dummy(5)); + pic_8259::allow(PicDeviceInt::TIMER); Scheduler::kickoff(); } |
