63 lines
1.2 KiB
C
63 lines
1.2 KiB
C
|
|
#include <types.h>
|
||
|
|
#include <port_io.h>
|
||
|
|
#include <stdio.h>
|
||
|
|
|
||
|
|
#include <scheduler.h>
|
||
|
|
|
||
|
|
#include <drivers/pit.h>
|
||
|
|
|
||
|
|
|
||
|
|
#define PIT_CHANNEL0 0x40
|
||
|
|
#define PIT_COMMAND 0x43
|
||
|
|
#define PIT_IRQ_LINE 0
|
||
|
|
#define PIT_FREQUENCY_BASE 1193182
|
||
|
|
|
||
|
|
volatile uint64_t pit_ticks = 0;
|
||
|
|
bool pit_initialized = false;
|
||
|
|
|
||
|
|
void pit_init(void)
|
||
|
|
{
|
||
|
|
#ifdef _DEBUG
|
||
|
|
printf("[ PIT ] Initializing the PIT...\n");
|
||
|
|
#endif
|
||
|
|
|
||
|
|
uint16_t divisor = (uint16_t) 1193;
|
||
|
|
|
||
|
|
/* Send command byte */
|
||
|
|
outb(PIT_COMMAND, 0x36); /* Channel 0, low/high byte, mode 3 (square wave), binary */
|
||
|
|
|
||
|
|
/* Send divisor low and high byte */
|
||
|
|
outb(PIT_CHANNEL0, (uint8_t)(divisor & 0xFF)); /* Low byte */
|
||
|
|
outb(PIT_CHANNEL0, (uint8_t)((divisor >> 8) & 0xFF)); /* High byte */
|
||
|
|
|
||
|
|
pit_initialized = true;
|
||
|
|
|
||
|
|
#ifdef _DEBUG
|
||
|
|
printf("[ PIT ] PIT Initialized\n");
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
void pit_handler(void)
|
||
|
|
{
|
||
|
|
pit_ticks++;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*void pit_sleep(uint64_t ms)
|
||
|
|
{
|
||
|
|
uint64_t target = pit_ticks + ms;
|
||
|
|
while (pit_ticks < target)
|
||
|
|
{
|
||
|
|
asm volatile ("hlt");
|
||
|
|
}
|
||
|
|
}*/
|
||
|
|
|
||
|
|
void pit_sleep(uint64_t ms)
|
||
|
|
{
|
||
|
|
extern task_t* current_task;
|
||
|
|
|
||
|
|
current_task->wakeup_tick = pit_ticks + ms;
|
||
|
|
current_task->state = TASK_SLEEPING;
|
||
|
|
|
||
|
|
asm volatile("int $32"); /* force reschedule immediately */
|
||
|
|
}
|