Files

50 lines
1.4 KiB
C

#include "pit.h"
#include "i8259.h"
#include "../interrupts/multiprocessing.h"
// Counter to maintain system time
volatile uint32_t pit_timer = 0;
/* void pit_init()
* @output: PIT generates interrupts at interval specified by PIT_INTERVAL
* @description: initializes PIT for scheduling.
*/
void pit_init() {
outb(PIT_MODE, PIT_REG_CMD);
outb((uint8_t) PIT_INTERVAL, PIT_REG_DATA);
outb((uint8_t) (PIT_INTERVAL >> 8), PIT_REG_DATA);
enable_irq(PIT_IRQ);
}
/* void pit_interrupt()
* @output: system switch to another process, for multiprocessing.
* @description: switches between processes to achieve background multiprocessing.
*/
void pit_interrupt() {
cli();
// Increment system time counter
pit_timer++;
send_eoi(PIT_IRQ);
// Do a context switch
int32_t new_terminal = (active_terminal_id + 1) % TERMINAL_COUNT;
terminal_switch_active(new_terminal);
sti();
}
/* void pit_sleep(uint32_t ms)
* @input: ms - milliseconds to wait
* @output: program waits for that many time
* @description: the sleep() function.
*/
void pit_sleep(uint32_t ms) {
uint32_t curr_time = pit_timer;
uint32_t ticks = ms / (MS_IN_S / PIT_FREQ);
uint32_t target_time = curr_time + ticks;
if(target_time < curr_time) {
// Timer wrap-around will happen, first wait for timer to wrap
while(pit_timer >= curr_time) wait_interrupt();
}
while(pit_timer < target_time) wait_interrupt();
}