Author: tkreuzer
Date: Thu Sep 8 08:15:39 2011
New Revision: 53634
URL:
http://svn.reactos.org/svn/reactos?rev=53634&view=rev
Log:
[HAL]
- Fix I/O APIC register access
- set APIC logical id based on Cpu (currently flat model with up to 8 cpus supported)
- In HalpInitializeTsc, setup the RTC clock, since the timer is initialized later
- in the TSC calibration ISR, send EOI and read RTC register C to get the next interrupt
Modified:
trunk/reactos/hal/halx86/apic/apic.c
trunk/reactos/hal/halx86/apic/apic.h
trunk/reactos/hal/halx86/apic/rtctimer.c
trunk/reactos/hal/halx86/apic/tsc.c
trunk/reactos/hal/halx86/apic/tsccal.S
Modified: trunk/reactos/hal/halx86/apic/apic.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/apic/apic.c?rev…
==============================================================================
--- trunk/reactos/hal/halx86/apic/apic.c [iso-8859-1] (original)
+++ trunk/reactos/hal/halx86/apic/apic.c [iso-8859-1] Thu Sep 8 08:15:39 2011
@@ -88,7 +88,7 @@
IOApicRead(UCHAR Register)
{
/* Select the register, then do the read */
- *(volatile ULONG *)(IOAPIC_BASE + IOAPIC_IOREGSEL) = Register;
+ *(volatile UCHAR *)(IOAPIC_BASE + IOAPIC_IOREGSEL) = Register;
return *(volatile ULONG *)(IOAPIC_BASE + IOAPIC_IOWIN);
}
@@ -97,7 +97,7 @@
IOApicWrite(UCHAR Register, ULONG Value)
{
/* Select the register, then do the write */
- *(volatile ULONG *)(IOAPIC_BASE + IOAPIC_IOREGSEL) = Register;
+ *(volatile UCHAR *)(IOAPIC_BASE + IOAPIC_IOREGSEL) = Register;
*(volatile ULONG *)(IOAPIC_BASE + IOAPIC_IOWIN) = Value;
}
@@ -240,6 +240,12 @@
SpIntRegister.SoftwareEnable = 1;
SpIntRegister.FocusCPUCoreChecking = 0;
ApicWrite(APIC_SIVR, SpIntRegister.Long);
+
+ /* Set the mode to flat (max 8 CPUs supported!) */
+ ApicWrite(APIC_DFR, APIC_DF_Flat);
+
+ /* Set logical apic ID */
+ ApicWrite(APIC_LDR, ApicLogicalId(Cpu) << 24);
/* Set the spurious ISR */
KeRegisterInterruptHandler(APIC_SPURIOUS_VECTOR, ApicSpuriousService);
@@ -409,9 +415,11 @@
/* Enable the timer interrupt */
ReDirReg.Vector = APIC_CLOCK_VECTOR;
- ReDirReg.DestinationMode = APIC_DM_Logical;
+ ReDirReg.DeliveryMode = APIC_MT_Fixed;
+ ReDirReg.DestinationMode = APIC_DM_Physical;
ReDirReg.TriggerMode = APIC_TGM_Edge;
ReDirReg.Mask = 0;
+ ReDirReg.Destination = ApicRead(APIC_ID);
IOApicWrite(IOAPIC_REDTBL + 2 * APIC_CLOCK_INDEX, ReDirReg.Long0);
}
@@ -519,6 +527,7 @@
IN KINTERRUPT_MODE InterruptMode)
{
IOAPIC_REDIRECTION_REGISTER ReDirReg;
+ PKPRCB Prcb = KeGetCurrentPrcb();
UCHAR Index;
ASSERT(Irql <= HIGH_LEVEL);
ASSERT((IrqlToTpr(Irql) & 0xF0) == (Vector & 0xF0));
@@ -531,6 +540,7 @@
ReDirReg.Vector = Vector;
ReDirReg.DeliveryMode = APIC_MT_LowestPriority;
ReDirReg.DestinationMode = APIC_DM_Logical;
+ ReDirReg.Destination |= ApicLogicalId(Prcb->Number);
ReDirReg.TriggerMode = 1 - InterruptMode;
ReDirReg.Mask = FALSE;
@@ -560,6 +570,14 @@
/* Write back lower dword */
IOApicWrite(IOAPIC_REDTBL + 2 * Irql, ReDirReg.Long0);
+}
+
+VOID
+NTAPI
+HalpSendEOI(VOID)
+{
+ /* Write 0 to the EndOfInterruptRegister */
+ ApicWrite(APIC_EOI, 0);
}
#ifndef _M_AMD64
@@ -592,7 +610,7 @@
/* Restore the old IRQL */
ApicSetCurrentIrql(OldIrql);
- /* Write 0 to the EndOfInterruptRegister for level triggered ints */
+ /* Write 0 to the EndOfInterruptRegister */
ApicWrite(APIC_EOI, 0);
}
Modified: trunk/reactos/hal/halx86/apic/apic.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/apic/apic.h?rev…
==============================================================================
--- trunk/reactos/hal/halx86/apic/apic.h [iso-8859-1] (original)
+++ trunk/reactos/hal/halx86/apic/apic.h [iso-8859-1] Thu Sep 8 08:15:39 2011
@@ -39,6 +39,7 @@
#define IOAPIC_PHYS_BASE 0xFEC00000
#define APIC_CLOCK_INDEX 8
+#define ApicLogicalId(Cpu) ((UCHAR)(1<< Cpu))
/* APIC Register Address Map */
#define APIC_ID 0x0020 /* Local APIC ID Register (R/W) */
@@ -108,6 +109,12 @@
enum
{
+ APIC_DF_Flat = 0xFFFFFFFF,
+ APIC_DF_Cluster = 0x0FFFFFFF
+};
+
+enum
+{
TIMER_DV_DivideBy2 = 0,
TIMER_DV_DivideBy4 = 1,
TIMER_DV_DivideBy8 = 2,
@@ -224,7 +231,7 @@
IOAPIC_ID = 0x00,
IOAPIC_VER = 0x01,
IOAPIC_ARB = 0x02,
- IOAPIC_REDTBL = 0x28
+ IOAPIC_REDTBL = 0x10
};
typedef union _IOAPIC_REDIRECTION_REGISTER
Modified: trunk/reactos/hal/halx86/apic/rtctimer.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/apic/rtctimer.c…
==============================================================================
--- trunk/reactos/hal/halx86/apic/rtctimer.c [iso-8859-1] (original)
+++ trunk/reactos/hal/halx86/apic/rtctimer.c [iso-8859-1] Thu Sep 8 08:15:39 2011
@@ -83,7 +83,9 @@
/* Release CMOS lock */
HalpReleaseCmosSpinLock();
- // RtcSetClockRate(HalpCurrentRate);
+ RtcSetClockRate(HalpCurrentRate);
+
+ DPRINT1("Clock initialized\n");
}
VOID
@@ -95,7 +97,6 @@
/* Enter trap */
KiEnterInterruptTrap(TrapFrame);
-__debugbreak();
/* Start the interrupt */
if (HalBeginSystemInterrupt(CLOCK_LEVEL, PRIMARY_VECTOR_BASE, &Irql))
Modified: trunk/reactos/hal/halx86/apic/tsc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/apic/tsc.c?rev=…
==============================================================================
--- trunk/reactos/hal/halx86/apic/tsc.c [iso-8859-1] (original)
+++ trunk/reactos/hal/halx86/apic/tsc.c [iso-8859-1] Thu Sep 8 08:15:39 2011
@@ -18,7 +18,7 @@
UCHAR TscCalibrationPhase;
LARGE_INTEGER TscCalibrationArray[NUM_SAMPLES];
-extern const UCHAR HalpClockVector;
+UCHAR HalpRtcClockVector = 0xD1;
/* PRIVATE FUNCTIONS *********************************************************/
@@ -29,6 +29,7 @@
ULONG_PTR Flags;
KIDTENTRY OldIdtEntry, *IdtPointer;
PKPCR Pcr = KeGetPcr();
+ UCHAR RegisterA, RegisterB;
/* Check if the CPU supports RDTSC */
if (!(KeGetCurrentPrcb()->FeatureBits & KF_RDTSC))
@@ -40,31 +41,41 @@
Flags = __readeflags();
_disable();
-__debugbreak();
+ /* Enable the periodic interrupt in the CMOS */
+ RegisterB = HalpReadCmos(RTC_REGISTER_B);
+ HalpWriteCmos(RTC_REGISTER_B, RegisterB | RTC_REG_B_PI);
- /* Initialze the PIT */
- //HalpInitializePIT();
+ /* Modify register A to get 4096 Hz */
+ RegisterA = HalpReadCmos(RTC_REGISTER_A);
+ RegisterA = (RegisterA & 0xF0) | 9;
+ HalpWriteCmos(RTC_REGISTER_A, RegisterA);
/* Save old IDT entry */
- IdtPointer = KiGetIdtEntry(Pcr, HalpClockVector);
+ IdtPointer = KiGetIdtEntry(Pcr, HalpRtcClockVector);
OldIdtEntry = *IdtPointer;
/* Set the calibration ISR */
- KeRegisterInterruptHandler(HalpClockVector, TscCalibrationISR);
+ KeRegisterInterruptHandler(HalpRtcClockVector, TscCalibrationISR);
/* Reset TSC value to 0 */
__writemsr(MSR_RDTSC, 0);
/* Enable the timer interupt */
- HalEnableSystemInterrupt(HalpClockVector, CLOCK_LEVEL, Latched);
+ HalEnableSystemInterrupt(HalpRtcClockVector, CLOCK_LEVEL, Latched);
+
+ /* Read register C, so that the next interrupt can happen */
+ HalpReadCmos(RTC_REGISTER_C);;
/* Wait for completion */
_enable();
while (TscCalibrationPhase < NUM_SAMPLES) _ReadWriteBarrier();
_disable();
+ /* Disable the periodic interrupt in the CMOS */
+ HalpWriteCmos(RTC_REGISTER_B, RegisterB & ~RTC_REG_B_PI);
+
/* Disable the timer interupt */
- HalDisableSystemInterrupt(HalpClockVector, CLOCK_LEVEL);
+ HalDisableSystemInterrupt(HalpRtcClockVector, CLOCK_LEVEL);
/* Restore old IDT entry */
*IdtPointer = OldIdtEntry;
Modified: trunk/reactos/hal/halx86/apic/tsccal.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/apic/tsccal.S?r…
==============================================================================
--- trunk/reactos/hal/halx86/apic/tsccal.S [iso-8859-1] (original)
+++ trunk/reactos/hal/halx86/apic/tsccal.S [iso-8859-1] Thu Sep 8 08:15:39 2011
@@ -8,6 +8,7 @@
EXTERN _TscCalibrationPhase:BYTE
EXTERN _TscCalibrationArray:QWORD
+EXTERN _HalpSendEOI@0:PROC
PUBLIC _TscCalibrationISR
_TscCalibrationISR:
@@ -26,13 +27,25 @@
jnb _CalibrationISR_Exit
/* Store the current value */
- mov dword ptr _TscCalibrationArray[ecx * 2], eax
- mov dword ptr _TscCalibrationArray[ecx * 2 + 4], edx
+ shl ecx, 3
+ mov dword ptr _TscCalibrationArray[ecx], eax
+ mov dword ptr _TscCalibrationArray[ecx + 4], edx
/* Advance phase */
inc byte ptr ds:[_TscCalibrationPhase]
_CalibrationISR_Exit:
+
+ /* Read CMOS register C */
+ mov al, HEX(0C)
+ out HEX(70), al
+ jmp $+2
+ in al, HEX(71)
+ jmp $+2
+
+ /* Send EOI */
+ call _HalpSendEOI@0
+
pop edx
pop ecx
pop eax