678 lines
17 KiB
C
678 lines
17 KiB
C
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
Copyright (c) 1992 Intel Corporation
|
|
All rights reserved
|
|
|
|
INTEL CORPORATION PROPRIETARY INFORMATION
|
|
|
|
This software is supplied to Microsoft under the terms
|
|
of a license agreement with Intel Corporation and may not be
|
|
copied nor disclosed except in accordance with the terms
|
|
of that agreement.
|
|
|
|
Module Name:
|
|
|
|
mpdebug.c
|
|
|
|
Abstract:
|
|
|
|
This module has some useful modules for debug aid.
|
|
|
|
Author:
|
|
|
|
Ron Mosgrove (Intel) - Aug 1993.
|
|
|
|
Environment:
|
|
|
|
Kernel mode or from textmode setup.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#ifndef _NTOS_
|
|
#include "halp.h"
|
|
#endif
|
|
|
|
#include "apic.inc"
|
|
#include "pcmp_nt.inc"
|
|
#include "stdio.h"
|
|
|
|
#define PCMP_TABLE_PTR_BASE 0x09f000
|
|
#define PCMP_TABLE_PTR_OFFSET 0x00000c00
|
|
|
|
// Create dummy PC+MP table at physical address 400K
|
|
#define PCMP_TEST_TABLE 0x64000
|
|
#define TEST_FLOAT_PTR 0x7d000
|
|
|
|
extern struct PcMpTable *PcMpTablePtr, *PcMpDefaultTablePtrs[];
|
|
//extern struct HalpMpInfo *HalpMpInfoPtr;
|
|
|
|
CHAR Cbuf[120];
|
|
|
|
UCHAR
|
|
ComputeCheckSum(
|
|
IN PUCHAR SourcePtr,
|
|
IN USHORT NumOfBytes
|
|
);
|
|
|
|
#ifdef OLD_DEBUG
|
|
extern struct PcMpConfigTable *PcMpTablePtr;
|
|
#endif
|
|
|
|
#ifdef DEBUGGING
|
|
|
|
ULONG HalpUseDbgPrint = 0;
|
|
|
|
void
|
|
HalpDisplayString(
|
|
IN PVOID String
|
|
)
|
|
{
|
|
if (!HalpUseDbgPrint) {
|
|
HalDisplayString(String);
|
|
} else {
|
|
DbgPrint(String);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
HalpDisplayItemBuf(
|
|
IN UCHAR Length,
|
|
IN PUCHAR Buffer,
|
|
IN PVOID Name
|
|
)
|
|
{
|
|
ULONG i;
|
|
CHAR TmpBuf[80];
|
|
|
|
sprintf(TmpBuf, " %s -", Name);
|
|
HalpDisplayString(TmpBuf);
|
|
for (i=0; i< Length; i++) {
|
|
sprintf(TmpBuf, " 0x%x", Buffer[i]);
|
|
HalpDisplayString(TmpBuf);
|
|
}
|
|
HalpDisplayString("\n");
|
|
}
|
|
|
|
void
|
|
HalpDisplayULItemBuf(
|
|
IN UCHAR Length,
|
|
IN PULONG Buffer,
|
|
IN PVOID Name
|
|
)
|
|
{
|
|
ULONG i;
|
|
CHAR TmpBuf[80];
|
|
|
|
sprintf(TmpBuf, " %s -", Name);
|
|
HalpDisplayString(TmpBuf);
|
|
for (i=0; i< Length; i++) {
|
|
sprintf(TmpBuf, " 0x%lx", Buffer[i]);
|
|
HalpDisplayString(TmpBuf);
|
|
}
|
|
HalpDisplayString("\n");
|
|
}
|
|
|
|
void
|
|
HalpDisplayItem(
|
|
IN ULONG Item,
|
|
IN PVOID ItemStr
|
|
)
|
|
{
|
|
CHAR TmpBuf[80];
|
|
|
|
sprintf(TmpBuf, " %s - 0x%x\n", ItemStr, Item);
|
|
HalpDisplayString(TmpBuf);
|
|
}
|
|
|
|
VOID
|
|
HalpDisplayBIOSSysCfg(
|
|
IN struct SystemConfigTable *SysCfgPtr
|
|
)
|
|
{
|
|
HalpDisplayString("BIOS System Configuration Table\n");
|
|
HalpDisplayItem(SysCfgPtr->ModelType, "ModelType");
|
|
HalpDisplayItem(SysCfgPtr->SubModelType, "SubModelType");
|
|
HalpDisplayItem(SysCfgPtr->BIOSRevision, "BIOSRevision");
|
|
HalpDisplayItemBuf(3,SysCfgPtr->FeatureInfoByte,"FeatureInfoByte");
|
|
HalpDisplayItem(SysCfgPtr->MpFeatureInfoByte1, "MpFeatureInfoByte1");
|
|
HalpDisplayItem(SysCfgPtr->MpFeatureInfoByte2, "MpFeatureInfoByte2");
|
|
}
|
|
|
|
VOID
|
|
HalpDisplayLocalUnit(
|
|
)
|
|
{
|
|
ULONG Data;
|
|
PKPCR pPCR;
|
|
|
|
pPCR = KeGetPcr();
|
|
|
|
sprintf(Cbuf, "\nLocal Apic for P%d\n", pPCR->Prcb->Number);
|
|
HalpDisplayString(Cbuf);
|
|
|
|
#define DisplayLuReg(Reg, RegStr) Data = *((PVULONG) (LOCALAPIC+Reg)); \
|
|
HalpDisplayItem(Data , RegStr);
|
|
|
|
|
|
DisplayLuReg( LU_ID_REGISTER , "LU_ID_REGISTER" );
|
|
DisplayLuReg( LU_VERS_REGISTER, "LU_VERS_REGISTER" );
|
|
DisplayLuReg( LU_TPR, "LU_TPR");
|
|
DisplayLuReg( LU_APR, "LU_APR");
|
|
DisplayLuReg( LU_PPR, "LU_PPR");
|
|
DisplayLuReg( LU_EOI, "LU_EOI");
|
|
DisplayLuReg( LU_REMOTE_REGISTER, "LU_REMOTE_REGISTER");
|
|
DisplayLuReg( LU_LOGICAL_DEST, "LU_LOGICAL_DEST");
|
|
|
|
DisplayLuReg( LU_DEST_FORMAT, "LU_DEST_FORMAT");
|
|
|
|
DisplayLuReg( LU_SPURIOUS_VECTOR , "LU_SPURIOUS_VECTOR" );
|
|
|
|
DisplayLuReg( LU_ISR_0, "LU_ISR_0");
|
|
DisplayLuReg( LU_TMR_0, "LU_TMR_0");
|
|
DisplayLuReg( LU_IRR_0, "LU_IRR_0");
|
|
DisplayLuReg( LU_ERROR_STATUS, "LU_ERROR_STATUS");
|
|
DisplayLuReg( LU_INT_CMD_LOW, "LU_INT_CMD_LOW");
|
|
DisplayLuReg( LU_INT_CMD_HIGH, "LU_INT_CMD_HIGH");
|
|
DisplayLuReg( LU_TIMER_VECTOR, "LU_TIMER_VECTOR");
|
|
DisplayLuReg( LU_INT_VECTOR_0, "LU_INT_VECTOR_0");
|
|
DisplayLuReg( LU_INT_VECTOR_1, "LU_INT_VECTOR_1");
|
|
DisplayLuReg( LU_INITIAL_COUNT, "LU_INITIAL_COUNT");
|
|
DisplayLuReg( LU_CURRENT_COUNT, "LU_CURRENT_COUNT");
|
|
|
|
DisplayLuReg( LU_DIVIDER_CONFIG, "LU_DIVIDER_CONFIG");
|
|
HalpDisplayString("\n");
|
|
|
|
}
|
|
|
|
VOID
|
|
HalpDisplayIoUnit(
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Verify that an IO Unit exists at the specified address
|
|
|
|
Arguments:
|
|
|
|
BaseAddress - Address of the IO Unit to test.
|
|
|
|
Return Value:
|
|
BOOLEAN - TRUE if a IO Unit was found at the passed address
|
|
- FALSE otherwise
|
|
|
|
--*/
|
|
|
|
{
|
|
#if 0
|
|
struct ApicIoUnit *IoUnitPtr;
|
|
ULONG Data,i,j;
|
|
PKPCR pPCR;
|
|
|
|
pPCR = KeGetPcr();
|
|
|
|
//
|
|
// The documented detection mechanism is to write all zeros to
|
|
// the Version register. Then read it back. The IO Unit exists if the
|
|
// same result is read both times and the Version is valid.
|
|
//
|
|
|
|
|
|
|
|
for (j=0; j<HalpMpInfoPtr->IOApicCount; j++) {
|
|
IoUnitPtr = (struct ApicIoUnit *) HalpMpInfoPtr->IoApicBase[j];
|
|
|
|
sprintf(Cbuf,"\nIoApic %d at Vaddr 0x%x\n",j,(ULONG) IoUnitPtr);
|
|
HalpDisplayString(Cbuf);
|
|
|
|
IoUnitPtr->RegisterSelect = IO_ID_REGISTER;
|
|
HalpDisplayItem(IoUnitPtr->RegisterWindow, "IO_ID_REGISTER");
|
|
|
|
|
|
IoUnitPtr->RegisterSelect = IO_VERS_REGISTER;
|
|
HalpDisplayItem(IoUnitPtr->RegisterWindow, "IO_VERS_REGISTER");
|
|
|
|
for (i=0; i<16; i++) {
|
|
|
|
IoUnitPtr->RegisterSelect = IO_REDIR_00_LOW+(i*2);
|
|
Data = IoUnitPtr->RegisterWindow;
|
|
sprintf(Cbuf, " Redir [0x%x] - 0x%x, ", i, Data);
|
|
HalpDisplayString(Cbuf);
|
|
|
|
IoUnitPtr->RegisterSelect = IO_REDIR_00_LOW+(i*2)+1;
|
|
Data = IoUnitPtr->RegisterWindow;
|
|
sprintf(Cbuf, "0x%x\n", Data);
|
|
HalpDisplayString(Cbuf);
|
|
|
|
} // for each Redirection entry
|
|
} // for all Io Apics
|
|
|
|
#endif
|
|
}
|
|
|
|
void
|
|
HalpDisplayConfigTable ()
|
|
/*+++
|
|
Debug routine to display the PC+MP config table
|
|
--*/
|
|
{
|
|
struct PcMpTable *MpPtr = PcMpTablePtr;
|
|
PPCMPPROCESSOR ProcPtr;
|
|
ULONG EntriesInTable = MpPtr->NumOfEntries;
|
|
union PL {
|
|
USHORT us;
|
|
POLARITYANDLEVEL PnL;
|
|
};
|
|
|
|
HalpDisplayString("PcMp Configuration Table\n");
|
|
|
|
HalpDisplayItem(MpPtr->Signature, "Signature");
|
|
HalpDisplayItem(MpPtr->TableLength, "TableLength");
|
|
HalpDisplayItem(MpPtr->Revision, "Revision");
|
|
HalpDisplayItem(MpPtr->Checksum, "Checksum");
|
|
|
|
HalpDisplayItemBuf(sizeof(MpPtr->OemId),
|
|
MpPtr->OemId,"OemId");
|
|
HalpDisplayItemBuf(sizeof(MpPtr->OemProductId),
|
|
MpPtr->OemProductId,"OemProductId");
|
|
|
|
HalpDisplayItem((ULONG) MpPtr->OemTablePtr, "OemTablePtr");
|
|
HalpDisplayItem(MpPtr->OemTableSize, "OemTableSize");
|
|
HalpDisplayItem(MpPtr->NumOfEntries, "NumOfEntries");
|
|
HalpDisplayItem((ULONG) MpPtr->LocalApicAddress, "LocalApicAddress");
|
|
HalpDisplayItem(MpPtr->Reserved, "Reserved");
|
|
|
|
ProcPtr = (PPCMPPROCESSOR) ((PUCHAR) MpPtr + HEADER_SIZE);
|
|
|
|
|
|
while (EntriesInTable) {
|
|
EntriesInTable--;
|
|
switch ( ProcPtr->EntryType ) {
|
|
case ENTRY_PROCESSOR: {
|
|
union xxx {
|
|
ULONG ul;
|
|
CPUIDENTIFIER CpuId;
|
|
} u;
|
|
|
|
sprintf (Cbuf, "Proc..: ApicId %x, Apic ver %x, Flags %x\n",
|
|
ProcPtr->LocalApicId,
|
|
ProcPtr->LocalApicVersion,
|
|
ProcPtr->CpuFlags
|
|
);
|
|
HalpDisplayString (Cbuf);
|
|
ProcPtr++;
|
|
break;
|
|
}
|
|
|
|
case ENTRY_BUS: {
|
|
PPCMPBUS BusPtr = (PPCMPBUS) ProcPtr;
|
|
|
|
sprintf (Cbuf, "Bus...: id %02x, type '%.6s'\n",
|
|
BusPtr->BusId, BusPtr->BusType);
|
|
|
|
HalpDisplayString (Cbuf);
|
|
BusPtr++;
|
|
ProcPtr = (PPCMPPROCESSOR) BusPtr;
|
|
break;
|
|
}
|
|
|
|
case ENTRY_IOAPIC: {
|
|
PPCMPIOAPIC IoApPtr = (PPCMPIOAPIC) ProcPtr;
|
|
|
|
sprintf (Cbuf, "IoApic: id %02x, ver %x, Flags %x, Address %x\n",
|
|
IoApPtr->IoApicId,
|
|
IoApPtr->IoApicVersion,
|
|
IoApPtr->IoApicFlag,
|
|
(ULONG) IoApPtr->IoApicAddress
|
|
);
|
|
HalpDisplayString (Cbuf);
|
|
|
|
IoApPtr++;
|
|
ProcPtr = (PPCMPPROCESSOR) IoApPtr;
|
|
break;
|
|
}
|
|
|
|
case ENTRY_INTI: {
|
|
PPCMPINTI IntiPtr = (PPCMPINTI) ProcPtr;
|
|
union PL u;
|
|
|
|
u.PnL = IntiPtr->Signal;
|
|
|
|
sprintf (Cbuf, "Inti..: t%x, s%x, SInt %x-%x, Inti %x-%x\n",
|
|
IntiPtr->IntType,
|
|
u.us,
|
|
IntiPtr->SourceBusId,
|
|
IntiPtr->SourceBusIrq,
|
|
IntiPtr->IoApicId,
|
|
IntiPtr->IoApicInti
|
|
);
|
|
HalpDisplayString (Cbuf);
|
|
|
|
IntiPtr++;
|
|
ProcPtr = (PPCMPPROCESSOR) IntiPtr;
|
|
break;
|
|
}
|
|
|
|
case ENTRY_LINTI: {
|
|
PPCMPLINTI LIntiPtr = (PPCMPLINTI) ProcPtr;
|
|
union PL u;
|
|
|
|
u.PnL = LIntiPtr->Signal;
|
|
|
|
sprintf (Cbuf, "Linti.: t%x, s%x, SInt %x-%x, Linti %x-%x\n",
|
|
LIntiPtr->IntType,
|
|
u.us,
|
|
LIntiPtr->SourceBusId,
|
|
LIntiPtr->SourceBusIrq,
|
|
LIntiPtr->DestLocalApicId,
|
|
LIntiPtr->DestLocalApicInti
|
|
);
|
|
HalpDisplayString (Cbuf);
|
|
|
|
LIntiPtr++;
|
|
ProcPtr = (PPCMPPROCESSOR) LIntiPtr;
|
|
break;
|
|
}
|
|
|
|
default: {
|
|
HalpDisplayItem(ProcPtr->EntryType, "Unknown Type");
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
HalpDisplayExtConfigTable ()
|
|
{
|
|
PMPS_EXTENTRY ExtTable;
|
|
extern struct HalpMpInfo HalpMpInfoTable;
|
|
|
|
|
|
ExtTable = HalpMpInfoTable.ExtensionTable;
|
|
while (ExtTable < HalpMpInfoTable.EndOfExtensionTable) {
|
|
switch (ExtTable->Type) {
|
|
|
|
case EXTTYPE_BUS_ADDRESS_MAP:
|
|
sprintf (Cbuf, "BusMap: id %02x, t%x Base %08x Len %08x\n",
|
|
ExtTable->u.AddressMap.BusId,
|
|
ExtTable->u.AddressMap.Type,
|
|
(ULONG) ExtTable->u.AddressMap.Base,
|
|
(ULONG) ExtTable->u.AddressMap.Length
|
|
);
|
|
HalpDisplayString (Cbuf);
|
|
break;
|
|
|
|
case EXTTYPE_BUS_HIERARCHY:
|
|
sprintf (Cbuf, "BusHie: id %02x, Parent:%x sd:%x\n",
|
|
ExtTable->u.BusHierarchy.BusId,
|
|
ExtTable->u.BusHierarchy.ParentBusId,
|
|
ExtTable->u.BusHierarchy.SubtractiveDecode
|
|
);
|
|
HalpDisplayString (Cbuf);
|
|
break;
|
|
|
|
case EXTTYPE_BUS_COMPATIBLE_MAP:
|
|
sprintf (Cbuf, "ComBus: id %02x %c List %x\n",
|
|
ExtTable->u.CompatibleMap.BusId,
|
|
ExtTable->u.CompatibleMap.Modifier ? '-' : '+',
|
|
ExtTable->u.CompatibleMap.List
|
|
);
|
|
HalpDisplayString (Cbuf);
|
|
break;
|
|
|
|
case EXTTYPE_PERSISTENT_STORE:
|
|
sprintf (Cbuf, "PreSTR: Address %08x Len %08x\n",
|
|
(ULONG) ExtTable->u.PersistentStore.Address,
|
|
(ULONG) ExtTable->u.PersistentStore.Length
|
|
);
|
|
HalpDisplayString (Cbuf);
|
|
break;
|
|
|
|
default:
|
|
HalpDisplayItem(ExtTable->Type, "Unknown Type");
|
|
break;
|
|
}
|
|
|
|
|
|
ExtTable = (PMPS_EXTENTRY) (((PUCHAR) ExtTable) + ExtTable->Length);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void
|
|
HalpDisplayMpInfo()
|
|
{
|
|
#if 0
|
|
struct HalpMpInfo *MpPtr = HalpMpInfoPtr;
|
|
|
|
HalpDisplayString("\nHAL: Private Mp Info\n");
|
|
|
|
HalpDisplayItem(MpPtr->ApicVersion, "ApicVersion");
|
|
HalpDisplayItem(MpPtr->ProcessorCount, "ProcessorCount");
|
|
HalpDisplayItem(MpPtr->BusCount, "BusCount");
|
|
HalpDisplayItem(MpPtr->IOApicCount, "IOApicCount");
|
|
HalpDisplayItem(MpPtr->IntiCount, "IntiCount");
|
|
HalpDisplayItem(MpPtr->LintiCount, "LintiCount");
|
|
HalpDisplayItem(MpPtr->IMCRPresent, "IMCRPresent");
|
|
|
|
HalpDisplayULItemBuf(4,(PULONG) MpPtr->IoApicBase,"IoApicBase");
|
|
HalpDisplayString("\n");
|
|
HalpDisplayConfigTable();
|
|
|
|
#endif
|
|
}
|
|
|
|
|
|
#ifdef OLD_DEBUG
|
|
|
|
BOOLEAN
|
|
HalpVerifyLocalUnit(
|
|
IN UCHAR ApicID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Verify that a Local Apic has the specified Apic Id.
|
|
|
|
Arguments:
|
|
|
|
ApicId - Id to verify.
|
|
|
|
Return Value:
|
|
BOOLEAN - TRUE if found
|
|
- FALSE otherwise
|
|
|
|
--*/
|
|
|
|
{
|
|
union ApicUnion Temp;
|
|
|
|
//
|
|
// The remote read command must be:
|
|
//
|
|
// Vector - Bits 4-9 of the Version register
|
|
// Destination Mode - Physical
|
|
// Trigger Mode - Edge
|
|
// Delivery Mode - Remote Read
|
|
// Destination Shorthand - Destination Field
|
|
//
|
|
|
|
#define LU_READ_REMOTE_VERSION ( (LU_VERS_REGISTER >> 4) | \
|
|
DELIVER_REMOTE_READ | \
|
|
ICR_USE_DEST_FIELD)
|
|
|
|
#define DEFAULT_DELAY 100
|
|
|
|
PVULONG LuDestAddress = (PVULONG) (LOCALAPIC + LU_INT_CMD_HIGH);
|
|
PVULONG LuICR = (PVULONG) (LOCALAPIC + LU_INT_CMD_LOW);
|
|
PVULONG LuRemoteReg = (PVULONG) (LOCALAPIC + LU_REMOTE_REGISTER);
|
|
ULONG RemoteReadStatus;
|
|
ULONG DelayCount = DEFAULT_DELAY;
|
|
|
|
//
|
|
// First make sure we can get to the Apic Bus
|
|
//
|
|
|
|
while ( ( DelayCount-- ) && ( *LuICR & DELIVERY_PENDING ) );
|
|
|
|
if (DelayCount == 0) {
|
|
//
|
|
// We're toast, can't gain access to the APIC Bus
|
|
//
|
|
return (FALSE);
|
|
}
|
|
|
|
//
|
|
// Set the Address of the APIC we're looking for
|
|
//
|
|
|
|
*LuDestAddress = (ApicID << DESTINATION_SHIFT);
|
|
|
|
//
|
|
// Issue the request
|
|
//
|
|
|
|
*LuICR = LU_READ_REMOTE_VERSION;
|
|
|
|
//
|
|
// Reset the Delay so we can get out of here just in case...
|
|
//
|
|
|
|
DelayCount = DEFAULT_DELAY;
|
|
|
|
while (DelayCount--) {
|
|
|
|
RemoteReadStatus = *LuICR & ICR_RR_STATUS_MASK;
|
|
|
|
if ( RemoteReadStatus == ICR_RR_INVALID) {
|
|
//
|
|
// No One responded, device timed out
|
|
//
|
|
return (FALSE);
|
|
}
|
|
|
|
if ( RemoteReadStatus == ICR_RR_VALID) {
|
|
//
|
|
// Someone is there and the Remote Register is valid
|
|
//
|
|
Temp.Raw = *LuRemoteReg;
|
|
|
|
//
|
|
// Do what we can to verify the Version
|
|
//
|
|
|
|
if (Temp.Ver.Version > 0x1f) {
|
|
//
|
|
// Only known devices are 0.x and 1.x
|
|
//
|
|
return (FALSE);
|
|
}
|
|
|
|
return (TRUE);
|
|
|
|
} // RemoteRead Successfull
|
|
|
|
} // While DelayCount
|
|
|
|
//
|
|
// No One responded, and the device did not time out
|
|
// This should never happen
|
|
//
|
|
|
|
return (FALSE);
|
|
}
|
|
|
|
#endif // OLD_DEBUG
|
|
|
|
VOID
|
|
CreateBIOSTables(
|
|
VOID)
|
|
/*++
|
|
|
|
Routine Description:
|
|
This routine is used to test the PC+MP detect code in the HAL.
|
|
It creates the PC+MP structures that are really created by the
|
|
BIOS. Since we presently do not have a BIOS that builds a PC+MP
|
|
table, we need this for now.
|
|
|
|
Arguments:
|
|
None.
|
|
|
|
Return Value:
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
PUCHAR TempPtr, BytePtr;
|
|
UCHAR CheckSum;
|
|
PULONG TraversePtr;
|
|
USHORT BytesToCopy;
|
|
|
|
HalpDisplayString("CreateBIOSTables : Entered\n");
|
|
// First, copy default PC+MP configuration 2 table at physical
|
|
// address PCMP_TEST_TABLE
|
|
TempPtr = (PUCHAR) HalpMapPhysicalMemory(
|
|
(PVOID) PCMP_TEST_TABLE, 1);
|
|
|
|
BytesToCopy = (PcMpDefaultTablePtrs[1])->TableLength;
|
|
RtlMoveMemory(TempPtr, (PUCHAR)PcMpDefaultTablePtrs[1],
|
|
BytesToCopy);
|
|
|
|
// Populate the checksum entry for the table.
|
|
CheckSum = ComputeCheckSum(TempPtr, BytesToCopy);
|
|
|
|
sprintf(Cbuf, "CreateBIOSTables: PC+MP table computed checksum = %x\n",
|
|
CheckSum);
|
|
HalpDisplayString(Cbuf);
|
|
|
|
CheckSum = ~CheckSum + 1;
|
|
((struct PcMpTable *)TempPtr)->Checksum = CheckSum;
|
|
|
|
sprintf(Cbuf, "CreateBIOSTables: PC+MP table written checksum = %x\n",
|
|
CheckSum);
|
|
HalpDisplayString(Cbuf);
|
|
|
|
|
|
// Now create the floating pointer structure for the table.
|
|
|
|
TraversePtr = (PULONG) HalpMapPhysicalMemory( (PVOID) TEST_FLOAT_PTR, 1);
|
|
TempPtr = (PUCHAR) TraversePtr;
|
|
|
|
*TraversePtr++ = MP_PTR_SIGNATURE;
|
|
*TraversePtr++ = PCMP_TEST_TABLE;
|
|
BytePtr = (PUCHAR)TraversePtr;
|
|
*BytePtr++ = 1; // Length in number of 16 byte paragraphs
|
|
*BytePtr++ = 1; // Spec Rev.
|
|
*BytePtr++ = 0; // CheckSum
|
|
*BytePtr++ = 0; // Reserved
|
|
TraversePtr = (PULONG)BytePtr;
|
|
*TraversePtr = 0; // Reserved
|
|
|
|
CheckSum = ComputeCheckSum(TempPtr,16);
|
|
|
|
sprintf(Cbuf, "CreateBIOSTables: FLOAT_PTR computed checksum = %x\n",
|
|
CheckSum);
|
|
HalpDisplayString(Cbuf);
|
|
|
|
CheckSum = ~CheckSum + 1;
|
|
|
|
sprintf(Cbuf, "CreateBIOSTables: FLOAT_PTR written checksum = %x\n",
|
|
CheckSum);
|
|
HalpDisplayString(Cbuf);
|
|
|
|
((struct PcMpTableLocator *)TempPtr)->TableChecksum = CheckSum;
|
|
|
|
HalpDisplayString("CreateBIOSTables : Done\n");
|
|
|
|
}
|
|
|
|
#endif // DEBUGGING
|