diff --git a/reactos/hal/halx86/Makefile b/reactos/hal/halx86/Makefile index 2ac742d43ee..b8d26a27ce8 100644 --- a/reactos/hal/halx86/Makefile +++ b/reactos/hal/halx86/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.9 2003/04/27 18:12:15 ekohl Exp $ +# $Id: Makefile,v 1.10 2003/06/19 16:00:03 gvg Exp $ PATH_TO_TOP = ../.. @@ -55,14 +55,13 @@ HAL_OBJECTS = \ misc.o \ mp.o \ pci.o \ - perfcnt.o \ portio.o \ reboot.o \ spinlock.o \ sysbus.o \ sysinfo.o \ time.o \ - udelay.o + timer.o #pwroff.o diff --git a/reactos/hal/halx86/perfcnt.c b/reactos/hal/halx86/perfcnt.c deleted file mode 100644 index e8644ece0cd..00000000000 --- a/reactos/hal/halx86/perfcnt.c +++ /dev/null @@ -1,62 +0,0 @@ -/* $Id: perfcnt.c,v 1.3 2002/09/08 10:22:24 chorns Exp $ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/hal/x86/perfcnt.c - * PURPOSE: Performance counter functions - * PROGRAMMER: David Welch (welch@mcmail.com) - * Eric Kohl (ekohl@rz-online.de) - * UPDATE HISTORY: - * 09/06/2000: Created - */ - - -/* INCLUDES ***************************************************************/ - -#include - -/* FUNCTIONS **************************************************************/ - - -VOID STDCALL -HalCalibratePerformanceCounter(ULONG Count) -{ - ULONG i; - - /* save flags and disable interrupts */ - __asm__("pushf\n\t" \ - "cli\n\t"); - - for (i = 0; i < Count; i++); - - /* restore flags */ - __asm__("popf\n\t"); -} - - -LARGE_INTEGER STDCALL -KeQueryPerformanceCounter(PLARGE_INTEGER PerformanceFreq) -/* - * FUNCTION: Queries the finest grained running count avaiable in the system - * ARGUMENTS: - * PerformanceFreq (OUT) = The routine stores the number of - * performance counters tick per second here - * RETURNS: The performance counter value in HERTZ - * NOTE: Returns the system tick count or the time-stamp on the pentium - */ -{ - if (PerformanceFreq != NULL) - { - PerformanceFreq->QuadPart = 0; - return *PerformanceFreq; - } - else - { - LARGE_INTEGER Value; - - Value.QuadPart = 0; - return Value; - } -} - -/* EOF */ diff --git a/reactos/hal/halx86/timer.c b/reactos/hal/halx86/timer.c new file mode 100644 index 00000000000..6e0825a7044 --- /dev/null +++ b/reactos/hal/halx86/timer.c @@ -0,0 +1,273 @@ +/* + * ReactOS kernel + * Copyright (C) 2000 David Welch + * Copyright (C) 1999 Gareth Owen , Ramon von Handel + * Copyright (C) 1991, 1992 Linus Torvalds + * + * This software 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; either version 2 of the + * License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write + * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, + * MA 02139, USA. + * + */ +/* $Id: timer.c,v 1.1 2003/06/19 16:00:03 gvg Exp $ + * + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/hal/x86/udelay.c + * PURPOSE: Busy waiting + * PROGRAMMER: David Welch (david.welch@seh.ox.ac.uk) + * UPDATE HISTORY: + * 06/11/99 Created + */ + +/* INCLUDES ***************************************************************/ + +#include + +#define NDEBUG +#include + +/* GLOBALS ******************************************************************/ + +static unsigned int delay_count = 1; + +#define TMR_CTRL 0x43 /* I/O for control */ +#define TMR_CNT0 0x40 /* I/O for counter 0 */ +#define TMR_CNT1 0x41 /* I/O for counter 1 */ +#define TMR_CNT2 0x42 /* I/O for counter 2 */ + +#define TMR_SC0 0 /* Select channel 0 */ +#define TMR_SC1 0x40 /* Select channel 1 */ +#define TMR_SC2 0x80 /* Select channel 2 */ + +#define TMR_LOW 0x10 /* RW low byte only */ +#define TMR_HIGH 0x20 /* RW high byte only */ +#define TMR_BOTH 0x30 /* RW both bytes */ + +#define TMR_MD0 0 /* Mode 0 */ +#define TMR_MD1 0x2 /* Mode 1 */ +#define TMR_MD2 0x4 /* Mode 2 */ +#define TMR_MD3 0x6 /* Mode 3 */ +#define TMR_MD4 0x8 /* Mode 4 */ +#define TMR_MD5 0xA /* Mode 5 */ + +#define TMR_BCD 1 /* BCD mode */ + +#define TMR_LATCH 0 /* Latch command */ + +#define TMR_READ 0xF0 /* Read command */ +#define TMR_CNT 0x20 /* CNT bit (Active low, subtract it) */ +#define TMR_STAT 0x10 /* Status bit (Active low, subtract it) */ +#define TMR_CH2 0x8 /* Channel 2 bit */ +#define TMR_CH1 0x4 /* Channel 1 bit */ +#define TMR_CH0 0x2 /* Channel 0 bit */ + +#define MILLISEC 10 /* Number of millisec between interrupts */ +#define HZ (1000 / MILLISEC) /* Number of interrupts per second */ +#define CLOCK_TICK_RATE 1193182 /* Clock frequency of the timer chip */ +#define LATCH (CLOCK_TICK_RATE / HZ) /* Count to program into the timer chip */ +#define PRECISION 8 /* Number of bits to calibrate for delay loop */ + +static BOOLEAN UdelayCalibrated = FALSE; + +/* FUNCTIONS **************************************************************/ + +VOID STDCALL +__KeStallExecutionProcessor(ULONG Loops) +{ + register unsigned int i; + for (i=0; i> 8); /* MSB */ + + /* Stage 1: Coarse calibration */ + + WaitFor8254Wraparound(); + + delay_count = 1; + + do + { + delay_count <<= 1; /* Next delay count to try */ + + WaitFor8254Wraparound(); + + __KeStallExecutionProcessor(delay_count); /* Do the delay */ + + CurCount = Read8254Timer(); + } + while (CurCount > LATCH / 2); + + delay_count >>= 1; /* Get bottom value for delay */ + + /* Stage 2: Fine calibration */ + DbgPrint("delay_count: %d", delay_count); + + calib_bit = delay_count; /* Which bit are we going to test */ + + for (i = 0; i < PRECISION; i++) + { + calib_bit >>= 1; /* Next bit to calibrate */ + if (!calib_bit) + { + break; /* If we have done all bits, stop */ + } + + delay_count |= calib_bit; /* Set the bit in delay_count */ + + WaitFor8254Wraparound(); + + __KeStallExecutionProcessor(delay_count); /* Do the delay */ + + CurCount = Read8254Timer(); + if (CurCount <= LATCH / 2) /* If a tick has passed, turn the */ + { /* calibrated bit back off */ + delay_count &= ~calib_bit; + } + } + + /* We're finished: Do the finishing touches */ + + delay_count /= (MILLISEC / 2); /* Calculate delay_count for 1ms */ + + DbgPrint("]\n"); + DbgPrint("delay_count: %d\n", delay_count); + DbgPrint("CPU speed: %d\n", delay_count / 250); +#if 0 + DbgPrint("About to start delay loop test\n"); + DbgPrint("Waiting for five minutes..."); + for (i = 0; i < (5*60*1000*20); i++) + { + KeStallExecutionProcessor(50); + } + DbgPrint("finished\n"); + for(;;); +#endif +} + + +VOID STDCALL +HalCalibratePerformanceCounter(ULONG Count) +{ + ULONG i; + + /* save flags and disable interrupts */ + __asm__("pushf\n\t" \ + "cli\n\t"); + + for (i = 0; i < Count; i++); + + /* restore flags */ + __asm__("popf\n\t"); +} + + +LARGE_INTEGER STDCALL +KeQueryPerformanceCounter(PLARGE_INTEGER PerformanceFreq) +/* + * FUNCTION: Queries the finest grained running count available in the system + * ARGUMENTS: + * PerformanceFreq (OUT) = The routine stores the number of + * performance counter ticks per second here + * RETURNS: The number of performance counter ticks since boot + */ +{ + LARGE_INTEGER TicksOld; + LARGE_INTEGER TicksNew; + LARGE_INTEGER Value; + ULONG CountsLeft; + + if (NULL != PerformanceFreq) + { + PerformanceFreq->QuadPart = CLOCK_TICK_RATE; + } + + do + { + KeQueryTickCount(&TicksOld); + CountsLeft = Read8254Timer(); + Value.QuadPart = TicksOld.QuadPart * LATCH + (LATCH - CountsLeft); + KeQueryTickCount(&TicksNew); + } + while (TicksOld.QuadPart != TicksNew.QuadPart); + + return Value; +} + +/* EOF */ diff --git a/reactos/hal/halx86/udelay.c b/reactos/hal/halx86/udelay.c deleted file mode 100644 index 8fce2071901..00000000000 --- a/reactos/hal/halx86/udelay.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * ReactOS kernel - * Copyright (C) 2000 David Welch - * Copyright (C) 1999 Gareth Owen , Ramon von Handel - * Copyright (C) 1991, 1992 Linus Torvalds - * - * This software 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; either version 2 of the - * License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; see the file COPYING. If not, write - * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, - * MA 02139, USA. - * - */ -/* $Id: udelay.c,v 1.3 2002/09/08 10:22:25 chorns Exp $ - * - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/hal/x86/udelay.c - * PURPOSE: Busy waiting - * PROGRAMMER: David Welch (david.welch@seh.ox.ac.uk) - * UPDATE HISTORY: - * 06/11/99 Created - */ - -/* INCLUDES ***************************************************************/ - -#include - -#define NDEBUG -#include - -/* GLOBALS ******************************************************************/ - -static unsigned int delay_count = 1; - -#define MILLISEC (10) -#define FREQ (1000/MILLISEC) - -#define PRECISION (8) - -#define TMR_CTRL 0x43 /* I/O for control */ -#define TMR_CNT0 0x40 /* I/O for counter 0 */ -#define TMR_CNT1 0x41 /* I/O for counter 1 */ -#define TMR_CNT2 0x42 /* I/O for counter 2 */ - -#define TMR_SC0 0 /* Select channel 0 */ -#define TMR_SC1 0x40 /* Select channel 1 */ -#define TMR_SC2 0x80 /* Select channel 2 */ - -#define TMR_LOW 0x10 /* RW low byte only */ -#define TMR_HIGH 0x20 /* RW high byte only */ -#define TMR_BOTH 0x30 /* RW both bytes */ - -#define TMR_MD0 0 /* Mode 0 */ -#define TMR_MD1 0x2 /* Mode 1 */ -#define TMR_MD2 0x4 /* Mode 2 */ -#define TMR_MD3 0x6 /* Mode 3 */ -#define TMR_MD4 0x8 /* Mode 4 */ -#define TMR_MD5 0xA /* Mode 5 */ - -#define TMR_BCD 1 /* BCD mode */ - -#define TMR_LATCH 0 /* Latch command */ - -#define TMR_READ 0xF0 /* Read command */ -#define TMR_CNT 0x20 /* CNT bit (Active low, subtract it) */ -#define TMR_STAT 0x10 /* Status bit (Active low, subtract it) */ -#define TMR_CH2 0x8 /* Channel 2 bit */ -#define TMR_CH1 0x4 /* Channel 1 bit */ -#define TMR_CH0 0x2 /* Channel 0 bit */ - -static BOOLEAN UdelayCalibrated = FALSE; - -/* FUNCTIONS **************************************************************/ - -void init_pit(float h, unsigned char channel) -{ - unsigned int temp=0; - - temp = 1193180/h; - -// WRITE_PORT_UCHAR((PUCHAR)TMR_CTRL, -// (channel*0x40) + TMR_BOTH + TMR_MD3); - WRITE_PORT_UCHAR((PUCHAR)TMR_CTRL, - (channel*0x40) + TMR_BOTH + TMR_MD2); - WRITE_PORT_UCHAR((PUCHAR)(0x40+channel), - (unsigned char) temp); - WRITE_PORT_UCHAR((PUCHAR)(0x40+channel), - (unsigned char) (temp>>8)); -} - -VOID STDCALL -__KeStallExecutionProcessor(ULONG Loops) -{ - register unsigned int i; - for (i=0; i> 8); /* MSB */ - - /* Stage 1: Coarse calibration */ - - WaitFor8254Wraparound(); - - delay_count = 1; - - do { - delay_count <<= 1; /* Next delay count to try */ - - WaitFor8254Wraparound(); - - __KeStallExecutionProcessor(delay_count); /* Do the delay */ - - CurCount = Read8254Timer(); - } while (CurCount > LATCH / 2); - - delay_count >>= 1; /* Get bottom value for delay */ - - /* Stage 2: Fine calibration */ - DbgPrint("delay_count: %d", delay_count); - - calib_bit = delay_count; /* Which bit are we going to test */ - - for(i=0;i>= 1; /* Next bit to calibrate */ - if(!calib_bit) break; /* If we have done all bits, stop */ - - delay_count |= calib_bit; /* Set the bit in delay_count */ - - WaitFor8254Wraparound(); - - __KeStallExecutionProcessor(delay_count); /* Do the delay */ - - CurCount = Read8254Timer(); - if (CurCount <= LATCH / 2) /* If a tick has passed, turn the */ - delay_count &= ~calib_bit; /* calibrated bit back off */ - } - - /* We're finished: Do the finishing touches */ - - delay_count /= (MILLISEC / 2); /* Calculate delay_count for 1ms */ - - DbgPrint("]\n"); - DbgPrint("delay_count: %d\n", delay_count); - DbgPrint("CPU speed: %d\n", delay_count/250); -#if 0 - DbgPrint("About to start delay loop test\n"); - DbgPrint("Waiting for five minutes..."); - for (i = 0; i < (5*60*1000*20); i++) - { - KeStallExecutionProcessor(50); - } - DbgPrint("finished\n"); - for(;;); -#endif -} - -/* EOF */