2019-09-03 11:58:42 +02:00
/*
* BootLog . c
*
*
* Created by Slice on 19.08 .11 .
* Edited by apianti 2012 - 09 - 08
* Initial idea from Kabyl
*/
2020-08-17 21:40:52 +02:00
# include <Platform.h> // Only use angled for Platform, else, xcode project won't compile
2020-04-16 09:15:26 +02:00
//#include <Library/MemLogLib.h>
# include "DataHubCpu.h"
2020-08-17 21:40:52 +02:00
# include "../Platform/Settings.h"
2020-10-03 19:02:31 +02:00
# include "Self.h"
2020-09-07 00:19:48 +02:00
# include "guid.h"
2019-09-03 11:58:42 +02:00
/** Prints Number of bytes in a row (hex and ascii). Row size is MaxNumber. */
2020-10-03 19:02:31 +02:00
void
2019-09-03 11:58:42 +02:00
PrintBytesRow ( IN UINT8 * Bytes , IN UINTN Number , IN UINTN MaxNumber )
{
UINTN Index ;
// print hex vals
for ( Index = 0 ; Index < Number ; Index + + ) {
2020-04-17 15:14:24 +02:00
DebugLog ( 1 , " %02hhX " , Bytes [ Index ] ) ;
2019-09-03 11:58:42 +02:00
}
// pad to MaxNumber if needed
for ( ; Index < MaxNumber ; Index + + ) {
DebugLog ( 1 , " " ) ;
}
DebugLog ( 1 , " | " ) ;
// print ASCII
for ( Index = 0 ; Index < Number ; Index + + ) {
if ( Bytes [ Index ] > = 0x20 & & Bytes [ Index ] < = 0x7e ) {
DebugLog ( 1 , " %c " , ( CHAR16 ) Bytes [ Index ] ) ;
} else {
DebugLog ( 1 , " %c " , L ' . ' ) ;
}
}
DebugLog ( 1 , " \n " ) ;
}
/** Prints series of bytes. */
2020-10-03 19:02:31 +02:00
void
PrintBytes ( IN void * Bytes , IN UINTN Number )
2019-09-03 11:58:42 +02:00
{
UINTN Index ;
for ( Index = 0 ; Index < Number ; Index + = 16 ) {
PrintBytesRow ( ( UINT8 * ) Bytes + Index , ( ( Index + 16 < Number ) ? 16 : ( Number - Index ) ) , 16 ) ;
}
}
2020-09-18 10:55:44 +02:00
static EFI_FILE_PROTOCOL * gLogFile = NULL ;
2019-09-03 11:58:42 +02:00
EFI_FILE_PROTOCOL * GetDebugLogFile ( )
{
EFI_STATUS Status ;
EFI_FILE_PROTOCOL * LogFile ;
2020-09-18 10:55:44 +02:00
if ( gLogFile ) return gLogFile ;
2020-10-03 19:02:31 +02:00
if ( ! self . isInitialized ( ) ) return NULL ;
2020-09-18 10:55:44 +02:00
2020-10-03 19:02:31 +02:00
// // get RootDir from device we are loaded from
// Status = gBS->HandleProtocol(gImageHandle, &gEfiLoadedImageProtocolGuid, (void **) &LoadedImage);
// if (EFI_ERROR(Status)) {
// return NULL;
// }
// RootDir = EfiLibOpenRoot(LoadedImage->DeviceHandle);
// if (RootDir == NULL) {
// return NULL;
// }
2019-09-03 11:58:42 +02:00
// Open log file from current root
2020-10-03 19:02:31 +02:00
Status = self . getCloverDir ( ) . Open ( & self . getCloverDir ( ) , & LogFile , DEBUG_LOG_new , EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE , 0 ) ;
2020-09-18 12:50:49 +02:00
if ( GlobalConfig . ScratchDebugLogAtStart & & Status = = EFI_SUCCESS )
{
EFI_STATUS StatusDelete ;
StatusDelete = LogFile - > Delete ( LogFile ) ;
if ( StatusDelete = = EFI_SUCCESS ) {
Status = EFI_NOT_FOUND ; // to get it created next.
} else {
2020-10-03 19:02:31 +02:00
DebugLog ( 1 , " Cannot delete log file %ls \\ %ls from current root : %s \n " , self . getCloverDirPathAsXStringW ( ) . wc_str ( ) , DEBUG_LOG_new , efiStrError ( StatusDelete ) ) ;
2020-09-18 12:50:49 +02:00
}
}
2019-09-03 11:58:42 +02:00
// If the log file is not found try to create it
if ( Status = = EFI_NOT_FOUND ) {
2020-10-03 19:02:31 +02:00
Status = self . getCloverDir ( ) . Open ( & self . getCloverDir ( ) , & LogFile , DEBUG_LOG_new , EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE , 0 ) ;
2019-09-03 11:58:42 +02:00
}
2020-10-03 19:02:31 +02:00
// RootDir->Close(RootDir);
// RootDir = NULL;
2019-09-03 11:58:42 +02:00
2020-10-03 19:02:31 +02:00
// Jief : do we really need this ?
2019-09-03 11:58:42 +02:00
if ( EFI_ERROR ( Status ) ) {
// try on first EFI partition
2020-10-03 19:02:31 +02:00
EFI_FILE * RootDir ;
2019-09-03 11:58:42 +02:00
Status = egFindESP ( & RootDir ) ;
if ( ! EFI_ERROR ( Status ) ) {
2020-10-03 19:02:31 +02:00
Status = RootDir - > Open ( RootDir , & LogFile , SWPrintf ( " %ls \\ %ls " , self . getCloverDirPathAsXStringW ( ) . wc_str ( ) , DEBUG_LOG_new ) . wc_str ( ) , EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE , 0 ) ;
2020-09-18 12:50:49 +02:00
if ( GlobalConfig . ScratchDebugLogAtStart & & Status = = EFI_SUCCESS )
{
EFI_STATUS StatusDelete ;
StatusDelete = LogFile - > Delete ( LogFile ) ;
if ( StatusDelete = = EFI_SUCCESS ) {
Status = EFI_NOT_FOUND ; // to get it created next.
} else {
2020-10-03 19:02:31 +02:00
DebugLog ( 1 , " Cannot delete log file %ls from 1st EFI partition : %s \n " , SWPrintf ( " %ls \\ %ls " , self . getCloverDirPathAsXStringW ( ) . wc_str ( ) , DEBUG_LOG_new ) . wc_str ( ) , efiStrError ( StatusDelete ) ) ;
2020-09-18 12:50:49 +02:00
}
}
2019-09-03 11:58:42 +02:00
// If the log file is not found try to create it
if ( Status = = EFI_NOT_FOUND ) {
2020-10-03 19:02:31 +02:00
Status = RootDir - > Open ( RootDir , & LogFile , SWPrintf ( " %ls \\ %ls " , self . getCloverDirPathAsXStringW ( ) . wc_str ( ) , DEBUG_LOG_new ) . wc_str ( ) , EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE , 0 ) ;
2019-09-03 11:58:42 +02:00
}
RootDir - > Close ( RootDir ) ;
RootDir = NULL ;
}
}
if ( EFI_ERROR ( Status ) ) {
LogFile = NULL ;
}
2020-09-18 10:55:44 +02:00
gLogFile = LogFile ;
2019-09-03 11:58:42 +02:00
return LogFile ;
}
2020-10-03 19:02:31 +02:00
void SaveMessageToDebugLogFile ( IN CHAR8 * LastMessage )
2019-09-03 11:58:42 +02:00
{
2020-09-18 10:55:44 +02:00
EFI_STATUS Status ;
2019-09-03 11:58:42 +02:00
STATIC BOOLEAN FirstTimeSave = TRUE ;
// STATIC UINTN Position = 0;
CHAR8 * MemLogBuffer ;
UINTN MemLogLen ;
CHAR8 * Text ;
UINTN TextLen ;
2020-10-03 19:02:31 +02:00
EFI_FILE * LogFile ;
2019-09-03 11:58:42 +02:00
MemLogBuffer = GetMemLogBuffer ( ) ;
MemLogLen = GetMemLogLen ( ) ;
Text = LastMessage ;
TextLen = AsciiStrLen ( LastMessage ) ;
LogFile = GetDebugLogFile ( ) ;
// Write to the log file
if ( LogFile ! = NULL ) {
// Advance to the EOF so we append
EFI_FILE_INFO * Info = EfiLibFileInfo ( LogFile ) ;
if ( Info ) {
2020-09-18 10:55:44 +02:00
Status = LogFile - > SetPosition ( LogFile , Info - > FileSize ) ;
2019-09-03 11:58:42 +02:00
// If we haven't had root before this write out whole log
if ( FirstTimeSave ) {
Text = MemLogBuffer ;
TextLen = MemLogLen ;
FirstTimeSave = FALSE ;
}
// Write out this message
2020-09-18 10:55:44 +02:00
Status = LogFile - > Write ( LogFile , & TextLen , Text ) ;
Status = LogFile - > Flush ( LogFile ) ;
( void ) Status ;
2019-09-03 11:58:42 +02:00
}
2020-09-18 10:55:44 +02:00
// LogFile->Close(LogFile);
2019-09-03 11:58:42 +02:00
}
}
2020-10-03 19:02:31 +02:00
void EFIAPI MemLogCallback ( IN INTN DebugMode , IN CHAR8 * LastMessage )
2019-09-03 11:58:42 +02:00
{
// Print message to console
if ( DebugMode > = 2 ) {
2020-03-29 14:47:04 +02:00
printf ( " %s " , LastMessage ) ;
2019-09-03 11:58:42 +02:00
}
if ( ( DebugMode > = 1 ) & & GlobalConfig . DebugLog ) {
SaveMessageToDebugLogFile ( LastMessage ) ;
}
}
// Changed MsgLog(...) it now calls this function
// with DebugMode == 0. - apianti
// DebugMode==0 Prints to msg log, only output to log on SaveBooterLog
// DebugMode==1 Prints to msg log and DEBUG_LOG
// DebugMode==2 Prints to msg log, DEBUG_LOG and display console
2020-10-03 19:02:31 +02:00
void EFIAPI DebugLog ( IN INTN DebugMode , IN CONST CHAR8 * FormatString , . . . )
2019-09-03 11:58:42 +02:00
{
VA_LIST Marker ;
//UINTN offset = 0;
// Make sure the buffer is intact for writing
if ( FormatString = = NULL | | DebugMode < 0 ) {
return ;
}
// Print message to log buffer
VA_START ( Marker , FormatString ) ;
2020-03-25 19:32:44 +01:00
MemLogfVA ( TRUE , DebugMode , FormatString , Marker ) ;
2019-09-03 11:58:42 +02:00
VA_END ( Marker ) ;
}
2020-10-03 19:02:31 +02:00
void InitBooterLog ( void )
2019-09-03 11:58:42 +02:00
{
SetMemLogCallback ( MemLogCallback ) ;
}
EFI_STATUS SetupBooterLog ( BOOLEAN AllowGrownSize )
{
EFI_STATUS Status = EFI_SUCCESS ;
CHAR8 * MemLogBuffer ;
UINTN MemLogLen ;
MemLogBuffer = GetMemLogBuffer ( ) ;
MemLogLen = GetMemLogLen ( ) ;
if ( MemLogBuffer = = NULL | | MemLogLen = = 0 ) {
return EFI_NOT_FOUND ;
}
if ( MemLogLen > MEM_LOG_INITIAL_SIZE & & ! AllowGrownSize ) {
CHAR8 PrevChar = MemLogBuffer [ MEM_LOG_INITIAL_SIZE - 1 ] ;
MemLogBuffer [ MEM_LOG_INITIAL_SIZE - 1 ] = ' \0 ' ;
Status = LogDataHub ( & gEfiMiscSubClassGuid , L " boot-log " , MemLogBuffer , MEM_LOG_INITIAL_SIZE ) ;
MemLogBuffer [ MEM_LOG_INITIAL_SIZE - 1 ] = PrevChar ;
} else {
Status = LogDataHub ( & gEfiMiscSubClassGuid , L " boot-log " , MemLogBuffer , ( UINT32 ) MemLogLen ) ;
}
return Status ;
}
// Made msgbuf and msgCursor private to this source
// so we need a different way of saving the msg log - apianti
2020-10-03 19:02:31 +02:00
EFI_STATUS SaveBooterLog ( const EFI_FILE * BaseDir OPTIONAL , IN CONST CHAR16 * FileName )
2019-09-03 11:58:42 +02:00
{
CHAR8 * MemLogBuffer ;
UINTN MemLogLen ;
MemLogBuffer = GetMemLogBuffer ( ) ;
MemLogLen = GetMemLogLen ( ) ;
if ( MemLogBuffer = = NULL | | MemLogLen = = 0 ) {
return EFI_NOT_FOUND ;
}
return egSaveFile ( BaseDir , FileName , ( UINT8 * ) MemLogBuffer , MemLogLen ) ;
}
2020-09-18 10:55:44 +02:00
/*
* Redirection of OpenCore log to Clover Log .
*/
/*
* This function is called from OpenCore when there is a DEBUG ( ( expression ) )
* Mapping from DEBUG to DebugLogForOC is made in OpenCoreFromClover . h
*/
2020-10-03 19:02:31 +02:00
void EFIAPI DebugLogForOC ( IN INTN DebugLevel , IN CONST CHAR8 * FormatString , . . . )
2020-09-18 10:55:44 +02:00
{
VA_LIST Marker ;
if ( FormatString = = NULL ) return ;
// Print message to log buffer
VA_START ( Marker , FormatString ) ;
MemLogVA ( TRUE , 1 , FormatString , Marker ) ;
VA_END ( Marker ) ;
}