diff options
author | Anton Kling <anton@kling.gg> | 2024-07-03 01:21:16 +0200 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2024-07-03 01:21:28 +0200 |
commit | dd9aece19f93c1cafe07dfc0e63e1599a06db04b (patch) | |
tree | af5ef66b2eba21d0eaa2d3a00abcfec64cea98b4 /kernel/arch | |
parent | 5751b4ff0baf41fd3f38b30b0cb58d09631e9bc0 (diff) |
Kernel: Add simple support for timer using TSC
Diffstat (limited to 'kernel/arch')
-rw-r--r-- | kernel/arch/i386/asm_tsc.s | 63 | ||||
-rw-r--r-- | kernel/arch/i386/tsc.h | 4 |
2 files changed, 67 insertions, 0 deletions
diff --git a/kernel/arch/i386/asm_tsc.s b/kernel/arch/i386/asm_tsc.s new file mode 100644 index 0000000..963687e --- /dev/null +++ b/kernel/arch/i386/asm_tsc.s @@ -0,0 +1,63 @@ +.intel_syntax noprefix + +.global get_tsc +.global get_hz + +# 1.193182 MHz +# So 0xFFFF is roughly 0.05492 seconds +# So take the result times 18 and you got your Hz + +get_tsc: + rdtsc + ret + +get_hz: + cli + # Disable the gate for channel 2 so the clock can be set. + # This should only matter if the channel already has count + inb al, 0x61 + and al, 0xFE + or al, 0x1 + outb 0x61, al + + # Set mode + mov al, 0b10110010 + outb 0x43, al + + # 0x2e9b = 11931 which is close to the PIT Hz divided by 100 + mov al, 0x9b + outb 0x42, al + mov al, 0x2e + outb 0x42, al + + rdtsc + mov ecx, eax + mov esi, edx + + # Set the gate for channel 2 + inb al, 0x61 + or al, 0x1 + outb 0x61, al + + # The fifth bit will(seems to) flip when the count is low. + and al, 0x20 + jnz none_zero_check + +zero_check: + inb al, 0x61 + andb al, 0x20 + cmp al, 0 + jz zero_check + jmp end + +none_zero_check: + inb al, 0x61 + andb al, 0x20 + cmp al, 0 + jnz none_zero_check +end: + rdtsc + + sub eax, ecx + sub edx, esi + ret diff --git a/kernel/arch/i386/tsc.h b/kernel/arch/i386/tsc.h new file mode 100644 index 0000000..2e29cf3 --- /dev/null +++ b/kernel/arch/i386/tsc.h @@ -0,0 +1,4 @@ +#include <typedefs.h> + +u64 get_tsc(); +u64 get_hz(); |