summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-07-05 15:41:36 -0700
committerH. Peter Anvin <hpa@zytor.com>2010-07-05 15:41:36 -0700
commit4a770eb97fc40ec8d9f394337614ac3c2074ee01 (patch)
tree975f52729eeb9b119c624308d454b214abec91f5
parent7072cf57e5f43449223c1fe75aebcbf82659e515 (diff)
downloadsyslinux-4a770eb97fc40ec8d9f394337614ac3c2074ee01.tar.gz
core: add a ms-denominated timer
Add a timer denominated in milliseconds. This is still driven by the 18.2 Hz timer interrupt, but counts "real" milliseconds, including handing the adjustment factor (which in reality means it advances by 55 for most timer ticks and 54 for some.) Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--com32/include/syslinux/pmapi.h4
-rw-r--r--core/include/core.h6
-rw-r--r--core/pmapi.c3
-rw-r--r--core/timer.inc15
4 files changed, 25 insertions, 3 deletions
diff --git a/com32/include/syslinux/pmapi.h b/com32/include/syslinux/pmapi.h
index c325b62b..fa390185 100644
--- a/com32/include/syslinux/pmapi.h
+++ b/com32/include/syslinux/pmapi.h
@@ -70,6 +70,10 @@ struct com32_pmapi {
int (*chdir)(const char *);
char *(*getcwd)(char *, size_t);
+
+ /* Should be "const volatile", but gcc miscompiles that sometimes */
+ volatile uint32_t *jiffies;
+ volatile uint32_t *ms_timer;
};
#endif /* _SYSLINUX_PMAPI_H */
diff --git a/core/include/core.h b/core/include/core.h
index eb7bfcdb..7db5dafe 100644
--- a/core/include/core.h
+++ b/core/include/core.h
@@ -65,10 +65,14 @@ __noreturn _kaboom(void);
/*
* Basic timer function...
*/
-extern volatile uint32_t __jiffies;
+extern volatile uint32_t __jiffies, __ms_timer;
static inline uint32_t jiffies(void)
{
return __jiffies;
}
+static inline uint32_t ms_timer(void)
+{
+ return __ms_timer;
+}
#endif /* CORE_H */
diff --git a/core/pmapi.c b/core/pmapi.c
index ff655330..4b1ccbb1 100644
--- a/core/pmapi.c
+++ b/core/pmapi.c
@@ -37,4 +37,7 @@ const struct com32_pmapi pm_api_vector =
.chdir = chdir,
.getcwd = getcwd,
+
+ .jiffies = &__jiffies,
+ .ms_timer = &__ms_timer,
};
diff --git a/core/timer.inc b/core/timer.inc
index 728812b1..b01ff917 100644
--- a/core/timer.inc
+++ b/core/timer.inc
@@ -19,6 +19,9 @@
;; about the BIOS_timer variable wrapping around at "midnight" and other
;; weird things.
;;
+;; This also maintains a timer variable calibrated in milliseconds
+;; (wraparound time = 49.7 days!)
+;;
section .text16
@@ -35,12 +38,20 @@ timer_cleanup:
mov [BIOS_timer_hook],eax
ret
+;
+; The specified frequency is 14.31818 MHz/12/65536; this turns out
+; to be a period of 54.92542 ms, or 0x36.ece8(187c) hexadecimal.
+;
timer_irq:
inc dword [cs:__jiffies]
+ add word [cs:__ms_timer_adj],0xece8
+ adc dword [cs:__ms_timer],0x36
jmp 0:0
BIOS_timer_next equ $-4
section .data16
alignz 4
- global __jiffies
-__jiffies dd 0 ; The actual timer variable
+ global __jiffies, __ms_timer
+__jiffies dd 0 ; Clock tick timer
+__ms_timer dd 0 ; Millisecond timer
+__ms_timer_adj dw 0 ; Millisecond timer correction factor