Author: ion
Date: Tue Nov 28 11:11:14 2006
New Revision: 24908
URL:
http://svn.reactos.org/svn/reactos?rev=24908&view=rev
Log:
- Fix prototype/definition of HalCalibratePerformanceCounter and properly implement it.
- Implement KeStallExecutionProcessor in its own assembly file isntead of using inlined
GCC assembly, and align the loop to 16 bytes for more streamlined execution speed.
- Mask out clock interrupt during Phase 0 and Initialize clock interrupt on HAL Phase 1.
This enables the HAL clock interrupt which was already written.
- Make the clock interrupt use HalpCurrentTimeIncrement instead of hardcoding a value.
- Re-implement HalpInitializeClock to allow for dynamic increments from 1ms to 15ms with
appropriate rollovers and to call KeSetTimeIncrement to update timer values with the
kernel.
- Implement HalSetTimeIncrement to allow changing the clock ms increment (but this
isn't yet respected).
- Remove system/runtime update routines from the deprecated IRQ implementation and use the
newer assembly ones already written, since we're now using the HAL clock interrupt.
Remove other unused code.
- Fix more bugs in new hal IRQ implementation (that still isn't used yet due to
regressions) and implement HalClearSoftwareInterrupt.
Modified:
trunk/reactos/hal/hal/hal.c
trunk/reactos/hal/hal/hal.def
trunk/reactos/hal/halx86/generic/generic.rbuild
trunk/reactos/hal/halx86/generic/halinit.c
trunk/reactos/hal/halx86/generic/irq.S
trunk/reactos/hal/halx86/generic/irql.c
trunk/reactos/hal/halx86/generic/systimer.S
trunk/reactos/hal/halx86/generic/timer.c
trunk/reactos/hal/halx86/include/halp.h
trunk/reactos/include/ndk/asm.h
trunk/reactos/ntoskrnl/deprecated/irq.c
trunk/reactos/ntoskrnl/ke/i386/irq.c
Modified: trunk/reactos/hal/hal/hal.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/hal/hal.c?rev=24908&am…
==============================================================================
--- trunk/reactos/hal/hal/hal.c (original)
+++ trunk/reactos/hal/hal/hal.c Tue Nov 28 11:11:14 2006
@@ -173,7 +173,8 @@
VOID
NTAPI
HalCalibratePerformanceCounter(
- ULONG Count)
+ volatile LONG *Count,
+ ULONGLONG NewCount)
{
UNIMPLEMENTED;
}
Modified: trunk/reactos/hal/hal/hal.def
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/hal/hal.def?rev=24908&…
==============================================================================
--- trunk/reactos/hal/hal/hal.def (original)
+++ trunk/reactos/hal/hal/hal.def Tue Nov 28 11:11:14 2006
@@ -30,7 +30,7 @@
HalAllocateCrashDumpRegisters@8
HalAssignSlotResources@32
HalBeginSystemInterrupt@12
-HalCalibratePerformanceCounter@4
+HalCalibratePerformanceCounter@12
HalDisableSystemInterrupt@8
HalDisplayString@4
HalEnableSystemInterrupt@12
Modified: trunk/reactos/hal/halx86/generic/generic.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/generic…
==============================================================================
--- trunk/reactos/hal/halx86/generic/generic.rbuild (original)
+++ trunk/reactos/hal/halx86/generic/generic.rbuild Tue Nov 28 11:11:14 2006
@@ -17,6 +17,7 @@
<file>sysbus.c</file>
<file>sysinfo.c</file>
<file>timer.c</file>
+ <file>systimer.S</file>
<pch>../include/hal.h</pch>
</module>
<module name="hal_generic_up" type="objectlibrary">
@@ -28,7 +29,6 @@
<file>irql.c</file>
<file>processor.c</file>
<file>spinlock.c</file>
- <file>systimer.S</file>
</module>
<module name="hal_generic_pc" type="objectlibrary">
<include base="hal_generic_pc">../include</include>
Modified: trunk/reactos/hal/halx86/generic/halinit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/halinit…
==============================================================================
--- trunk/reactos/hal/halx86/generic/halinit.c (original)
+++ trunk/reactos/hal/halx86/generic/halinit.c Tue Nov 28 11:11:14 2006
@@ -113,7 +113,7 @@
HalpInitNonBusHandler();
/* Initialize the clock interrupt */
- //HalpInitPhase1();
+ HalpInitPhase1();
/* Initialize DMA. NT does this in Phase 0 */
HalpInitDma();
Modified: trunk/reactos/hal/halx86/generic/irq.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/irq.S?r…
==============================================================================
--- trunk/reactos/hal/halx86/generic/irq.S (original)
+++ trunk/reactos/hal/halx86/generic/irq.S Tue Nov 28 11:11:14 2006
@@ -67,18 +67,21 @@
.long 0xFFFFFFFB /* IRQL 31 */
HalpSysIntHandler:
-.rept 8
+.rept 7
.long GenericIRQ /* IRQ 0-7 */
.endr
.long IRQ7 /* IRQ 7 */
-.rept 8
+.rept 7
.long GenericIRQ /* IRQ 8-15 */
.endr
.long IRQ15 /* IRQ 15 */
.rept 20
.long GenericIRQ /* IRQ 16-35 */
+.endr
+#if DBG
.rept 172
.long InvalidIRQ /* IRQ 36-207 */
+#endif
.endr
SoftIntByteTable:
@@ -147,25 +150,38 @@
ret
.endfunc
-.globl @HalRequestSoftwareInterrupt@4
-.func @HalRequestSoftwareInterrupt@4
-_@HalRequestSoftwareInterrupt@4:
-@HalRequestSoftwareInterrupt@4:
+.globl @HalClearSoftwareInterrupt@4
+.func @HalClearSoftwareInterrupt@4, @HalClearSoftwareInterrupt@4
+@HalClearSoftwareInterrupt@4:
/* Get IRR mask */
mov eax, 1
shl eax, cl
+ not eax
+
+ /* Set IRR */
+ and PCR[KPCR_IRR], eax
+ ret
+.endfunc
+
+.globl @HalRequestSoftwareInterrupt@4
+.func @HalRequestSoftwareInterrupt@4, @HalRequestSoftwareInterrupt@4
+@HalRequestSoftwareInterrupt@4:
+
+ /* Get IRR mask */
+ mov eax, 1
+ shl eax, cl
/* Disable interrupts */
pushf
cli
/* Set IRR and get IRQL */
- or [fs:KPCR_IRR], eax
- mov ecx, [fs:KPCR_IRQL]
+ or PCR[KPCR_IRR], eax
+ mov ecx, PCR[KPCR_IRQL]
/* Get software IRR mask */
- mov eax, [fs:KPCR_IRR]
+ mov eax, PCR[KPCR_IRR]
and eax, 3
/* Get highest pending software interrupt and check if it's higher */
@@ -196,7 +212,7 @@
mov edx, 1
shl edx, cl
cli
- or [fs:KPCR_IDR], edx
+ or PCR[KPCR_IDR], edx
/* Get the current mask */
xor eax, eax
@@ -263,12 +279,12 @@
shl eax, cl
not eax
cli
- and [fs:KPCR_IDR], eax
+ and PCR[KPCR_IDR], eax
/* Get the current IRQL and mask the IRQs in the PIC */
- mov eax, [fs:KPCR_IRQL]
+ movzx eax, byte ptr PCR[KPCR_IRQL]
mov eax, KiI8259MaskTable[eax*4]
- or eax, [fs:KPCR_IDR]
+ or eax, PCR[KPCR_IDR]
out 0x21, al
shr eax, 8
out 0xA1, al
@@ -281,7 +297,9 @@
Invalid:
/* Fail, invalid IRQ */
+#if DBG
int 3
+#endif
xor eax, eax
ret 12
.endfunc
@@ -291,7 +309,7 @@
_HalBeginSystemInterrupt@12:
/* Convert to IRQ and call the handler */
- mov edx, [esp+8]
+ movzx edx, byte ptr [esp+8]
sub edx, PRIMARY_VECTOR_BASE
jmp HalpSysIntHandler[edx*4]
@@ -326,22 +344,22 @@
GenericIRQ:
/* Return the current IRQL */
mov eax, [esp+12]
- mov ecx, [fs:KPCR_IRQL]
+ movzx ecx, byte ptr PCR[KPCR_IRQL]
mov [eax], cl
/* Set the new IRQL */
movzx eax, byte ptr [esp+4]
- mov [fs:KPCR_IRQL], eax
+ mov PCR[KPCR_IRQL], al
/* Set IRQ mask in the PIC */
mov eax, KiI8259MaskTable[eax*4]
- or eax, [fs:KPCR_IDR]
+ or eax, PCR[KPCR_IDR]
out 0x21, al
shr eax, 8
out 0xA1, al
/* Check to which PIC the EOI was sent */
- mov eax, ebx
+ mov eax, edx
cmp eax, 8
jnb Pic1
@@ -363,11 +381,13 @@
sti
mov eax, 1
ret 12
-
+
+#if DBG
InvalidIRQ:
/* Dismiss it */
mov eax, 0
ret 12
+#endif
.endfunc
.globl _HalEndSystemInterrupt@8
@@ -376,12 +396,12 @@
/* Get the IRQL and check if it's a software interrupt */
movzx ecx, byte ptr [esp+4]
- cmp dword ptr [fs:KPCR_IRQL], DISPATCH_LEVEL
+ cmp byte ptr PCR[KPCR_IRQL], DISPATCH_LEVEL
jbe SkipMask2
/* Hardware interrupt, mask the appropriate IRQs in the PIC */
mov eax, KiI8259MaskTable[ecx*4]
- or eax, [fs:KPCR_IDR]
+ or eax, PCR[KPCR_IDR]
out 0x21, al
shr eax, 8
out 0xA1, al
@@ -389,8 +409,8 @@
SkipMask2:
/* Set IRQL and check if there are pending software interrupts */
- mov [fs:KPCR_IRQL], ecx
- mov eax, [fs:KPCR_IRR]
+ mov PCR[KPCR_IRQL], cl
+ mov eax, PCR[KPCR_IRR]
mov al, SoftIntByteTable[eax]
cmp al, cl
ja DoCall
@@ -411,15 +431,21 @@
/* Save flags since we'll disable interrupts */
pushf
+ /* Validate IRQL */
+ movzx ecx, cl
+#if DBG
+ cmp cl, PCR[KPCR_IRQL]
+ ja InvalidIrql
+#endif
+
/* Disable interrupts and check if IRQL is below DISPATCH_LEVEL */
- movzx ecx, cl
- cmp dword ptr [fs:KPCR_IRQL], DISPATCH_LEVEL
+ cmp byte ptr PCR[KPCR_IRQL], DISPATCH_LEVEL
cli
jbe SkipMask
/* Clear interrupt masks since there's a pending hardware interrupt */
mov eax, KiI8259MaskTable[ecx*4]
- or eax, [fs:KPCR_IDR]
+ or eax, PCR[KPCR_IDR]
out 0x21, al
shr eax, 8
out 0xA1, al
@@ -427,8 +453,8 @@
SkipMask:
/* Set the new IRQL and check if there's a pending software interrupt */
- mov [fs:KPCR_IRQL], ecx
- mov eax, [fs:KPCR_IRR]
+ mov PCR[KPCR_IRQL], cl
+ mov eax, PCR[KPCR_IRR]
mov al, SoftIntByteTable[eax]
cmp al, cl
ja DoCall3
@@ -436,6 +462,22 @@
/* Restore interrupts and return */
popf
ret
+
+#if DBG
+InvalidIrql:
+ /* Set HIGH_LEVEL */
+ movzx eax, byte ptr PCR[KPCR_IRQL]
+ mov byte ptr PCR[KPCR_IRQL], HIGH_LEVEL
+
+ /* Bugcheck the system */
+ push 3
+ push 0
+ push ecx
+ push eax
+ push IRQL_NOT_LESS_OR_EQUAL
+ call _KeBugCheckEx@20
+#endif
+
DoCall3:
/* There is, call it */
call SoftIntHandlerTable[eax*4]
@@ -450,10 +492,19 @@
_@KfRaiseIrql@4:
@KfRaiseIrql@4:
- /* Get the IRQL and check if it's Software level only */
- mov eax, [fs:KPCR_IRQL]
+ /* Get the IRQL */
+ xor eax, eax
+ mov al, PCR[KPCR_IRQL]
movzx ecx, cl
- cmp ecx, DISPATCH_LEVEL
+
+#if DBG
+ /* Validate it */
+ cmp eax, ecx
+ ja InvalidKfRaise
+#endif
+
+ /* Check if it's in the software level */
+ cmp cl, DISPATCH_LEVEL
jbe SetIrql
/* Save the current IRQL */
@@ -464,11 +515,11 @@
cli
/* Set the new IRQL */
- mov [fs:KPCR_IRQL], cl
+ mov PCR[KPCR_IRQL], cl
/* Mask the interrupts in the PIC */
mov eax, KiI8259MaskTable[ecx*4]
- or eax, [fs:KPCR_IDR]
+ or eax, PCR[KPCR_IDR]
out 0x21, al
shr eax, 8
out 0xA1, al
@@ -481,8 +532,22 @@
SetIrql:
/* Set the IRQL and return */
- mov [fs:KPCR_IRQL], ecx
- ret
+ mov PCR[KPCR_IRQL], cl
+ ret
+
+#if DBG
+InvalidKfRaise:
+ /* Set to passive */
+ mov byte ptr PCR[KPCR_IRQL], PASSIVE_LEVEL
+
+ /* Bugcheck the system */
+ push 9
+ push 0
+ push ecx
+ push eax
+ push IRQL_NOT_GREATER_OR_EQUAL
+ call _KeBugCheckEx@20
+#endif
.endfunc
.globl _KeGetCurrentIrql@0
@@ -490,7 +555,7 @@
_KeGetCurrentIrql@0:
/* Return the IRQL */
- mov eax, [fs:KPCR_IRQL]
+ movzx eax, byte ptr PCR[KPCR_IRQL]
ret
.endfunc
@@ -499,11 +564,29 @@
_KeRaiseIrqlToDpcLevel@0:
/* Get the current IRQL */
- mov eax, [fs:KPCR_IRQL]
+ xor eax, eax
+ mov al, PCR[KPCR_IRQL]
/* Set DISPATCH_LEVEL */
- mov dword ptr [fs:KPCR_IRQL], DISPATCH_LEVEL
- ret
+ mov byte ptr PCR[KPCR_IRQL], DISPATCH_LEVEL
+
+#if DBG
+ /* Make sure we were not higher then dispatch */
+ cmp al, DISPATCH_LEVEL
+ ja InvalidRaise
+#endif
+ ret
+
+#if DBG
+InvalidRaise:
+ /* Bugcheck the system */
+ push 1
+ push 0
+ push DISPATCH_LEVEL
+ push eax
+ push IRQL_NOT_GREATER_OR_EQUAL
+ call _KeBugCheckEx@20
+#endif
.endfunc
.globl _KeRaiseIrqlToSynchLevel@0
@@ -516,16 +599,35 @@
/* Mask out interrupts */
mov eax, KiI8259MaskTable[DISPATCH_LEVEL*4]
- or eax, [fs:KPCR_IDR]
+ or eax, PCR[KPCR_IDR]
out 0x21, al
shr eax, 8
out 0xA1, al
/* Return the old IRQL, enable interrupts and set to DISPATCH */
- mov eax, [fs:KPCR_IRQL]
- mov dword ptr [fs:KPCR_IRQL], DISPATCH_LEVEL
+ mov al, PCR[KPCR_IRQL]
+ mov byte ptr PCR[KPCR_IRQL], DISPATCH_LEVEL
popf
- ret
+
+#if DBG
+ /* Validate raise */
+ cmp al, DISPATCH_LEVEL
+ ja InvalidSyRaise
+#endif
+
+ /* Return */
+ ret
+
+#if DBG
+InvalidSyRaise:
+ /* Bugcheck the system */
+ push 2
+ push 0
+ push DISPATCH_LEVEL
+ push eax
+ push IRQL_NOT_GREATER_OR_EQUAL
+ call _KeBugCheckEx@20
+#endif
.endfunc
.globl _HalpApcInterrupt
@@ -547,9 +649,9 @@
_HalpApcInterrupt2ndEntry:
/* Save current IRQL and set to APC level */
- push [fs:KPCR_IRQL]
- mov dword ptr [fs:KPCR_IRQL], APC_LEVEL
- and dword ptr [fs:KPCR_IRR], ~(1 << APC_LEVEL)
+ push PCR[KPCR_IRQL]
+ mov dword ptr PCR[KPCR_IRQL], APC_LEVEL
+ and dword ptr PCR[KPCR_IRR], ~(1 << APC_LEVEL)
/* Enable interrupts and check if we came from User/V86 mode */
sti
@@ -594,9 +696,9 @@
_HalpDispatchInterrupt2ndEntry:
/* Save current IRQL and set to DPC level */
- push [fs:KPCR_IRQL]
- mov dword ptr [fs:KPCR_IRQL], DISPATCH_LEVEL
- and dword ptr [fs:KPCR_IRR], ~(1 << DISPATCH_LEVEL)
+ push PCR[KPCR_IRQL]
+ mov dword ptr PCR[KPCR_IRQL], DISPATCH_LEVEL
+ and dword ptr PCR[KPCR_IRR], ~(1 << DISPATCH_LEVEL)
/* Enable interrupts and let the kernel handle this */
sti
@@ -614,20 +716,20 @@
/* Get the IRQL and check if we're in the software region */
movzx ecx, byte ptr [esp+4]
- cmp dword ptr [fs:KPCR_IRQL], DISPATCH_LEVEL
+ cmp dword ptr PCR[KPCR_IRQL], DISPATCH_LEVEL
jbe SoftwareInt
/* Set the right mask in the PIC for the hardware IRQ */
mov eax, KiI8259MaskTable[ecx*4]
- or eax, [fs:KPCR_IDR]
+ or eax, PCR[KPCR_IDR]
out 0x21, al
shr eax, 8
out 0xA1, al
SoftwareInt:
/* Check if there are pending software interrupts */
- mov [fs:KPCR_IRQL], ecx
- mov eax, [fs:KPCR_IRR]
+ mov PCR[KPCR_IRQL], ecx
+ mov eax, PCR[KPCR_IRR]
mov al, SoftIntByteTable[eax]
cmp al, cl
ja DoCall2
Modified: trunk/reactos/hal/halx86/generic/irql.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/irql.c?…
==============================================================================
--- trunk/reactos/hal/halx86/generic/irql.c (original)
+++ trunk/reactos/hal/halx86/generic/irql.c Tue Nov 28 11:11:14 2006
@@ -96,8 +96,8 @@
WRITE_PORT_UCHAR((PUCHAR)0x21, 0x1);
WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x1);
/* Enable interrupts */
- WRITE_PORT_UCHAR((PUCHAR)0x21, pic_mask.master);
- WRITE_PORT_UCHAR((PUCHAR)0xa1, pic_mask.slave);
+ WRITE_PORT_UCHAR((PUCHAR)0x21, 0xFF);
+ WRITE_PORT_UCHAR((PUCHAR)0xa1, 0xFF);
/* We can now enable interrupts */
_enable();
@@ -305,7 +305,7 @@
KIRQL STDCALL
KeRaiseIrqlToSynchLevel (VOID)
{
- return KfRaiseIrql (CLOCK2_LEVEL);
+ return KfRaiseIrql (DISPATCH_LEVEL);
}
Modified: trunk/reactos/hal/halx86/generic/systimer.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/systime…
==============================================================================
--- trunk/reactos/hal/halx86/generic/systimer.S (original)
+++ trunk/reactos/hal/halx86/generic/systimer.S Tue Nov 28 11:11:14 2006
@@ -10,8 +10,40 @@
#include <asm.h>
#include <internal/i386/asmmacro.S>
.intel_syntax noprefix
+.extern _HalpCurrentTimeIncrement
/* FUNCTIONS *****************************************************************/
+
+.globl _KeStallExecutionProcessor@4
+.func KeStallExecutionProcessor@4
+_KeStallExecutionProcessor@4:
+
+ /* Get the number of microseconds required */
+ mov ecx, [esp+4]
+ jecxz Done
+
+ /* Multiply by the stall factor */
+ mov eax, fs:[KPCR_STALL_SCALE_FACTOR]
+ mul ecx
+
+ /* Align to 16 bytes */
+ .align 16
+
+ /* Jump to subtraction loop */
+ jmp SubtractLoop
+
+ /* Align to 16 bytes */
+ .align 16
+
+ /* Subtract one count */
+SubtractLoop:
+ sub eax, 1
+ jnz SubtractLoop
+
+Done:
+ /* Return */
+ ret 4
+.endfunc
.globl _HalpClockInterrupt@0
.func HalpClockInterrupt@0
@@ -35,7 +67,8 @@
jz Spurious
/* Do a tick */
- mov eax, 100000
+ mov eax, _HalpCurrentTimeIncrement
+ xor ebx, ebx
jmp _KeUpdateSystemTime@0
Spurious:
Modified: trunk/reactos/hal/halx86/generic/timer.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/timer.c…
==============================================================================
--- trunk/reactos/hal/halx86/generic/timer.c (original)
+++ trunk/reactos/hal/halx86/generic/timer.c Tue Nov 28 11:11:14 2006
@@ -38,127 +38,146 @@
/* GLOBALS ******************************************************************/
-#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 **************************************************************/
+/* GLOBALS *******************************************************************/
+
+BOOLEAN HalpClockSetMSRate;
+ULONG HalpCurrentTimeIncrement;
+ULONG HalpCurrentRollOver;
+ULONG HalpNextMSRate = 14;
+ULONG HalpLargestClockMS = 15;
+
+LARGE_INTEGER HalpRolloverTable[15] =
+{
+ {{1197, 10032}},
+ {{2394, 20064}},
+ {{3591, 30096}},
+ {{4767, 39952}},
+ {{5964, 49984}},
+ {{7161, 60016}},
+ {{8358, 70048}},
+ {{9555, 80080}},
+ {{10731, 89936}},
+ {{11949, 100144}},
+ {{13125, 110000}},
+ {{14322, 120032}},
+ {{15519, 130064}},
+ {{16695, 139920}},
+ {{17892, 149952}}
+};
+
+/* PRIVATE FUNCTIONS *********************************************************/
+
+VOID
+NTAPI
+HalpInitializeClock(VOID)
+{
+ PKPRCB Prcb = KeGetCurrentPrcb();
+ ULONG Increment;
+ USHORT RollOver;
+
+ /* Check the CPU Type */
+ if (Prcb->CpuType <= 4)
+ {
+ /* 486's or equal can't go higher then 10ms */
+ HalpLargestClockMS = 10;
+ HalpNextMSRate = 9;
+ }
+
+ /* Get increment and rollover for the largest time clock ms possible */
+ Increment= HalpRolloverTable[HalpLargestClockMS - 1].HighPart;
+ RollOver = (USHORT)HalpRolloverTable[HalpLargestClockMS - 1].LowPart;
+
+ /* Set the maximum and minimum increment with the kernel */
+ HalpCurrentTimeIncrement = Increment;
+ KeSetTimeIncrement(Increment, HalpRolloverTable[0].HighPart);
+
+ /* Disable interrupts */
+ _disable();
+
+ /* Set the rollover */
+ __outbyte(TIMER_CONTROL_PORT, TIMER_SC0 | TIMER_BOTH | TIMER_MD2);
+ __outbyte(TIMER_DATA_PORT0, RollOver & 0xFF);
+ __outbyte(TIMER_DATA_PORT0, RollOver >> 8);
+
+ /* Restore interrupts */
+ _enable();
+
+ /* Save rollover and return */
+ HalpCurrentRollOver = RollOver;
+}
+
+/* PUBLIC FUNCTIONS ***********************************************************/
/*
- * NOTE: This function MUST NOT be optimized by the compiler!
- * If it is, it obviously will not delay AT ALL, and the system
- * will appear completely frozen at boot since
- * HalpCalibrateStallExecution will never return.
- * There are three options to stop optimization:
- * 1. Use a volatile automatic variable. Making it delay quite a bit
- * due to memory accesses, and keeping the code portable. However,
- * as this involves memory access it depends on both the CPU cache,
- * e.g. if the stack used is already in a cache line or not, and
- * whether or not we're MP. If MP, another CPU could (probably would)
- * also access RAM at the same time - making the delay imprecise.
- * 2. Use compiler-specific #pragma's to disable optimization.
- * 3. Use inline assembly, making it equally unportable as #2.
- * For supported compilers we use inline assembler. For the others,
- * portable plain C.
- */
-DECLSPEC_NOINLINE VOID STDCALL
-__KeStallExecutionProcessor(ULONG Loops)
-{
- if (!Loops)
- {
- return;
- }
-#if defined(__GNUC__)
- __asm__ __volatile__ (
- "mov %0, %%eax\n"
- "ROSL1: dec %%eax\n"
- "jnz ROSL1" : : "d" (Loops));
-
-#elif defined(_MSC_VER)
- __asm mov eax, Loops
-ROSL1:
- __asm dec eax
- __asm jnz ROSL1
-#else
- unsigned int target = Loops;
- volatile unsigned int i;
- for (i=0; i<target;i++);
-#endif
-}
-
+ * @implemented
+ */
VOID
-STDCALL
-KeStallExecutionProcessor(ULONG Microseconds)
-{
- PKIPCR Pcr = (PKIPCR)KeGetPcr();
-
- if (Pcr->PrcbData.FeatureBits & KF_RDTSC)
- {
- LARGE_INTEGER EndCount, CurrentCount;
- EndCount.QuadPart = (LONGLONG)__rdtsc();
- EndCount.QuadPart += Microseconds * (ULONGLONG)Pcr->PrcbData.MHz;
- do
- {
- CurrentCount.QuadPart = (LONGLONG)__rdtsc();
- }
- while (CurrentCount.QuadPart < EndCount.QuadPart);
- }
- else
- {
- __KeStallExecutionProcessor((Pcr->StallScaleFactor*Microseconds)/1000);
- }
-}
-
-static ULONG Read8254Timer(VOID)
-{
- ULONG Count;
-
- /* Disable interrupts */
- _disable();
-
- WRITE_PORT_UCHAR((PUCHAR) TMR_CTRL, TMR_SC0 | TMR_LATCH);
- Count = READ_PORT_UCHAR((PUCHAR) TMR_CNT0);
- Count |= READ_PORT_UCHAR((PUCHAR) TMR_CNT0) << 8;
-
- _enable();
- return Count;
-}
-
+NTAPI
+HalCalibratePerformanceCounter(IN volatile PLONG Count,
+ IN ULONGLONG NewCount)
+{
+ /* Disable interrupts */
+ _disable();
+
+ /* Do a decrement for this CPU */
+ //_InterlockedDecrement(Count);
+ InterlockedDecrement(Count);
+
+ /* Wait for other CPUs */
+ while (*Count);
+
+ /* Bring interrupts back */
+ _enable();
+}
+
+/*
+ * @implemented
+ */
+ULONG
+NTAPI
+HalSetTimeIncrement(IN ULONG Increment)
+{
+ /* Round increment to ms */
+ Increment /= 10000;
+
+ /* Normalize between our minimum (1 ms) and maximum (variable) setting */
+ if (Increment > HalpLargestClockMS) Increment = HalpLargestClockMS;
+ if (Increment < 0) Increment = 1;
+
+ /* Set the rate and tell HAL we want to change it */
+ HalpNextMSRate = Increment;
+ HalpClockSetMSRate = TRUE;
+
+ /* Return the increment */
+ return HalpRolloverTable[Increment - 1].HighPart;
+}
+
+/* STUFF *********************************************************************/
+
+ULONG
+FORCEINLINE
+Read8254Timer(VOID)
+{
+ ULONG Count;
+
+ /* Disable interrupts */
+ _disable();
+
+ /* Set the rollover */
+ __outbyte(TIMER_CONTROL_PORT, TIMER_SC0);
+ Count = __inbyte(TIMER_DATA_PORT0);
+ Count |= __inbyte(TIMER_DATA_PORT0) << 8;
+
+ /* Restore interrupts and return count*/
+ _enable();
+ return Count;
+}
VOID WaitFor8254Wraparound(VOID)
{
@@ -183,20 +202,6 @@
while (Delta < 300);
}
-VOID
-NTAPI
-HalpInitializeClock(VOID)
-{
- /* FIXME: Make dynamic */
-
- /* Initialize the clock */
- WRITE_PORT_UCHAR((PUCHAR) TMR_CTRL, TMR_SC0 | TMR_BOTH | TMR_MD2); /* binary, mode
2, LSB/MSB, ch 0 */
-
- /* Set the increment */
- WRITE_PORT_UCHAR((PUCHAR) TMR_CNT0, LATCH & 0xff); /* LSB */
- WRITE_PORT_UCHAR((PUCHAR) TMR_CNT0, LATCH >> 8); /* MSB */
-}
-
VOID HalpCalibrateStallExecution(VOID)
{
ULONG i;
@@ -205,12 +210,6 @@
PKIPCR Pcr;
LARGE_INTEGER StartCount, EndCount;
- if (UdelayCalibrated)
- {
- return;
- }
-
- UdelayCalibrated = TRUE;
Pcr = (PKIPCR)KeGetPcr();
if (Pcr->PrcbData.FeatureBits & KF_RDTSC)
@@ -242,7 +241,7 @@
WaitFor8254Wraparound();
- __KeStallExecutionProcessor(Pcr->StallScaleFactor); /* Do the delay */
+ KeStallExecutionProcessor(Pcr->StallScaleFactor); /* Do the delay */
CurCount = Read8254Timer();
}
@@ -267,7 +266,7 @@
WaitFor8254Wraparound();
- __KeStallExecutionProcessor(Pcr->StallScaleFactor); /* Do the delay */
+ KeStallExecutionProcessor(Pcr->StallScaleFactor); /* Do the delay */
CurCount = Read8254Timer();
if (CurCount <= LATCH / 2) /* If a tick has passed, turn the */
@@ -294,19 +293,6 @@
for(;;);
#endif
}
-
-
-VOID STDCALL
-HalCalibratePerformanceCounter(ULONG Count)
-{
- /* Disable interrupts */
- _disable();
-
- __KeStallExecutionProcessor(Count);
-
- _enable();
-}
-
LARGE_INTEGER
STDCALL
@@ -360,12 +346,4 @@
return Value;
}
-ULONG
-NTAPI
-HalSetTimeIncrement(IN ULONG Increment)
-{
- /* FIXME: TODO */
- return Increment;
-}
-
/* EOF */
Modified: trunk/reactos/hal/halx86/include/halp.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/include/halp.h?…
==============================================================================
--- trunk/reactos/hal/halx86/include/halp.h (original)
+++ trunk/reactos/hal/halx86/include/halp.h Tue Nov 28 11:11:14 2006
@@ -21,6 +21,13 @@
#define RTC_REGISTER_B 0x0B
#define RTC_REG_A_UIP 0x80
#define RTC_REGISTER_CENTURY 0x32
+
+/* Timer Registers and Ports */
+#define TIMER_CONTROL_PORT 0x43
+#define TIMER_DATA_PORT0 0x40
+#define TIMER_SC0 0
+#define TIMER_BOTH 0x30
+#define TIMER_MD2 0x4
/* Conversion functions */
#define BCD_INT(bcd) \
Modified: trunk/reactos/include/ndk/asm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/asm.h?rev=2490…
==============================================================================
--- trunk/reactos/include/ndk/asm.h (original)
+++ trunk/reactos/include/ndk/asm.h Tue Nov 28 11:11:14 2006
@@ -19,6 +19,17 @@
#ifndef _ASM_H
#define _ASM_H
+
+//
+// PCR Access
+//
+#ifdef __ASM__
+#ifdef CONFIG_SMP
+#define PCR fs:
+#else
+#define PCR ds:[0xFF000000]
+#endif
+#endif
//
// CPU Modes
@@ -145,6 +156,7 @@
#define KPCR_IDT 0x38
#define KPCR_GDT 0x3C
#define KPCR_TSS 0x40
+#define KPCR_STALL_SCALE_FACTOR 0x4C
#define KPCR_SET_MEMBER 0x48
#define KPCR_NUMBER 0x51
#define KPCR_PRCB_DATA 0x120
@@ -489,6 +501,8 @@
#define STATUS_FLOAT_MULTIPLE_FAULTS 0xC00002B4
#define STATUS_FLOAT_MULTIPLE_TRAPS 0xC00002B5
#define APC_INDEX_MISMATCH 0x01
+#define IRQL_NOT_GREATER_OR_EQUAL 0x09
+#define IRQL_NOT_LESS_OR_EQUAL 0x0A
#define TRAP_CAUSE_UNKNOWN 0x12
#define KMODE_EXCEPTION_NOT_HANDLED 0x13
#define IRQL_GT_ZERO_AT_SYSTEM_SERVICE 0x4A
Modified: trunk/reactos/ntoskrnl/deprecated/irq.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/deprecated/irq.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/deprecated/irq.c (original)
+++ trunk/reactos/ntoskrnl/deprecated/irq.c Tue Nov 28 11:11:14 2006
@@ -177,231 +177,6 @@
}
}
-static VOID
-KeIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame,
- PKTRAP_FRAME TrapFrame)
-{
- TrapFrame->SegGs = (USHORT)IrqTrapFrame->Gs;
- TrapFrame->SegFs = (USHORT)IrqTrapFrame->Fs;
- TrapFrame->SegEs = (USHORT)IrqTrapFrame->Es;
- TrapFrame->SegDs = (USHORT)IrqTrapFrame->Ds;
- TrapFrame->Eax = IrqTrapFrame->Eax;
- TrapFrame->Ecx = IrqTrapFrame->Ecx;
- TrapFrame->Edx = IrqTrapFrame->Edx;
- TrapFrame->Ebx = IrqTrapFrame->Ebx;
- TrapFrame->HardwareEsp = IrqTrapFrame->Esp;
- TrapFrame->Ebp = IrqTrapFrame->Ebp;
- TrapFrame->Esi = IrqTrapFrame->Esi;
- TrapFrame->Edi = IrqTrapFrame->Edi;
- TrapFrame->Eip = IrqTrapFrame->Eip;
- TrapFrame->SegCs = IrqTrapFrame->Cs;
- TrapFrame->EFlags = IrqTrapFrame->Eflags;
-}
-
-static VOID
-KeTrapFrameToIRQTrapFrame(PKTRAP_FRAME TrapFrame,
- PKIRQ_TRAPFRAME IrqTrapFrame)
-{
- IrqTrapFrame->Gs = TrapFrame->SegGs;
- IrqTrapFrame->Fs = TrapFrame->SegFs;
- IrqTrapFrame->Es = TrapFrame->SegEs;
- IrqTrapFrame->Ds = TrapFrame->SegDs;
- IrqTrapFrame->Eax = TrapFrame->Eax;
- IrqTrapFrame->Ecx = TrapFrame->Ecx;
- IrqTrapFrame->Edx = TrapFrame->Edx;
- IrqTrapFrame->Ebx = TrapFrame->Ebx;
- IrqTrapFrame->Esp = TrapFrame->HardwareEsp;
- IrqTrapFrame->Ebp = TrapFrame->Ebp;
- IrqTrapFrame->Esi = TrapFrame->Esi;
- IrqTrapFrame->Edi = TrapFrame->Edi;
- IrqTrapFrame->Eip = TrapFrame->Eip;
- IrqTrapFrame->Cs = TrapFrame->SegCs;
- IrqTrapFrame->Eflags = TrapFrame->EFlags;
-}
-
-/*
- * NOTE: On Windows this function takes exactly one parameter and EBP is
- * guaranteed to point to KTRAP_FRAME. The function is used only
- * by HAL, so there's no point in keeping that prototype.
- *
- * @implemented
- */
-VOID
-STDCALL
-KeUpdateRunTime(IN PKTRAP_FRAME TrapFrame,
- IN KIRQL Irql)
-{
- PKPRCB Prcb = KeGetCurrentPrcb();
- PKTHREAD CurrentThread;
- PKPROCESS CurrentProcess;
-
- /* Make sure we don't go further if we're in early boot phase. */
- if (!(Prcb) || !(Prcb->CurrentThread)) return;
-
- /* Get the current thread and process */
- CurrentThread = Prcb->CurrentThread;
- CurrentProcess = CurrentThread->ApcState.Process;
-
- /* Check if we came from user mode */
- if (TrapFrame->PreviousPreviousMode != KernelMode)
- {
- /* Update user times */
- CurrentThread->UserTime++;
- InterlockedIncrement((PLONG)&CurrentProcess->UserTime);
- Prcb->UserTime++;
- }
- else
- {
- /* Check IRQ */
- if (Irql > DISPATCH_LEVEL)
- {
- /* This was an interrupt */
- Prcb->InterruptTime++;
- }
- else if ((Irql < DISPATCH_LEVEL) || !(Prcb->DpcRoutineActive))
- {
- /* This was normal kernel time */
- CurrentThread->KernelTime++;
- InterlockedIncrement((PLONG)&CurrentProcess->KernelTime);
- }
- else if (Irql == DISPATCH_LEVEL)
- {
- /* This was DPC time */
- Prcb->DpcTime++;
- }
-
- /* Update CPU kernel time in all cases */
- Prcb->KernelTime++;
- }
-
- /* Set the last DPC Count and request rate */
- Prcb->DpcLastCount = Prcb->DpcData[0].DpcCount;
- Prcb->DpcRequestRate = ((Prcb->DpcData[0].DpcCount - Prcb->DpcLastCount) +
- Prcb->DpcRequestRate) / 2;
-
- /* Check if we should request a DPC */
- if ((Prcb->DpcData[0].DpcQueueDepth) && !(Prcb->DpcRoutineActive))
- {
- /* Request one */
- HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
-
- /* Update the depth if needed */
- if ((Prcb->DpcRequestRate < KiIdealDpcRate) &&
- (Prcb->MaximumDpcQueueDepth > 1))
- {
- /* Decrease the maximum depth by one */
- Prcb->MaximumDpcQueueDepth--;
- }
- }
- else
- {
- /* Decrease the adjustment threshold */
- if (!(--Prcb->AdjustDpcThreshold))
- {
- /* We've hit 0, reset it */
- Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
-
- /* Check if we've hit queue maximum */
- if (KiMaximumDpcQueueDepth != Prcb->MaximumDpcQueueDepth)
- {
- /* Increase maximum by one */
- Prcb->MaximumDpcQueueDepth++;
- }
- }
- }
-
- /*
- * If we're at end of quantum request software interrupt. The rest
- * is handled in KiDispatchInterrupt.
- *
- * NOTE: If one stays at DISPATCH_LEVEL for a long time the DPC routine
- * which checks for quantum end will not be executed and decrementing
- * the quantum here can result in overflow. This is not a problem since
- * we don't care about the quantum value anymore after the QuantumEnd
- * flag is set.
- */
- if ((CurrentThread->Quantum -= 3) <= 0)
- {
- Prcb->QuantumEnd = TRUE;
- HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
- }
-}
-
-
-/*
- * NOTE: On Windows this function takes exactly zero parameters and EBP is
- * guaranteed to point to KTRAP_FRAME. Also [esp+0] contains an IRQL.
- * The function is used only by HAL, so there's no point in keeping
- * that prototype.
- *
- * @implemented
- */
-VOID
-STDCALL
-KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame,
- IN KIRQL Irql,
- IN ULONG Increment)
-{
- LONG OldOffset;
- LARGE_INTEGER Time;
- ASSERT(KeGetCurrentIrql() == PROFILE_LEVEL);
- if (!KiClockSetupComplete) return;
-
- /* Update interrupt time */
- Time.LowPart = SharedUserData->InterruptTime.LowPart;
- Time.HighPart = SharedUserData->InterruptTime.High1Time;
- Time.QuadPart += Increment;
- SharedUserData->InterruptTime.High2Time = Time.u.HighPart;
- SharedUserData->InterruptTime.LowPart = Time.u.LowPart;
- SharedUserData->InterruptTime.High1Time = Time.u.HighPart;
-
- /* Increase the tick offset */
- KiTickOffset -= Increment;
- OldOffset = KiTickOffset;
-
- /* Check if this isn't a tick yet */
- if (KiTickOffset > 0)
- {
- /* Expire timers */
- KeInsertQueueDpc(&KiExpireTimerDpc, (PVOID)TrapFrame->Eip, 0);
- }
- else
- {
- /* Setup time structure for system time */
- Time.LowPart = SharedUserData->SystemTime.LowPart;
- Time.HighPart = SharedUserData->SystemTime.High1Time;
- Time.QuadPart += KeTimeAdjustment;
- SharedUserData->SystemTime.High2Time = Time.HighPart;
- SharedUserData->SystemTime.LowPart = Time.LowPart;
- SharedUserData->SystemTime.High1Time = Time.HighPart;
-
- /* Setup time structure for tick time */
- Time.LowPart = KeTickCount.LowPart;
- Time.HighPart = KeTickCount.High1Time;
- Time.QuadPart += 1;
- KeTickCount.High2Time = Time.HighPart;
- KeTickCount.LowPart = Time.LowPart;
- KeTickCount.High1Time = Time.HighPart;
- SharedUserData->TickCount.High2Time = Time.HighPart;
- SharedUserData->TickCount.LowPart = Time.LowPart;
- SharedUserData->TickCount.High1Time = Time.HighPart;
-
- /* Update tick count in shared user data as well */
- SharedUserData->TickCountLowDeprecated++;
-
- /* Queue a DPC that will expire timers */
- KeInsertQueueDpc(&KiExpireTimerDpc, (PVOID)TrapFrame->Eip, 0);
- }
-
- /* Update process and thread times */
- if (OldOffset <= 0)
- {
- /* This was a tick, calculate the next one */
- KiTickOffset += KeMaximumIncrement;
- KeUpdateRunTime(TrapFrame, Irql);
- }
-}
-
VOID STDCALL
KiInterruptDispatch2 (ULONG vector, KIRQL old_level)
/*
@@ -453,9 +228,7 @@
*/
{
KIRQL old_level;
- KTRAP_FRAME KernelTrapFrame;
PKTHREAD CurrentThread;
- PKTRAP_FRAME OldTrapFrame=NULL;
/*
* At this point we have interrupts disabled, nothing has been done to
@@ -482,20 +255,12 @@
*/
_enable();
-#ifndef CONFIG_SMP
- if (VECTOR2IRQ(vector) == 0)
- {
- KeIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame);
- KeUpdateSystemTime(&KernelTrapFrame, old_level, 100000);
- }
- else
-#endif
- {
+ ASSERT (VECTOR2IRQ(vector) != 0);
+
/*
* Actually call the ISR.
*/
KiInterruptDispatch2(vector, old_level);
- }
/*
* End the system interrupt.
@@ -514,23 +279,14 @@
((PETHREAD)CurrentThread)->Cid.UniqueThread,
Trapframe->Cs,
CurrentThread->TrapFrame ? CurrentThread->TrapFrame->SegCs :
0);
- if (CurrentThread->TrapFrame == NULL)
- {
- OldTrapFrame = CurrentThread->TrapFrame;
- KeIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame);
- CurrentThread->TrapFrame = &KernelTrapFrame;
- }
+ ASSERT (CurrentThread->TrapFrame);
_enable();
KiDeliverApc(UserMode, NULL, NULL);
_disable();
ASSERT(KeGetCurrentThread() == CurrentThread);
- if (CurrentThread->TrapFrame == &KernelTrapFrame)
- {
- KeTrapFrameToIRQTrapFrame(&KernelTrapFrame, Trapframe);
- CurrentThread->TrapFrame = OldTrapFrame;
- }
+ ASSERT (CurrentThread->TrapFrame);
}
KeLowerIrql(PASSIVE_LEVEL);
}
Modified: trunk/reactos/ntoskrnl/ke/i386/irq.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/irq.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/irq.c (original)
+++ trunk/reactos/ntoskrnl/ke/i386/irq.c Tue Nov 28 11:11:14 2006
@@ -226,7 +226,7 @@
/* Set the system affinity and acquire the dispatcher lock */
KeSetSystemAffinityThread(1 << Number);
- OldIrql = KeAcquireDispatcherDatabaseLock();
+ OldIrql = KiAcquireDispatcherLock();
/* Check if it's already been connected */
if (!Interrupt->Connected)
@@ -272,7 +272,7 @@
}
/* Unlock the dispatcher and revert affinity */
- KeReleaseDispatcherDatabaseLock(OldIrql);
+ KiReleaseDispatcherLock(OldIrql);
KeRevertToUserAffinityThread();
/* Return to caller */
@@ -296,7 +296,7 @@
KeSetSystemAffinityThread(1 << Interrupt->Number);
/* Lock the dispatcher */
- OldIrql = KeAcquireDispatcherDatabaseLock();
+ OldIrql = KiAcquireDispatcherLock();
/* Check if it's actually connected */
State = Interrupt->Connected;
@@ -354,7 +354,7 @@
}
/* Unlock the dispatcher and revert affinity */
- KeReleaseDispatcherDatabaseLock(OldIrql);
+ KiReleaseDispatcherLock(OldIrql);
KeRevertToUserAffinityThread();
/* Return to caller */