From 75d4dec2f651c9f25fa95d6b6960db7c4dcfd7a0 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 2 Sep 2009 17:44:32 -0700 Subject: core: hook INT 1Ch for a simple monotonic timer The BIOS_timer variable at 4C6h is somewhat unreliable... it is documented to wrap at "midnight", norminally after 1627419 ticks (0x18d51b), which is a rather awkward number to deal with modulo. Instead, hook the INT 1Ch secondary timer interrupt and just count a simple incrementing variable. Signed-off-by: H. Peter Anvin --- core/bios.inc | 7 ++++++- core/cleanup.inc | 2 ++ core/common.inc | 1 + core/include/core.h | 8 ++++++++ core/init.inc | 5 +++++ core/timer.inc | 45 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 core/timer.inc diff --git a/core/bios.inc b/core/bios.inc index 4c6c5b59..33a3cd4c 100644 --- a/core/bios.inc +++ b/core/bios.inc @@ -20,10 +20,15 @@ %define _BIOS_INC global BIOS_fbm, BIOS_timer - absolute 4*1Eh ; In the interrupt table + ; Interrupt vectors + absolute 4*1Ch +BIOS_timer_hook resd 1 + + absolute 4*1Eh fdctab equ $ fdctab1 resw 1 fdctab2 resw 1 + absolute 0400h serial_base resw 4 ; Base addresses for 4 serial ports absolute 0413h diff --git a/core/cleanup.inc b/core/cleanup.inc index 35967f68..300584c7 100644 --- a/core/cleanup.inc +++ b/core/cleanup.inc @@ -52,6 +52,8 @@ cleanup_hardware: call comboot_cleanup_api + call timer_cleanup + popad ; If we enabled serial port interrupts, clean them up now diff --git a/core/common.inc b/core/common.inc index 80dbb4f9..7078011e 100644 --- a/core/common.inc +++ b/core/common.inc @@ -18,6 +18,7 @@ %include "strcpy.inc" ; strcpy() %include "idle.inc" ; Idle handling %include "adv.inc" ; Auxillary Data Vector +%include "timer.inc" ; Timer handling ; Note: the prefix section is included late, to avoid problems with some ; versions of NASM that had issues with forward references to EQU symbols. diff --git a/core/include/core.h b/core/include/core.h index c13aa16f..dbcbff1c 100644 --- a/core/include/core.h +++ b/core/include/core.h @@ -43,5 +43,13 @@ void call16(void (*)(void), const com32sys_t *, com32sys_t *); __noreturn _kaboom(void); #define kaboom() _kaboom() +/* + * Basic timer function... + */ +extern const volatile uint32_t __jiffies; +static inline uint32_t jiffies(void) +{ + return __jiffies; +} #endif /* CORE_H */ diff --git a/core/init.inc b/core/init.inc index 8e393b67..a3fe3041 100644 --- a/core/init.inc +++ b/core/init.inc @@ -28,6 +28,11 @@ common_init: cmp eax,__pm_code_len jne kaboom +; +; Initialize timer +; + call timer_init + ; ; Initialize configuration information ; diff --git a/core/timer.inc b/core/timer.inc new file mode 100644 index 00000000..caae8265 --- /dev/null +++ b/core/timer.inc @@ -0,0 +1,45 @@ +;; ----------------------------------------------------------------------- +;; +;; Copyright 2009 Intel Corporation; author: H. Peter Anvin +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +;; Boston MA 02110-1301, USA; either version 2 of the License, or +;; (at your option) any later version; incorporated herein by reference. +;; +;; ----------------------------------------------------------------------- + +;; +;; timer.inc +;; +;; Very simple counting timer +;; +;; This lets us have a simple incrementing variable without worrying +;; about the BIOS_timer variable wrapping around at "midnight" and other +;; weird things. +;; + + section .text16 + +timer_init: + ; Hook INT 1Ch + mov eax,[BIOS_timer_hook] + mov [BIOS_timer_next],eax + mov dword [BIOS_timer_hook],timer_irq + ret + +timer_cleanup: + ; Unhook INT 1Ch + mov eax,[BIOS_timer_next] + mov [BIOS_timer_hook],eax + ret + +timer_irq: + inc dword [cs:__jiffies] + jmp 0:0 +BIOS_timer_next equ $-4 + + section .bss16 + global __jiffies +__jiffies resd 1 ; The actual timer variable -- cgit v1.2.1