-
Notifications
You must be signed in to change notification settings - Fork 6
/
pit.c
executable file
·107 lines (91 loc) · 1.88 KB
/
pit.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
* pit.c
*
* Created on: 16.03.2014
* Author: pascal
*/
#include "pit.h"
#include "util.h"
#include "list.h"
#include "stdlib.h"
#include "scheduler.h"
#include "lock.h"
#define CH0 0x40
#define CH1 0x41
#define CH2 0x42
#define CH_BASE CH0
#define REGINIT 0x43
#define FRQB 1193182
typedef struct{
thread_t *thread;
uint64_t timeout;
}timer_t;
static list_t Timerlist;
static lock_t Timerlist_lock = LOCK_INIT;
void pit_Init(uint32_t freq)
{
pit_InitChannel(0, 2, (uint64_t)(FRQB / freq));
Timerlist = NULL;
Uptime = 0;
}
void pit_InitChannel(uint8_t channel, uint8_t mode, uint16_t data)
{
if(channel > 2) return;
outb(REGINIT, 0 | ((mode & 0x7) << 1) | (0x3 << 4) | (channel << 6));
outb(CH_BASE + channel, data & 0xFF);
outb(CH_BASE + channel, data >> 8);
}
//Registriert einen Timer
void pit_RegisterTimer(thread_t *thread, uint64_t msec)
{
if(msec != 0)
{
timer_t *Timer;
size_t i;
uint64_t t;
Timer = malloc(sizeof(timer_t));
Timer->thread = thread;
Timer->timeout = ((t = Uptime + msec) < Uptime) ? -1ul : t;
LOCKED_TASK(Timerlist_lock, {
if(Timerlist == NULL)
Timerlist = list_create();
//Timerliste sortiere, sodass das Element vorne immer das Element ist, welches
//zuerst abläuft
timer_t *item;
for(i = 0; (item = list_get(Timerlist, i)); i++)
{
if(item->timeout > Timer->timeout)
break;
}
list_insert(Timerlist, i, Timer);
});
//Entsprechenden Thread schlafen legen
thread_block_self(NULL, NULL, THREAD_BLOCKED_WAIT_TIMER);
}
else
{
//Thread switchen
yield();
}
}
void pit_Handler(void)