summaryrefslogtreecommitdiffstats
path: root/src/arch/i386/drivers/timer_bios.c
diff options
context:
space:
mode:
authorAlexey Zaytsev2007-12-01 05:07:01 +0100
committerAlexey Zaytsev2008-03-02 01:15:07 +0100
commit4006d229e50204c93c1aa04c58385ce2e66d597e (patch)
tree1c07ed3523e40304e0c4b81aaa33c6316d1bd11a /src/arch/i386/drivers/timer_bios.c
parent[DHCP] Fix RFC4390 client identifier constructions. (diff)
downloadipxe-4006d229e50204c93c1aa04c58385ce2e66d597e.tar.gz
ipxe-4006d229e50204c93c1aa04c58385ce2e66d597e.tar.xz
ipxe-4006d229e50204c93c1aa04c58385ce2e66d597e.zip
Introduce the new timer subsystem.
Timer subsystem initialization code in core/timer.c Split the BIOS and RTDSC timer drivers from i386_timer.c Split arch/i386/firmware/pcbios/bios.c into the RTSDC timer driver and arch/i386/core/nap.c Split the headers properly: include/unistd.h - delay functions to be used by the gPXE core and drivers. include/gpxe/timer.h - the fimer subsystem interface to be used by the timer drivers and currticks() to be used by the code gPXE subsystems. include/latch.h - removed include/timer.h - scheduled for removal. Some driver are using currticks, which is only for core subsystems. Signed-off-by: Alexey Zaytsev <alexey.zaytsev@gmail.com>
Diffstat (limited to 'src/arch/i386/drivers/timer_bios.c')
-rw-r--r--src/arch/i386/drivers/timer_bios.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/arch/i386/drivers/timer_bios.c b/src/arch/i386/drivers/timer_bios.c
new file mode 100644
index 000000000..f9caf8d9a
--- /dev/null
+++ b/src/arch/i386/drivers/timer_bios.c
@@ -0,0 +1,57 @@
+/*
+ * Etherboot routines for PCBIOS firmware.
+ *
+ * Body of routines taken from old pcbios.S
+ */
+
+#include <gpxe/init.h>
+#include <gpxe/timer.h>
+#include <stdio.h>
+#include <realmode.h>
+#include <bios.h>
+#include <bits/timer2.h>
+
+/* A bit faster actually, but we don't care. */
+#define TIMER2_TICKS_PER_SEC 18
+
+/*
+ * Use direct memory access to BIOS variables, longword 0040:006C (ticks
+ * today) and byte 0040:0070 (midnight crossover flag) instead of calling
+ * timeofday BIOS interrupt.
+ */
+
+static tick_t bios_currticks ( void ) {
+ static int days = 0;
+ uint32_t ticks;
+ uint8_t midnight;
+
+ /* Re-enable interrupts so that the timer interrupt can occur */
+ __asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ "cli\n\t" ) : : );
+
+ get_real ( ticks, BDA_SEG, 0x006c );
+ get_real ( midnight, BDA_SEG, 0x0070 );
+
+ if ( midnight ) {
+ midnight = 0;
+ put_real ( midnight, BDA_SEG, 0x0070 );
+ days += 0x1800b0;
+ }
+
+ return ( (days + ticks) * (USECS_IN_SEC / TIMER2_TICKS_PER_SEC) );
+}
+
+static int bios_ts_init(void)
+{
+ DBG("BIOS timer installed\n");
+ return 0;
+}
+
+struct timer bios_ts __timer ( 02 ) = {
+ .init = bios_ts_init,
+ .udelay = i386_timer2_udelay,
+ .currticks = bios_currticks,
+};
+