diff --git a/arch/x86/kernel/timer.c b/arch/x86/kernel/timer.c index 0ea49d0b..d6b71d2c 100644 --- a/arch/x86/kernel/timer.c +++ b/arch/x86/kernel/timer.c @@ -127,6 +127,9 @@ int timer_wait(unsigned int ticks) } #define LATCH(f) ((CLOCK_TICK_RATE + f/2) / f) +#define WAIT_SOME_TIME() do { uint64_t start = rdtsc(); \ + while(rdtsc() - start < 1000000) ; \ + } while (0) /* * Sets up the system clock by installing the timer handler @@ -134,10 +137,6 @@ int timer_wait(unsigned int ticks) */ int timer_init(void) { -#ifndef CONFIG_ROCKCREEK - uint64_t start; -#endif - /* * Installs 'timer_handler' for the PIC and APIC timer, * only one handler will be later used. @@ -150,16 +149,27 @@ int timer_init(void) * Therefore, we have not to configure the PIC timer. */ #ifndef CONFIG_ROCKCREEK + /* + * Port 0x43 is for initializing the PIT: + * + * 0x34 means the following: + * 0b... (step-by-step binary representation) + * ... 00 - channel 0 + * ... 11 - write two values to counter register: + * first low-, then high-byte + * ... 010 - mode number 2: "rate generator" / frequency divider + * ... 0 - binary counter (the alternative is BCD) + */ outportb(0x43, 0x34); - /* before we write to 0x40, we wait some time */ - start = rdtsc(); - while(rdtsc() - start < 1000000) - ; + + WAIT_SOME_TIME(); + + /* Port 0x40 is for the counter register of channel 0 */ + outportb(0x40, LATCH(TIMER_FREQ) & 0xFF); /* low byte */ - /* before we write to 0x40, we wait some time */ - start = rdtsc(); - while(rdtsc() - start < 1000000) - ; + + WAIT_SOME_TIME(); + outportb(0x40, LATCH(TIMER_FREQ) >> 8); /* high byte */ #endif