WIP - pit timer

This commit is contained in:
Thomas Lovén 2017-03-24 11:01:29 +01:00
parent 0b27ddca2c
commit 9ae3b014da
5 changed files with 94 additions and 1 deletions

View File

@ -10,6 +10,7 @@
#include <acpi.h>
#include <apic.h>
#include <sse.h>
#include <timer.h>
void thread_function()
{
@ -38,6 +39,7 @@ int kmain(uint64_t multiboot_magic, void *multiboot_data)
apic_init();
ioapic_init();
sse_init();
pit_init();
process_t *p1 = process_spawn(0);

78
kernel/drivers/pit.c Normal file
View File

@ -0,0 +1,78 @@
#include <timer.h>
#include <int.h>
#include <pit.h>
#include <debug.h>
#include <ports.h>
#include <apic.h>
#include <stdint.h>
#define PIT_CH0 0x40
#define PIT_CH2 0x42
#define PIT_CMD 0x43
#define PIT_USE_CH0 0x00
#define PIT_USE_CH2 0x80
#define PIT_RW_LOHI 0x30
#define PIT_MODE(M) ((M)<<1)
#define PIT_FREQ 1193182
#define CH2_PORT 0x61
#define CH2_ENABLE 0x01
#define CH2_OUT 0x20
void delay(uint8_t ms)
{
// Turn off channel 2
uint8_t ch2 = inb(CH2_PORT);
ch2 &= ~CH2_ENABLE;
outb(CH2_PORT, ch2);
// Set up a countdown on channel 2
outb(PIT_CMD, PIT_USE_CH2 | PIT_RW_LOHI | PIT_MODE(0));
uint16_t count = PIT_FREQ * ms/1000;
outb(PIT_CH2, count & 0xFF);
outb(PIT_CH2, (count >> 8) & 0xFF);
// Turn on channel 2
ch2 |= CH2_ENABLE;
outb(CH2_PORT, ch2);
// Busy wait (Ultimately, we'll only use this a few times during boot)
while(!(inb(CH2_PORT) & CH2_OUT));
}
void pit_delay(uint32_t ms)
{
while(ms > 50)
{
delay(50);
ms -= 50;
}
if(ms)
delay(ms);
}
uint64_t system_ticks = 0;
registers_t *timer_tick(registers_t *r)
{
apic_ack();
system_ticks ++;
return r;
}
uint64_t get_ticks()
{
return system_ticks;
}
void pit_init()
{
register_int_handler(IRQ_INT(IRQ_TIMER), timer_tick);
outb(PIT_CMD, PIT_USE_CH0 | PIT_RW_LOHI | PIT_MODE(3));
uint16_t count = PIT_FREQ/TICK_FREQ;
outb(PIT_CH0, (count & 0xFF));
outb(PIT_CH0, (count >> 8));
IRQ_UNMASK(IRQ_TIMER);
}

View File

@ -68,6 +68,7 @@
#ifndef __ASSEMBLER__
#include <stdint.h>
#include <apic.h>
struct int_gate_descriptor
{
@ -88,7 +89,7 @@ struct idtr
void pic_init();
extern unsigned int irq_map[24];
#define IRQ_INT(irq) (INT_IRQ0 + irq)
#define IRQ_INT(irq) (INT_IRQ0 + IRQ(irq))
#define IRQ(irq) (irq_map[irq])
#define IRQ_MASK(irq) ioapic_mask(IRQ(irq))
#define IRQ_UNMASK(irq) ioapic_unmask(IRQ(irq))

5
kernel/include/pit.h Normal file
View File

@ -0,0 +1,5 @@
#pragma once
#include <stdint.h>
void pit_delay(uint32_t ms);
void pit_init();

7
kernel/include/timer.h Normal file
View File

@ -0,0 +1,7 @@
#pragma once
#include <stdint.h>
#define TICK_FREQ 1000
void pit_init();
uint64_t get_ticks();