diff options
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(); |