You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
643 lines
20 KiB
643 lines
20 KiB
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
Copyright (c) 1998 Intel Corporation
|
|
|
|
|
|
Module Name:
|
|
|
|
sumain.c
|
|
|
|
Abstract:
|
|
SuMain() sets up NT specific data structures for OsLoader.c. This
|
|
is necessary since we don't have the ARC firmware to do the work
|
|
for us. SuMain() is call by SuSetup() which is an assembly level
|
|
routine that does IA64 specific setup.
|
|
|
|
Author:
|
|
|
|
Allen Kay (akay) 19-May-95
|
|
|
|
--*/
|
|
|
|
#include "bldr.h"
|
|
#include "sudata.h"
|
|
#include "sal.h"
|
|
#include "efi.h"
|
|
#include "efip.h"
|
|
#include "bootia64.h"
|
|
#include "smbios.h"
|
|
|
|
extern EFI_SYSTEM_TABLE *EfiST;
|
|
|
|
//
|
|
// External functions
|
|
//
|
|
extern VOID NtProcessStartup();
|
|
extern VOID SuFillExportTable();
|
|
extern VOID CpuSpecificWork();
|
|
|
|
extern EFI_STATUS
|
|
GetSystemConfigurationTable(
|
|
IN EFI_GUID *TableGuid,
|
|
IN OUT VOID **Table
|
|
);
|
|
|
|
//
|
|
// Define export entry table.
|
|
//
|
|
PVOID ExportEntryTable[ExMaximumRoutine];
|
|
|
|
// M E M O R Y D E S C R I P T O R
|
|
//
|
|
// Memory Descriptor - each contiguous block of physical memory is
|
|
// described by a Memory Descriptor. The descriptors are a table, with
|
|
// the last entry having a BlockBase and BlockSize of zero. A pointer
|
|
// to the beginning of this table is passed as part of the BootContext
|
|
// Record to the OS Loader.
|
|
//
|
|
|
|
BOOT_CONTEXT BootContext;
|
|
|
|
//
|
|
// Global EFI data
|
|
//
|
|
|
|
#define EFI_ARRAY_SIZE 100
|
|
#define EFI_PAGE_SIZE 4096
|
|
#define EFI_PAGE_SHIFT 12
|
|
|
|
#define MEM_4K 0x1000
|
|
#define MEM_8K 0x2000
|
|
#define MEM_16K 0x4000
|
|
#define MEM_64K 0x10000
|
|
#define MEM_256K 0x40000
|
|
#define MEM_1M 0x100000
|
|
#define MEM_4M 0x400000
|
|
#define MEM_16M 0x1000000
|
|
#define MEM_64M 0x4000000
|
|
#define MEM_256M 0x10000000
|
|
|
|
EFI_HANDLE EfiImageHandle;
|
|
EFI_SYSTEM_TABLE *EfiST;
|
|
EFI_BOOT_SERVICES *EfiBS;
|
|
EFI_RUNTIME_SERVICES *EfiRS;
|
|
PSST_HEADER SalSystemTable;
|
|
PVOID AcpiTable;
|
|
PVOID SMBiosTable;
|
|
|
|
//
|
|
// EFI GUID defines
|
|
//
|
|
EFI_GUID EfiLoadedImageProtocol = LOADED_IMAGE_PROTOCOL;
|
|
EFI_GUID EfiDevicePathProtocol = DEVICE_PATH_PROTOCOL;
|
|
EFI_GUID EfiDeviceIoProtocol = DEVICE_IO_PROTOCOL;
|
|
EFI_GUID EfiBlockIoProtocol = BLOCK_IO_PROTOCOL;
|
|
EFI_GUID EfiDiskIoProtocol = DISK_IO_PROTOCOL;
|
|
EFI_GUID EfiFilesystemProtocol = SIMPLE_FILE_SYSTEM_PROTOCOL;
|
|
|
|
|
|
EFI_GUID AcpiTable_Guid = ACPI_TABLE_GUID;
|
|
EFI_GUID SmbiosTableGuid = SMBIOS_TABLE_GUID;
|
|
EFI_GUID SalSystemTableGuid = SAL_SYSTEM_TABLE_GUID;
|
|
|
|
//
|
|
// PAL, SAL, and IO port space data
|
|
//
|
|
|
|
TR_INFO Pal,Sal,SalGP;
|
|
|
|
ULONGLONG PalProcPhysical;
|
|
ULONGLONG PalPhysicalBase = 0;
|
|
ULONGLONG PalTrPs;
|
|
|
|
ULONGLONG IoPortPhysicalBase;
|
|
ULONGLONG IoPortTrPs;
|
|
ULONG WakeupVector;
|
|
|
|
//
|
|
// Function Prototypes
|
|
//
|
|
|
|
VOID
|
|
GetPalProcEntryPoint(
|
|
IN PSST_HEADER SalSystemTable
|
|
);
|
|
|
|
ULONG
|
|
GetDevPathSize(
|
|
IN EFI_DEVICE_PATH *DevPath
|
|
);
|
|
|
|
#if DBG
|
|
#define DBG_TRACE(_X) EfiPrint(_X)
|
|
#else
|
|
#define DBG_TRACE(_X)
|
|
#endif
|
|
|
|
#ifdef FORCE_CD_BOOT
|
|
|
|
EFI_HANDLE
|
|
GetCd(
|
|
);
|
|
|
|
EFI_HANDLE
|
|
GetCdTest(
|
|
VOID
|
|
);
|
|
|
|
#endif // for FORCE_CD_BOOT
|
|
|
|
|
|
VOID
|
|
SuMain(
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Main entrypoint of the SU module. Control is passed from the boot
|
|
sector to startup.asm which does some run-time fixups on the stack
|
|
and data segments and then passes control here.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Returns:
|
|
|
|
Does not return. Passes control to the OS loader
|
|
|
|
|
|
--*/
|
|
{
|
|
PIMAGE_DOS_HEADER DosHeader;
|
|
PIMAGE_NT_HEADERS NtHeader;
|
|
PIMAGE_FILE_HEADER FileHeader;
|
|
PIMAGE_OPTIONAL_HEADER OptionalHeader;
|
|
PIMAGE_SECTION_HEADER SectionHeader;
|
|
ULONG NumberOfSections;
|
|
BOOLEAN ResourceFound = FALSE;
|
|
|
|
ULONGLONG Destination;
|
|
ULONGLONG VirtualSize;
|
|
ULONGLONG SizeOfRawData;
|
|
USHORT Section;
|
|
|
|
EFI_GUID EfiLoadedImageProtocol = LOADED_IMAGE_PROTOCOL;
|
|
EFI_LOADED_IMAGE *EfiImageInfo;
|
|
EFI_STATUS Status;
|
|
|
|
EFI_DEVICE_PATH *DevicePath, *TestPath;
|
|
EFI_DEVICE_PATH_ALIGNED TestPathAligned;
|
|
PCI_DEVICE_PATH *PciDevicePath;
|
|
HARDDRIVE_DEVICE_PATH *HdDevicePath;
|
|
ACPI_HID_DEVICE_PATH *AcpiDevicePath;
|
|
ATAPI_DEVICE_PATH *AtapiDevicePath;
|
|
SCSI_DEVICE_PATH *ScsiDevicePath;
|
|
IPv4_DEVICE_PATH *IpV4DevicePath;
|
|
IPv6_DEVICE_PATH *IpV6DevicePath;
|
|
UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *UnknownDevicePath;
|
|
|
|
ULONG i;
|
|
|
|
PBOOT_DEVICE_ATAPI BootDeviceAtapi;
|
|
PBOOT_DEVICE_SCSI BootDeviceScsi;
|
|
PBOOT_DEVICE_FLOPPY BootDeviceFloppy;
|
|
PBOOT_DEVICE_IPv4 BootDeviceIpV4;
|
|
PBOOT_DEVICE_IPv6 BootDeviceIpV6;
|
|
PBOOT_DEVICE_UNKNOWN BootDeviceUnknown;
|
|
|
|
PSMBIOS_EPS_HEADER SMBiosEPSHeader;
|
|
PUCHAR SMBiosEPSPtr;
|
|
UCHAR CheckSum;
|
|
UINT8 Channel = 0; // for SCSI boot devices - default to 0
|
|
|
|
|
|
//
|
|
// EFI global variables
|
|
//
|
|
EfiImageHandle = ImageHandle;
|
|
EfiST = SystemTable;
|
|
EfiBS = SystemTable->BootServices;
|
|
EfiRS = SystemTable->RuntimeServices;
|
|
|
|
DBG_TRACE(L"SuMain: entry\r\n");
|
|
|
|
//
|
|
// Get the SAL System Table
|
|
//
|
|
Status = GetSystemConfigurationTable(&SalSystemTableGuid, &SalSystemTable);
|
|
if (EFI_ERROR(Status)) {
|
|
EfiPrint(L"SuMain: HandleProtocol failed\n");
|
|
EfiBS->Exit(EfiImageHandle, Status, 0, 0);
|
|
}
|
|
|
|
#if 0
|
|
//
|
|
// Get the MPS Table
|
|
//
|
|
Status = GetSystemConfigurationTable(&MpsTableGuid, &MpsTable);
|
|
if (EFI_ERROR(Status)) {
|
|
EfiPrint(L"SuMain: HandleProtocol failed\n");
|
|
EfiBS->Exit(EfiImageHandle, Status, 0, 0);
|
|
}
|
|
#endif
|
|
//
|
|
// Get the ACPI Tables
|
|
//
|
|
|
|
//
|
|
// Get the ACPI 2.0 Table, if present
|
|
//
|
|
//DbgPrint("Looking for ACPi 2.0\n");
|
|
Status = GetSystemConfigurationTable(&AcpiTable_Guid, &AcpiTable);
|
|
if (EFI_ERROR(Status)) {
|
|
//DbgPrint("returned error\n");
|
|
AcpiTable = NULL;
|
|
}
|
|
|
|
//DbgPrint("AcpiTable: %p\n", AcpiTable);
|
|
|
|
if (!AcpiTable) {
|
|
EfiPrint(L"SuMain: HandleProtocol failed\n");
|
|
EfiBS->Exit(EfiImageHandle, Status, 0, 0);
|
|
}
|
|
|
|
|
|
//
|
|
// Get the SMBIOS Table
|
|
//
|
|
Status = GetSystemConfigurationTable(&SmbiosTableGuid, &SMBiosTable);
|
|
if (EFI_ERROR(Status)) {
|
|
//DbgPrint("returned error\n");
|
|
SMBiosTable = NULL;
|
|
} else {
|
|
//
|
|
// Validate SMBIOS EPS Header
|
|
//
|
|
SMBiosEPSHeader = (PSMBIOS_EPS_HEADER)SMBiosTable;
|
|
SMBiosEPSPtr = (PUCHAR)SMBiosTable;
|
|
|
|
if ((*((PULONG)SMBiosEPSHeader->Signature) == SMBIOS_EPS_SIGNATURE) &&
|
|
(SMBiosEPSHeader->Length >= sizeof(SMBIOS_EPS_HEADER)) &&
|
|
(*((PULONG)SMBiosEPSHeader->Signature2) == DMI_EPS_SIGNATURE) &&
|
|
(SMBiosEPSHeader->Signature2[4] == '_' ))
|
|
{
|
|
CheckSum = 0;
|
|
for (i = 0; i < SMBiosEPSHeader->Length ; i++)
|
|
{
|
|
CheckSum = CheckSum + SMBiosEPSPtr[i];
|
|
}
|
|
|
|
if (CheckSum != 0)
|
|
{
|
|
DBG_TRACE(L"SMBios Table has bad checksum.....\r\n");
|
|
SMBiosTable = NULL;
|
|
} else {
|
|
DBG_TRACE(L"SMBios Table has been validated.....\r\n");
|
|
}
|
|
|
|
} else {
|
|
DBG_TRACE(L"SMBios Table is incorrectly formed.....\r\n");
|
|
SMBiosTable = NULL;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Get the image info for NTLDR
|
|
//
|
|
Status = EfiBS->HandleProtocol (
|
|
ImageHandle,
|
|
&EfiLoadedImageProtocol,
|
|
&EfiImageInfo
|
|
);
|
|
|
|
if (EFI_ERROR(Status)) {
|
|
EfiPrint(L"SuMain: HandleProtocol failed\n");
|
|
EfiBS->Exit(EfiImageHandle, Status, 0, 0);
|
|
}
|
|
|
|
//
|
|
// Get device path of the DeviceHandle associated with this image handle.
|
|
//
|
|
Status = EfiBS->HandleProtocol (
|
|
EfiImageInfo->DeviceHandle,
|
|
&EfiDevicePathProtocol,
|
|
&DevicePath
|
|
);
|
|
|
|
if (EFI_ERROR(Status)) {
|
|
EfiPrint(L"SuMain: HandleProtocol failed\r\n");
|
|
EfiBS->Exit(EfiImageHandle, Status, 0, 0);
|
|
}
|
|
|
|
//
|
|
// Get the MediaType and Partition information and save them in the
|
|
// BootContext.
|
|
//
|
|
EfiAlignDp( &TestPathAligned,
|
|
DevicePath,
|
|
DevicePathNodeLength(DevicePath) );
|
|
|
|
|
|
TestPath = (EFI_DEVICE_PATH *) &TestPathAligned;
|
|
|
|
while (TestPath->Type != END_DEVICE_PATH_TYPE) {
|
|
|
|
//
|
|
// save the channel in case its needed later. We may
|
|
// need this information to help further distinguish
|
|
// between devices that share the same SCSI ID/LUN, but
|
|
// may be sitting on different controllers.
|
|
//
|
|
if (TestPath->Type == HW_PCI_DP) {
|
|
PciDevicePath = (PCI_DEVICE_PATH *)TestPath;
|
|
Channel = PciDevicePath->Function;
|
|
}
|
|
|
|
if (TestPath->Type == MESSAGING_DEVICE_PATH) {
|
|
if (TestPath->SubType == MSG_ATAPI_DP) {
|
|
AtapiDevicePath = (ATAPI_DEVICE_PATH *) TestPath;
|
|
BootContext.BusType = BootBusAtapi;
|
|
BootDeviceAtapi = (PBOOT_DEVICE_ATAPI) &(BootContext.BootDevice);
|
|
|
|
BootDeviceAtapi->PrimarySecondary = AtapiDevicePath->PrimarySecondary;
|
|
BootDeviceAtapi->SlaveMaster = AtapiDevicePath->SlaveMaster;
|
|
BootDeviceAtapi->Lun = AtapiDevicePath->Lun;
|
|
} else if (TestPath->SubType == MSG_SCSI_DP) {
|
|
ScsiDevicePath = (SCSI_DEVICE_PATH *) TestPath;
|
|
BootContext.BusType = BootBusScsi;
|
|
BootDeviceScsi = (PBOOT_DEVICE_SCSI) &(BootContext.BootDevice);
|
|
|
|
// Remember his specifics
|
|
BootDeviceScsi->Channel = Channel;
|
|
BootDeviceScsi->Pun = ScsiDevicePath->Pun;
|
|
BootDeviceScsi->Lun = ScsiDevicePath->Lun;
|
|
} else if (TestPath->SubType == MSG_MAC_ADDR_DP) {
|
|
BootContext.MediaType = BootMediaTcpip;
|
|
} else if (TestPath->SubType == MSG_IPv4_DP) {
|
|
IpV4DevicePath = (IPv4_DEVICE_PATH *) TestPath;
|
|
BootContext.MediaType = BootMediaTcpip;
|
|
BootDeviceIpV4 = (PBOOT_DEVICE_IPv4) &(BootContext.BootDevice);
|
|
|
|
BootDeviceIpV4->RemotePort = IpV4DevicePath->RemotePort;
|
|
BootDeviceIpV4->LocalPort = IpV4DevicePath->LocalPort;
|
|
RtlCopyMemory(&BootDeviceIpV4->Ip, &IpV4DevicePath->LocalIpAddress, sizeof(EFI_IPv4_ADDRESS));
|
|
} else if (TestPath->SubType == MSG_IPv6_DP) {
|
|
IpV6DevicePath = (IPv6_DEVICE_PATH *) TestPath;
|
|
BootContext.MediaType = BootMediaTcpip;
|
|
BootDeviceIpV6 = (PBOOT_DEVICE_IPv6) &(BootContext.BootDevice);
|
|
|
|
BootDeviceIpV6->RemotePort = IpV6DevicePath->RemotePort;
|
|
BootDeviceIpV6->LocalPort = IpV6DevicePath->LocalPort;
|
|
#if 0
|
|
BootDeviceIpV6->Ip = IpV6DevicePath->Ip;
|
|
#endif
|
|
}
|
|
} else if (TestPath->Type == ACPI_DEVICE_PATH) {
|
|
AcpiDevicePath = (ACPI_HID_DEVICE_PATH *) TestPath;
|
|
if (AcpiDevicePath->HID == EISA_ID(PNP_EISA_ID_CONST, 0x0303)) {
|
|
BootDeviceFloppy = (PBOOT_DEVICE_FLOPPY) &(BootContext.BootDevice);
|
|
BootDeviceFloppy->DriveNumber = AcpiDevicePath->UID;
|
|
}
|
|
} else if (TestPath->Type == HARDWARE_DEVICE_PATH) {
|
|
if (TestPath->SubType == HW_VENDOR_DP) {
|
|
UnknownDevicePath = (UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *) TestPath;
|
|
BootDeviceUnknown = (PBOOT_DEVICE_UNKNOWN) &(BootContext.BootDevice);
|
|
RtlCopyMemory( &(BootDeviceUnknown->Guid),
|
|
&(UnknownDevicePath->DevicePath.Guid),
|
|
sizeof(EFI_GUID));
|
|
|
|
BootContext.BusType = BootBusVendor;
|
|
BootDeviceUnknown->LegacyDriveLetter = UnknownDevicePath->LegacyDriveLetter;
|
|
}
|
|
} else if (TestPath->Type == MEDIA_DEVICE_PATH) {
|
|
BootContext.MediaType = TestPath->SubType;
|
|
if (TestPath->SubType == MEDIA_HARDDRIVE_DP) {
|
|
HdDevicePath = (HARDDRIVE_DEVICE_PATH *) TestPath;
|
|
|
|
BootContext.MediaType = BootMediaHardDisk;
|
|
BootContext.PartitionNumber = (UCHAR) HdDevicePath->PartitionNumber;
|
|
} else if (TestPath->SubType == MEDIA_CDROM_DP) {
|
|
BootContext.MediaType = BootMediaCdrom;
|
|
}
|
|
}
|
|
|
|
DevicePath = NextDevicePathNode(DevicePath);
|
|
EfiAlignDp( &TestPathAligned,
|
|
DevicePath,
|
|
DevicePathNodeLength(DevicePath) );
|
|
TestPath = (EFI_DEVICE_PATH *) &TestPathAligned;
|
|
}
|
|
|
|
#ifdef FORCE_CD_BOOT
|
|
BootContext.MediaType = BootMediaCdrom;
|
|
#endif
|
|
//
|
|
// Fill out the rest of BootContext fields
|
|
//
|
|
|
|
DosHeader = EfiImageInfo->ImageBase;
|
|
NtHeader = (PIMAGE_NT_HEADERS) ((PUCHAR) DosHeader + DosHeader->e_lfanew);
|
|
FileHeader = &(NtHeader->FileHeader);
|
|
OptionalHeader = (PIMAGE_OPTIONAL_HEADER)
|
|
((PUCHAR)FileHeader + sizeof(IMAGE_FILE_HEADER));
|
|
SectionHeader = (PIMAGE_SECTION_HEADER) ((PUCHAR)OptionalHeader +
|
|
FileHeader->SizeOfOptionalHeader);
|
|
|
|
BootContext.ExternalServicesTable = (PEXTERNAL_SERVICES_TABLE)
|
|
&ExportEntryTable;
|
|
|
|
BootContext.MachineType = MACHINE_TYPE_ISA;
|
|
|
|
BootContext.OsLoaderBase = (ULONG_PTR)EfiImageInfo->ImageBase;
|
|
BootContext.OsLoaderExports = (ULONG_PTR)EfiImageInfo->ImageBase +
|
|
OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
|
|
|
|
BootContext.BootFlags = 0;
|
|
|
|
//
|
|
// Calculate the start address and the end address of OS loader.
|
|
//
|
|
|
|
BootContext.OsLoaderStart = (ULONG_PTR)EfiImageInfo->ImageBase +
|
|
SectionHeader->VirtualAddress;
|
|
BootContext.OsLoaderEnd = (ULONG_PTR)EfiImageInfo->ImageBase +
|
|
SectionHeader->SizeOfRawData;
|
|
|
|
for (Section=FileHeader->NumberOfSections ; Section-- ; SectionHeader++) {
|
|
Destination = (ULONG_PTR)EfiImageInfo->ImageBase + SectionHeader->VirtualAddress;
|
|
VirtualSize = SectionHeader->Misc.VirtualSize;
|
|
SizeOfRawData = SectionHeader->SizeOfRawData;
|
|
|
|
if (VirtualSize == 0) {
|
|
VirtualSize = SizeOfRawData;
|
|
}
|
|
if (Destination < BootContext.OsLoaderStart) {
|
|
BootContext.OsLoaderStart = Destination;
|
|
}
|
|
if (Destination+VirtualSize > BootContext.OsLoaderEnd) {
|
|
BootContext.OsLoaderEnd = Destination+VirtualSize;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Find .rsrc section
|
|
//
|
|
SectionHeader = (PIMAGE_SECTION_HEADER) ((PUCHAR)OptionalHeader +
|
|
FileHeader->SizeOfOptionalHeader);
|
|
NumberOfSections = FileHeader->NumberOfSections;
|
|
while (NumberOfSections) {
|
|
if (_stricmp((PCHAR)SectionHeader->Name, ".rsrc")==0) {
|
|
BootContext.ResourceDirectory =
|
|
(ULONGLONG) ((ULONG_PTR)EfiImageInfo->ImageBase + SectionHeader->VirtualAddress);
|
|
|
|
BootContext.ResourceOffset = (ULONGLONG)((LONG)SectionHeader->VirtualAddress);
|
|
ResourceFound = TRUE;
|
|
}
|
|
|
|
++SectionHeader;
|
|
--NumberOfSections;
|
|
}
|
|
|
|
if (ResourceFound == FALSE) {
|
|
EfiPrint(L"SuMain: Resource section not found\n");
|
|
EfiBS->Exit(EfiImageHandle, Status, 0, 0);
|
|
}
|
|
|
|
DBG_TRACE( L"SuMain: About to call NtProcessStartup\r\n");
|
|
|
|
|
|
//
|
|
// See if someone called us w/ a TFTP restart block.
|
|
//
|
|
if( EfiImageInfo->LoadOptionsSize == (sizeof(TFTP_RESTART_BLOCK)) ) {
|
|
|
|
//
|
|
// Likely. Make sure it's really a TFTP restart block and if so, go retrieve all
|
|
// its contents.
|
|
//
|
|
if( EfiImageInfo->LoadOptions != NULL ) {
|
|
|
|
extern TFTP_RESTART_BLOCK gTFTPRestartBlock;
|
|
PTFTP_RESTART_BLOCK restartBlock = NULL;
|
|
|
|
restartBlock = (PTFTP_RESTART_BLOCK)(EfiImageInfo->LoadOptions);
|
|
|
|
RtlCopyMemory( &gTFTPRestartBlock,
|
|
restartBlock,
|
|
sizeof(TFTP_RESTART_BLOCK) );
|
|
|
|
DBG_TRACE( L"SuMain: copied TFTP_RESTART_BLOCK into gTFTPRestartBlock\r\n");
|
|
}
|
|
}
|
|
|
|
GetPalProcEntryPoint( SalSystemTable );
|
|
|
|
//
|
|
// construct arc memory descriptors for the first 128 mb of memory.
|
|
// the loader will not use anything over 128 mb and efi may still
|
|
// change the memory descriptors in it's memory map. let the loader's
|
|
// memory map be for as small a memory region as possible, so that
|
|
// the chance for the loader's/efi's memory map to get out of sync
|
|
// is minimal
|
|
//
|
|
ConstructArcMemoryDescriptorsWithAllocation(0, BL_DRIVER_RANGE_HIGH << PAGE_SHIFT);
|
|
|
|
//
|
|
// Applies CPU specific workarounds
|
|
//
|
|
CpuSpecificWork();
|
|
|
|
SuFillExportTable( );
|
|
|
|
NtProcessStartup( &BootContext );
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
GetPalProcEntryPoint(
|
|
IN PSST_HEADER SalSystemTable
|
|
)
|
|
{
|
|
PVOID NextEntry;
|
|
PPAL_SAL_ENTRY_POINT PalSalEntryPoint;
|
|
PAP_WAKEUP_DESCRIPTOR ApWakeupDescriptor;
|
|
ULONG i;
|
|
|
|
|
|
DBG_TRACE(L"GetPalProcEntryPoint: entry\n");
|
|
|
|
//
|
|
// Get PalProc entry point from SAL System Table
|
|
//
|
|
|
|
|
|
NextEntry = (PUCHAR) SalSystemTable + sizeof(SST_HEADER);
|
|
for (i = 0; i < SalSystemTable->EntryCount; i++) {
|
|
switch ( *(PUCHAR)NextEntry ) {
|
|
case PAL_SAL_EP_TYPE:
|
|
PalSalEntryPoint = (PPAL_SAL_ENTRY_POINT) NextEntry;
|
|
|
|
PalProcPhysical = Pal.PhysicalAddress = PalSalEntryPoint->PalEntryPoint;
|
|
Sal.PhysicalAddress = PalSalEntryPoint->SalEntryPoint;
|
|
SalGP.PhysicalAddress = PalSalEntryPoint->GlobalPointer;
|
|
|
|
NextEntry = (PPAL_SAL_ENTRY_POINT)NextEntry + 1;
|
|
break;
|
|
case SAL_MEMORY_TYPE:
|
|
|
|
NextEntry = (PSAL_MEMORY_DESCRIPTOR)NextEntry + 1;
|
|
break;
|
|
case PLATFORM_FEATURES_TYPE:
|
|
|
|
NextEntry = (PPLATFORM_FEATURES)NextEntry + 1;
|
|
break;
|
|
case TRANSLATION_REGISTER_TYPE:
|
|
|
|
NextEntry = (PTRANSLATION_REGISTER)NextEntry + 1;
|
|
break;
|
|
case PTC_COHERENCE_TYPE:
|
|
|
|
NextEntry = (PPTC_COHERENCE_DOMAIN)NextEntry + 1;
|
|
break;
|
|
case AP_WAKEUP_TYPE:
|
|
ApWakeupDescriptor = (PAP_WAKEUP_DESCRIPTOR)NextEntry;
|
|
WakeupVector = (ULONG) ApWakeupDescriptor->WakeupVector;
|
|
NextEntry = (PAP_WAKEUP_DESCRIPTOR)NextEntry + 1;
|
|
break;
|
|
default:
|
|
|
|
EfiPrint(L"SST: Invalid SST entry\n");
|
|
EfiBS->Exit(EfiImageHandle, 0, 0, 0);
|
|
}
|
|
}
|
|
|
|
DBG_TRACE(L"GetPalProcEntryPoint: exit\n");
|
|
}
|
|
|
|
ULONG
|
|
GetDevPathSize(
|
|
IN EFI_DEVICE_PATH *DevPath
|
|
)
|
|
{
|
|
EFI_DEVICE_PATH *Start;
|
|
|
|
//
|
|
// Search for the end of the device path structure
|
|
//
|
|
Start = DevPath;
|
|
while (DevPath->Type != END_DEVICE_PATH_TYPE) {
|
|
DevPath = NextDevicePathNode(DevPath);
|
|
}
|
|
|
|
//
|
|
// Compute the size
|
|
//
|
|
return (ULONG)((ULONGLONG)DevPath - (ULONGLONG)Start);
|
|
}
|
|
|