254 lines
7.4 KiB
C
254 lines
7.4 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1992 NCR Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
ncrdetect.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Authors:
|
|||
|
|
|||
|
Richard Barton (o-richb) 24-Jan-1992
|
|||
|
Brian Weischedel 30-Nov-1992
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
Kernel mode only.
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#ifndef _NTOS_
|
|||
|
#include "nthal.h"
|
|||
|
#endif
|
|||
|
|
|||
|
PVOID
|
|||
|
HalpMapPhysicalMemory(
|
|||
|
IN PVOID PhysicalAddress,
|
|||
|
IN ULONG NumberPages
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
ReadCMOS(
|
|||
|
IN ULONG StartingOffset,
|
|||
|
IN ULONG Count,
|
|||
|
IN PUCHAR ReturnValuePtr);
|
|||
|
|
|||
|
ULONG NCRPlatform;
|
|||
|
|
|||
|
#define NCR3450 0x35333433 // Copied here to build standalone
|
|||
|
#define NCR3550 0x30353834
|
|||
|
#define NCR3360 0x33333630
|
|||
|
|
|||
|
// WPD definitions:
|
|||
|
|
|||
|
PUCHAR WPDStringID = "NCR Voyager-1";
|
|||
|
PUCHAR WPDPlatformName = "System 3360";
|
|||
|
#define WPDStringIDLength 13
|
|||
|
#define WPDStringIDRangeStart (0xE000 << 4) // physical address
|
|||
|
#define WPDStringIDRangeSize 0x10000 // 1 segment (64k)
|
|||
|
|
|||
|
// MSBU definitions:
|
|||
|
|
|||
|
PUCHAR MSBUCopyrightString = "Copyright (C) ???? NCR\0";
|
|||
|
#define MSBUCopyrightStringLen 23
|
|||
|
#define MSBUCopyrightPhysicalPtr ((0xF000 << 4) + (0xE020))
|
|||
|
typedef struct {
|
|||
|
ULONG ClassFromFirmware;
|
|||
|
PUCHAR PlatformName;
|
|||
|
} MSBUPlatformMapEntry;
|
|||
|
MSBUPlatformMapEntry MSBUPlatformMap[] = {{NCR3450, "System 3450"},
|
|||
|
{NCR3550, "System 3550"},
|
|||
|
{0, 0}};
|
|||
|
|
|||
|
PUCHAR
|
|||
|
NCRDeterminePlatform(
|
|||
|
OUT PBOOLEAN IsConfiguredMp
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
Determine on which NCR platform we are running. For now just display
|
|||
|
a message. Later we may not continue the boot if we're on an
|
|||
|
unrecognized platform.
|
|||
|
|
|||
|
Arguments:
|
|||
|
none.
|
|||
|
|
|||
|
Return Value:
|
|||
|
Pointer to character string identifying which NCR platform. NULL means
|
|||
|
it is unrecognized, and we shouldn't continue.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
BOOLEAN Matchfound;
|
|||
|
MSBUPlatformMapEntry *MSBUPlatformMapPtr;
|
|||
|
PVOID BIOSPagePtr;
|
|||
|
PUCHAR StringPtr;
|
|||
|
PUCHAR CopyrightPtr;
|
|||
|
PUCHAR SearchPtr;
|
|||
|
UCHAR CpuFlags;
|
|||
|
|
|||
|
|
|||
|
// first check for a WPD platform by searching the 0xE000 BIOS segment
|
|||
|
// for a ROM string that identifies this system as a 3360
|
|||
|
|
|||
|
|
|||
|
// get virtual address to the BIOS region (assuming region is both
|
|||
|
// page aligned and multiple pages in size)
|
|||
|
|
|||
|
BIOSPagePtr = HalpMapPhysicalMemory((PVOID) WPDStringIDRangeStart,
|
|||
|
(WPDStringIDRangeSize >> 12));
|
|||
|
|
|||
|
if (BIOSPagePtr != NULL) {
|
|||
|
|
|||
|
SearchPtr = BIOSPagePtr; // begin search at start of region
|
|||
|
Matchfound = FALSE;
|
|||
|
|
|||
|
// search until string is found or we are beyond the region
|
|||
|
|
|||
|
while (!Matchfound && (SearchPtr <= (PUCHAR)((ULONG)BIOSPagePtr +
|
|||
|
WPDStringIDRangeSize -
|
|||
|
WPDStringIDLength))) {
|
|||
|
|
|||
|
// see if SearchPtr points to the desired string
|
|||
|
|
|||
|
StringPtr = (PUCHAR)((ULONG)SearchPtr++);
|
|||
|
CopyrightPtr = WPDStringID;
|
|||
|
|
|||
|
// continue compare as long as characters compare
|
|||
|
// and not at end of string
|
|||
|
|
|||
|
while ((Matchfound = (*CopyrightPtr++ == *StringPtr++)) &&
|
|||
|
(CopyrightPtr < WPDStringID + WPDStringIDLength));
|
|||
|
}
|
|||
|
|
|||
|
// see if string was found (i.e., if this is a 3360)
|
|||
|
|
|||
|
if (Matchfound) {
|
|||
|
|
|||
|
// store system identifier ("3360") for later HAL use
|
|||
|
|
|||
|
NCRPlatform = NCR3360;
|
|||
|
|
|||
|
// read CPU good flags from CMOS and determine if MP
|
|||
|
|
|||
|
ReadCMOS(0x88A, 1, &CpuFlags);
|
|||
|
// *IsConfiguredMp = (CpuFlags & (CpuFlags-1)) ? TRUE : FALSE;
|
|||
|
|
|||
|
// This is an MP hal
|
|||
|
*IsConfiguredMp = TRUE;
|
|||
|
|
|||
|
return(WPDPlatformName);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// now check for an MSBU platform
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
* Map in the BIOS text so we can look for our copyright string.
|
|||
|
*/
|
|||
|
BIOSPagePtr = (PVOID)((ULONG)MSBUCopyrightPhysicalPtr &
|
|||
|
~(PAGE_SIZE - 1));
|
|||
|
BIOSPagePtr = HalpMapPhysicalMemory(BIOSPagePtr, 2);
|
|||
|
if (BIOSPagePtr == NULL)
|
|||
|
return(NULL);
|
|||
|
|
|||
|
StringPtr = (PUCHAR)((ULONG)BIOSPagePtr +
|
|||
|
((ULONG)MSBUCopyrightPhysicalPtr & (PAGE_SIZE - 1)))
|
|||
|
+ (MSBUCopyrightStringLen - 1);
|
|||
|
CopyrightPtr = MSBUCopyrightString + (MSBUCopyrightStringLen - 1);
|
|||
|
do {
|
|||
|
Matchfound = ((*CopyrightPtr == '?') ||
|
|||
|
(*CopyrightPtr == *StringPtr));
|
|||
|
--CopyrightPtr;
|
|||
|
--StringPtr;
|
|||
|
} while (Matchfound && (CopyrightPtr >= MSBUCopyrightString));
|
|||
|
|
|||
|
//
|
|||
|
// /*
|
|||
|
// * Clear the mapping to BIOS. We mapped in two pages.
|
|||
|
// */
|
|||
|
// BIOSPagePtr = MiGetPteAddress(BIOSPagePtr);
|
|||
|
// *(PULONG)BIOSPagePtr = 0;
|
|||
|
// *(((PULONG)BIOSPagePtr)+1) = 0;
|
|||
|
// /*
|
|||
|
// * Flush the TLB.
|
|||
|
// */
|
|||
|
// _asm {
|
|||
|
// mov eax, cr3
|
|||
|
// mov cr3, eax
|
|||
|
// }
|
|||
|
//
|
|||
|
|
|||
|
if (Matchfound) {
|
|||
|
/*
|
|||
|
* must be an MSBU machine..determine which.
|
|||
|
*/
|
|||
|
ReadCMOS(0xB16, 4, (PUCHAR)&NCRPlatform);
|
|||
|
for (MSBUPlatformMapPtr = MSBUPlatformMap;
|
|||
|
(MSBUPlatformMapPtr->ClassFromFirmware != 0);
|
|||
|
++MSBUPlatformMapPtr) {
|
|||
|
if (MSBUPlatformMapPtr->ClassFromFirmware ==
|
|||
|
NCRPlatform) {
|
|||
|
|
|||
|
*IsConfiguredMp = TRUE;
|
|||
|
return(MSBUPlatformMapPtr->PlatformName);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* prerelease version of firmware had this machine class
|
|||
|
* at the wrong offset into CMOS. until all those versions
|
|||
|
* of firmware are extinguished from the face of the earth
|
|||
|
* we should recognize them with this:
|
|||
|
*/
|
|||
|
ReadCMOS(0xAB3, 4, (PUCHAR)&NCRPlatform);
|
|||
|
for (MSBUPlatformMapPtr = MSBUPlatformMap;
|
|||
|
(MSBUPlatformMapPtr->ClassFromFirmware != 0);
|
|||
|
++MSBUPlatformMapPtr) {
|
|||
|
if (MSBUPlatformMapPtr->ClassFromFirmware ==
|
|||
|
NCRPlatform) {
|
|||
|
*IsConfiguredMp = TRUE;
|
|||
|
return(MSBUPlatformMapPtr->PlatformName);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return(NULL);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#ifndef SETUP // if built with Hal, must provide ReadCMOS routine
|
|||
|
|
|||
|
ULONG
|
|||
|
HalpGetCmosData (
|
|||
|
IN ULONG SourceLocation,
|
|||
|
IN ULONG SourceAddress,
|
|||
|
IN PUCHAR Buffer,
|
|||
|
IN ULONG Length);
|
|||
|
|
|||
|
VOID
|
|||
|
ReadCMOS(
|
|||
|
IN ULONG StartingOffset,
|
|||
|
IN ULONG Count,
|
|||
|
IN PUCHAR ReturnValuePtr
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This routine simply converts a ReadCMOS call (a routine in setup) to
|
|||
|
the corresponding routine provided in the Hal (HalpGetCmosData).
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
HalpGetCmosData(1, StartingOffset, ReturnValuePtr, Count);
|
|||
|
}
|
|||
|
#endif
|