diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2010-05-23 11:38:53 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2010-05-23 11:38:53 -0400 |
commit | b5cc2ca5d06b4982139afd1205a0390944c60c7d (patch) | |
tree | 878aa59ad1e9adaf1fe30d3017e0f8966068bca8 | |
parent | 144817be2de1e0f51ad9e138c72660932a4ef07d (diff) | |
download | seabios-b5cc2ca5d06b4982139afd1205a0390944c60c7d.tar.gz |
Generalize timer based delay code.
Move the timer based counting code in serial.c to clock.c.
Rework the interface to make it similar to the tsc based timers.
-rw-r--r-- | src/clock.c | 26 | ||||
-rw-r--r-- | src/serial.c | 37 | ||||
-rw-r--r-- | src/util.h | 3 |
3 files changed, 34 insertions, 32 deletions
diff --git a/src/clock.c b/src/clock.c index 05679550..062658c1 100644 --- a/src/clock.c +++ b/src/clock.c @@ -54,7 +54,6 @@ * TSC timer ****************************************************************/ -#define TICKS_PER_DAY (u32)((u64)60*60*24*PIT_TICK_RATE / PIT_TICK_INTERVAL) #define CALIBRATE_COUNT 0x800 // Approx 1.7ms u32 cpu_khz VAR16VISIBLE; @@ -223,6 +222,31 @@ timer_setup(void) * Standard clock functions ****************************************************************/ +#define TICKS_PER_DAY (u32)((u64)60*60*24*PIT_TICK_RATE / PIT_TICK_INTERVAL) + +// Calculate the timer value at 'count' number of full timer ticks in +// the future. +u32 +calc_future_timer_ticks(u32 count) +{ + return (GET_BDA(timer_counter) + count + 1) % TICKS_PER_DAY; +} +// Return the timer value that is 'msecs' time in the future. +u32 +calc_future_timer(u32 msecs) +{ + u32 kticks = DIV_ROUND_UP((u64)(msecs * PIT_TICK_RATE), PIT_TICK_INTERVAL); + u32 ticks = DIV_ROUND_UP(kticks, 1000); + return calc_future_timer_ticks(ticks); +} +// Check if the given timer value has passed. +int +check_timer(u32 end) +{ + return (((GET_BDA(timer_counter) + TICKS_PER_DAY - end) % TICKS_PER_DAY) + < (TICKS_PER_DAY/2)); +} + // get current clock count static void handle_1a00(struct bregs *regs) diff --git a/src/serial.c b/src/serial.c index 3f68bc47..21b4bd01 100644 --- a/src/serial.c +++ b/src/serial.c @@ -9,31 +9,6 @@ #include "util.h" // debug_enter #include "bregs.h" // struct bregs -// Timers based on 18.2Hz clock irq. -struct tick_timer_s { - u16 last_tick, remaining; -}; - -struct tick_timer_s -initTickTimer(u16 count) -{ - struct tick_timer_s tt = {GET_BDA(timer_counter), count}; - return tt; -} - -int -checkTickTimer(struct tick_timer_s *tt) -{ - u16 timer = GET_BDA(timer_counter); - if (tt->last_tick != timer) { - tt->last_tick = timer; - tt->last_tick--; - if (!tt->last_tick) - return 1; - } - return 0; -} - /**************************************************************** * COM ports @@ -117,7 +92,7 @@ handle_1401(struct bregs *regs) u16 addr = getComAddr(regs); if (!addr) return; - struct tick_timer_s tt = initTickTimer(GET_BDA(com_timeout[regs->dx])); + u32 end = calc_future_timer_ticks(GET_BDA(com_timeout[regs->dx])); for (;;) { u8 lsr = inb(addr+SEROFF_LSR); if ((lsr & 0x60) == 0x60) { @@ -127,7 +102,7 @@ handle_1401(struct bregs *regs) regs->ah = lsr; break; } - if (checkTickTimer(&tt)) { + if (check_timer(end)) { // Timed out - can't write data. regs->ah = lsr | 0x80; break; @@ -144,7 +119,7 @@ handle_1402(struct bregs *regs) u16 addr = getComAddr(regs); if (!addr) return; - struct tick_timer_s tt = initTickTimer(GET_BDA(com_timeout[regs->dx])); + u32 end = calc_future_timer_ticks(GET_BDA(com_timeout[regs->dx])); for (;;) { u8 lsr = inb(addr+SEROFF_LSR); if (lsr & 0x01) { @@ -153,7 +128,7 @@ handle_1402(struct bregs *regs) regs->ah = lsr; break; } - if (checkTickTimer(&tt)) { + if (check_timer(end)) { // Timed out - can't read data. regs->ah = lsr | 0x80; break; @@ -261,7 +236,7 @@ handle_1700(struct bregs *regs) if (!addr) return; - struct tick_timer_s tt = initTickTimer(GET_BDA(lpt_timeout[regs->dx])); + u32 end = calc_future_timer_ticks(GET_BDA(lpt_timeout[regs->dx])); outb(regs->al, addr); u8 val8 = inb(addr+2); @@ -276,7 +251,7 @@ handle_1700(struct bregs *regs) regs->ah = v ^ 0x48; break; } - if (checkTickTimer(&tt)) { + if (check_timer(end)) { // Timeout regs->ah = (v ^ 0x48) | 0x01; break; @@ -304,6 +304,9 @@ void usleep(u32 count); void msleep(u32 count); u64 calc_future_tsc(u32 msecs); u64 calc_future_tsc_usec(u32 usecs); +u32 calc_future_timer_ticks(u32 count); +u32 calc_future_timer(u32 msecs); +int check_timer(u32 end); void handle_1583(struct bregs *regs); void handle_1586(struct bregs *regs); void useRTC(void); |