Add drivers/pit.c by 3Hren.
This commit is contained in:
parent
703ddafc34
commit
c84d214daa
2
Makefile
2
Makefile
@ -76,7 +76,7 @@ image.bin: mbr.bin fs.img
|
||||
|
||||
kernel.bin: kernel.o console.o drivers/vga.o drivers/keyboard.o \
|
||||
drivers/ata.o cpu/vectors.o cpu/idt.o cpu/gdt.o drivers/uart.o \
|
||||
fs/fs.o lib/mem.o lib/string.o proc.o cpu/swtch.o
|
||||
fs/fs.o lib/mem.o lib/string.o proc.o cpu/swtch.o drivers/pit.o
|
||||
$(LD) $(LDFLAGS) $(LDKERNELFLAGS) -o $@ -Ttext 0x1000 $^
|
||||
|
||||
%.o: %.c
|
||||
|
||||
76
drivers/pit.c
Normal file
76
drivers/pit.c
Normal file
@ -0,0 +1,76 @@
|
||||
#include "pit.h"
|
||||
#include "port.h"
|
||||
#include "../cpu/isr.h"
|
||||
|
||||
enum {
|
||||
PIT_CRYSTAL_HZ = 1193182,
|
||||
|
||||
CLOCK_PRECISION_HZ = 100,
|
||||
|
||||
PIT_PROGRAM_REG = PIT_CRYSTAL_HZ / CLOCK_PRECISION_HZ,
|
||||
|
||||
PIT_SELECT_CHANNEL0 = 0x0,
|
||||
PIT_SELECT_CHANNEL1 = 0x1,
|
||||
PIT_SELECT_CHANNEL2 = 0x2,
|
||||
PIT_SELECT_CHANNEL_RB = 0x3,
|
||||
PIT_ACCESS_MODE_LATCH_COUNT_VALUE_COMMAND = 0x0,
|
||||
PIT_ACCESS_MODE_LOBYTE_ONLY = 0x1,
|
||||
PIT_ACCESS_MODE_HIBYTE_ONLY = 0x2,
|
||||
PIT_ACCESS_MODE_LOHIBYTE = 0x3,
|
||||
PIT_MODE_INTERRUPT_ON_TERMINAL_COUNT = 0x0,
|
||||
PIT_MODE_HW_ONESHOT = 0x1,
|
||||
PIT_MODE_RATE_GENERATOR = 0x2,
|
||||
PIT_MODES_SQUARE_WAVE_GENERATOR = 0x3,
|
||||
PIT_MODES_SW_TRIGGERRED_STROBE = 0x4,
|
||||
PIT_MODES_HW_TRIGGERRED_STROBE = 0x5,
|
||||
};
|
||||
|
||||
static timer_callback callbacks[100];
|
||||
static int registered_callbacks = 0;
|
||||
|
||||
void add_timer_callback(timer_callback tc) {
|
||||
callbacks[registered_callbacks++] = tc;
|
||||
}
|
||||
|
||||
static void timer_interrupt_handler(registers_t *r) {
|
||||
for (int i = 0; i < registered_callbacks; ++i) {
|
||||
callbacks[i]();
|
||||
}
|
||||
}
|
||||
|
||||
struct pit_command_t {
|
||||
unsigned char bcd : 1;
|
||||
unsigned char operating_mode : 3;
|
||||
unsigned char access_mode : 2;
|
||||
unsigned char select_channel : 2;
|
||||
} __attribute__((packed));
|
||||
|
||||
static void dec_sleep_counter(void);
|
||||
|
||||
void init_pit() {
|
||||
struct pit_command_t cmd = {
|
||||
.select_channel = PIT_SELECT_CHANNEL0,
|
||||
.access_mode = PIT_ACCESS_MODE_LOHIBYTE,
|
||||
.operating_mode = PIT_MODES_SQUARE_WAVE_GENERATOR,
|
||||
.bcd = 0,
|
||||
};
|
||||
port_byte_out(0x43, *(unsigned char *)(&cmd));
|
||||
port_byte_out(0x40, PIT_PROGRAM_REG & 0xff);
|
||||
port_byte_out(0x40, (PIT_PROGRAM_REG & 0xff00) >> 8);
|
||||
|
||||
register_interrupt_handler(IRQ0, timer_interrupt_handler);
|
||||
add_timer_callback(dec_sleep_counter);
|
||||
}
|
||||
|
||||
static int sleep_counter = 0;
|
||||
|
||||
static void dec_sleep_counter(void) {
|
||||
sleep_counter--;
|
||||
}
|
||||
|
||||
void msleep(int ms) {
|
||||
sleep_counter = ms / 10;
|
||||
while (sleep_counter > 0) {
|
||||
asm("hlt");
|
||||
}
|
||||
}
|
||||
8
drivers/pit.h
Normal file
8
drivers/pit.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
typedef void (*timer_callback)(void);
|
||||
|
||||
void init_pit(void);
|
||||
void add_timer_callback(timer_callback tc);
|
||||
|
||||
void msleep(int ms);
|
||||
7
kernel.c
7
kernel.c
@ -7,6 +7,7 @@ asm(".asciz \"kernel start\\n\"");
|
||||
#include "drivers/vga.h"
|
||||
#include "drivers/ata.h"
|
||||
#include "drivers/misc.h"
|
||||
#include "drivers/pit.h"
|
||||
#include "drivers/uart.h"
|
||||
#include "fs/fs.h"
|
||||
#include "lib/string.h"
|
||||
@ -16,6 +17,7 @@ asm(".asciz \"kernel start\\n\"");
|
||||
void _start() {
|
||||
load_gdt();
|
||||
init_keyboard();
|
||||
init_pit();
|
||||
uartinit();
|
||||
load_idt();
|
||||
sti();
|
||||
@ -35,6 +37,11 @@ void _start() {
|
||||
if (kbd_buf_size > 0 && kbd_buf[kbd_buf_size-1] == '\n') {
|
||||
if (!strncmp("halt\n", kbd_buf, kbd_buf_size)) {
|
||||
qemu_shutdown();
|
||||
} else if (!strncmp("work\n", kbd_buf, kbd_buf_size)) {
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
msleep(1000);
|
||||
printk(".");
|
||||
}
|
||||
} else if (!strncmp("run ", kbd_buf, 4)) {
|
||||
kbd_buf[kbd_buf_size-1] = '\0';
|
||||
const char* cmd = kbd_buf + 4;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user