⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpconfig.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
	   Count += sizeof(MP_CONFIGURATION_BUS);
	   break;
	 }
       case MPCTE_IOAPIC:
	 {
	   HaliMPIOApicInfo((PMP_CONFIGURATION_IOAPIC)Entry);
	   Entry += sizeof(MP_CONFIGURATION_IOAPIC);
	   Count += sizeof(MP_CONFIGURATION_IOAPIC);
	   break;
	 }
       case MPCTE_INTSRC:
	 {
	   HaliMPIntSrcInfo((PMP_CONFIGURATION_INTSRC)Entry);
	   Entry += sizeof(MP_CONFIGURATION_INTSRC);
	   Count += sizeof(MP_CONFIGURATION_INTSRC);
	   break;
	 }
       case MPCTE_LINTSRC:
	 {
	   HaliMPIntLocalInfo((PMP_CONFIGURATION_INTLOCAL)Entry);
	   Entry += sizeof(MP_CONFIGURATION_INTLOCAL);
	   Count += sizeof(MP_CONFIGURATION_INTLOCAL);
	   break;
	 }
       default:
	 DPRINT1("Unknown entry in MPC table\n");
	 KEBUGCHECK(0);
	 return FALSE;
       }
   }
   return TRUE;
}

static VOID 
HaliConstructDefaultIOIrqMPTable(ULONG Type)
{
	MP_CONFIGURATION_INTSRC intsrc;
	ULONG i;

	intsrc.Type = MPCTE_INTSRC;
	intsrc.IrqFlag = 0;			/* conforming */
	intsrc.SrcBusId = 0;
	intsrc.DstApicId = IOAPICMap[0].ApicId;

	intsrc.IrqType = INT_VECTORED;
	for (i = 0; i < 16; i++) {
		switch (Type) {
		case 2:
			if (i == 0 || i == 13)
				continue;	/* IRQ0 & IRQ13 not connected */
			/* Fall through */
		default:
			if (i == 2)
				continue;	/* IRQ2 is never connected */
		}

		intsrc.SrcBusIrq = i;
		intsrc.DstApicInt = i ? i : 2; /* IRQ0 to INTIN2 */
		HaliMPIntSrcInfo(&intsrc);
	}

	intsrc.IrqType = INT_EXTINT;
	intsrc.SrcBusIrq = 0;
	intsrc.DstApicInt = 0; /* 8259A to INTIN0 */
	HaliMPIntSrcInfo(&intsrc);
}

static VOID 
HaliConstructDefaultISAMPTable(ULONG Type)
{
  MP_CONFIGURATION_PROCESSOR processor;
  MP_CONFIGURATION_BUS bus;
  MP_CONFIGURATION_IOAPIC ioapic;
  MP_CONFIGURATION_INTLOCAL lintsrc;
  ULONG linttypes[2] = { INT_EXTINT, INT_NMI };
  ULONG i;

  /*
   * 2 CPUs, numbered 0 & 1.
   */
  processor.Type = MPCTE_PROCESSOR;
  /* Either an integrated APIC or a discrete 82489DX. */
  processor.ApicVersion = Type > 4 ? 0x10 : 0x01;
  processor.CpuFlags = CPU_FLAG_ENABLED | CPU_FLAG_BSP;
  /* FIXME: Get this from the bootstrap processor */
  processor.CpuSignature = 0;
  processor.FeatureFlags = 0;
  processor.Reserved[0] = 0;
  processor.Reserved[1] = 0;
  for (i = 0; i < 2; i++) 
  {
    processor.ApicId = i;
    HaliMPProcessorInfo(&processor);
    processor.CpuFlags &= ~CPU_FLAG_BSP;
  }

  bus.Type = MPCTE_BUS;
  bus.BusId = 0;
  switch (Type) 
  {
    default:
    DPRINT("Unknown standard configuration %d\n", Type);
      /* Fall through */
    case 1:
    case 5:
      memcpy(bus.BusType, "ISA   ", 6);
      break;
    case 2:
    case 6:
    case 3:
      memcpy(bus.BusType, "EISA  ", 6);
      break;
    case 4:
    case 7:
      memcpy(bus.BusType, "MCA   ", 6);
  }
  HaliMPBusInfo(&bus);
  if (Type > 4) 
  {
    bus.Type = MPCTE_BUS;
    bus.BusId = 1;
    memcpy(bus.BusType, "PCI   ", 6);
    HaliMPBusInfo(&bus);
  }

  ioapic.Type = MPCTE_IOAPIC;
  ioapic.ApicId = 2;
  ioapic.ApicVersion = Type > 4 ? 0x10 : 0x01;
  ioapic.ApicFlags = MP_IOAPIC_USABLE;
  ioapic.ApicAddress = IOAPIC_DEFAULT_BASE;
  HaliMPIOApicInfo(&ioapic);

  /*
   * We set up most of the low 16 IO-APIC pins according to MPS rules.
   */
  HaliConstructDefaultIOIrqMPTable(Type);

  lintsrc.Type = MPCTE_LINTSRC;
  lintsrc.IrqType = 0;
  lintsrc.IrqFlag = 0;  /* conforming */
  lintsrc.SrcBusId = 0;
  lintsrc.SrcBusIrq = 0;
  lintsrc.DstApicId = MP_APIC_ALL;
  for (i = 0; i < 2; i++) 
  {
    lintsrc.IrqType = linttypes[i];
    lintsrc.DstApicLInt = i;
    HaliMPIntLocalInfo(&lintsrc);
  }
}


static BOOLEAN
HaliScanForMPConfigTable(ULONG Base,
			 ULONG Size)
{
/*
   PARAMETERS:
      Base = Base address of region
      Size = Length of region to check
   RETURNS:
      TRUE if a valid MP configuration table was found
 */

   PULONG bp = (PULONG)Base;
   MP_FLOATING_POINTER* mpf;
   UCHAR Checksum;

   while (Size > 0)
   {
      mpf = (MP_FLOATING_POINTER*)bp;
      if (mpf->Signature == MPF_SIGNATURE)
      {
	 Checksum = MPChecksum((PUCHAR)bp, 16);
	 DPRINT("Found MPF signature at %x, checksum %x\n", bp, Checksum);
         if (Checksum == 0 &&
	     mpf->Length == 1)
         {
            DPRINT("Intel MultiProcessor Specification v1.%d compliant system.\n",
                   mpf->Specification);

            if (mpf->Feature2 & FEATURE2_IMCRP) 
	    {
               DPRINT("Running in IMCR and PIC compatibility mode.\n");
            } 
	    else 
	    {
               DPRINT("Running in Virtual Wire compatibility mode.\n");
	    }
	

            switch (mpf->Feature1)
            {
               case 0:
                  /* Non standard configuration */
                  break;
               case 1:
                  DPRINT("ISA\n");
                  break;
               case 2:
                  DPRINT("EISA with no IRQ8 chaining\n");
                  break;
               case 3:
                  DPRINT("EISA\n");
                  break;
               case 4:
                  DPRINT("MCA\n");
                  break;
               case 5:
                  DPRINT("ISA and PCI\n");
                  break;
               case 6:
                  DPRINT("EISA and PCI\n");
                  break;
               case 7:
                  DPRINT("MCA and PCI\n");
                  break;
               default:
                  DPRINT("Unknown standard configuration %d\n", mpf->Feature1);
                  return FALSE;
            }
            Mpf = mpf; 
            return TRUE;
         }
      }
      bp += 4;
      Size -= 16;
   }
   return FALSE;
}

static BOOLEAN
HaliGetSmpConfig(VOID)
{
   if (Mpf == NULL)
   {
      return FALSE;
   }

   if (Mpf->Feature2 & FEATURE2_IMCRP)
   {
      DPRINT("Running in IMCR and PIC compatibility mode.\n");
      APICMode = amPIC;
   }
   else
   {
      DPRINT("Running in Virtual Wire compatibility mode.\n");
      APICMode = amVWIRE;
   }

   if (Mpf->Feature1 == 0 && Mpf->Address)
   {
      if(!HaliReadMPConfigTable((PMP_CONFIGURATION_TABLE)Mpf->Address))
      {
         DPRINT("BIOS bug, MP table errors detected!...\n");
	 DPRINT("... disabling SMP support. (tell your hw vendor)\n");
	 return FALSE;
      }
      if (IRQCount == 0)
      {
         MP_CONFIGURATION_BUS bus;

         DPRINT("BIOS bug, no explicit IRQ entries, using default mptable. (tell your hw vendor)\n");

         bus.BusId = 1;
	 memcpy(bus.BusType, "ISA   ", 6);
         HaliMPBusInfo(&bus);
	 HaliConstructDefaultIOIrqMPTable(bus.BusId);
      }

   } 
   else if(Mpf->Feature1 != 0)
   {
      HaliConstructDefaultISAMPTable(Mpf->Feature1);
   }
   else
   {
      KEBUGCHECK(0);
   }
   return TRUE;
}    

BOOLEAN 
HaliFindSmpConfig(VOID)
{
   /*
     Scan the system memory for an MP configuration table
       1) Scan the first KB of system base memory
       2) Scan the last KB of system base memory
       3) Scan the BIOS ROM address space between 0F0000h and 0FFFFFh
       4) Scan the first KB from the Extended BIOS Data Area
   */

   if (!HaliScanForMPConfigTable(0x0, 0x400)) 
   {
      if (!HaliScanForMPConfigTable(0x9FC00, 0x400)) 
      {
         if (!HaliScanForMPConfigTable(0xF0000, 0x10000)) 
         {
            if (!HaliScanForMPConfigTable(*((PUSHORT)0x040E) << 4, 0x400)) 
	    {
               DPRINT("No multiprocessor compliant system found.\n");
               return FALSE;
            }
         }
      }
   }

   if (HaliGetSmpConfig())
   {
      return TRUE;
   }
   else
   {
      DPRINT("No MP config table found\n");
      return FALSE;
   }

}

/* EOF */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -