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
|
.global pit_init
.global pit_interrupt_handler
.global pit_get_ticks
ticks:
.int 0
pit_get_ticks:
mov (ticks),%eax
ret
pit_interrupt_handler:
push %eax // persist
// INC TICK COUNTER
mov $ticks, %eax
incl (%eax)
// ACK IRQ
mov $0x20,%al
out %al,$0x20
pop %eax // load original
///////
pusha //Push all standard registers
push %ds //Push data segment
push %es //etc...
push %fs
push %gs
mov %esp, %eax // remember current %esp
movl $stack_top, %esp // switch to our small scheduler stack
push %eax // set original %esp as param and...
call task_switch_next // call scheduler
mov %eax, %esp // use %esp we got from scheduler
pop %gs
pop %fs
pop %es
pop %ds
popa
iret
pit_init:
// configure ticking 25 times a second
// 1193180 / 25 = 47727.2
mov $47727, %dx
mov $0b00110100, %al
outb %al,$0x43
mov %dx,%ax
out %al, $0x40
xchg %ah,%al
out %al, $0x40
ret
|