From dd9aece19f93c1cafe07dfc0e63e1599a06db04b Mon Sep 17 00:00:00 2001 From: Anton Kling Date: Wed, 3 Jul 2024 01:21:16 +0200 Subject: Kernel: Add simple support for timer using TSC --- kernel/arch/i386/asm_tsc.s | 63 ++++++++++++++++++++++++++++++++++++++++++++++ kernel/arch/i386/tsc.h | 4 +++ 2 files changed, 67 insertions(+) create mode 100644 kernel/arch/i386/asm_tsc.s create mode 100644 kernel/arch/i386/tsc.h (limited to 'kernel/arch') 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 + +u64 get_tsc(); +u64 get_hz(); -- cgit v1.2.3