implements the PIT
This commit is contained in:
@ -6,6 +6,7 @@
|
|||||||
#include <kernel/_kernel.h>
|
#include <kernel/_kernel.h>
|
||||||
#include <kernel/x86/idt.h>
|
#include <kernel/x86/idt.h>
|
||||||
#include <kernel/x86/pic.h>
|
#include <kernel/x86/pic.h>
|
||||||
|
#include <kernel/x86/pit.h>
|
||||||
#include <kernel/x86/io.h>
|
#include <kernel/x86/io.h>
|
||||||
#include <kernel/x86/keyb.h>
|
#include <kernel/x86/keyb.h>
|
||||||
|
|
||||||
@ -16,8 +17,7 @@ static idtr_t idtr;
|
|||||||
|
|
||||||
static bool vectors[IDT_MAX_DESCRIPTORS];
|
static bool vectors[IDT_MAX_DESCRIPTORS];
|
||||||
|
|
||||||
extern struct keyboard_state keyb_state;
|
extern struct pit_state pit;
|
||||||
|
|
||||||
|
|
||||||
#define EXTERNAL_BIT (0x1)
|
#define EXTERNAL_BIT (0x1)
|
||||||
|
|
||||||
@ -229,6 +229,10 @@ void exception_handler(struct cpu_state __attribute__((unused)) cpu, uint32_t in
|
|||||||
/** EXCEPTIONS END **/
|
/** EXCEPTIONS END **/
|
||||||
|
|
||||||
/** PIC BEGIN **/
|
/** PIC BEGIN **/
|
||||||
|
case PIC_PIT:
|
||||||
|
pit.interrupts++;
|
||||||
|
PIC_sendEOI(0);
|
||||||
|
break;
|
||||||
case PIC_KEYB:
|
case PIC_KEYB:
|
||||||
inbyte = inb(0x60);
|
inbyte = inb(0x60);
|
||||||
do_keypress(decode_scancode(inbyte));
|
do_keypress(decode_scancode(inbyte));
|
||||||
@ -276,6 +280,7 @@ void idt_init(void)
|
|||||||
|
|
||||||
PIC_remap(0x20, 0x28);
|
PIC_remap(0x20, 0x28);
|
||||||
pic_disable(); // mask everything
|
pic_disable(); // mask everything
|
||||||
|
IRQ_clear_mask(0);
|
||||||
IRQ_clear_mask(1);
|
IRQ_clear_mask(1);
|
||||||
|
|
||||||
__asm__ volatile("sti"); // set the interrupt flag
|
__asm__ volatile("sti"); // set the interrupt flag
|
||||||
|
@ -61,4 +61,15 @@ void set_pit_count(uint8_t channel, uint16_t count) // Only in lobyte/hibyte mod
|
|||||||
// TODO: make sure to set interrupts
|
// TODO: make sure to set interrupts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init_pit(uint8_t init_command, uint8_t channel, uint32_t divisor)
|
||||||
|
{
|
||||||
|
uint32_t normalized_div = normalize_divisor(divisor);
|
||||||
|
|
||||||
|
pit.divisor = normalized_div;
|
||||||
|
pit.interrupts = 0;
|
||||||
|
|
||||||
|
outb(PIT_CMD_REG, init_command); // access mode must be lobyte/hibyte
|
||||||
|
|
||||||
|
outb(channel, normalized_div & 0xFF);
|
||||||
|
outb(channel, (normalized_div & 0xFF00) >> 8);
|
||||||
|
}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
enum PIT_CHANNEL {
|
enum PIT_CHANNEL {
|
||||||
CHANNEL_0 = 0x0,
|
CHANNEL_0 = 0x0,
|
||||||
CHANNEL_1,
|
CHANNEL_1, // this channel isn't always here...
|
||||||
CHANNEL_2,
|
CHANNEL_2,
|
||||||
/**
|
/**
|
||||||
* Isn't supported on 8253 chips, but should be supported on AT and later (except for PS/2).
|
* Isn't supported on 8253 chips, but should be supported on AT and later (except for PS/2).
|
||||||
@ -245,9 +245,12 @@ enum PIT_DIGIT_MODE {
|
|||||||
|
|
||||||
struct pit_state {
|
struct pit_state {
|
||||||
uint32_t divisor;
|
uint32_t divisor;
|
||||||
|
// this allows us to track a.. very long time before an overflow... 52ms * INT64MAX = 4.8e20ms = 5.6e12 days = 1.5e7 centuries
|
||||||
|
// TODO: ... handle overflow? :p
|
||||||
|
uint64_t interrupts;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
void init_pit(uint32_t divisor);
|
void init_pit(uint8_t init_command, uint8_t channel, uint32_t divisor);
|
||||||
|
|
||||||
double get_time_from_divisor(uint32_t divisor);
|
double get_time_from_divisor(uint32_t divisor);
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <kernel/x86/idt.h>
|
#include <kernel/x86/idt.h>
|
||||||
#include <kernel/x86/io.h>
|
#include <kernel/x86/io.h>
|
||||||
#include <kernel/x86/keyb.h>
|
#include <kernel/x86/keyb.h>
|
||||||
|
#include <kernel/x86/pit.h>
|
||||||
|
|
||||||
#include <kernel/x86/pit.h>
|
#include <kernel/x86/pit.h>
|
||||||
|
|
||||||
@ -28,6 +29,8 @@ void kmain(void)
|
|||||||
|
|
||||||
init_kb();
|
init_kb();
|
||||||
|
|
||||||
|
init_pit(0x36, PIT_CHANNEL_0, 0);
|
||||||
|
|
||||||
printf("%f\n", get_time_from_divisor(10));
|
printf("%f\n", get_time_from_divisor(10));
|
||||||
|
|
||||||
printf("Entering loop...\n");
|
printf("Entering loop...\n");
|
||||||
|
Reference in New Issue
Block a user