Mon 14 Oct 23:06:38 CEST 2024
This commit is contained in:
parent
5b0f5cf2c2
commit
39561050f8
80
kernel/clock.c
Normal file
80
kernel/clock.c
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
Copyright (C) 2015-2019 The University of Notre Dame
|
||||
This software is distributed under the GNU General Public License.
|
||||
See the file LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "interrupt.h"
|
||||
#include "clock.h"
|
||||
#include "ioports.h"
|
||||
#include "process.h"
|
||||
|
||||
// Minimum PIT frequency is 18.2Hz.
|
||||
#define CLICKS_PER_SECOND 20
|
||||
|
||||
#define TIMER0 0x40
|
||||
#define TIMER_MODE 0x43
|
||||
#define SQUARE_WAVE 0x36
|
||||
#define TIMER_FREQ 1193182
|
||||
#define TIMER_COUNT (((unsigned)TIMER_FREQ)/CLICKS_PER_SECOND)
|
||||
|
||||
static uint32_t clicks = 0;
|
||||
static uint32_t seconds = 0;
|
||||
|
||||
static struct list queue = { 0, 0 };
|
||||
|
||||
static void clock_interrupt(int i, int code)
|
||||
{
|
||||
clicks++;
|
||||
process_wakeup_all(&queue);
|
||||
if(clicks >= CLICKS_PER_SECOND) {
|
||||
clicks = 0;
|
||||
seconds++;
|
||||
process_preempt();
|
||||
}
|
||||
}
|
||||
|
||||
clock_t clock_read()
|
||||
{
|
||||
clock_t result;
|
||||
result.seconds = seconds;
|
||||
result.millis = 1000 * clicks / CLICKS_PER_SECOND;
|
||||
return result;
|
||||
}
|
||||
|
||||
clock_t clock_diff(clock_t start, clock_t stop)
|
||||
{
|
||||
clock_t result;
|
||||
if(stop.millis < start.millis) {
|
||||
stop.millis += 1000;
|
||||
stop.seconds -= 1;
|
||||
}
|
||||
result.seconds = stop.seconds - start.seconds;
|
||||
result.millis = stop.millis - start.millis;
|
||||
return result;
|
||||
}
|
||||
|
||||
void clock_wait(uint32_t millis)
|
||||
{
|
||||
clock_t start, elapsed;
|
||||
uint32_t total;
|
||||
|
||||
start = clock_read();
|
||||
do {
|
||||
process_wait(&queue);
|
||||
elapsed = clock_diff(start, clock_read());
|
||||
total = elapsed.millis + elapsed.seconds * 1000;
|
||||
} while(total < millis);
|
||||
}
|
||||
|
||||
void clock_init()
|
||||
{
|
||||
outb(SQUARE_WAVE, TIMER_MODE);
|
||||
outb((TIMER_COUNT & 0xff), TIMER0);
|
||||
outb((TIMER_COUNT >> 8) & 0xff, TIMER0);
|
||||
|
||||
interrupt_register(32, clock_interrupt);
|
||||
interrupt_enable(32);
|
||||
|
||||
printf("clock: ticking\n");
|
||||
}
|
Loading…
Reference in New Issue
Block a user