Skip to content

Commit dcc14a2

Browse files
author
Ian Seyler
committed
PIT additions
1 parent 8b88a91 commit dcc14a2

File tree

4 files changed

+100
-8
lines changed

4 files changed

+100
-8
lines changed

src/init/pit.asm

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,59 @@
99
init_pit:
1010
; Enable PIT
1111
; Base rate is 1193182 Hz
12-
mov al, 0x36 ; Channel 0 (7:6), Access Mode lo/hi (5:4), Mode 3 (3:1), Binary (0)
12+
mov al, 0x34 ; Channel 0 (7:6), Access Mode lo/hi (5:4), Mode 2 (3:1), Binary (0)
1313
out 0x43, al
14-
mov al, 0x3C ; 60
14+
; Set divisor to 12 (1193182 Hz / 12 = ~99432 Hz)
15+
; This gives a precision of ~10 microseconds
16+
mov al, 0x74
1517
out 0x40, al ; Set low byte of PIT reload value
1618
mov al, 0x00
1719
out 0x40, al ; Set high byte of PIT reload value
18-
; New rate is 19866 Hz (1193182 / 60)
19-
; 0.050286633812733 milliseconds (ms)
20-
; 50.28663381273300814 microseconds (us)
20+
21+
; Create gate for PIT IRQ
22+
mov edi, 0x20
23+
mov eax, pit_irq
24+
call create_gate
25+
26+
; Enable PIT Interrupt via the PIC
27+
in al, 0x21
28+
mov al, 11111110b ; Enable PIT
29+
out 0x21, al
30+
31+
ret
32+
33+
34+
; -----------------------------------------------------------------------------
35+
; os_pit_delay -- Delay by X microseconds
36+
; IN: RAX = Time microseconds
37+
; OUT: All registers preserved
38+
; Note: There are 1,000,000 microseconds in a second
39+
; There are 1,000 milliseconds in a second
40+
os_pit_delay:
41+
push rdx
42+
push rcx
43+
push rbx
44+
push rax
45+
46+
; The PIT only gives us a precision of ~10 microseconds
47+
; We need to divide RAX by 10
48+
mov ecx, 10
49+
xor edx, edx
50+
div rcx
51+
52+
add rax, [p_Counter_Timer]
53+
54+
os_pit_delay_loop:
55+
mov rbx, [p_Counter_Timer]
56+
cmp rax, rbx
57+
jae os_pit_delay_loop
58+
59+
pop rax
60+
pop rbx
61+
pop rcx
62+
pop rdx
2163
ret
64+
; -----------------------------------------------------------------------------
2265

2366

2467
; =============================================================================

src/init/smp.asm

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88

99
init_smp:
10+
sti ; Enable interrupts in case PIT is needed
11+
1012
; Check if we want the AP's to be enabled.. if not then skip to end
1113
cmp byte [cfg_smpinit], 1 ; Check if SMP should be enabled
1214
jne noMP ; If not then skip SMP init
@@ -50,7 +52,7 @@ smp_send_INIT_done:
5052

5153
; Wait 500 microseconds
5254
mov eax, 500
53-
call os_hpet_delay
55+
call delay
5456

5557
mov esi, IM_DetectedCoreIDs
5658
xor ecx, ecx
@@ -82,7 +84,7 @@ smp_send_SIPI_done:
8284

8385
; Wait 10000 microseconds for the AP's to finish
8486
mov eax, 10000
85-
call os_hpet_delay
87+
call delay
8688

8789
noMP:
8890
; Gather and store the APIC ID of the BSP
@@ -100,7 +102,7 @@ noMP:
100102
rdtsc
101103
push rax
102104
mov rax, 1024
103-
call os_hpet_delay
105+
call delay
104106
rdtsc
105107
pop rdx
106108
sub rax, rdx
@@ -109,7 +111,35 @@ noMP:
109111
div rcx
110112
mov [p_cpu_speed], ax
111113

114+
cli ; Disable interrupts in case PIT was needed
115+
116+
ret
117+
118+
119+
; -----------------------------------------------------------------------------
120+
; delay -- Delay by X microseconds
121+
; IN: RAX = Time microseconds
122+
; OUT: All registers preserved
123+
; Note: There are 1,000,000 microseconds in a second
124+
; There are 1,000 milliseconds in a second
125+
delay:
126+
push rax
127+
push rbx
128+
129+
mov rbx, [p_HPET_Address] ; Was HPET detected?
130+
cmp rbx, 0
131+
je delay_pit ; If not, use PIT for timing
132+
call os_hpet_delay
133+
jmp delay_done
134+
135+
delay_pit:
136+
call os_pit_delay
137+
138+
delay_done:
139+
pop rbx
140+
pop rax
112141
ret
142+
; -----------------------------------------------------------------------------
113143

114144

115145
; =============================================================================

src/interrupt.asm

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,22 @@ interrupt_gate: ; handler for all other interrupts
2323
; -----------------------------------------------------------------------------
2424

2525

26+
; -----------------------------------------------------------------------------
27+
; PIT interrupt. IRQ 0x00, INT 0x20
28+
align 16
29+
pit_irq:
30+
push rax
31+
32+
inc qword [p_Counter_Timer]
33+
34+
mov al, 0x20 ; Acknowledge the IRQ
35+
out 0x20, al
36+
37+
pop rax
38+
iretq
39+
; -----------------------------------------------------------------------------
40+
41+
2642
; -----------------------------------------------------------------------------
2743
; Floppy drive interrupt. IRQ 0x06, INT 0x26
2844
; This IRQ runs when floppy drive reads from or writes to whole disk

src/pure64.asm

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,9 @@ pde_end:
769769
call debug_block
770770
%endif
771771

772+
; Configure system timer
773+
; HPET is preferred but may not exist. If there was no ACPI table entry then use PIT
774+
772775
mov rax, [p_HPET_Address]
773776
cmp rax, 0
774777
jz skip_hpet

0 commit comments

Comments
 (0)