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

📄 hwcpu.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:

  /* Get 'VendorIdentifier' */
  GetCpuid(0, &eax, &ebx, &ecx, &edx);
  tmpVendorIdentifier[12] = 0;
  Ptr = (ULONG*)&tmpVendorIdentifier[0];
  *Ptr = ebx;
  Ptr++;
  *Ptr = edx;
  Ptr++;
  *Ptr = ecx;
  swprintf(VendorIdentifier, L"%S", tmpVendorIdentifier);

  /* Get 'Identifier' */
  swprintf(Identifier,
	  L"x86 Family %u Model %u Stepping %u",
	  (ULONG)((CpuEntry->CpuSignature >> 8) & 0x0F),
	  (ULONG)((CpuEntry->CpuSignature >> 4) & 0x0F),
	  (ULONG)(CpuEntry->CpuSignature & 0x0F));

  /* Get FeatureSet */
  FeatureSet = CpuEntry->FeatureFlags;

  /* Check if Extended CPUID information is supported */
  GetCpuid(0x80000000, &eax, &ebx, &ecx, &edx);

  if(eax >= 0x80000004)
  {
    /* Get 'ProcessorNameString' */
    tmpProcessorNameString[48] = 0;
    Ptr = (ULONG*)&tmpProcessorNameString[0];

    for (i = 0x80000002; i <= 0x80000004; i++)
    {
      GetCpuid(i, &eax, &ebx, &ecx, &edx);
      *Ptr = eax;
      Ptr++;
      *Ptr = ebx;
      Ptr++;
      *Ptr = ecx;
      Ptr++;
      *Ptr = edx;
      Ptr++;
    }

    swprintf(ProcessorNameString, L"%S", tmpProcessorNameString);


    /* Set 'ProcessorNameString' value (CPU only) */
    DbgPrint((DPRINT_HWDETECT, "Processor Name String: %S\n", ProcessorNameString));

    Error = RegSetValue(CpuInstKey,
                        L"ProcessorNameString",
	                      REG_SZ,
		                    (PCHAR)ProcessorNameString,
		                    (wcslen(ProcessorNameString) + 1) * sizeof(WCHAR));
    if (Error != ERROR_SUCCESS)
      DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
  }

  /* Set 'Configuration Data' value (CPU and FPU) */
  SetComponentInformation(CpuInstKey,
			  0,
			  CpuEntry->LocalApicId,
			  1 << CpuEntry->LocalApicId);

  SetComponentInformation(FpuInstKey,
			  0,
			  CpuEntry->LocalApicId,
			  1 << CpuEntry->LocalApicId);

  /* Set 'FeatureSet' value (CPU only) */
  DbgPrint((DPRINT_HWDETECT, "FeatureSet: %x\n", FeatureSet));

  Error = RegSetValue(CpuInstKey,
		      L"FeatureSet",
		      REG_DWORD,
		      (PCHAR)&FeatureSet,
		      sizeof(ULONG));
  if (Error != ERROR_SUCCESS)
    {
      DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
    }

  /* Set 'Identifier' value (CPU and FPU) */
  DbgPrint((DPRINT_HWDETECT, "Identifier: %S\n", Identifier));

  Error = RegSetValue(CpuInstKey,
		      L"Identifier",
		      REG_SZ,
		      (PCHAR)Identifier,
		      (wcslen(Identifier) + 1) * sizeof(WCHAR));
  if (Error != ERROR_SUCCESS)
    {
      DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
    }

  Error = RegSetValue(FpuInstKey,
		      L"Identifier",
		      REG_SZ,
		      (PCHAR)Identifier,
		      (wcslen(Identifier) + 1) * sizeof(WCHAR));
  if (Error != ERROR_SUCCESS)
    {
      DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
    }

  /* Set 'VendorIdentifier' value (CPU only) */
  DbgPrint((DPRINT_HWDETECT, "Vendor Identifier: %S\n", VendorIdentifier));

  Error = RegSetValue(CpuInstKey,
		      L"VendorIdentifier",
		      REG_SZ,
		      (PCHAR)VendorIdentifier,
		      (wcslen(VendorIdentifier) + 1) * sizeof(WCHAR));
  if (Error != ERROR_SUCCESS)
    {
      DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
    }

  /* FIXME: Set 'Update Signature' value (CPU only) */

  /* FIXME: Set 'Update Status' value (CPU only) */

  /* Set '~MHz' value (CPU only) */

     
  if ((CpuEntry->FeatureFlags  & 0x10) == 0x10)
  {
      if ((CpuEntry->FeatureFlags  & 0x20) == 0x20)
      {
           CpuSpeed = GetCpuSpeed(TRUE);
      }
      else
      {
          DbgPrint((DPRINT_HWDETECT, "Does not support MSR that are need for mesure the speed correct\n", (int)Error));
          CpuSpeed = GetCpuSpeed(FALSE);
      }

      Error = RegSetValue(CpuInstKey,
			  L"~MHz",
			  REG_DWORD,
			  (PCHAR)&CpuSpeed,
			  sizeof(ULONG));
      if (Error != ERROR_SUCCESS)
      {

	     DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
	  }
  }
}


static PMP_FLOATING_POINT_TABLE
GetMpFloatingPointTable(VOID)
{
  PMP_FLOATING_POINT_TABLE FpTable;
  char *Ptr;
  UCHAR Sum;
  ULONG Length;
  ULONG i;

  FpTable = (PMP_FLOATING_POINT_TABLE)0xF0000;
  while ((ULONG)FpTable < 0x100000)
    {
      if (FpTable->Signature == MP_FP_SIGNATURE)
	{
	  Length = FpTable->Length * 0x10;
	  Ptr = (char *)FpTable;
	  Sum = 0;
	  for (i = 0; i < Length; i++)
	    {
	      Sum += Ptr[i];
	    }
	  DbgPrint((DPRINT_HWDETECT,
		    "Checksum: %u\n",
		    Sum));

	  if (Sum != 0)
	    {
	      DbgPrint((DPRINT_HWDETECT,
			"Invalid MP floating point checksum: %u\n",
			Sum));
	      return NULL;
	    }

	  return FpTable;
	}

      FpTable = (PMP_FLOATING_POINT_TABLE)((ULONG)FpTable + 0x10);
    }

  return NULL;
}


static PMP_CONFIGURATION_TABLE
GetMpConfigurationTable(PMP_FLOATING_POINT_TABLE FpTable)
{
  PMP_CONFIGURATION_TABLE ConfigTable;
  char *Ptr;
  UCHAR Sum;
  ULONG Length;
  ULONG i;

  if (FpTable->FeatureByte[0] != 0 ||
      FpTable->PhysicalAddressPointer == 0)
    return NULL;

  ConfigTable = (PMP_CONFIGURATION_TABLE)FpTable->PhysicalAddressPointer;
  if (ConfigTable->Signature != MP_CT_SIGNATURE)
    return NULL;

  DbgPrint((DPRINT_HWDETECT,
	    "MP Configuration Table at: %x\n",
	    (ULONG)ConfigTable));

  /* Calculate base table checksum */
  Length = ConfigTable->BaseTableLength;
  Ptr = (char *)ConfigTable;
  Sum = 0;
  for (i = 0; i < Length; i++)
    {
      Sum += Ptr[i];
    }
  DbgPrint((DPRINT_HWDETECT,
	    "MP Configuration Table base checksum: %u\n",
	    Sum));

  if (Sum != 0)
    {
      DbgPrint((DPRINT_HWDETECT,
		"Invalid MP Configuration Table base checksum: %u\n",
		Sum));
      return NULL;
    }

  if (ConfigTable->ExtendedTableLength != 0)
    {
      /* FIXME: Check extended table */
    }

  return ConfigTable;
}


static BOOLEAN
DetectMps(FRLDRHKEY CpuKey,
	  FRLDRHKEY FpuKey)
{
  PMP_FLOATING_POINT_TABLE FpTable;
  PMP_CONFIGURATION_TABLE ConfigTable;
  PMP_PROCESSOR_ENTRY CpuEntry;
  char *Ptr;
  ULONG Offset;

  /* Get floating point table */
  FpTable = GetMpFloatingPointTable();
  if (FpTable == NULL)
    return FALSE;

  DbgPrint((DPRINT_HWDETECT,
	    "MP Floating Point Table at: %x\n",
	    (ULONG)FpTable));

  if (FpTable->FeatureByte[0] == 0)
    {
      /* Get configuration table */
      ConfigTable = GetMpConfigurationTable(FpTable);
      if (ConfigTable == NULL)
	{
	  DbgPrint((DPRINT_HWDETECT,
		    "Failed to find the MP Configuration Table\n"));
	  return FALSE;
	}

      Offset = sizeof(MP_CONFIGURATION_TABLE);
      while (Offset < ConfigTable->BaseTableLength)
	{
	  Ptr = (char*)((ULONG)ConfigTable + Offset);

	  switch (*Ptr)
	    {
	      case 0:
		CpuEntry = (PMP_PROCESSOR_ENTRY)Ptr;

		DbgPrint((DPRINT_HWDETECT, "Processor Entry\n"));
		DbgPrint((DPRINT_HWDETECT,
			  "APIC Id %u  APIC Version %u  Flags %x  Signature %x  Feature %x\n",
			  CpuEntry->LocalApicId,
			  CpuEntry->LocalApicVersion,
			  CpuEntry->CpuFlags,
			  CpuEntry->CpuSignature,
			  CpuEntry->FeatureFlags));
		DbgPrint((DPRINT_HWDETECT,
			  "Processor %u: x86 Family %u Model %u Stepping %u\n",
			  CpuEntry->LocalApicId,
			  (ULONG)((CpuEntry->CpuSignature >> 8) & 0x0F),
			  (ULONG)((CpuEntry->CpuSignature >> 4) & 0x0F),
			  (ULONG)(CpuEntry->CpuSignature & 0x0F)));

		SetMpsProcessor(CpuKey, FpuKey, CpuEntry);
		Offset += 0x14;
		break;

	      case 1:
		DbgPrint((DPRINT_HWDETECT, "Bus Entry\n"));
		Offset += 0x08;
		break;

	      case 2:
		DbgPrint((DPRINT_HWDETECT, "I/0 APIC Entry\n"));
		Offset += 0x08;
		break;

	      case 3:
		DbgPrint((DPRINT_HWDETECT, "I/0 Interrupt Assignment Entry\n"));
		Offset += 0x08;
		break;

	      case 4:
		DbgPrint((DPRINT_HWDETECT, "Local Interrupt Assignment Entry\n"));
		Offset += 0x08;
		break;

	      default:
		DbgPrint((DPRINT_HWDETECT, "Unknown Entry %u\n",(ULONG)*Ptr));
		return FALSE;
	    }
	}
    }
  else
    {
      DbgPrint((DPRINT_HWDETECT,
	       "Unsupported MPS configuration: %x\n",
	       FpTable->FeatureByte[0]));

      /* FIXME: Identify default configurations */

      return FALSE;
    }

  return TRUE;
}



VOID
DetectCPUs(FRLDRHKEY SystemKey)
{
  FRLDRHKEY CpuKey;
  FRLDRHKEY FpuKey;
  LONG Error;

  /* Create the 'CentralProcessor' key */
  Error = RegCreateKey(SystemKey,
		       L"CentralProcessor",
		       &CpuKey);
  if (Error != ERROR_SUCCESS)
    {
      DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
      return;
    }

  /* Create the 'FloatingPointProcessor' key */
  Error = RegCreateKey(SystemKey,
		       L"FloatingPointProcessor",
		       &FpuKey);
  if (Error != ERROR_SUCCESS)
    {
      DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
      return;
    }

  /* Detect CPUs */
  if (!DetectMps(CpuKey, FpuKey))
    {
      DetectCPU(CpuKey, FpuKey);
    }
}

/* EOF */

⌨️ 快捷键说明

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