1458 lines
27 KiB
C
1458 lines
27 KiB
C
//++
|
|
//
|
|
// Copyright (c) Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
//
|
|
// bl.h
|
|
//
|
|
// Abstract:
|
|
//
|
|
// This module contains definitions for the boot loader.
|
|
//
|
|
// Environment:
|
|
//
|
|
// Boot loader.
|
|
//
|
|
//--
|
|
|
|
#pragma once
|
|
|
|
#pragma warning(disable:4127) // conditional expression is constant
|
|
#pragma warning(disable:4152) // function/data pointer conversion in expression
|
|
#pragma warning(disable:4200) // zero-sized array in struct/union
|
|
#pragma warning(disable:4201) // nameless struct/union
|
|
#pragma warning(disable:4214) // bit field types other than int
|
|
|
|
//
|
|
// Constants for selectively enabling verbose debug output.
|
|
//
|
|
|
|
#define ACPI_VERBOSE 0
|
|
#define APM_VERBOSE 0
|
|
#define CDROM_VERBOSE 0
|
|
#define COM_VERBOSE 0
|
|
#define DISTRO_VERBOSE 1
|
|
#define FAT_VERBOSE 0
|
|
#define KD_VERBOSE 0
|
|
#define MM_VERBOSE 0
|
|
#define MPS_VERBOSE 0
|
|
#define PCI_VERBOSE 0
|
|
#define PECOFF_VERBOSE 0
|
|
#define PNP_VERBOSE 0
|
|
#define POOL_VERBOSE 0
|
|
#define PXE_VERBOSE 0
|
|
#define SINGULARITY_VERBOSE 0
|
|
#define SMAP_VERBOSE 0
|
|
|
|
//
|
|
// Basic platform constants.
|
|
//
|
|
|
|
#define PAGE_SIZE 4096
|
|
#define LEGACY_MEMORY_LIMIT 0x100000
|
|
|
|
//
|
|
// Compile-time assertion support.
|
|
//
|
|
|
|
#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
|
|
|
|
//
|
|
// Basic integer types.
|
|
//
|
|
|
|
typedef char CHAR;
|
|
typedef unsigned char UCHAR;
|
|
|
|
typedef char INT8;
|
|
typedef unsigned char UINT8;
|
|
typedef short INT16;
|
|
typedef unsigned short UINT16;
|
|
typedef long INT32;
|
|
typedef unsigned long UINT32;
|
|
typedef __int64 INT64;
|
|
typedef unsigned __int64 UINT64;
|
|
|
|
#if defined(BOOT_X86)
|
|
|
|
typedef INT32 LONG_PTR;
|
|
typedef UINT32 ULONG_PTR;
|
|
|
|
#elif defined (BOOT_X64)
|
|
|
|
typedef INT64 LONG_PTR;
|
|
typedef UINT64 ULONG_PTR;
|
|
|
|
#endif
|
|
|
|
|
|
//
|
|
// Basic boolean type.
|
|
//
|
|
|
|
typedef unsigned char BOOLEAN;
|
|
|
|
//
|
|
// Basic pointer types.
|
|
//
|
|
|
|
typedef void VOID;
|
|
typedef VOID * PVOID;
|
|
typedef const VOID * PCVOID;
|
|
typedef CHAR * PCHAR;
|
|
typedef INT8 * PINT8;
|
|
typedef UINT8 * PUINT8;
|
|
typedef INT16 * PINT16;
|
|
typedef UINT16 * PUINT16;
|
|
typedef INT32 * PINT32;
|
|
typedef UINT32 * PUINT32;
|
|
typedef INT64 * PINT64;
|
|
typedef UINT64 * PUINT64;
|
|
typedef LONG_PTR * PLONG_PTR;
|
|
typedef ULONG_PTR * PULONG_PTR;
|
|
typedef BOOLEAN PBOOLEAN;
|
|
|
|
//
|
|
// Wide character types.
|
|
//
|
|
|
|
typedef wchar_t WCHAR;
|
|
typedef WCHAR * PWCHAR;
|
|
typedef const WCHAR * PCWSTR;
|
|
typedef const CHAR * PCSTR;
|
|
|
|
//
|
|
// Structure macros.
|
|
//
|
|
|
|
#define FIELD_OFFSET(Type, Field) ((UINT32) (ULONG_PTR) &(((Type *) 0)->Field))
|
|
#define CONTAINING_RECORD(Address, Type, Field) ((Type *) ((ULONG_PTR) (Address) - FIELD_OFFSET(Type, Field)))
|
|
#define ARRAY_SIZE(Array) (sizeof(Array) / sizeof(Array[0]))
|
|
|
|
//
|
|
// Macros for rounding up.
|
|
//
|
|
|
|
#define ROUND_UP_TO_POWER2(X, P) (((X) + ((P) - 1)) & (~((P) - 1)))
|
|
#define ROUND_UP_TO_PAGES(X) ROUND_UP_TO_POWER2(X, PAGE_SIZE)
|
|
|
|
//
|
|
// The following macro is used to satisfy the compiler. Note that the
|
|
// expressions/statements passed to this macro are not necessary for
|
|
// correctness, but without them the compiler cannot compile with W4.
|
|
//
|
|
|
|
#define SATISFY_OVERZEALOUS_COMPILER(X) X
|
|
|
|
//
|
|
// Function modifiers.
|
|
//
|
|
|
|
#define FORCEINLINE __forceinline
|
|
|
|
//
|
|
// Basic constants.
|
|
//
|
|
|
|
#define FALSE 0
|
|
#define TRUE 1
|
|
#define NULL 0
|
|
|
|
//
|
|
// va support (from vadefs.h).
|
|
//
|
|
|
|
typedef char *va_list;
|
|
|
|
#if defined(BOOT_X86)
|
|
|
|
#define _ADDRESSOF(v) ( &(v) )
|
|
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
|
|
|
|
#define _crt_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
|
|
#define _crt_va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
|
|
#define _crt_va_end(ap) ( ap = (va_list)0 )
|
|
|
|
#elif defined(BOOT_X64)
|
|
|
|
extern "C" void __cdecl __va_start(va_list *, ...);
|
|
|
|
#define _crt_va_start(ap, x) ( __va_start(&ap, x) )
|
|
#define _crt_va_arg(ap, t) \
|
|
( ( sizeof(t) > sizeof(__int64) || ( sizeof(t) & (sizeof(t) - 1) ) != 0 ) \
|
|
? **(t **)( ( ap += sizeof(__int64) ) - sizeof(__int64) ) \
|
|
: *(t *)( ( ap += sizeof(__int64) ) - sizeof(__int64) ) )
|
|
#define _crt_va_end(ap) ( ap = (va_list)0 )
|
|
|
|
#endif
|
|
|
|
#define va_start _crt_va_start
|
|
#define va_arg _crt_va_arg
|
|
#define va_end _crt_va_end
|
|
|
|
//
|
|
// Runtime assertion support.
|
|
//
|
|
|
|
BOOLEAN
|
|
BlRtlPrintf(
|
|
PCSTR Format,
|
|
...
|
|
);
|
|
|
|
VOID
|
|
BlRtlHaltInternal(
|
|
PCSTR FileName,
|
|
UINT32 LineNumber
|
|
);
|
|
|
|
VOID
|
|
BlRtlAssertFailed(
|
|
PCSTR FileName,
|
|
UINT32 LineNumber
|
|
);
|
|
|
|
VOID
|
|
BlRtlAssertFailedPtr(
|
|
PCSTR FileName,
|
|
UINT32 LineNumber,
|
|
ULONG_PTR Param
|
|
);
|
|
|
|
#define BlRtlHalt() BlRtlHaltInternal(__FILE__, __LINE__)
|
|
|
|
#define BLASSERT(X) \
|
|
if (!(X)) { \
|
|
BlRtlAssertFailed(__FILE__, __LINE__); \
|
|
}
|
|
|
|
#define BLASSERT_PTR(X, P) \
|
|
if (!(X)) { \
|
|
BlRtlAssertFailedPtr(__FILE__, __LINE__, (ULONG_PTR) (P)); \
|
|
}
|
|
|
|
//
|
|
// Linked list support.
|
|
//
|
|
|
|
typedef struct _LIST_ENTRY {
|
|
struct _LIST_ENTRY *Flink;
|
|
struct _LIST_ENTRY *Blink;
|
|
} LIST_ENTRY, *PLIST_ENTRY;
|
|
|
|
VOID
|
|
BlRtlInitializeListHead(
|
|
PLIST_ENTRY Head
|
|
);
|
|
|
|
BOOLEAN
|
|
BlRtlIsListEmpty(
|
|
PLIST_ENTRY Head
|
|
);
|
|
|
|
BOOLEAN
|
|
BlRtlRemoveEntryList(
|
|
PLIST_ENTRY Entry
|
|
);
|
|
|
|
PLIST_ENTRY
|
|
BlRtlRemoveHeadList(
|
|
PLIST_ENTRY Head
|
|
);
|
|
|
|
PLIST_ENTRY
|
|
BlRtlRemoveTailList(
|
|
PLIST_ENTRY Head
|
|
);
|
|
|
|
VOID
|
|
BlRtlInsertTailList(
|
|
PLIST_ENTRY Head,
|
|
PLIST_ENTRY Entry
|
|
);
|
|
|
|
VOID
|
|
BlRtlInsertHeadList(
|
|
PLIST_ENTRY Head,
|
|
PLIST_ENTRY Entry
|
|
);
|
|
|
|
//
|
|
// Legacy far pointer support.
|
|
//
|
|
|
|
typedef struct _FAR_POINTER {
|
|
UINT16 Offset;
|
|
UINT16 Segment;
|
|
} FAR_POINTER, *PFAR_POINTER;
|
|
|
|
C_ASSERT(sizeof(FAR_POINTER) == sizeof(UINT32));
|
|
|
|
VOID
|
|
BlRtlConvertLinearPointerToFarPointer(
|
|
PVOID LinearPointer,
|
|
PFAR_POINTER FarPointer
|
|
);
|
|
|
|
PVOID
|
|
BlRtlConvertFarPointerToLinearPointer(
|
|
PFAR_POINTER FarPointer
|
|
);
|
|
|
|
//
|
|
// Boot environment block.
|
|
//
|
|
|
|
typedef struct _BEB {
|
|
UINT32 BootType;
|
|
UINT32 BootDriveNumber;
|
|
UINT32 FlashImage;
|
|
UINT32 SmapAddr;
|
|
UINT32 SmapSize;
|
|
UINT32 LegacyCallAddress;
|
|
UINT32 LegacyReturnAddress;
|
|
UINT32 LegacyReturnCr3;
|
|
UINT32 LegacyCall_OpCode;
|
|
UINT32 LegacyCall_Vector;
|
|
UINT32 LegacyCall_ax;
|
|
UINT32 LegacyCall_bx;
|
|
UINT32 LegacyCall_cx;
|
|
UINT32 LegacyCall_dx;
|
|
UINT32 LegacyCall_si;
|
|
UINT32 LegacyCall_di;
|
|
UINT32 LegacyCall_ds;
|
|
UINT32 LegacyCall_es;
|
|
UINT32 LegacyCall_flags;
|
|
FAR_POINTER LegacyCall_FramePtr;
|
|
UINT32 LegacyCall_FrameSize;
|
|
FAR_POINTER LegacyCall_FuncPtr;
|
|
FAR_POINTER ApEntry16;
|
|
UINT32 ApEntry;
|
|
FAR_POINTER ApStartupLock;
|
|
} BEB, *PBEB;
|
|
|
|
#define BEB_BASE ((ULONG_PTR) 0x2F000)
|
|
|
|
FORCEINLINE
|
|
PBEB
|
|
BlGetBeb(
|
|
VOID
|
|
)
|
|
|
|
//++
|
|
//
|
|
//Routine Description:
|
|
//
|
|
// This function returns a pointer to the boot environment block.
|
|
//
|
|
//Return Value:
|
|
//
|
|
// Pointer to the boot environment block.
|
|
//
|
|
//--
|
|
|
|
{
|
|
return ((PBEB) BEB_BASE);
|
|
}
|
|
|
|
//
|
|
// Boot sources.
|
|
//
|
|
|
|
#define BL_CD_BOOT 1
|
|
#define BL_FAT16_BOOT 2
|
|
#define BL_FAT32_BOOT 3
|
|
#define BL_PXE_BOOT 4
|
|
#define BL_FLASH_BOOT 5
|
|
|
|
//
|
|
// Legacy call context.
|
|
//
|
|
|
|
typedef struct _BL_LEGACY_CALL_CONTEXT {
|
|
UINT32 eax;
|
|
UINT32 ebx;
|
|
UINT32 ecx;
|
|
UINT32 edx;
|
|
UINT32 esi;
|
|
UINT32 edi;
|
|
UINT32 ds;
|
|
UINT32 es;
|
|
UINT32 eflags;
|
|
} BL_LEGACY_CALL_CONTEXT, *PBL_LEGACY_CALL_CONTEXT;
|
|
|
|
//
|
|
// Legacy call opcodes.
|
|
//
|
|
|
|
#define LC_NOP 0x0000
|
|
#define LC_INTXX 0x0001
|
|
#define LC_FARCALL 0x0002
|
|
|
|
//
|
|
// RFLAGS.
|
|
//
|
|
|
|
#define RFLAGS_CF 0x0001
|
|
|
|
//
|
|
// Utility functions.
|
|
//
|
|
|
|
VOID
|
|
BlRtlZeroMemory(
|
|
PVOID Buffer,
|
|
ULONG_PTR Length
|
|
);
|
|
|
|
VOID
|
|
BlRtlCopyMemory(
|
|
PVOID Destination,
|
|
PCVOID Source,
|
|
ULONG_PTR Length
|
|
);
|
|
|
|
BOOLEAN
|
|
BlRtlCompareMemory(
|
|
PCVOID Buffer1,
|
|
PCVOID Buffer2,
|
|
ULONG_PTR Length
|
|
);
|
|
|
|
VOID
|
|
BlRtlCallLegacyInterruptService(
|
|
UINT8 Vector,
|
|
PBL_LEGACY_CALL_CONTEXT Input,
|
|
PBL_LEGACY_CALL_CONTEXT Output
|
|
);
|
|
|
|
VOID
|
|
BlRtlCallLegacyFunction(
|
|
UINT16 CodeSegment16,
|
|
UINT16 CodeOffset16,
|
|
PVOID CallFrame,
|
|
UINT32 CallFrameSize,
|
|
PBL_LEGACY_CALL_CONTEXT Input,
|
|
PBL_LEGACY_CALL_CONTEXT Output
|
|
);
|
|
|
|
UINT8
|
|
BlRtlComputeChecksum8(
|
|
PCVOID Buffer,
|
|
UINT32 Size
|
|
);
|
|
|
|
UINT32
|
|
BlGetCpuidEax(
|
|
UINT32 reg
|
|
);
|
|
|
|
UINT32
|
|
BlGetCpuidEbx(
|
|
UINT32 reg
|
|
);
|
|
|
|
UINT32
|
|
BlGetCpuidEcx(
|
|
UINT32 reg
|
|
);
|
|
|
|
UINT32
|
|
BlGetCpuidEdx(
|
|
UINT32 reg
|
|
);
|
|
|
|
//
|
|
// Constants and macros for accessing the keyboard controller.
|
|
//
|
|
|
|
#define BL_KEYBOARD_STATUS_PORT 0x0064
|
|
#define BL_KEYBOARD_COMMAND_PORT 0x0064
|
|
#define BL_KEYBOARD_DATA_PORT 0x0060
|
|
|
|
#define BL_KEYBOARD_STATUS_INPUT_BUFFER_FULL 0x02
|
|
|
|
#define BL_KEYBOARD_COMMAND_WRITE_OUTPUT_PORT 0xD1
|
|
#define BL_KEYBOARD_COMMAND_PULSE_RESET_BIT 0xFE
|
|
#define BL_KEYBOARD_COMMAND_PULSE_OUTPUT_PORT 0xFF
|
|
|
|
#define BL_KEYBOARD_A20_ENABLE 0xDF
|
|
|
|
#define BL_KEYBOARD_WAIT_FOR_IDLE() \
|
|
while ((BlRtlReadPort8(BL_KEYBOARD_STATUS_PORT) & BL_KEYBOARD_STATUS_INPUT_BUFFER_FULL) != 0) { \
|
|
}
|
|
|
|
#define BL_KEYBOARD_WRITE_COMMAND(X) \
|
|
{ \
|
|
BL_KEYBOARD_WAIT_FOR_IDLE(); \
|
|
BlRtlWritePort8(BL_KEYBOARD_COMMAND_PORT, (X)); \
|
|
BL_KEYBOARD_WAIT_FOR_IDLE(); \
|
|
}
|
|
|
|
#define BL_KEYBOARD_WRITE_OUTPUT_PORT(X) \
|
|
{ \
|
|
BL_KEYBOARD_WAIT_FOR_IDLE(); \
|
|
BlRtlWritePort8(BL_KEYBOARD_COMMAND_PORT, BL_KEYBOARD_COMMAND_WRITE_OUTPUT_PORT); \
|
|
BL_KEYBOARD_WAIT_FOR_IDLE(); \
|
|
BlRtlWritePort8(BL_KEYBOARD_DATA_PORT, (X)); \
|
|
BL_KEYBOARD_WAIT_FOR_IDLE(); \
|
|
}
|
|
|
|
VOID
|
|
BlRtlResetSystem(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
BlRtlShutdownSystem(
|
|
VOID
|
|
);
|
|
|
|
//
|
|
// Drive access routines.
|
|
//
|
|
|
|
#pragma pack(1)
|
|
|
|
typedef struct _INT13_DRIVE_PARAMETERS {
|
|
UINT16 StructureSize;
|
|
UINT16 InformationFlags;
|
|
UINT32 NumberOfCylinders;
|
|
UINT32 NumberOfHeads;
|
|
UINT32 SectorsPerTrack;
|
|
UINT64 TotalNumberOfSectors;
|
|
UINT16 BytesPerSector;
|
|
} INT13_DRIVE_PARAMETERS, *PINT13_DRIVE_PARAMETERS;
|
|
|
|
C_ASSERT(sizeof(INT13_DRIVE_PARAMETERS) == 0x1A);
|
|
|
|
#pragma pack()
|
|
|
|
BOOLEAN
|
|
BlRtlGetDriveParameters(
|
|
UINT8 DriveId,
|
|
PINT13_DRIVE_PARAMETERS DriveParameters
|
|
);
|
|
|
|
BOOLEAN
|
|
BlRtlReadDrive(
|
|
UINT8 DriveId,
|
|
UINT64 FirstBlock,
|
|
UINT16 NumberOfBlocks,
|
|
PVOID Buffer
|
|
);
|
|
|
|
//
|
|
// I/O port access routines.
|
|
//
|
|
|
|
UINT8
|
|
BlRtlReadPort8(
|
|
UINT16 Port
|
|
);
|
|
|
|
UINT32
|
|
BlRtlReadPort32(
|
|
UINT16 Port
|
|
);
|
|
|
|
VOID
|
|
BlRtlWritePort8(
|
|
UINT16 Port,
|
|
UINT8 Value
|
|
);
|
|
|
|
VOID
|
|
BlRtlWritePort32(
|
|
UINT16 Port,
|
|
UINT32 Value
|
|
);
|
|
|
|
//
|
|
// String support.
|
|
//
|
|
|
|
CHAR
|
|
BlRtlConvertCharacterToUpperCase(
|
|
CHAR C
|
|
);
|
|
|
|
PCSTR
|
|
BlRtlFindSubstring(
|
|
PCSTR String,
|
|
PCSTR Substring
|
|
);
|
|
|
|
BOOLEAN
|
|
BlRtlParsePositiveDecimal(
|
|
PCSTR String,
|
|
PUINT32 Number,
|
|
PUINT32 CharactersConsumed
|
|
);
|
|
|
|
BOOLEAN
|
|
BlRtlFormatString(
|
|
PCHAR Output,
|
|
UINT32 OutputSize,
|
|
PCSTR Format,
|
|
va_list ArgumentList
|
|
);
|
|
|
|
UINT32
|
|
BlRtlStringLength(
|
|
PCSTR String
|
|
);
|
|
|
|
UINT32
|
|
BlRtlStringLengthW(
|
|
PCWSTR String
|
|
);
|
|
|
|
BOOLEAN
|
|
BlRtlEqualStringN(
|
|
PCSTR String1,
|
|
PCSTR String2,
|
|
UINT32 Count
|
|
);
|
|
|
|
BOOLEAN
|
|
BlRtlEqualStringI(
|
|
PCSTR String1,
|
|
PCSTR String2
|
|
);
|
|
|
|
//
|
|
// Video support.
|
|
//
|
|
|
|
VOID
|
|
BlVideoPrintString(
|
|
PCSTR String
|
|
);
|
|
|
|
BOOLEAN
|
|
BlVideoPrintf(
|
|
PCSTR Format,
|
|
...
|
|
);
|
|
|
|
VOID
|
|
BlVideoInitialize(
|
|
VOID
|
|
);
|
|
|
|
//
|
|
// COM port support.
|
|
//
|
|
|
|
#define COM_MAX_PORT 4
|
|
|
|
extern const UINT16 BlComBasePort[COM_MAX_PORT + 1];
|
|
|
|
BOOLEAN
|
|
BlComInitialize(
|
|
UINT8 PortNumber,
|
|
UINT32 BaudRate
|
|
);
|
|
|
|
BOOLEAN
|
|
BlComSendByte(
|
|
UINT8 PortNumber,
|
|
UINT8 Byte
|
|
);
|
|
|
|
BOOLEAN
|
|
BlComDataAvailable(
|
|
UINT8 PortNumber
|
|
);
|
|
|
|
UINT8
|
|
BlComReceiveByte(
|
|
UINT8 PortNumber
|
|
);
|
|
|
|
//
|
|
// KD support.
|
|
//
|
|
|
|
#define KD_RETRY_COUNT 16
|
|
|
|
#define KD_PACKET_LEADER 0x30303030
|
|
#define KD_CONTROL_PACKET_LEADER 0x69696969
|
|
|
|
#define KD_PACKET_TYPE_KD_DEBUG_IO 3
|
|
#define KD_PACKET_TYPE_KD_RESEND 5 // Packet-control type
|
|
#define KD_PACKET_TYPE_KD_RESET 6 // Packet-control type
|
|
|
|
#define KD_API_PRINT_STRING 0x00003230
|
|
|
|
typedef struct _KD_PACKET {
|
|
UINT32 PacketLeader;
|
|
UINT16 PacketType;
|
|
UINT16 ByteCount;
|
|
UINT32 PacketId;
|
|
UINT32 Checksum;
|
|
} KD_PACKET, *PKD_PACKET;
|
|
|
|
typedef struct _KD_PRINT_STRING {
|
|
UINT32 LengthOfString;
|
|
} KD_PRINT_STRING, *PKD_PRINT_STRING;
|
|
|
|
typedef struct _KD_GET_STRING {
|
|
UINT32 LengthOfPromptString;
|
|
UINT32 LengthOfStringRead;
|
|
} KD_GET_STRING, *PKD_GET_STRING;
|
|
|
|
typedef struct _KD_DEBUG_IO {
|
|
UINT32 ApiNumber;
|
|
UINT16 ProcessorLevel;
|
|
UINT16 Processor;
|
|
union {
|
|
KD_PRINT_STRING PrintString;
|
|
KD_GET_STRING GetString;
|
|
} u1;
|
|
} KD_DEBUG_IO, *PKD_DEBUG_IO;
|
|
|
|
extern UINT8 BlSingularityOhci1394Buffer[3 * PAGE_SIZE];
|
|
|
|
extern UINT8 BlKdComPort;
|
|
|
|
extern UINT32 BlKdNextPacketId;
|
|
|
|
VOID
|
|
BlKdInitialize(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
BlKdSpin(
|
|
VOID
|
|
);
|
|
|
|
BOOLEAN
|
|
BlKdPrintString(
|
|
PCSTR String
|
|
);
|
|
|
|
BOOLEAN
|
|
BlKdPrintf(
|
|
PCSTR Format,
|
|
...
|
|
);
|
|
|
|
UINT32
|
|
BlKdComputeChecksum(
|
|
PCVOID Buffer,
|
|
UINT32 Length
|
|
);
|
|
|
|
BOOLEAN
|
|
BlKd1394Connect(
|
|
VOID
|
|
);
|
|
|
|
BOOLEAN
|
|
BlKd1394SendPacket(
|
|
UINT16 PacketType,
|
|
PCVOID Header,
|
|
UINT16 HeaderSize,
|
|
PCVOID Data,
|
|
UINT16 DataSize
|
|
);
|
|
|
|
BOOLEAN
|
|
BlKdComConnect(
|
|
VOID
|
|
);
|
|
|
|
BOOLEAN
|
|
BlKdComSendPacket(
|
|
UINT16 PacketType,
|
|
PCVOID Header,
|
|
UINT16 HeaderSize,
|
|
PCVOID Data,
|
|
UINT16 DataSize
|
|
);
|
|
|
|
//
|
|
// System memory map (SMAP) support.
|
|
//
|
|
|
|
#define BL_SMAP_AVAILABLE 1
|
|
#define BL_SMAP_RESERVED 2
|
|
#define BL_SMAP_ACPI_RECLAIM 3
|
|
#define BL_SMAP_ACPI_NVS 4
|
|
#define BL_SMAP_UNUSABLE 5
|
|
#define BL_SMAP_KERNEL_NONGC 6
|
|
#define BL_SMAP_KERNEL_STACK 7
|
|
|
|
typedef struct _BL_SMAP_ENTRY {
|
|
UINT64 Base;
|
|
UINT64 Size;
|
|
UINT32 Type;
|
|
UINT32 ExtendedAttributes;
|
|
} BL_SMAP_ENTRY, *PBL_SMAP_ENTRY;
|
|
|
|
#define BL_MAX_SMAP_ENTRIES 128
|
|
|
|
typedef struct _BL_SMAP {
|
|
BL_SMAP_ENTRY Entry[BL_MAX_SMAP_ENTRIES];
|
|
UINT32 EntryCount;
|
|
} BL_SMAP, *PBL_SMAP;
|
|
|
|
extern BL_SMAP BlSystemMemoryMap;
|
|
|
|
VOID
|
|
BlSmapInitialize(
|
|
VOID
|
|
);
|
|
|
|
//
|
|
// Pool support.
|
|
//
|
|
|
|
VOID
|
|
BlPoolInitialize(
|
|
VOID
|
|
);
|
|
|
|
PVOID
|
|
BlPoolAllocateBlock(
|
|
UINT32 Size
|
|
);
|
|
|
|
VOID
|
|
BlPoolFreeBlock(
|
|
PVOID P
|
|
);
|
|
|
|
//
|
|
// PNP BIOS support.
|
|
//
|
|
|
|
#pragma pack(1)
|
|
|
|
typedef struct _PNP_INSTALLATION_CHECK {
|
|
CHAR Signature[4];
|
|
UINT8 Version;
|
|
UINT8 Length;
|
|
UINT16 ControlField;
|
|
UINT8 Checksum;
|
|
UINT32 EventNotificationFlagAddress;
|
|
UINT16 RealModeCodeOffset16;
|
|
UINT16 RealModeCodeSegment16;
|
|
UINT16 ProtectedModeCodeOffset16;
|
|
UINT32 ProtectedModeCodeSegmentBase32;
|
|
UINT32 OEMDeviceId;
|
|
UINT16 RealModeDataSegment16;
|
|
UINT32 ProtectedModeDataSegmentBase32;
|
|
} PNP_INSTALLATION_CHECK, *PPNP_INSTALLATION_CHECK;
|
|
|
|
C_ASSERT(sizeof(PNP_INSTALLATION_CHECK) == 0x21);
|
|
|
|
typedef struct _PNP_SYSTEM_DEVICE_NODE {
|
|
UINT16 Size;
|
|
UINT8 Handle;
|
|
UINT32 ProductId;
|
|
UINT8 DeviceTypeCode[3];
|
|
UINT16 DeviceNodeAttributes;
|
|
} PNP_SYSTEM_DEVICE_NODE, *PPNP_SYSTEM_DEVICE_NODE;
|
|
|
|
typedef struct _PNP_ISA_CONFIGURATION {
|
|
UINT8 Revision;
|
|
UINT8 NumberOfCardSelectNumbers;
|
|
UINT16 DataReadPort;
|
|
UINT16 Reserved;
|
|
} PNP_ISA_CONFIGURATION, *PPNP_ISA_CONFIGURATION;
|
|
|
|
#pragma pack()
|
|
|
|
extern PPNP_SYSTEM_DEVICE_NODE BlPnpSystemDeviceNodeList;
|
|
extern UINT32 BlPnpSystemDeviceNodeListSize;
|
|
extern PNP_ISA_CONFIGURATION BlPnpIsaConfiguration;
|
|
|
|
VOID
|
|
BlPnpInitialize(
|
|
VOID
|
|
);
|
|
|
|
//
|
|
// PCI support.
|
|
//
|
|
|
|
typedef struct _PCI_INSTALLATION_CHECK {
|
|
UINT32 Eax;
|
|
UINT32 Ebx;
|
|
UINT32 Ecx;
|
|
UINT32 Edx;
|
|
UINT8 HardwareCharacteristics;
|
|
UINT8 MajorVersion;
|
|
UINT8 MinorVersion;
|
|
UINT8 LastBusNumber;
|
|
UINT32 ProtectedModeEntryPoint;
|
|
} PCI_INSTALLATION_CHECK, *PPCI_INSTALLATION_CHECK;
|
|
|
|
extern PCI_INSTALLATION_CHECK BlPciInstallationCheck;
|
|
extern UINT32 BlPciOhci1394BaseAddress;
|
|
|
|
VOID
|
|
BlPciInitialize(
|
|
VOID
|
|
);
|
|
|
|
//
|
|
// ACPI support.
|
|
//
|
|
|
|
extern UINT32 BlAcpiNumberOfProcessors;
|
|
extern PVOID BlAcpiRsdpAddress;
|
|
|
|
VOID
|
|
BlAcpiInitialize(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
BlAcpiResetSystem(
|
|
VOID
|
|
);
|
|
|
|
//
|
|
// Segment management.
|
|
//
|
|
|
|
#define NULL_SELECTOR 0x0000
|
|
#define RM_VIDEO_SELECTOR 0x0008
|
|
#define RM_CODE_SELECTOR 0x0010
|
|
#define RM_DATA_SELECTOR 0x0018
|
|
#define PM_CODE_SELECTOR 0x0020
|
|
#define PM_DATA_SELECTOR 0x0028
|
|
#define LM_CODE_SELECTOR 0x0030
|
|
#define LM_DATA_SELECTOR 0x0038
|
|
#define UM_CODE_SELECTOR 0x0040
|
|
#define UM_DATA_SELECTOR 0x0048
|
|
#define PROCESSOR_SELECTOR 0x0050
|
|
#define UNUSED_SELECTOR 0x0058
|
|
#define TSS_SELECTOR 0x0060
|
|
|
|
typedef struct _CODE_SEGMENT {
|
|
UINT64 Limit_15_0:16;
|
|
UINT64 Base_23_0:24;
|
|
UINT64 Accessed:1;
|
|
UINT64 Readable:1;
|
|
UINT64 Conforming:1;
|
|
UINT64 Code:1;
|
|
UINT64 S:1;
|
|
UINT64 Dpl:2;
|
|
UINT64 Present:1;
|
|
UINT64 Limit_19_16:4;
|
|
UINT64 Unused:1;
|
|
UINT64 Long:1;
|
|
UINT64 Default:1;
|
|
UINT64 Granularity:1;
|
|
UINT64 Base_31_24:8;
|
|
} CODE_SEGMENT, *PCODE_SEGMENT;
|
|
|
|
typedef struct _DATA_SEGMENT {
|
|
UINT64 Limit_15_0:16;
|
|
UINT64 Base_23_0:24;
|
|
UINT64 Accessed:1;
|
|
UINT64 Writable:1;
|
|
UINT64 Expansion:1;
|
|
UINT64 Code:1;
|
|
UINT64 S:1;
|
|
UINT64 Dpl:2;
|
|
UINT64 Present:1;
|
|
UINT64 Limit_19_16:4;
|
|
UINT64 Unused:1;
|
|
UINT64 Reserved:1;
|
|
UINT64 Big:1;
|
|
UINT64 Granularity:1;
|
|
UINT64 Base_31_24:8;
|
|
} DATA_SEGMENT, *PDATA_SEGMENT;
|
|
|
|
#define SSDT_AVAILABLE_TSS 0x09
|
|
#define SSDT_BUSY_TSS 0x0B
|
|
|
|
typedef struct _SYSTEM_SEGMENT {
|
|
UINT64 Limit_15_0:16;
|
|
UINT64 Base_23_0:24;
|
|
UINT64 Type:4;
|
|
UINT64 S:1;
|
|
UINT64 Dpl:2;
|
|
UINT64 Present:1;
|
|
UINT64 Limit_19_16:4;
|
|
UINT64 Unused:1;
|
|
UINT64 Reserved1:2;
|
|
UINT64 Granularity:1;
|
|
UINT64 Base_31_24:8;
|
|
#if defined(BOOT_X64)
|
|
UINT64 Base_63_32:32;
|
|
UINT64 Reserved2:32;
|
|
#endif
|
|
} SYSTEM_SEGMENT, *PSYSTEM_SEGMENT;
|
|
|
|
#pragma pack(1)
|
|
|
|
typedef struct _GDTR {
|
|
UINT16 Limit;
|
|
UINT64 Base;
|
|
} GDTR, *PGDTR;
|
|
|
|
C_ASSERT(sizeof(GDTR) == 10);
|
|
|
|
typedef struct _IDTR {
|
|
UINT16 Limit;
|
|
UINT64 Base;
|
|
} IDTR, *PIDTR;
|
|
|
|
C_ASSERT(sizeof(IDTR) == 10);
|
|
|
|
#pragma pack()
|
|
|
|
extern GDTR BlMmInitialGdtr;
|
|
|
|
ULONG_PTR
|
|
BlMmGetCr3(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
BlMmSetCr3(
|
|
ULONG_PTR Value
|
|
);
|
|
|
|
#if defined(BOOT_X86)
|
|
|
|
UINT16
|
|
BlMmGetFs(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
BlMmSetFs(
|
|
UINT16 Value
|
|
);
|
|
|
|
#elif defined(BOOT_X64)
|
|
|
|
UINT16
|
|
BlMmGetGs(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
BlMmSetGs(
|
|
UINT16 Value
|
|
);
|
|
|
|
#endif
|
|
|
|
VOID
|
|
BlMmSwitchStack(
|
|
PVOID Stack,
|
|
PVOID Function
|
|
);
|
|
|
|
VOID
|
|
BlMmGetGdtr(
|
|
PGDTR Gdtr
|
|
);
|
|
|
|
VOID
|
|
BlMmSetGdtr(
|
|
PGDTR Gdtr
|
|
);
|
|
|
|
VOID
|
|
BlMmInitializeCodeSegment(
|
|
PCODE_SEGMENT CodeSegment
|
|
);
|
|
|
|
VOID
|
|
BlMmInitializeDataSegment(
|
|
PDATA_SEGMENT DataSegment,
|
|
UINT32 Base,
|
|
UINT32 Limit
|
|
);
|
|
|
|
VOID
|
|
BlMmInitializeSystemSegment(
|
|
PSYSTEM_SEGMENT SystemSegment,
|
|
UINT32 Type,
|
|
ULONG_PTR Base,
|
|
UINT32 Limit
|
|
);
|
|
|
|
//
|
|
// Memory management.
|
|
//
|
|
|
|
#define PAGE_PRESENT ((UINT64) 0x01)
|
|
#define PAGE_WRITEABLE ((UINT64) 0x02)
|
|
#define PAGE_WRITETHROUGH ((UINT64) 0x08)
|
|
#define PAGE_CACHEDISABLE ((UINT64) 0x10)
|
|
#define PAGE_ACCESSED ((UINT64) 0x20)
|
|
#define PAGE_2MB ((UINT64) 0x80)
|
|
|
|
#define BL_MM_PHYSICAL_REGION_MIN_TYPE 0x00000001
|
|
#define BL_MM_PHYSICAL_REGION_FREE 0x00000001
|
|
#define BL_MM_PHYSICAL_REGION_BIOS 0x00000002
|
|
#define BL_MM_PHYSICAL_REGION_BOOT_LOADER 0x00000003
|
|
#define BL_MM_PHYSICAL_REGION_SMAP_RESERVED 0x00000004
|
|
#define BL_MM_PHYSICAL_REGION_DISTRO 0x00000005
|
|
#define BL_MM_PHYSICAL_REGION_KERNEL_IMAGE 0x00000006
|
|
#define BL_MM_PHYSICAL_REGION_NATIVE_PLATFORM 0x00000007
|
|
#define BL_MM_PHYSICAL_REGION_NATIVE_PROCESSOR 0x00000008
|
|
#define BL_MM_PHYSICAL_REGION_LOG_RECORD 0x00000009
|
|
#define BL_MM_PHYSICAL_REGION_LOG_TEXT 0x0000000A
|
|
#define BL_MM_PHYSICAL_REGION_KERNEL_STACK 0x0000000B
|
|
#define BL_MM_PHYSICAL_REGION_CONTEXT 0x0000000C
|
|
#define BL_MM_PHYSICAL_REGION_TASK 0x0000000D
|
|
#define BL_MM_PHYSICAL_REGION_SINGULARITY 0x0000000E
|
|
#define BL_MM_PHYSICAL_REGION_BOOT_STACK 0x0000000F
|
|
#define BL_MM_PHYSICAL_REGION_SINGULARITY_SMAP 0x00000010
|
|
#define BL_MM_PHYSICAL_REGION_MAX_TYPE 0x00000010
|
|
|
|
#define BL_MM_BIOS_SIZE (1024 * 1024)
|
|
|
|
typedef struct _BL_MM_PHYSICAL_REGION {
|
|
LIST_ENTRY Entry;
|
|
UINT64 Start;
|
|
UINT64 Size;
|
|
UINT64 Limit;
|
|
UINT32 Type;
|
|
} BL_MM_PHYSICAL_REGION, *PBL_MM_PHYSICAL_REGION;
|
|
|
|
extern ULONG_PTR BlMmBootCr3;
|
|
|
|
VOID
|
|
BlMmEnableA20Gate(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
BlMmInitializeSystem(
|
|
VOID
|
|
);
|
|
|
|
PCHAR
|
|
BlMmPhysicalRegionTypeString(
|
|
UINT32 Type
|
|
);
|
|
|
|
UINT64
|
|
BlMmAllocatePhysicalRegion(
|
|
UINT32 Size,
|
|
UINT32 Type
|
|
);
|
|
|
|
BOOLEAN
|
|
BlMmAllocateSpecificPhysicalRegion(
|
|
UINT64 Base,
|
|
UINT64 Size,
|
|
UINT32 Type
|
|
);
|
|
|
|
BOOLEAN
|
|
BlMmFindFreePhysicalRegion(
|
|
PUINT64 Base,
|
|
PUINT64 Size
|
|
);
|
|
|
|
BOOLEAN
|
|
BlMmGetNextPhysicalRegion(
|
|
PVOID *Handle,
|
|
PUINT64 Base,
|
|
PUINT64 Size,
|
|
PUINT32 Type
|
|
);
|
|
|
|
VOID
|
|
BlMmDumpPhysicalRegionList(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
BlMmMapVirtualPage(
|
|
PVOID VirtualAddress,
|
|
PVOID PhysicalAddress,
|
|
BOOLEAN Writeable,
|
|
BOOLEAN Cacheable,
|
|
BOOLEAN WriteThrough
|
|
);
|
|
|
|
VOID
|
|
BlMmMapVirtualRange(
|
|
PVOID VirtualAddress,
|
|
PVOID PhysicalAddress,
|
|
ULONG_PTR Size,
|
|
BOOLEAN Writeable,
|
|
BOOLEAN Cacheable,
|
|
BOOLEAN WriteThrough
|
|
);
|
|
|
|
extern PVOID BlMmExtendedBiosDataArea;
|
|
|
|
//
|
|
// File system support.
|
|
//
|
|
|
|
extern
|
|
BOOLEAN
|
|
(*BlFsGetFileSize)(
|
|
PCSTR Path,
|
|
PUINT32 FileSize
|
|
);
|
|
|
|
extern
|
|
BOOLEAN
|
|
(*BlFsReadFile)(
|
|
PCSTR Path,
|
|
PVOID Buffer,
|
|
UINT32 NumberOfBytes
|
|
);
|
|
|
|
//
|
|
// CDROM support.
|
|
//
|
|
|
|
VOID
|
|
BlCdInitialize(
|
|
UINT8 DriveId
|
|
);
|
|
|
|
//
|
|
// FAT support.
|
|
//
|
|
|
|
#define MBR_FAT32LBA 0x0C
|
|
#define MBR_FAT16LBA 0x0E
|
|
|
|
VOID
|
|
BlFatInitialize(
|
|
UINT8 DriveId,
|
|
UINT8 FatType
|
|
);
|
|
|
|
//
|
|
// Flash support.
|
|
//
|
|
|
|
VOID
|
|
BlFlashInitialize(
|
|
PVOID SearchBegin,
|
|
PVOID SearchLimit
|
|
);
|
|
|
|
//
|
|
// PXE support.
|
|
//
|
|
|
|
VOID
|
|
BlPxeInitialize(
|
|
VOID
|
|
);
|
|
|
|
//
|
|
// PE/COFF support.
|
|
//
|
|
|
|
VOID
|
|
BlPeGetVirtualRange(
|
|
PVOID Image,
|
|
PVOID *VirtualBase,
|
|
ULONG_PTR *VirtualSize
|
|
);
|
|
|
|
VOID
|
|
BlPeLoadImage(
|
|
PVOID LoadBase,
|
|
PVOID Image,
|
|
PVOID *EntryPoint
|
|
);
|
|
|
|
//
|
|
// RTC support.
|
|
//
|
|
|
|
typedef struct _BL_TIME {
|
|
UINT32 Year;
|
|
UINT8 Month;
|
|
UINT8 Day;
|
|
UINT8 Hour;
|
|
UINT8 Minute;
|
|
UINT8 Second;
|
|
} BL_TIME, *PBL_TIME;
|
|
|
|
VOID
|
|
BlRtlGetCurrentTime(
|
|
PBL_TIME Time
|
|
);
|
|
|
|
extern BL_TIME BlStartTime;
|
|
|
|
//
|
|
// MPS support.
|
|
//
|
|
|
|
VOID
|
|
BlMpsInitialize(
|
|
VOID
|
|
);
|
|
|
|
extern PVOID BlMpsFps;
|
|
|
|
//
|
|
// VESA Support.
|
|
//
|
|
|
|
BOOLEAN
|
|
BlVesaInitialize(
|
|
VOID
|
|
);
|
|
|
|
extern ULONG_PTR BlVesaVideoBuffer;
|
|
|
|
//
|
|
// Call stack support.
|
|
//
|
|
|
|
#if defined(BOOT_X86)
|
|
|
|
PVOID
|
|
BlRtlGetEbp(
|
|
VOID
|
|
);
|
|
|
|
#elif defined(BOOT_X64)
|
|
|
|
PVOID
|
|
BlRtlGetRbp(
|
|
VOID
|
|
);
|
|
|
|
#endif
|
|
|
|
VOID
|
|
BlRtlCaptureCallStack(
|
|
PVOID *FrameArray,
|
|
UINT32 FrameCount
|
|
);
|
|
|
|
//
|
|
// Trap Support.
|
|
//
|
|
|
|
typedef struct _BL_TRAP_CONTEXT {
|
|
|
|
#if defined(BOOT_X86)
|
|
|
|
UINT32 Cr2;
|
|
UINT32 Esp;
|
|
UINT32 Ebp;
|
|
UINT32 Edi;
|
|
UINT32 Esi;
|
|
UINT32 Edx;
|
|
UINT32 Ecx;
|
|
UINT32 Ebx;
|
|
UINT32 Eax;
|
|
UINT32 Num;
|
|
UINT32 Err;
|
|
UINT32 Eip;
|
|
UINT32 Cs0;
|
|
UINT32 Efl;
|
|
|
|
#elif defined (BOOT_X64)
|
|
|
|
UINT64 Cr2;
|
|
UINT64 Rsp;
|
|
UINT64 R15;
|
|
UINT64 R14;
|
|
UINT64 R13;
|
|
UINT64 R12;
|
|
UINT64 R11;
|
|
UINT64 R10;
|
|
UINT64 R9;
|
|
UINT64 R8;
|
|
UINT64 Rbp;
|
|
UINT64 Rdi;
|
|
UINT64 Rsi;
|
|
UINT64 Rdx;
|
|
UINT64 Rcx;
|
|
UINT64 Rbx;
|
|
UINT64 Rax;
|
|
UINT64 Num;
|
|
UINT64 Err;
|
|
UINT64 Rip;
|
|
UINT64 Cs0;
|
|
UINT64 Rfl;
|
|
|
|
#endif
|
|
|
|
} BL_TRAP_CONTEXT, *PBL_TRAP_CONTEXT;
|
|
|
|
typedef struct _IDTE {
|
|
|
|
UINT16 Offset0To15;
|
|
UINT16 Selector;
|
|
UINT8 Flags;
|
|
UINT8 Access;
|
|
UINT16 Offset16To31;
|
|
|
|
#if defined(BOOT_X64)
|
|
|
|
UINT32 Offset32To63;
|
|
UINT32 Reserved;
|
|
|
|
#endif
|
|
|
|
} IDTE, *PIDTE;
|
|
|
|
|
|
VOID
|
|
BlTrapEnable(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
BlTrapEnter(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
BlTrapFatal(
|
|
UINT32 Trap,
|
|
PBL_TRAP_CONTEXT Context
|
|
);
|
|
|
|
VOID
|
|
BlTrapSetIdtr(
|
|
PIDTR Idtr
|
|
);
|
|
|
|
|
|
//
|
|
// Singularity bridge.
|
|
//
|
|
|
|
extern PWCHAR BlCommandLine;
|
|
|
|
VOID
|
|
BlSingularityInitialize(
|
|
UINT32 NumberOfProcessors,
|
|
PFAR_POINTER ApEntry16,
|
|
PFAR_POINTER ApStartupLock
|
|
);
|
|
|
|
VOID
|
|
BlSingularityApEntry(
|
|
VOID
|
|
);
|
|
|
|
extern "C" void * _ReturnAddress(void);
|
|
|
|
#pragma intrinsic(_ReturnAddress)
|
|
|