summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-09-02 17:44:32 -0700
committerH. Peter Anvin <hpa@zytor.com>2009-09-02 17:44:32 -0700
commit75d4dec2f651c9f25fa95d6b6960db7c4dcfd7a0 (patch)
tree1fc477d5f43577a31eaaff7c5a17f719c4e69e1d
parent94a6e382a7a253fdab67a3bff981844dd5f6d4cb (diff)
downloadsyslinux-75d4dec2f651c9f25fa95d6b6960db7c4dcfd7a0.tar.gz
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 <hpa@zytor.com>
-rw-r--r--core/bios.inc7
-rw-r--r--core/cleanup.inc2
-rw-r--r--core/common.inc1
-rw-r--r--core/include/core.h8
-rw-r--r--core/init.inc5
-rw-r--r--core/timer.inc45
6 files changed, 67 insertions, 1 deletions
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
@@ -29,6 +29,11 @@ common_init:
jne kaboom
;
+; Initialize timer
+;
+ call timer_init
+
+;
; Initialize configuration information
;
call reset_config
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