CoolPotOS/kernel/timer.c

119 lines
3.0 KiB
C

#include "../include/timer.h"
#include "../include/io.h"
#include "../include/graphics.h"
#include "../include/cmos.h"
uint32_t tick = 0;
extern struct task_struct *current;
struct TIMERCTL timerctl;
unsigned int time(void) {
unsigned int t;
t = get_year() * get_mon() * get_day_of_month() * get_hour() * get_min() * get_sec() + timerctl.count + timerctl.next;
t |= (int)timerctl.t0;
t |= get_day_of_week();
return t;
}
static void timer_handle(registers_t *regs) {
io_cli();
tick++;
schedule();
io_sti();
}
void clock_sleep(uint32_t timer){
uint32_t sleep = tick + timer;
while(1){
printf("");
if(tick >= sleep) break;
}
}
void init_pit(void) {
io_out8(0x43, 0x34);
io_out8(0x40, 0x9c);
io_out8(0x40, 0x2e);
int i;
struct TIMER *t;
timerctl.count = 0;
for (i = 0; i < MAX_TIMER; i++) {
timerctl.timers0[i].flags = 0; /* 没有使用 */
}
t = timer_alloc(); /* 取得一个 */
t->timeout = 0xffffffff;
t->flags = TIMER_FLAGS_USING;
t->next = 0; /* 末尾 */
timerctl.t0 = t; /* 因为现在只有哨兵,所以他就在最前面*/
timerctl.next =
0xffffffff; /* 因为只有哨兵,所以下一个超时时刻就是哨兵的时刻 */
return;
}
void init_timer(uint32_t timer) {
printf("REG TIMER INT: %d, function address: %08x.\n",IRQ0, &timer_handle);
register_interrupt_handler(IRQ0, &timer_handle);
uint32_t divisor = 1193180 / timer;
outb(0x43, 0x36); // 频率
uint8_t l = (uint8_t) (divisor & 0xFF);
uint8_t h = (uint8_t) ((divisor >> 8) & 0xFF);
outb(0x40, l);
outb(0x40, h);
}
struct TIMER *timer_alloc(void) {
int i;
for (i = 0; i < MAX_TIMER; i++) {
if (timerctl.timers0[i].flags == 0) {
timerctl.timers0[i].flags = TIMER_FLAGS_ALLOC;
timerctl.timers0[i].waiter = NULL;
return &timerctl.timers0[i];
}
}
return 0; /* 没找到 */
}
void timer_free(struct TIMER *timer) {
timer->flags = 0; /* 未使用 */
timer->waiter = NULL;
return;
}
void timer_init(struct TIMER *timer, struct FIFO8 *fifo, unsigned char data) {
timer->fifo = fifo;
timer->data = data;
return;
}
void timer_settime(struct TIMER *timer, unsigned int timeout) {
int e;
struct TIMER *t, *s;
timer->timeout = timeout + timerctl.count;
timer->flags = TIMER_FLAGS_USING;
e = io_load_eflags();
t = timerctl.t0;
if (timer->timeout <= t->timeout) {
/* 插入最前面的情况 */
timerctl.t0 = timer;
timer->next = t; /* 下面是设定t */
timerctl.next = timer->timeout;
io_store_eflags(e);
return;
}
for (;;) {
s = t;
t = t->next;
if (timer->timeout <= t->timeout) {
/* 插入s和t之间的情况 */
s->next = timer; /* s下一个是timer */
timer->next = t; /* timer的下一个是t */
io_store_eflags(e);
return;
}
}
}