WIP - pit timer
This commit is contained in:
parent
0b27ddca2c
commit
9ae3b014da
@ -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
78
kernel/drivers/pit.c
Normal 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);
|
||||
}
|
@ -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
5
kernel/include/pit.h
Normal 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
7
kernel/include/timer.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
#define TICK_FREQ 1000
|
||||
|
||||
void pit_init();
|
||||
uint64_t get_ticks();
|
Loading…
x
Reference in New Issue
Block a user