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=53634&r1=53633&r2=53634&view=diff
==============================================================================
--- 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=53634&r1=53633&r2=53634&view=diff
==============================================================================
--- 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?rev=53634&r1=53633&r2=53634&view=diff
==============================================================================
--- 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=53634&r1=53633&r2=53634&view=diff
==============================================================================
--- 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?rev=53634&r1=53633&r2=53634&view=diff
==============================================================================
--- 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


Reply via email to