浏览代码

Fixed a couple APIC logical clustered mode issues.

VMWare with 8+ processors wasn't booting, as it was failing to set up
logical clustered mode properly. First of all logical flat mode can be
used with 8 processors, so I tweaked that. Secondly, we weren't setting
the logical cluster ID correctly in the local APIC.

Also fixed a minor compile x86rel compile issue in codec.c.
Evan Green 7 年之前
父节点
当前提交
2213a2d125
共有 3 个文件被更改,包括 22 次插入8 次删除
  1. 1 0
      drivers/sound/intel/hda/codec.c
  2. 11 8
      kernel/hl/ipi.c
  3. 10 0
      kernel/hl/x86/apic.c

+ 1 - 0
drivers/sound/intel/hda/codec.c

@@ -734,6 +734,7 @@ Return Value:
     }
 
     InputRightGainMute = 0;
+    OutputLeftGainMute = 0;
     OutputRightGainMute = 0;
 
     //

+ 11 - 8
kernel/hl/ipi.c

@@ -224,6 +224,7 @@ Return Value:
     ULONG Processor;
     KSTATUS Status;
     INTERRUPT_HARDWARE_TARGET Target;
+    PINTERRUPT_HARDWARE_TARGET TargetPointer;
     ULONG Vector;
 
     ASSERT((KeGetRunLevel() >= RunLevelDispatch) ||
@@ -231,6 +232,7 @@ Return Value:
 
     Processor = KeGetCurrentProcessorNumber();
     Controller = HlProcessorTargets[Processor].Controller;
+    TargetPointer = &Target;
 
     //
     // Compute the interrupt target in terms the hardware can understand.
@@ -254,7 +256,7 @@ Return Value:
         break;
 
     case ProcessorTargetSingleProcessor:
-        Target = HlProcessorTargets[Processors->U.Number].Target;
+        TargetPointer = &(HlProcessorTargets[Processors->U.Number].Target);
         break;
 
     case ProcessorTargetAny:
@@ -274,7 +276,7 @@ Return Value:
                                                     Controller->PrivateContext,
                                                     IpiLine,
                                                     Vector,
-                                                    &Target);
+                                                    TargetPointer);
 
     if (Enabled != FALSE) {
         ArEnableInterrupts();
@@ -785,6 +787,7 @@ Return Value:
 {
 
     PINTERRUPT_CONTROLLER Controller;
+    ULONG PhysicalId;
     PVOID PrivateContext;
     ULONG ProcessorIndex;
     ULONG SearchIndex;
@@ -869,6 +872,7 @@ Return Value:
 
     Controller = HlProcessorTargets[ProcessorIndex].Controller;
     SetAddressing = Controller->FunctionTable.SetLocalUnitAddressing;
+    PhysicalId = HlProcessorTargets[ProcessorIndex].PhysicalId;
     PrivateContext = Controller->PrivateContext;
     Targeting = &(HlProcessorTargets[ProcessorIndex].Target);
 
@@ -890,7 +894,8 @@ Return Value:
     //
 
     Status = STATUS_NOT_SUPPORTED;
-    if ((HlMaxProcessors < HlLogicalFlatLimit) &&
+    if ((HlLogicalFlatLimit != 0) &&
+        (HlMaxProcessors <= HlLogicalFlatLimit) &&
         (HlLogicalClusteredMode == FALSE)) {
 
         ASSERT(HlLogicalFlatLimit <= 32);
@@ -910,10 +915,8 @@ Return Value:
         (ProcessorIndex < HlMaxClusters * HlMaxClusterSize)) {
 
         Targeting->Addressing = InterruptAddressingLogicalClustered;
-        Targeting->U.Cluster.Id = Targeting->U.PhysicalId / HlMaxClusterSize;
-        Targeting->U.Cluster.Mask =
-                             1 << (Targeting->U.PhysicalId % HlMaxClusterSize);
-
+        Targeting->U.Cluster.Id = PhysicalId / HlMaxClusterSize;
+        Targeting->U.Cluster.Mask = 1 << (PhysicalId % HlMaxClusterSize);
         Status = SetAddressing(PrivateContext, Targeting);
 
         //
@@ -934,7 +937,7 @@ Return Value:
 
     if (!KSUCCESS(Status)) {
         Targeting->Addressing = InterruptAddressingPhysical;
-        Targeting->U.PhysicalId = HlProcessorTargets[ProcessorIndex].PhysicalId;
+        Targeting->U.PhysicalId = PhysicalId;
         Status = SetAddressing(PrivateContext, Targeting);
         if (!KSUCCESS(Status)) {
             KeCrashSystem(CRASH_HARDWARE_LAYER_FAILURE,

+ 10 - 0
kernel/hl/x86/apic.c

@@ -754,8 +754,16 @@ Return Value:
 {
 
     ULONG LogicalDestination;
+    ULONG OriginalVector;
     KSTATUS Status;
 
+    //
+    // Intel says the destination format register must be set before the
+    // APIC is software enabled.
+    //
+
+    OriginalVector = READ_LOCAL_APIC(ApicSpuriousVector);
+    WRITE_LOCAL_APIC(ApicSpuriousVector, VECTOR_SPURIOUS_INTERRUPT);
     switch (Target->Addressing) {
 
     //
@@ -783,6 +791,7 @@ Return Value:
         WRITE_LOCAL_APIC(ApicDestinationFormat, APIC_LOGICAL_CLUSTERED);
         LogicalDestination = Target->U.Cluster.Id << APIC_MAX_CLUSTER_SIZE;
         LogicalDestination |= Target->U.Cluster.Mask;
+        LogicalDestination <<= APIC_DESTINATION_SHIFT;
         WRITE_LOCAL_APIC(ApicLogicalDestination, LogicalDestination);
         if (READ_LOCAL_APIC(ApicLogicalDestination) != LogicalDestination) {
             Status = STATUS_NOT_SUPPORTED;
@@ -799,6 +808,7 @@ Return Value:
     Status = STATUS_SUCCESS;
 
 SetProcessorTargetingEnd:
+    WRITE_LOCAL_APIC(ApicSpuriousVector, OriginalVector);
     return Status;
 }