Files
my-kern/kernel/cpu/timer.c
2021-02-10 18:56:47 +01:00

68 lines
2.2 KiB
C

//
// Created by rick on 9/22/19.
//
#include "timer.h"
#include <drivers/ports.h>
#include <cpu/isr.h>
#include <libc/libc.h>
#include <libk.h>
#include <kprint.h>
// https://wiki.osdev.org/PIT
#define PIT_MODE_BIN_BCD (1 << 0)
#define PIT_MODE_BIN (0 << 0)
#define PIT_MODE_BCD (1 << 0)
#define PIT_GENERATOR_MODE (0b111 << 1)
#define PIT_MODE_INTERRUPT_ON_TERMINAL_COUNT (0b000 << 1)
#define PIT_MODE_HARDWARE_RETRIGGERABLE_ONE_SHOT (0b001 << 1)
#define PIT_MODE_HARDWARE_RATE_GENERATOR (0b010 << 1)
#define PIT_MODE_HARDWARE_SQUARE_WAVE_GENERATOR (0b011 << 1)
#define PIT_MODE_SOFTWARE_TRIGGERED_STROBE (0b100 << 1)
#define PIT_MODE_HARDWARE_TRIGGERED_STROBE (0b101 << 1)
#define PIT_ACCESS_MODE (0b11 << 4)
#define PIT_ACCESS_MODE_LATCH_COUNT (0b00 << 4)
#define PIT_ACCESS_MODE_L (0b01 << 4)
#define PIT_ACCESS_MODE_H (0b10 << 4)
#define PIT_ACCESS_MODE_LH (0b11 << 4)
#define PIT_CHANNEL (0b11 << 6)
#define PIT_CHANNEL_0 (0b00 << 6)
#define PIT_CHANNEL_1 (0b01 << 6)
#define PIT_CHANNEL_2 (0b10 << 6)
#define PIT_CHANNEL_READ_BACK (0b11 << 6)
u32 tick = 0;
static void timer_callback(registers_t regs) {
tick++;
}
void sleep(u32 milliseconds) {
u32 done = tick + milliseconds;
while (tick != done) {
k_wait_for_interrupt();
}
}
void print_current_tick() {
char msg[32];
memset(msg, 0, 32);
itoa(tick, msg, 10);
kprint(msg);
kprint("\n");
}
int init_timer(u32 freq) {
register_interrupt_handler(IRQ0, timer_callback);
u32 divisor = 1193180 / freq;
u8 low = (u8) (divisor & 0xFF);
u8 high = (u8) ((divisor >> 8) & 0xFF);
port_byte_out(PORT_PIT_COMMAND,
PIT_MODE_BIN | PIT_MODE_HARDWARE_SQUARE_WAVE_GENERATOR | PIT_ACCESS_MODE_LH | PIT_CHANNEL_0);
port_byte_out(PORT_PIT_DATA_0, low);
port_byte_out(PORT_PIT_DATA_0, high);
return 0;
}