2019-09-03 11:58:42 +02:00
/**
initial concept of DSDT patching by mackerintel
Re - Work by Slice 2011.
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
* */
2021-02-06 18:16:46 +01:00
# include <Platform.h> // Only use angled for Platform, else, xcode project won't compile
# include <Efi.h>
# include "../libeg/BmLib.h"
2019-09-03 11:58:42 +02:00
# include "StateGenerator.h"
# include "AmlGenerator.h"
2020-04-16 09:15:26 +02:00
# include "AcpiPatcher.h"
# include "FixBiosDsdt.h"
# include "platformdata.h"
# include "smbios.h"
# include "cpu.h"
2021-04-28 20:30:34 +02:00
# include "../Settings/Self.h"
# include "../Settings/SelfOem.h"
# include "Settings.h"
2019-09-03 11:58:42 +02:00
2020-04-16 11:09:22 +02:00
# define EBDA_BASE_ADDRESS 0x40E
2019-09-03 11:58:42 +02:00
# define HPET_SIGN SIGNATURE_32('H','P','E','T')
# define APIC_SIGN SIGNATURE_32('A','P','I','C')
# define MCFG_SIGN SIGNATURE_32('M','C','F','G')
# define ECDT_SIGN SIGNATURE_32('E','C','D','T')
# define DMAR_SIGN SIGNATURE_32('D','M','A','R')
# define BGRT_SIGN SIGNATURE_32('B','G','R','T')
# define SLIC_SIGN SIGNATURE_32('S','L','I','C')
# define APPLE_OEM_ID { 'A', 'P', 'P', 'L', 'E', ' ' }
# define APPLE_OEM_TABLE_ID { 'A', 'p', 'p', 'l', 'e', '0', '0', ' ' }
# define APPLE_CREATOR_ID { 'L', 'o', 'k', 'i' }
# define IGNORE_INDEX (~((UINTN)0)) // index ignored for matching (not ignored for >= 0)
# define AUTOMERGE_PASS1 1 // load just those that match existing entries
# define AUTOMERGE_PASS2 2 // load the rest
CONST CHAR8 oemID [ 6 ] = APPLE_OEM_ID ;
CONST CHAR8 oemTableID [ 8 ] = APPLE_OEM_TABLE_ID ;
CONST CHAR8 creatorID [ 4 ] = APPLE_CREATOR_ID ;
//Global pointers
RSDT_TABLE * Rsdt = NULL ;
XSDT_TABLE * Xsdt = NULL ;
UINTN * XsdtReplaceSizes = NULL ;
# define IndexFromEntryPtr(xsdt_or_rsdt, entry_ptr) \
( ( UINT32 ) ( ( ( CHAR8 * ) ( entry_ptr ) - ( CHAR8 * ) & ( xsdt_or_rsdt ) - > Entry ) / sizeof ( ( xsdt_or_rsdt ) - > Entry ) ) )
# define IndexFromRsdtEntryPtr(entry_ptr) IndexFromEntryPtr(Rsdt, entry_ptr)
# define IndexFromXsdtEntryPtr(entry_ptr) IndexFromEntryPtr(Xsdt, entry_ptr)
# define TableCount(xsdt_or_rsdt) \
( ( ( xsdt_or_rsdt ) - > Header . Length - sizeof ( EFI_ACPI_DESCRIPTION_HEADER ) ) / sizeof ( ( xsdt_or_rsdt ) - > Entry ) )
# define RsdtTableCount() TableCount(Rsdt)
# define XsdtTableCount() TableCount(Xsdt)
# define RsdtEntryPtrFromIndex(index) (&Rsdt->Entry + index)
# define XsdtEntryPtrFromIndex(index) ((UINT64*)((CHAR8*)&Xsdt->Entry + sizeof(UINT64)*(index)))
# define RsdtEntryFromIndex(index) (EFI_ACPI_DESCRIPTION_HEADER*)(UINTN)*RsdtEntryPtrFromIndex(index)
# define XsdtEntryFromIndex(index) (EFI_ACPI_DESCRIPTION_HEADER*)(UINTN)ReadUnaligned64(XsdtEntryPtrFromIndex(index))
UINT64 BiosDsdt ;
UINT32 BiosDsdtLen ;
UINT8 acpi_cpu_count ;
2019-09-14 11:31:25 +02:00
CHAR8 * acpi_cpu_name [ acpi_cpu_max ] ;
UINT8 acpi_cpu_processor_id [ acpi_cpu_max ] ;
2019-09-03 11:58:42 +02:00
CHAR8 * acpi_cpu_score ;
UINT64 machineSignature ;
extern OPER_REGION * gRegions ;
//-----------------------------------
UINT8 pmBlock [ ] = {
/*0070: 0xA5, 0x84, 0x00, 0x00,*/ 0x01 , 0x08 , 0x00 , 0x01 , 0xF9 , 0x0C , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
/*0080:*/ 0x06 , 0x00 , 0x00 , 0x00 , 0x00 , 0xA0 , 0x67 , 0xBF , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xF0 , 0x6F , 0xBF ,
/*0090:*/ 0x00 , 0x00 , 0x00 , 0x00 , 0x01 , 0x20 , 0x00 , 0x03 , 0x00 , 0x04 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
/*00A0:*/ 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 , 0x10 , 0x00 , 0x02 ,
/*00B0:*/ 0x04 , 0x04 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
/*00C0:*/ 0x00 , 0x00 , 0x00 , 0x00 , 0x01 , 0x08 , 0x00 , 0x00 , 0x50 , 0x04 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
/*00D0:*/ 0x01 , 0x20 , 0x00 , 0x03 , 0x08 , 0x04 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 , 0x80 , 0x00 , 0x01 ,
/*00E0:*/ 0x20 , 0x04 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 ,
/*00F0:*/ 0x00 , 0x00 , 0x00 , 0x00
} ;
// RehabMan: for stripping trailing spaces
static void stripTrailingSpaces ( CHAR8 * sgn )
{
CHAR8 * lastNonSpace = sgn - 1 ;
for ( ; * sgn ; sgn + + ) {
if ( * sgn ! = ' ' ) {
lastNonSpace = sgn ;
}
}
lastNonSpace [ 1 ] = 0 ;
}
2020-10-03 19:02:31 +02:00
void * FindAcpiRsdPtr ( )
2019-09-03 11:58:42 +02:00
{
UINTN Address ;
UINTN Index ;
//
// First Seach 0x0e0000 - 0x0fffff for RSD Ptr
//
for ( Address = 0xe0000 ; Address < 0xfffff ; Address + = 0x10 ) {
if ( * ( UINT64 * ) ( Address ) = = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE ) {
2020-10-03 19:02:31 +02:00
return ( void * ) Address ;
2019-09-03 11:58:42 +02:00
}
}
//
// Search EBDA
//
Address = ( * ( UINT16 * ) ( UINTN ) ( EBDA_BASE_ADDRESS ) ) < < 4 ;
2020-03-04 22:54:59 +01:00
if ( Address = = 0 ) return 0 ; // Jief : if Address==0, the first access at *(UINT64 *)(Address + Index) is at address 0. It's supposed to crash.
2019-09-03 11:58:42 +02:00
for ( Index = 0 ; Index < 0x400 ; Index + = 16 ) {
if ( * ( UINT64 * ) ( Address + Index ) = = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE ) {
2020-10-03 19:02:31 +02:00
return ( void * ) Address ;
2019-09-03 11:58:42 +02:00
}
}
return NULL ;
}
2020-10-03 19:02:31 +02:00
UINT8 Checksum8 ( void * startPtr , UINT32 len )
2019-09-03 11:58:42 +02:00
{
UINT8 Value = 0 ;
UINT8 * ptr = ( UINT8 * ) startPtr ;
UINT8 * endPtr = ptr + len ;
while ( ptr < endPtr )
Value + = * ptr + + ;
return Value ;
}
void FixChecksum ( EFI_ACPI_DESCRIPTION_HEADER * Table )
{
Table - > Checksum = 0 ;
Table - > Checksum = ( UINT8 ) ( 256 - Checksum8 ( Table , Table - > Length ) ) ;
}
void SaveMergedXsdtEntrySize ( UINT32 Index , UINTN Size )
{
// manage XsdtReplaceSizes (free existing, store new)
if ( XsdtReplaceSizes ) {
if ( XsdtReplaceSizes [ Index ] ) {
// came from patched table in ACPI/patched, so free original pages
gBS - > FreePages ( ( EFI_PHYSICAL_ADDRESS ) ( UINTN ) XsdtEntryFromIndex ( Index ) , XsdtReplaceSizes [ Index ] ) ;
XsdtReplaceSizes [ Index ] = 0 ;
}
XsdtReplaceSizes [ Index ] = EFI_SIZE_TO_PAGES ( Size ) ;
}
}
2021-09-28 10:28:45 +02:00
XBool IsXsdtEntryMerged ( UINT32 Index )
2019-09-03 11:58:42 +02:00
{
if ( ! XsdtReplaceSizes ) {
2021-09-28 10:28:45 +02:00
return false ;
2019-09-03 11:58:42 +02:00
}
return 0 ! = XsdtReplaceSizes [ Index ] ;
}
UINT32 * ScanRSDT2 ( UINT32 Signature , UINT64 TableId , UINTN MatchIndex )
{
if ( ! Rsdt | | ( 0 = = Signature & & 0 = = TableId ) ) {
return NULL ;
}
UINT32 Count = RsdtTableCount ( ) ;
UINTN MatchingCount = 0 ;
UINT32 * Ptr = RsdtEntryPtrFromIndex ( 0 ) ;
UINT32 * EndPtr = RsdtEntryPtrFromIndex ( Count ) ;
for ( ; Ptr < EndPtr ; Ptr + + ) {
EFI_ACPI_DESCRIPTION_HEADER * Table = ( EFI_ACPI_DESCRIPTION_HEADER * ) ( UINTN ) * Ptr ;
if ( ! Table ) {
// skip NULL entry
continue ;
}
if ( 0 = = Signature | | Table - > Signature = = Signature ) {
if ( ( 0 = = TableId | | Table - > OemTableId = = TableId ) & & ( IGNORE_INDEX = = MatchIndex | | MatchingCount = = MatchIndex ) ) {
return Ptr ; // pointer to the matching entry
}
+ + MatchingCount ;
}
}
return NULL ;
}
UINT32 * ScanRSDT ( UINT32 Signature , UINT64 TableId )
{
return ScanRSDT2 ( Signature , TableId , IGNORE_INDEX ) ;
}
UINT64 * ScanXSDT2 ( UINT32 Signature , UINT64 TableId , UINTN MatchIndex )
{
if ( ! Xsdt | | ( 0 = = Signature & & 0 = = TableId ) ) {
return NULL ;
}
UINT32 Count = XsdtTableCount ( ) ;
UINTN MatchingCount = 0 ;
UINT64 * Ptr = XsdtEntryPtrFromIndex ( 0 ) ;
UINT64 * EndPtr = XsdtEntryPtrFromIndex ( Count ) ;
for ( ; Ptr < EndPtr ; Ptr + + ) {
EFI_ACPI_DESCRIPTION_HEADER * Table = ( EFI_ACPI_DESCRIPTION_HEADER * ) ( UINTN ) ReadUnaligned64 ( Ptr ) ;
if ( ! Table ) {
// skip NULL entry
continue ;
}
if ( 0 = = Signature | | Table - > Signature = = Signature ) {
if ( ( 0 = = TableId | | Table - > OemTableId = = TableId ) & & ( IGNORE_INDEX = = MatchIndex | | MatchingCount = = MatchIndex ) ) {
return Ptr ; // pointer to the matching entry
}
+ + MatchingCount ;
}
}
return NULL ;
}
UINT64 * ScanXSDT ( UINT32 Signature , UINT64 TableId )
{
return ScanXSDT2 ( Signature , TableId , IGNORE_INDEX ) ;
}
void AddDropTable ( EFI_ACPI_DESCRIPTION_HEADER * Table , UINT32 Index )
{
CHAR8 sign [ 5 ] , OTID [ 9 ] ;
sign [ 4 ] = 0 ;
OTID [ 8 ] = 0 ;
CopyMem ( & sign [ 0 ] , & Table - > Signature , 4 ) ;
CopyMem ( & OTID [ 0 ] , & Table - > OemTableId , 8 ) ;
2020-03-25 19:32:44 +01:00
//DBG(" Found table: %s %s len=%d\n", sign, OTID, (INT32)Table->Length);
DBG ( " - [%02d]: %s %s len=%d \n " , Index , sign , OTID , ( INT32 ) Table - > Length ) ;
2020-08-09 17:55:30 +02:00
ACPI_DROP_TABLE * DropTable = new ACPI_DROP_TABLE ;
2019-09-03 11:58:42 +02:00
DropTable - > Signature = Table - > Signature ;
DropTable - > TableId = Table - > OemTableId ;
DropTable - > Length = Table - > Length ;
2021-09-28 10:28:45 +02:00
DropTable - > MenuItem . BValue = false ;
2021-02-11 12:41:59 +01:00
DropTable - > Next = GlobalConfig . ACPIDropTables ;
GlobalConfig . ACPIDropTables = DropTable ;
2019-09-03 11:58:42 +02:00
}
2020-10-03 19:02:31 +02:00
void GetAcpiTablesList ( )
2019-09-03 11:58:42 +02:00
{
DbgHeader ( " GetAcpiTablesList " ) ;
GetFadt ( ) ; //this is a first call to acpi, we need it to make a pointer to Xsdt
2021-02-11 12:41:59 +01:00
GlobalConfig . ACPIDropTables = NULL ;
2019-09-03 11:58:42 +02:00
DBG ( " Get Acpi Tables List " ) ;
if ( Xsdt ) {
UINT32 Count = XsdtTableCount ( ) ;
UINT64 * Ptr = XsdtEntryPtrFromIndex ( 0 ) ;
UINT64 * EndPtr = XsdtEntryPtrFromIndex ( Count ) ;
DBG ( " from XSDT: \n " ) ;
for ( ; Ptr < EndPtr ; Ptr + + ) {
EFI_ACPI_DESCRIPTION_HEADER * Table = ( EFI_ACPI_DESCRIPTION_HEADER * ) ( UINTN ) ReadUnaligned64 ( Ptr ) ;
if ( ! Table ) {
// skip NULL entry
continue ;
}
AddDropTable ( Table , IndexFromXsdtEntryPtr ( Ptr ) ) ;
}
} else if ( Rsdt ) {
DBG ( " from RSDT: \n " ) ;
UINT32 Count = RsdtTableCount ( ) ;
UINT32 * Ptr = RsdtEntryPtrFromIndex ( 0 ) ;
UINT32 * EndPtr = RsdtEntryPtrFromIndex ( Count ) ;
for ( ; Ptr < EndPtr ; Ptr + + ) {
EFI_ACPI_DESCRIPTION_HEADER * Table = ( EFI_ACPI_DESCRIPTION_HEADER * ) ( UINTN ) * Ptr ;
if ( ! Table ) {
// skip NULL entry
continue ;
}
AddDropTable ( Table , IndexFromRsdtEntryPtr ( Ptr ) ) ;
}
} else {
DBG ( " : [!] Error! ACPI not found: \n " ) ;
}
}
void DropTableFromRSDT ( UINT32 Signature , UINT64 TableId , UINT32 Length )
{
if ( ! Rsdt | | ( 0 = = Signature & & 0 = = TableId ) ) {
return ;
}
CHAR8 sign [ 5 ] , OTID [ 9 ] ;
sign [ 4 ] = 0 ;
OTID [ 8 ] = 0 ;
2020-04-28 09:51:58 +02:00
CopyMem ( & sign [ 0 ] , & Signature , 4 ) ;
CopyMem ( & OTID [ 0 ] , & TableId , 8 ) ;
2020-03-25 19:32:44 +01:00
DBG ( " Drop tables from RSDT, SIGN=%s TableID=%s Length=%d \n " , sign , OTID , ( INT32 ) Length ) ;
2019-09-03 11:58:42 +02:00
UINT32 Count = RsdtTableCount ( ) ;
//DBG(" Rsdt has tables count=%d\n", Count);
UINT32 * Ptr = RsdtEntryPtrFromIndex ( 0 ) ;
UINT32 * EndPtr = RsdtEntryPtrFromIndex ( Count ) ;
for ( ; Ptr < EndPtr ; Ptr + + ) {
EFI_ACPI_DESCRIPTION_HEADER * Table = ( EFI_ACPI_DESCRIPTION_HEADER * ) ( UINTN ) * Ptr ;
if ( ! Table ) {
// skip NULL entry
continue ;
}
2020-04-28 09:51:58 +02:00
CopyMem ( & sign [ 0 ] , & Table - > Signature , 4 ) ;
CopyMem ( & OTID [ 0 ] , & Table - > OemTableId , 8 ) ;
2020-03-25 19:32:44 +01:00
//DBG(" Found table: %s %s\n", sign, OTID);
2019-09-03 11:58:42 +02:00
if ( ! ( ( Signature & & Table - > Signature = = Signature ) & &
( ! TableId | | Table - > OemTableId = = TableId ) & &
( ! Length | | Table - > Length = = Length ) ) ) {
continue ;
}
if ( IsXsdtEntryMerged ( IndexFromXsdtEntryPtr ( Ptr ) ) ) {
2020-03-25 19:32:44 +01:00
DBG ( " attempt to drop already merged table[%d]: %s %s %d ignored \n " , IndexFromXsdtEntryPtr ( Ptr ) , sign , OTID , ( INT32 ) Table - > Length ) ;
2019-09-03 11:58:42 +02:00
continue ;
}
// drop matching table by simply replacing entry with NULL
* Ptr = 0 ;
2020-03-25 19:32:44 +01:00
DBG ( " Table[%d]: %s %s %d dropped \n " , IndexFromXsdtEntryPtr ( Ptr ) , sign , OTID , ( INT32 ) Table - > Length ) ;
2019-09-03 11:58:42 +02:00
}
}
void DropTableFromXSDT ( UINT32 Signature , UINT64 TableId , UINT32 Length )
{
if ( ! Xsdt | | ( 0 = = Signature & & 0 = = TableId ) ) {
return ;
}
CHAR8 sign [ 5 ] , OTID [ 9 ] ;
sign [ 4 ] = 0 ;
OTID [ 8 ] = 0 ;
2020-04-28 09:51:58 +02:00
CopyMem ( & sign [ 0 ] , & Signature , 4 ) ;
CopyMem ( & OTID [ 0 ] , & TableId , 8 ) ;
2020-03-25 19:32:44 +01:00
DBG ( " Drop tables from XSDT, SIGN=%s TableID=%s Length=%d \n " , sign , OTID , ( INT32 ) Length ) ;
2019-09-03 11:58:42 +02:00
UINT32 Count = XsdtTableCount ( ) ;
//DBG(" Xsdt has tables count=%d\n", Count);
UINT64 * Ptr = XsdtEntryPtrFromIndex ( 0 ) ;
UINT64 * EndPtr = XsdtEntryPtrFromIndex ( Count ) ;
for ( ; Ptr < EndPtr ; Ptr + + ) {
EFI_ACPI_DESCRIPTION_HEADER * Table = ( EFI_ACPI_DESCRIPTION_HEADER * ) ( UINTN ) ReadUnaligned64 ( Ptr ) ;
if ( ! Table ) {
// skip NULL entry
continue ;
}
2020-04-28 09:51:58 +02:00
CopyMem ( & sign [ 0 ] , & Table - > Signature , 4 ) ;
CopyMem ( & OTID [ 0 ] , & Table - > OemTableId , 8 ) ;
2020-03-25 19:32:44 +01:00
//DBG(" Found table: %s %s\n", sign, OTID);
2019-09-03 11:58:42 +02:00
if ( ! ( ( Signature & & Table - > Signature = = Signature ) & &
( ! TableId | | Table - > OemTableId = = TableId ) & &
( ! Length | | Table - > Length = = Length ) ) ) {
continue ;
}
if ( IsXsdtEntryMerged ( IndexFromXsdtEntryPtr ( Ptr ) ) ) {
2020-03-25 19:32:44 +01:00
DBG ( " attempt to drop already merged table[%d]: %s %s %d ignored \n " , IndexFromXsdtEntryPtr ( Ptr ) , sign , OTID , ( INT32 ) Table - > Length ) ;
2019-09-03 11:58:42 +02:00
continue ;
}
// drop matching table by simply replacing entry with NULL
WriteUnaligned64 ( Ptr , 0 ) ;
2020-03-25 19:32:44 +01:00
DBG ( " Table[%d]: %s %s %d dropped \n " , IndexFromXsdtEntryPtr ( Ptr ) , sign , OTID , ( INT32 ) Table - > Length ) ;
2019-09-03 11:58:42 +02:00
}
}
// by cecekpawon, edited by Slice, further edits by RehabMan
2021-09-28 10:28:45 +02:00
XBool FixAsciiTableHeader ( UINT8 * Str , UINTN Len )
2019-09-03 11:58:42 +02:00
{
2021-09-28 10:28:45 +02:00
XBool NonAscii = false ;
2019-09-03 11:58:42 +02:00
UINT8 * StrEnd = Str + Len ;
for ( ; Str < StrEnd ; Str + + ) {
if ( ! * Str ) continue ; // NUL is allowed
if ( * Str < ' ' ) {
* Str = ' ' ;
2021-09-28 10:28:45 +02:00
NonAscii = true ;
2019-09-03 11:58:42 +02:00
}
else if ( * Str > 0x7e ) {
* Str = ' _ ' ;
2021-09-28 10:28:45 +02:00
NonAscii = true ;
2019-09-03 11:58:42 +02:00
}
}
return NonAscii ;
}
2021-09-28 10:28:45 +02:00
XBool PatchTableHeader ( EFI_ACPI_DESCRIPTION_HEADER * Header )
2019-09-03 11:58:42 +02:00
{
2021-09-28 10:28:45 +02:00
XBool Ret1 , Ret2 , Ret3 ;
2021-05-19 14:11:21 +02:00
if ( ! gSettings . ACPI . FixHeaders ) {
2021-09-28 10:28:45 +02:00
return false ;
2019-09-03 11:58:42 +02:00
}
Ret1 = FixAsciiTableHeader ( ( UINT8 * ) & Header - > CreatorId , 4 ) ;
Ret2 = FixAsciiTableHeader ( ( UINT8 * ) & Header - > OemTableId , 8 ) ;
Ret3 = FixAsciiTableHeader ( ( UINT8 * ) & Header - > OemId , 6 ) ;
return ( Ret1 | | Ret2 | | Ret3 ) ;
}
2020-10-03 19:02:31 +02:00
void PatchAllTables ( )
2019-09-03 11:58:42 +02:00
{
UINT32 Count = XsdtTableCount ( ) ;
UINT64 * Ptr = XsdtEntryPtrFromIndex ( 0 ) ;
UINT64 * EndPtr = XsdtEntryPtrFromIndex ( Count ) ;
for ( ; Ptr < EndPtr ; Ptr + + ) {
2021-09-28 10:28:45 +02:00
XBool Patched = false ;
2019-09-03 11:58:42 +02:00
EFI_ACPI_DESCRIPTION_HEADER * Table = ( EFI_ACPI_DESCRIPTION_HEADER * ) ( UINTN ) ReadUnaligned64 ( Ptr ) ;
if ( ! Table ) {
// skip NULL entry
continue ;
}
if ( EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE = = Table - > Signature ) {
// may be also EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE?
continue ; // will be patched elsewhere
}
//do new table with patched header
UINT32 Len = Table - > Length ;
EFI_PHYSICAL_ADDRESS BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS ;
EFI_STATUS Status = gBS - > AllocatePages ( AllocateMaxAddress ,
EfiACPIReclaimMemory ,
EFI_SIZE_TO_PAGES ( Len + 4096 ) ,
& BufferPtr ) ;
if ( EFI_ERROR ( Status ) ) {
//DBG(" ... not patched\n");
continue ;
}
EFI_ACPI_DESCRIPTION_HEADER * NewTable = ( EFI_ACPI_DESCRIPTION_HEADER * ) ( UINTN ) BufferPtr ;
CopyMem ( NewTable , Table , Len ) ;
2021-05-19 14:11:21 +02:00
if ( gSettings . ACPI . FixHeaders ) {
2019-09-03 11:58:42 +02:00
// Merged tables already have the header patched, so no need to do it again
if ( ! IsXsdtEntryMerged ( IndexFromXsdtEntryPtr ( Ptr ) ) ) {
// table header NOT already patched
Patched = PatchTableHeader ( NewTable ) ;
}
}
if ( NewTable - > Signature = = EFI_ACPI_4_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE ) {
2021-02-11 12:41:59 +01:00
if ( gSettings . ACPI . DSDT . DSDTPatchArray . size ( ) > 0 ) {
DBG ( " Patching SSDTs: %zu patches each \n " , gSettings . ACPI . DSDT . DSDTPatchArray . size ( ) ) ;
2020-08-06 20:53:01 +02:00
// CHAR8 OTID[9];
// OTID[8] = 0;
// CopyMem(OTID, &NewTable->OemTableId, 8);
// DBG("Patching SSDT %s Length=%d\n", OTID, (INT32)Len);
2021-02-11 12:41:59 +01:00
for ( UINT32 i = 0 ; i < gSettings . ACPI . DSDT . DSDTPatchArray . size ( ) ; i + + ) {
if ( gSettings . ACPI . DSDT . DSDTPatchArray [ i ] . PatchDsdtFind . isEmpty ( ) ) {
2019-09-03 11:58:42 +02:00
continue ;
}
2020-08-06 20:53:01 +02:00
// DBG("%d. [%s]:", i, gSettings.PatchDsdtLabel[i]);
2021-02-11 12:41:59 +01:00
if ( ! gSettings . ACPI . DSDT . DSDTPatchArray [ i ] . PatchDsdtMenuItem . BValue ) {
2020-08-06 20:53:01 +02:00
// DBG(" disabled\n");
2019-09-03 11:58:42 +02:00
continue ;
}
2021-02-11 12:41:59 +01:00
if ( gSettings . ACPI . DSDT . DSDTPatchArray [ i ] . PatchDsdtTgt . isEmpty ( ) ) {
2020-06-30 14:56:16 +02:00
Len = FixAny ( ( UINT8 * ) NewTable , Len ,
2021-02-11 12:41:59 +01:00
gSettings . ACPI . DSDT . DSDTPatchArray [ i ] . PatchDsdtFind ,
gSettings . ACPI . DSDT . DSDTPatchArray [ i ] . PatchDsdtReplace ) ;
2020-06-30 14:56:16 +02:00
//DBG(" OK\n");
} else {
//DBG("Patching: renaming in bridge\n");
2021-02-11 12:41:59 +01:00
Len = FixRenameByBridge2 ( ( UINT8 * ) NewTable , Len , gSettings . ACPI . DSDT . DSDTPatchArray [ i ] . PatchDsdtTgt , gSettings . ACPI . DSDT . DSDTPatchArray [ i ] . PatchDsdtFind , gSettings . ACPI . DSDT . DSDTPatchArray [ i ] . PatchDsdtReplace ) ;
2020-06-30 14:56:16 +02:00
}
2019-09-03 11:58:42 +02:00
}
}
// fixup length and checksum
NewTable - > Length = Len ;
RenameDevices ( ( UINT8 * ) NewTable ) ;
GetBiosRegions ( ( UINT8 * ) NewTable ) ; //take Regions from SSDT even if they will be dropped
2021-09-28 10:28:45 +02:00
Patched = true ;
2019-09-03 11:58:42 +02:00
}
2021-02-11 12:41:59 +01:00
if ( NewTable - > Signature = = MCFG_SIGN & & gSettings . ACPI . FixMCFG ) {
2019-09-03 11:58:42 +02:00
INTN Len1 = ( ( Len + 4 - 1 ) / 16 + 1 ) * 16 - 4 ;
CopyMem ( NewTable , Table , Len1 ) ; //Len increased but less than EFI_PAGE
2021-09-28 10:28:45 +02:00
NewTable - > Length = ( UINT32 ) ( UINTN ) Len1 ; Patched = true ;
2019-09-03 11:58:42 +02:00
}
if ( Patched ) {
WriteUnaligned64 ( Ptr , BufferPtr ) ;
FixChecksum ( NewTable ) ;
}
else {
gBS - > FreePages ( BufferPtr , EFI_SIZE_TO_PAGES ( Len + 4096 ) ) ;
}
}
}
2020-10-03 19:02:31 +02:00
EFI_STATUS InsertTable ( void * TableEntry , UINTN Length )
2019-09-03 11:58:42 +02:00
{
if ( ! TableEntry ) {
return EFI_NOT_FOUND ;
}
EFI_PHYSICAL_ADDRESS BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS ;
EFI_STATUS Status = gBS - > AllocatePages (
AllocateMaxAddress ,
EfiACPIReclaimMemory ,
EFI_SIZE_TO_PAGES ( Length ) ,
& BufferPtr
) ;
//if success insert table pointer into ACPI tables
if ( ! EFI_ERROR ( Status ) ) {
// DBG("page is allocated, write SSDT into\n");
EFI_ACPI_DESCRIPTION_HEADER * TableHeader = ( EFI_ACPI_DESCRIPTION_HEADER * ) ( UINTN ) BufferPtr ;
CopyMem ( TableHeader , TableEntry , Length ) ;
// Now is a good time to fix the table header and checksum
PatchTableHeader ( TableHeader ) ;
FixChecksum ( TableHeader ) ;
//insert into RSDT
if ( Rsdt ) {
UINT32 * Ptr = RsdtEntryPtrFromIndex ( RsdtTableCount ( ) ) ;
* Ptr = ( UINT32 ) ( UINTN ) BufferPtr ;
Rsdt - > Header . Length + = sizeof ( UINT32 ) ;
//DBG("Rsdt->Length = %d\n", Rsdt->Header.Length);
}
//insert into XSDT
if ( Xsdt ) {
UINT64 * Ptr = XsdtEntryPtrFromIndex ( XsdtTableCount ( ) ) ;
WriteUnaligned64 ( Ptr , BufferPtr ) ;
Xsdt - > Header . Length + = sizeof ( UINT64 ) ;
//DBG("Xsdt->Length = %d\n", Xsdt->Header.Length);
}
}
return Status ;
}
2020-08-09 17:55:30 +02:00
UINTN IndexFromFileName ( CONST CHAR16 * FileName )
2019-09-03 11:58:42 +02:00
{
// FileName must be as "XXXX-number-..." or "XXXX-number.aml", such as "SSDT-9.aml", or "SSDT-11-SaSsdt.aml"
// But just checking for '-' or '.' following the number.
// search for '-'
UINTN Result = IGNORE_INDEX ;
2020-08-09 17:55:30 +02:00
CONST CHAR16 * temp = FileName ;
2019-09-03 11:58:42 +02:00
for ( ; * temp ! = 0 & & * temp ! = ' - ' ; temp + + ) ;
if ( ' - ' = = * temp & & 4 = = temp - FileName ) {
+ + temp ;
if ( * temp > = ' 0 ' & & * temp < = ' 9 ' ) {
Result = 0 ;
for ( ; * temp > = ' 0 ' & & * temp < = ' 9 ' ; temp + + ) {
Result * = 10 ;
Result + = * temp - ' 0 ' ;
}
// a FileName such as "SSDT-4x30s.aml" is not considered as "SSDT-4.aml"
if ( ' . ' ! = * temp & & ' - ' ! = * temp )
Result = IGNORE_INDEX ;
}
}
return Result ;
}
2020-10-03 19:02:31 +02:00
EFI_STATUS ReplaceOrInsertTable ( void * TableEntry , UINTN Length , UINTN MatchIndex , INTN Pass )
2019-09-03 11:58:42 +02:00
{
if ( ! TableEntry ) {
return EFI_NOT_FOUND ;
}
EFI_PHYSICAL_ADDRESS BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS ;
EFI_STATUS Status = gBS - > AllocatePages (
AllocateMaxAddress ,
EfiACPIReclaimMemory ,
EFI_SIZE_TO_PAGES ( Length ) ,
& BufferPtr
) ;
EFI_ACPI_DESCRIPTION_HEADER * hdr = ( EFI_ACPI_DESCRIPTION_HEADER * ) TableEntry ;
//if success insert or replace table pointer into ACPI tables
if ( ! EFI_ERROR ( Status ) ) {
Status = EFI_ABORTED ;
//DBG("page is allocated, write SSDT into\n");
EFI_ACPI_DESCRIPTION_HEADER * TableHeader = ( EFI_ACPI_DESCRIPTION_HEADER * ) ( UINTN ) BufferPtr ;
CopyMem ( TableHeader , TableEntry , Length ) ;
#if 0 //REVIEW: seems as if Rsdt is always NULL for ReplaceOrInsertTable scenarios (macOS/OS X)
//insert/modify into RSDT
if ( Rsdt ) {
UINT32 * Ptr = NULL ;
if ( hdr - > Signature ! = EFI_ACPI_4_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE | | MatchIndex ! = IGNORE_INDEX ) {
// SSDT with target index or non-SSDT, try to find matching entry
Ptr = ScanRSDT2 ( hdr - > Signature , hdr - > OemTableId , MatchIndex ) ;
}
if ( Ptr ) {
* Ptr = ( UINT32 ) ( UINTN ) BufferPtr ;
Status = EFI_SUCCESS ;
} else if ( AUTOMERGE_PASS2 = = Pass ) {
Ptr = RsdtEntryPtrFromIndex ( RsdtTableCount ( ) ) ;
* Ptr = ( UINT32 ) ( UINTN ) BufferPtr ;
Rsdt - > Header . Length + = sizeof ( UINT32 ) ;
//DBG("Rsdt->Length = %d\n", Rsdt->Header.Length);
Status = EFI_SUCCESS ;
}
}
# endif
//insert/modify into XSDT
if ( Xsdt ) {
UINT64 * Ptr = NULL ;
if ( hdr - > Signature ! = EFI_ACPI_4_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE | | MatchIndex ! = IGNORE_INDEX ) {
// SSDT with target index or non-SSDT, try to find matching entry
Ptr = ScanXSDT2 ( hdr - > Signature , hdr - > OemTableId , MatchIndex ) ;
}
// Now is a good time to fix the table header and checksum (*MUST* be done after matching)
PatchTableHeader ( TableHeader ) ;
FixChecksum ( TableHeader ) ;
if ( Ptr ) {
UINT32 Index = IndexFromXsdtEntryPtr ( Ptr ) ;
2020-03-25 19:32:44 +01:00
DBG ( " @%llu " , ( UINT64 ) Index ) ;
2019-09-03 11:58:42 +02:00
// keep track of new table size in case it needs to be freed later
SaveMergedXsdtEntrySize ( Index , Length ) ;
WriteUnaligned64 ( Ptr , BufferPtr ) ;
Status = EFI_SUCCESS ;
} else if ( AUTOMERGE_PASS2 = = Pass ) {
Ptr = XsdtEntryPtrFromIndex ( XsdtTableCount ( ) ) ;
WriteUnaligned64 ( Ptr , BufferPtr ) ;
Xsdt - > Header . Length + = sizeof ( UINT64 ) ;
//DBG("Xsdt->Length = %d\n", Xsdt->Header.Length);
Status = EFI_SUCCESS ;
}
}
}
return Status ;
}
void PreCleanupRSDT ( )
{
if ( ! Rsdt ) {
return ;
}
//REVIEW: really?
// Если адрес RSDT < адреса XSDT и хвост RSDT наползает на XSDT, то подрезаем хвост RSDT до начала XSDT
// English: If the RSDT address of the XSDT address and the tail of the RSDT crawls onto the XSDT, then we
// trim the RSDT tail before the XSDT starts
if ( ( UINTN ) Rsdt < ( UINTN ) Xsdt & & ( UINTN ) Rsdt + Rsdt - > Header . Length > ( UINTN ) Xsdt ) {
2020-03-11 15:23:58 +01:00
UINTN v = ( ( UINTN ) Xsdt - ( UINTN ) Rsdt ) & ~ 3 ;
2021-02-21 14:49:09 +01:00
// if ( v > MAX_UINT32 ) panic("((UINTN)Xsdt - (UINTN)Rsdt) & ~3 > MAX_UINT32");
2020-03-11 15:23:58 +01:00
Rsdt - > Header . Length = ( UINT32 ) v ;
2019-09-03 11:58:42 +02:00
DBG ( " Cropped Rsdt->Header.Length=%d \n " , ( UINT32 ) Rsdt - > Header . Length ) ;
}
//REVIEW: why?
// terminate RSDT table at first double zero, if present
UINT32 Count = RsdtTableCount ( ) ;
if ( Count < = 2 ) {
return ;
}
DBG ( " PreCleanup RSDT: count=%d, length=%d \n " , Count , ( UINT32 ) Rsdt - > Header . Length ) ;
UINT32 * Ptr = RsdtEntryPtrFromIndex ( 0 ) ;
UINT32 * EndPtr = RsdtEntryPtrFromIndex ( Count - 1 ) ;
for ( ; Ptr < EndPtr ; Ptr + + ) {
if ( 0 = = Ptr [ 0 ] & & 0 = = Ptr [ 1 ] ) {
// double zero found, terminate RSDT entry table here
DBG ( " DoubleZero in RSDT table \n " ) ;
Rsdt - > Header . Length = ( UINT32 ) ( ( CHAR8 * ) Ptr - ( CHAR8 * ) Rsdt ) ;
break ;
}
}
DBG ( " PreCleanup RSDT, corrected RSDT: count=%d, length=%d \n " , Count , ( UINT32 ) Rsdt - > Header . Length ) ;
}
void PostCleanupRSDT ( )
{
if ( ! Rsdt ) {
return ;
}
// remove NULL entries from RSDT table
UINT32 Count = RsdtTableCount ( ) ;
DBG ( " Cleanup RSDT: count=%d, length=%d \n " , Count , ( UINT32 ) Rsdt - > Header . Length ) ;
UINT32 * Source = RsdtEntryPtrFromIndex ( 0 ) ;
UINT32 * Dest = Source ;
UINT32 * EndPtr = RsdtEntryPtrFromIndex ( Count ) ;
while ( Source < EndPtr ) {
if ( 0 = = * Source ) {
// skip NULL entry
Source + + ;
continue ;
}
* Dest + + = * Source + + ;
}
// fix header length
Rsdt - > Header . Length = ( UINT32 ) ( ( CHAR8 * ) Dest - ( CHAR8 * ) Rsdt ) ;
Count = RsdtTableCount ( ) ;
DBG ( " corrected RSDT: count=%d, length=%d \n " , Count , ( UINT32 ) Rsdt - > Header . Length ) ;
FixChecksum ( & Rsdt - > Header ) ;
}
void PreCleanupXSDT ( )
{
UINT64 * Ptr , * EndPtr ;
if ( ! Xsdt ) {
return ;
}
//REVIEW: why?
// terminate RSDT table at first double zero, if present
UINT32 Count = XsdtTableCount ( ) ;
if ( Count < = 2 ) {
return ;
}
DBG ( " PreCleanup XSDT: count=%d, length=%d \n " , Count , ( UINT32 ) Xsdt - > Header . Length ) ;
Ptr = XsdtEntryPtrFromIndex ( 0 ) ;
EndPtr = XsdtEntryPtrFromIndex ( Count - 1 ) ;
for ( ; Ptr < EndPtr ; Ptr + + ) {
if ( 0 = = ReadUnaligned64 ( Ptr + 0 ) & & 0 = = ReadUnaligned64 ( Ptr + 1 ) ) {
// double zero found, terminate XSDT entry table here
DBG ( " DoubleZero in XSDT table \n " ) ;
Xsdt - > Header . Length = ( UINT32 ) ( ( CHAR8 * ) Ptr - ( CHAR8 * ) Xsdt ) ;
break ;
}
}
DBG ( " PreCleanup XSDT, corrected XSDT: count=%d, length=%d \n " , Count , ( UINT32 ) Xsdt - > Header . Length ) ;
}
void PostCleanupXSDT ( )
{
UINT64 * Dest , * EndPtr , * Source ;
if ( ! Xsdt ) {
return ;
}
// remove NULL entries from XSDT table
UINT32 Count = XsdtTableCount ( ) ;
DBG ( " Cleanup XSDT: count=%d, length=%d \n " , Count , ( UINT32 ) Xsdt - > Header . Length ) ;
Source = XsdtEntryPtrFromIndex ( 0 ) ;
Dest = Source ;
EndPtr = XsdtEntryPtrFromIndex ( Count ) ;
while ( Source < EndPtr ) {
if ( 0 = = * Source ) {
// skip NULL entry
Source + + ;
continue ;
}
WriteUnaligned64 ( Dest + + , ReadUnaligned64 ( Source + + ) ) ;
}
// fix header length
Xsdt - > Header . Length = ( UINT32 ) ( ( CHAR8 * ) Dest - ( CHAR8 * ) Xsdt ) ;
Count = XsdtTableCount ( ) ;
DBG ( " corrected XSDT count=%d, length=%d \n " , Count , ( UINT32 ) Xsdt - > Header . Length ) ;
FixChecksum ( & Xsdt - > Header ) ;
}
2020-10-03 19:02:31 +02:00
/** Saves Buffer of Length to disk as OemDir\\DirName\\FileName. */
EFI_STATUS SaveBufferToDisk ( void * Buffer , UINTN Length , CONST CHAR16 * DirName , CONST CHAR16 * FileName )
2019-09-03 11:58:42 +02:00
{
if ( DirName = = NULL | | FileName = = NULL ) {
return EFI_INVALID_PARAMETER ;
}
2020-08-09 17:55:30 +02:00
XStringW PathName = SWPrintf ( " %ls \\ %ls " , DirName , FileName ) ;
2019-09-03 11:58:42 +02:00
2020-10-17 15:01:33 +02:00
EFI_STATUS Status = egSaveFile ( & selfOem . getConfigDir ( ) , PathName . wc_str ( ) , Buffer , Length ) ;
2020-10-03 19:02:31 +02:00
// Do not write outside OemDir
// if (EFI_ERROR(Status)) {
// Status = egSaveFile(NULL, PathName.wc_str(), Buffer, Length);
// }
2019-09-03 11:58:42 +02:00
return Status ;
}
//
// Remembering saved tables
//
# define SAVED_TABLES_ALLOC_ENTRIES 64
2020-10-03 19:02:31 +02:00
void * * mSavedTables = NULL ;
2019-09-03 11:58:42 +02:00
UINTN mSavedTablesEntries = 0 ;
UINTN mSavedTablesNum = 0 ;
2021-09-28 10:28:45 +02:00
/** Returns true is TableEntry is already saved. */
XBool IsTableSaved ( void * TableEntry )
2019-09-03 11:58:42 +02:00
{
UINTN Index ;
if ( mSavedTables ! = NULL ) {
for ( Index = 0 ; Index < mSavedTablesNum ; Index + + ) {
if ( mSavedTables [ Index ] = = TableEntry ) {
2021-09-28 10:28:45 +02:00
return true ;
2019-09-03 11:58:42 +02:00
}
}
}
2021-09-28 10:28:45 +02:00
return false ;
2019-09-03 11:58:42 +02:00
}
/** Adds TableEntry to mSavedTables if not already there. */
2020-10-03 19:02:31 +02:00
void MarkTableAsSaved ( void * TableEntry )
2019-09-03 11:58:42 +02:00
{
//
// If mSavedTables does not exists yet - allocate it
//
if ( mSavedTables = = NULL ) {
//DBG(" Allocaing mSavedTables");
mSavedTablesEntries = SAVED_TABLES_ALLOC_ENTRIES ;
mSavedTablesNum = 0 ;
2020-08-15 15:47:56 +02:00
mSavedTables = ( __typeof__ ( mSavedTables ) ) AllocateZeroPool ( sizeof ( * mSavedTables ) * mSavedTablesEntries ) ;
2019-09-03 11:58:42 +02:00
if ( mSavedTables = = NULL ) {
return ;
}
}
//
// If TableEntry is not in mSavedTables - add it
//
2020-10-10 15:31:14 +02:00
//DBG(" MarkTableAsSaved %llx", TableEntry);
2019-09-03 11:58:42 +02:00
if ( IsTableSaved ( TableEntry ) ) {
// already saved
//DBG(" - already saved\n");
return ;
}
//
// If mSavedTables is full - extend it
//
if ( mSavedTablesNum + 1 > = mSavedTablesEntries ) {
// not enough space
//DBG(" - extending mSavedTables from %d", mSavedTablesEntries);
2019-12-21 01:31:49 +01:00
mSavedTables = ( __typeof__ ( mSavedTables ) ) ReallocatePool (
2019-09-03 11:58:42 +02:00
sizeof ( * mSavedTables ) * mSavedTablesEntries ,
sizeof ( * mSavedTables ) * ( mSavedTablesEntries + SAVED_TABLES_ALLOC_ENTRIES ) ,
mSavedTables
) ;
if ( mSavedTables = = NULL ) {
return ;
}
mSavedTablesEntries = mSavedTablesEntries + SAVED_TABLES_ALLOC_ENTRIES ;
//DBG(" to %d", mSavedTablesEntries);
}
//
// Add TableEntry to mSavedTables
//
mSavedTables [ mSavedTablesNum ] = TableEntry ;
//DBG(" - added to index %d\n", mSavedTablesNum);
mSavedTablesNum + + ;
}
# define AML_OP_NAME 0x08
# define AML_OP_PACKAGE 0x12
STATIC CHAR8 NameSSDT [ ] = { AML_OP_NAME , ' S ' , ' S ' , ' D ' , ' T ' , AML_OP_PACKAGE } ;
STATIC CHAR8 NameCSDT [ ] = { AML_OP_NAME , ' C ' , ' S ' , ' D ' , ' T ' , AML_OP_PACKAGE } ;
STATIC CHAR8 NameTSDT [ ] = { AML_OP_NAME , ' T ' , ' S ' , ' D ' , ' T ' , AML_OP_PACKAGE } ;
// OperationRegion (SSDT, SystemMemory, 0xDF5DAC18, 0x038C)
STATIC UINT8 NameSSDT2 [ ] = { 0x80 , 0x53 , 0x53 , 0x44 , 0x54 } ;
// OperationRegion (CSDT, SystemMemory, 0xDF5DBE18, 0x84)
STATIC UINT8 NameCSDT2 [ ] = { 0x80 , 0x43 , 0x53 , 0x44 , 0x54 } ;
//UINT32 get_size(UINT8 * An, UINT32 ); // Let borrow from FixBiosDsdt.
2020-08-09 17:55:30 +02:00
static XStringW GenerateFileName ( CONST CHAR16 * FileNamePrefix , UINTN SsdtCount , UINTN ChildCount , CHAR8 OemTableId [ 9 ] )
2019-09-03 11:58:42 +02:00
// ChildCount == IGNORE_INDEX indicates normal SSDT
// SsdtCount == IGNORE_INDEX indicates dynamic SSDT in DSDT
// otherwise is child SSDT from normal SSDT
{
2020-08-09 17:55:30 +02:00
XStringW FileName ;
2019-09-03 11:58:42 +02:00
CHAR8 Suffix [ 10 ] ; // "-" + OemTableId + NUL
2021-02-11 12:41:59 +01:00
if ( gSettings . ACPI . SSDT . NoOemTableId | | 0 = = OemTableId [ 0 ] ) {
2019-09-03 11:58:42 +02:00
Suffix [ 0 ] = 0 ;
} else {
Suffix [ 0 ] = ' - ' ;
CopyMem ( Suffix + 1 , OemTableId , 9 ) ;
}
if ( IGNORE_INDEX = = ChildCount ) {
// normal SSDT
2020-08-09 17:55:30 +02:00
FileName = SWPrintf ( " %lsSSDT-%llu%s.aml " , FileNamePrefix , SsdtCount , Suffix ) ;
2019-09-03 11:58:42 +02:00
} else if ( IGNORE_INDEX = = SsdtCount ) {
// dynamic SSDT in DSDT
2020-08-09 17:55:30 +02:00
FileName = SWPrintf ( " %lsSSDT-xDSDT_%llu%s.aml " , FileNamePrefix , ChildCount , Suffix ) ;
2019-09-03 11:58:42 +02:00
} else {
// dynamic SSDT in static SSDT
2020-08-09 17:55:30 +02:00
FileName = SWPrintf ( " %lsSSDT-x%llu_%llu%s.aml " , FileNamePrefix , SsdtCount , ChildCount , Suffix ) ;
2019-09-03 11:58:42 +02:00
}
return FileName ;
}
2020-10-03 19:02:31 +02:00
void DumpChildSsdt ( EFI_ACPI_DESCRIPTION_HEADER * TableEntry , CONST CHAR16 * DirName , CONST CHAR16 * FileNamePrefix , UINTN SsdtCount )
2019-09-03 11:58:42 +02:00
{
EFI_STATUS Status = EFI_SUCCESS ;
INTN j , k , pacLen , pacCount ;
CHAR8 Signature [ 5 ] ;
CHAR8 OemTableId [ 9 ] ;
UINTN adr , len ;
UINT8 * Entry ;
UINT8 * End ;
UINT8 * pacBody ;
INTN ChildCount = 0 ;
2021-02-11 12:41:59 +01:00
if ( gSettings . ACPI . SSDT . NoDynamicExtract ) {
2019-09-03 11:58:42 +02:00
return ;
}
Entry = ( UINT8 * ) TableEntry ; //first entry is parent SSDT
End = Entry + TableEntry - > Length ;
while ( Entry < End ) {
if ( ( CompareMem ( Entry , NameSSDT , sizeof ( NameSSDT ) ) = = 0 ) | |
( CompareMem ( Entry , NameCSDT , sizeof ( NameCSDT ) ) = = 0 ) | |
( CompareMem ( Entry , NameTSDT , sizeof ( NameTSDT ) ) = = 0 ) ) {
pacLen = get_size ( Entry , sizeof ( NameSSDT ) ) ;
pacBody = Entry + sizeof ( NameSSDT ) + ( pacLen > 63 ? 2 : 1 ) ; // Our packages are not huge
pacCount = * pacBody + + ;
if ( pacCount > 0 & & pacCount % 3 = = 0 ) {
pacCount / = 3 ;
2021-09-01 18:38:35 +02:00
DBG ( " (Found hidden SSDT %lld pcs) \n " , pacCount ) ;
2019-09-03 11:58:42 +02:00
while ( pacCount - - > 0 ) {
// Skip text marker and addr type tag
pacBody + = 1 + 8 + 1 + 1 ;
adr = ReadUnaligned32 ( ( UINT32 * ) ( pacBody ) ) ;
len = 0 ;
pacBody + = 4 ;
if ( * pacBody = = AML_CHUNK_DWORD ) {
len = ReadUnaligned32 ( ( UINT32 * ) ( pacBody + 1 ) ) ;
pacBody + = 5 ;
} else if ( * pacBody = = AML_CHUNK_WORD ) {
len = ReadUnaligned16 ( ( UINT16 * ) ( pacBody + 1 ) ) ;
pacBody + = 3 ;
}
// Take Signature and OemId for printing
2020-04-28 09:51:58 +02:00
CopyMem ( & Signature [ 0 ] , & ( ( EFI_ACPI_DESCRIPTION_HEADER * ) adr ) - > Signature , 4 ) ;
2019-09-03 11:58:42 +02:00
Signature [ 4 ] = 0 ;
2020-04-28 09:51:58 +02:00
CopyMem ( & OemTableId [ 0 ] , & ( ( EFI_ACPI_DESCRIPTION_HEADER * ) adr ) - > OemTableId , 8 ) ;
2019-09-03 11:58:42 +02:00
OemTableId [ 8 ] = 0 ;
stripTrailingSpaces ( OemTableId ) ;
2021-09-01 18:38:35 +02:00
int innLen = ( ( EFI_ACPI_DESCRIPTION_HEADER * ) adr ) - > Length ;
if ( innLen < 0 | | innLen > 0x20000 ) break ;
DBG ( " * %llu: '%s', '%s', Rev: %d, Len: %d " , adr , Signature , OemTableId ,
( ( EFI_ACPI_DESCRIPTION_HEADER * ) adr ) - > Revision , innLen ) ;
2019-09-03 11:58:42 +02:00
for ( k = 0 ; k < 16 ; k + + ) {
2020-04-17 15:14:24 +02:00
DBG ( " %02hhX " , ( ( UINT8 * ) adr ) [ k ] ) ;
2019-09-03 11:58:42 +02:00
}
2020-10-03 19:02:31 +02:00
if ( ( AsciiStrCmp ( Signature , " SSDT " ) = = 0 ) & & ( len < 0x20000 ) & & DirName ! = NULL & & ! IsTableSaved ( ( void * ) adr ) ) {
2020-08-09 17:55:30 +02:00
XStringW FileName = GenerateFileName ( FileNamePrefix , SsdtCount , ChildCount , OemTableId ) ;
2019-09-03 11:58:42 +02:00
len = ( ( UINT16 * ) adr ) [ 2 ] ;
2020-08-09 17:55:30 +02:00
DBG ( " Internal length = %llu " , len ) ;
2020-10-03 19:02:31 +02:00
Status = SaveBufferToDisk ( ( void * ) adr , len , DirName , FileName . wc_str ( ) ) ;
2019-09-03 11:58:42 +02:00
if ( ! EFI_ERROR ( Status ) ) {
2020-08-09 17:55:30 +02:00
DBG ( " -> %ls " , FileName . wc_str ( ) ) ;
2020-10-03 19:02:31 +02:00
MarkTableAsSaved ( ( void * ) adr ) ;
2019-09-03 11:58:42 +02:00
ChildCount + + ;
} else {
2020-08-25 17:35:19 +02:00
DBG ( " -> %s " , efiStrError ( Status ) ) ;
2019-09-03 11:58:42 +02:00
}
}
DBG ( " \n " ) ;
}
}
Entry + = sizeof ( NameSSDT ) + pacLen ;
} else if ( CompareMem ( Entry , NameSSDT2 , 5 ) = = 0 | |
CompareMem ( Entry , NameCSDT2 , 5 ) = = 0 ) {
adr = ReadUnaligned32 ( ( UINT32 * ) ( Entry + 7 ) ) ;
len = 0 ;
j = * ( Entry + 11 ) ;
if ( j = = 0x0b ) {
len = ReadUnaligned16 ( ( UINT16 * ) ( Entry + 12 ) ) ;
} else if ( j = = 0x0a ) {
len = * ( Entry + 12 ) ;
} else {
//not a number so skip for security
Entry + = 5 ;
continue ;
}
if ( len > 0 ) {
// Take Signature and OemId for printing
CopyMem ( & Signature , & ( ( EFI_ACPI_DESCRIPTION_HEADER * ) adr ) - > Signature , 4 ) ;
Signature [ 4 ] = 0 ;
CopyMem ( & OemTableId , & ( ( EFI_ACPI_DESCRIPTION_HEADER * ) adr ) - > OemTableId , 8 ) ;
OemTableId [ 8 ] = 0 ;
stripTrailingSpaces ( OemTableId ) ;
2020-03-25 19:32:44 +01:00
DBG ( " * %llu: '%s', '%s', Rev: %d, Len: %d " , adr , Signature , OemTableId ,
2019-09-03 11:58:42 +02:00
( ( EFI_ACPI_DESCRIPTION_HEADER * ) adr ) - > Revision , ( ( EFI_ACPI_DESCRIPTION_HEADER * ) adr ) - > Length ) ;
for ( k = 0 ; k < 16 ; k + + ) {
2020-04-17 15:14:24 +02:00
DBG ( " %02hhX " , ( ( UINT8 * ) adr ) [ k ] ) ;
2019-09-03 11:58:42 +02:00
}
2020-10-03 19:02:31 +02:00
if ( ( AsciiStrCmp ( Signature , " SSDT " ) = = 0 ) & & ( len < 0x20000 ) & & DirName ! = NULL & & ! IsTableSaved ( ( void * ) adr ) ) {
2020-08-09 17:55:30 +02:00
XStringW FileName = GenerateFileName ( FileNamePrefix , SsdtCount , ChildCount , OemTableId ) ;
2020-10-03 19:02:31 +02:00
Status = SaveBufferToDisk ( ( void * ) adr , len , DirName , FileName . wc_str ( ) ) ;
2019-09-03 11:58:42 +02:00
if ( ! EFI_ERROR ( Status ) ) {
2020-08-09 17:55:30 +02:00
DBG ( " -> %ls " , FileName . wc_str ( ) ) ;
2020-10-03 19:02:31 +02:00
MarkTableAsSaved ( ( void * ) adr ) ;
2019-09-03 11:58:42 +02:00
ChildCount + + ;
} else {
2020-08-25 17:35:19 +02:00
DBG ( " -> %s " , efiStrError ( Status ) ) ;
2019-09-03 11:58:42 +02:00
}
}
DBG ( " \n " ) ;
}
Entry + = 5 ;
} else {
Entry + + ;
}
}
}
/** Saves Table to disk as DirName\\FileName (DirName != NULL)
* or just prints basic table data to log ( DirName = = NULL ) .
*/
2020-08-09 17:55:30 +02:00
EFI_STATUS DumpTable ( EFI_ACPI_DESCRIPTION_HEADER * TableEntry , CONST CHAR8 * CheckSignature , CONST CHAR16 * DirName , const XStringW & FileName , CONST CHAR16 * FileNamePrefix , INTN * SsdtCount )
2019-09-03 11:58:42 +02:00
{
EFI_STATUS Status ;
CHAR8 Signature [ 5 ] ;
CHAR8 OemTableId [ 9 ] ;
// Take Signature and OemId for printing
2020-04-28 09:51:58 +02:00
CopyMem ( & Signature [ 0 ] , & TableEntry - > Signature , 4 ) ;
2019-09-03 11:58:42 +02:00
Signature [ 4 ] = 0 ;
2020-04-28 09:51:58 +02:00
CopyMem ( & OemTableId [ 0 ] , & TableEntry - > OemTableId , 8 ) ;
2019-09-03 11:58:42 +02:00
OemTableId [ 8 ] = 0 ;
stripTrailingSpaces ( OemTableId ) ;
2020-10-11 08:06:50 +02:00
DBG ( " %llx: '%s', '%s', Rev: %d, Len: %d " , ( uintptr_t ) TableEntry , Signature , OemTableId , TableEntry - > Revision , TableEntry - > Length ) ;
2019-09-03 11:58:42 +02:00
//
// Additional checks
//
if ( CheckSignature ! = NULL & & AsciiStrCmp ( Signature , CheckSignature ) ! = 0 ) {
2020-03-25 19:32:44 +01:00
DBG ( " -> invalid signature, expecting %s \n " , CheckSignature ) ;
2019-09-03 11:58:42 +02:00
return EFI_INVALID_PARAMETER ;
}
// XSDT checks
if ( TableEntry - > Signature = = EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE ) {
if ( TableEntry - > Length < sizeof ( XSDT_TABLE ) ) {
DBG ( " -> invalid length \n " ) ;
return EFI_INVALID_PARAMETER ;
}
}
// RSDT checks
if ( TableEntry - > Signature = = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE ) {
if ( TableEntry - > Length < sizeof ( RSDT_TABLE ) ) {
DBG ( " -> invalid length \n " ) ;
return EFI_INVALID_PARAMETER ;
}
}
// FADT/FACP checks
if ( TableEntry - > Signature = = EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE ) {
if ( TableEntry - > Length < sizeof ( EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE ) ) {
DBG ( " -> invalid length \n " ) ;
return EFI_INVALID_PARAMETER ;
}
}
// DSDT checks
if ( TableEntry - > Signature = = EFI_ACPI_1_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE ) {
if ( TableEntry - > Length < sizeof ( EFI_ACPI_DESCRIPTION_HEADER ) ) {
DBG ( " -> invalid length \n " ) ;
return EFI_INVALID_PARAMETER ;
}
}
// SSDT checks
if ( TableEntry - > Signature = = EFI_ACPI_1_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE ) {
if ( TableEntry - > Length < sizeof ( EFI_ACPI_DESCRIPTION_HEADER ) ) {
DBG ( " -> invalid length \n " ) ;
return EFI_INVALID_PARAMETER ;
}
}
if ( DirName = = NULL | | IsTableSaved ( TableEntry ) ) {
// just debug log dump
return EFI_SUCCESS ;
}
if ( FileNamePrefix = = NULL ) {
FileNamePrefix = L " " ;
}
2020-08-09 17:55:30 +02:00
XStringW ReleaseFileName = FileName ;
if ( ReleaseFileName . isEmpty ( ) ) {
2019-09-03 11:58:42 +02:00
// take the name from the signature
if ( TableEntry - > Signature = = EFI_ACPI_1_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE & & SsdtCount ! = NULL ) {
2020-08-09 17:55:30 +02:00
ReleaseFileName = GenerateFileName ( FileNamePrefix , * SsdtCount , IGNORE_INDEX , OemTableId ) ;
2019-09-03 11:58:42 +02:00
} else {
2020-08-09 17:55:30 +02:00
ReleaseFileName = SWPrintf ( " %ls%s.aml " , FileNamePrefix , Signature ) ;
2019-09-03 11:58:42 +02:00
}
}
2020-08-09 17:55:30 +02:00
DBG ( " -> %ls " , ReleaseFileName . wc_str ( ) ) ;
2019-09-03 11:58:42 +02:00
// Save it
2020-08-09 17:55:30 +02:00
Status = SaveBufferToDisk ( TableEntry , TableEntry - > Length , DirName , ReleaseFileName . wc_str ( ) ) ;
2019-09-03 11:58:42 +02:00
MarkTableAsSaved ( TableEntry ) ;
if ( TableEntry - > Signature = = EFI_ACPI_1_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE & & SsdtCount ! = NULL ) {
DumpChildSsdt ( TableEntry , DirName , FileNamePrefix , * SsdtCount ) ;
* SsdtCount + = 1 ;
}
return Status ;
}
/** Saves to disk (DirName != NULL) or prints to log (DirName == NULL) Fadt tables: Dsdt and Facs. */
2020-02-17 21:41:09 +01:00
EFI_STATUS DumpFadtTables ( EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * Fadt , CONST CHAR16 * DirName , CONST CHAR16 * FileNamePrefix , INTN * SsdtCount )
2019-09-03 11:58:42 +02:00
{
EFI_ACPI_DESCRIPTION_HEADER * TableEntry ;
EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE * Facs ;
EFI_STATUS Status = EFI_SUCCESS ;
UINT64 DsdtAdr ;
UINT64 FacsAdr ;
CHAR8 Signature [ 5 ] ;
//
// if Fadt->Revision < 3 (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION), then it is Acpi 1.0
// and fields after Flags are not available
//
2020-03-25 19:32:44 +01:00
DBG ( " (Dsdt: %X, Facs: %X " , Fadt - > Dsdt , Fadt - > FirmwareCtrl ) ;
2019-09-03 11:58:42 +02:00
// for Acpi 1.0
DsdtAdr = Fadt - > Dsdt ;
FacsAdr = Fadt - > FirmwareCtrl ;
if ( Fadt - > Header . Revision > = EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION ) {
// Acpi 2.0 or up
// may have it in XDsdt or XFirmwareCtrl
2020-03-25 19:32:44 +01:00
DBG ( " , XDsdt: %llx, XFacs: %llx " , Fadt - > XDsdt , Fadt - > XFirmwareCtrl ) ;
2021-09-02 17:43:38 +02:00
if ( ( Fadt - > XDsdt ! = 0 ) & & ( Fadt - > XDsdt < 0xFFFFFFF0ull ) ) {
2019-09-03 11:58:42 +02:00
DsdtAdr = Fadt - > XDsdt ;
}
if ( Fadt - > XFirmwareCtrl ! = 0 ) {
FacsAdr = Fadt - > XFirmwareCtrl ;
}
}
DBG ( " ) \n " ) ;
//
// Save Dsdt
//
if ( DsdtAdr ! = 0 ) {
DBG ( " " ) ;
TableEntry = ( EFI_ACPI_DESCRIPTION_HEADER * ) ( UINTN ) DsdtAdr ;
2020-08-09 17:55:30 +02:00
Status = DumpTable ( TableEntry , " DSDT " , DirName , L " " _XSW , FileNamePrefix , NULL ) ;
2019-09-03 11:58:42 +02:00
if ( EFI_ERROR ( Status ) ) {
2020-08-25 17:35:19 +02:00
DBG ( " - %s \n " , efiStrError ( Status ) ) ;
2019-09-03 11:58:42 +02:00
return Status ;
}
DBG ( " \n " ) ;
DumpChildSsdt ( TableEntry , DirName , FileNamePrefix , IGNORE_INDEX ) ;
}
//
// Save Facs
//
if ( FacsAdr ! = 0 ) {
// Taking it as structure from Acpi 2.0 just to get Version (it's reserved field in Acpi 1.0 and == 0)
Facs = ( EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE * ) ( UINTN ) FacsAdr ;
// Take Signature for printing
2020-04-28 09:51:58 +02:00
CopyMem ( & Signature [ 0 ] , & Facs - > Signature , 4 ) ;
2019-09-03 11:58:42 +02:00
Signature [ 4 ] = 0 ;
2020-10-11 08:06:50 +02:00
DBG ( " %llx: '%s', Ver: %d, Len: %d " , ( uintptr_t ) Facs , Signature , Facs - > Version , Facs - > Length ) ;
2019-09-03 11:58:42 +02:00
// FACS checks
if ( Facs - > Signature ! = EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE ) {
DBG ( " -> invalid signature, expecting FACS \n " ) ;
return EFI_INVALID_PARAMETER ;
}
if ( Facs - > Length < sizeof ( EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE ) ) {
DBG ( " -> invalid length \n " ) ;
return EFI_INVALID_PARAMETER ;
}
if ( DirName ! = NULL & & ! IsTableSaved ( Facs ) ) {
2020-08-09 17:55:30 +02:00
XStringW FileName = SWPrintf ( " %lsFACS.aml " , FileNamePrefix ) ;
DBG ( " -> %ls " , FileName . wc_str ( ) ) ;
Status = SaveBufferToDisk ( Facs , Facs - > Length , DirName , FileName . wc_str ( ) ) ;
2019-09-03 11:58:42 +02:00
MarkTableAsSaved ( Facs ) ;
if ( EFI_ERROR ( Status ) ) {
2020-08-25 17:35:19 +02:00
DBG ( " - %s \n " , efiStrError ( Status ) ) ;
2019-09-03 11:58:42 +02:00
return Status ;
}
}
DBG ( " \n " ) ;
}
return Status ;
}
EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * GetFadt ( )
{
EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER * RsdPtr ;
EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * FadtPointer = NULL ;
// EFI_STATUS Status;
2020-02-20 15:28:24 +01:00
RsdPtr = ( __typeof__ ( RsdPtr ) ) FindAcpiRsdPtr ( ) ;
2019-09-03 11:58:42 +02:00
if ( RsdPtr = = NULL ) {
2020-10-03 19:02:31 +02:00
/*Status = */ EfiGetSystemConfigurationTable ( & gEfiAcpi20TableGuid , ( void * * ) & RsdPtr ) ;
2019-09-03 11:58:42 +02:00
if ( RsdPtr = = NULL ) {
2020-10-03 19:02:31 +02:00
/*Status = */ EfiGetSystemConfigurationTable ( & gEfiAcpi10TableGuid , ( void * * ) & RsdPtr ) ;
2019-09-03 11:58:42 +02:00
if ( RsdPtr = = NULL ) {
return NULL ;
}
}
}
Rsdt = ( RSDT_TABLE * ) ( UINTN ) ( RsdPtr - > RsdtAddress ) ;
if ( RsdPtr - > Revision > 0 ) {
if ( Rsdt = = NULL | | Rsdt - > Header . Signature ! = EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE ) {
Xsdt = ( XSDT_TABLE * ) ( UINTN ) ( RsdPtr - > XsdtAddress ) ;
}
}
if ( Rsdt = = NULL & & Xsdt = = NULL ) {
//
// Search Acpi 2.0 or newer in UEFI Sys.Tables
//
RsdPtr = NULL ;
2020-10-03 19:02:31 +02:00
/*Status = */ EfiGetSystemConfigurationTable ( & gEfiAcpi20TableGuid , ( void * * ) & RsdPtr ) ;
2019-09-03 11:58:42 +02:00
if ( RsdPtr ! = NULL ) {
2020-10-11 08:06:50 +02:00
DBG ( " Found UEFI Acpi 2.0 RSDP at %llx \n " , ( uintptr_t ) RsdPtr ) ;
2019-09-03 11:58:42 +02:00
Rsdt = ( RSDT_TABLE * ) ( UINTN ) ( RsdPtr - > RsdtAddress ) ;
if ( RsdPtr - > Revision > 0 ) {
if ( Rsdt = = NULL | | Rsdt - > Header . Signature ! = EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE ) {
Xsdt = ( XSDT_TABLE * ) ( UINTN ) ( RsdPtr - > XsdtAddress ) ;
}
}
}
if ( Rsdt = = NULL & & Xsdt = = NULL ) {
DBG ( " No RSDT or XSDT found! \n " ) ;
return NULL ;
}
}
if ( Rsdt ) {
FadtPointer = ( EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * ) ( UINTN ) ( Rsdt - > Entry ) ;
}
if ( Xsdt ) {
//overwrite previous find as xsdt priority
FadtPointer = ( EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * ) ( UINTN ) ( Xsdt - > Entry ) ;
}
return FadtPointer ;
}
/** Saves to disk (DirName != NULL)
* or prints to debug log ( DirName = = NULL )
* ACPI tables given by RsdPtr .
* Takes tables from Xsdt if present or from Rsdt if Xsdt is not present .
*/
2020-10-03 19:02:31 +02:00
void DumpTables ( void * RsdPtrVoid , CONST CHAR16 * DirName )
2019-09-03 11:58:42 +02:00
{
EFI_STATUS Status ;
UINTN Length ;
INTN SsdtCount ;
2020-02-17 21:41:09 +01:00
CONST CHAR16 * FileNamePrefix ;
2019-09-03 11:58:42 +02:00
//
// RSDP
// Take it as Acpi 2.0, but take care that if RsdPtr->Revision == 0
// then it is actually Acpi 1.0 and fields after RsdtAddress (like XsdtAddress)
// are not available
//
EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER * RsdPtr = ( EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER * ) RsdPtrVoid ;
if ( DirName ! = NULL ) {
2020-10-11 08:06:50 +02:00
DBG ( " Saving ACPI tables from RSDP %llx to %ls ... \n " , ( uintptr_t ) RsdPtr , DirName ) ;
2019-09-03 11:58:42 +02:00
} else {
2020-10-11 08:06:50 +02:00
DBG ( " Printing ACPI tables from RSDP %llx ... \n " , ( uintptr_t ) RsdPtr ) ;
2019-09-03 11:58:42 +02:00
}
if ( RsdPtr - > Signature ! = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE ) {
2020-10-11 08:06:50 +02:00
DBG ( " RsdPrt at %llx has invaid signature 0x%llx - exiting. \n " , ( uintptr_t ) RsdPtr , RsdPtr - > Signature ) ;
2019-09-03 11:58:42 +02:00
return ;
}
// Take Signature for printing
CHAR8 Signature [ 9 ] ;
2020-04-28 09:51:58 +02:00
CopyMem ( & Signature [ 0 ] , & RsdPtr - > Signature , 8 ) ;
2019-09-03 11:58:42 +02:00
Signature [ 8 ] = 0 ;
// Take Rsdt and Xsdt
Rsdt = NULL ;
Xsdt = NULL ;
2020-10-11 08:06:50 +02:00
DBG ( " %llx: '%s', Rev: %d " , ( uintptr_t ) RsdPtr , Signature , RsdPtr - > Revision ) ;
2019-09-03 11:58:42 +02:00
if ( RsdPtr - > Revision = = 0 ) {
// Acpi 1.0
Length = sizeof ( EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER ) ;
DBG ( " (Acpi 1.0) " ) ;
} else {
// Acpi 2.0 or newer
Length = RsdPtr - > Length ;
DBG ( " (Acpi 2.0 or newer) " ) ;
}
2020-03-25 19:32:44 +01:00
DBG ( " , Len: %llu " , Length ) ;
2019-09-03 11:58:42 +02:00
//
// Save RsdPtr
//
if ( DirName ! = NULL & & ! IsTableSaved ( RsdPtr ) ) {
DBG ( " -> RSDP.aml " ) ;
Status = SaveBufferToDisk ( RsdPtr , Length , DirName , L " RSDP.aml " ) ;
MarkTableAsSaved ( RsdPtr ) ;
if ( EFI_ERROR ( Status ) ) {
2020-08-25 17:35:19 +02:00
DBG ( " - %s \n " , efiStrError ( Status ) ) ;
2019-09-03 11:58:42 +02:00
return ;
}
}
DBG ( " \n " ) ;
if ( RsdPtr - > Revision = = 0 ) {
// Acpi 1.0 - no Xsdt
Rsdt = ( RSDT_TABLE * ) ( UINTN ) ( RsdPtr - > RsdtAddress ) ;
2020-10-10 15:31:14 +02:00
DBG ( " (Rsdt: %llx) \n " , ( UINTN ) Rsdt ) ;
2019-09-03 11:58:42 +02:00
} else {
// Acpi 2.0 or newer - may have Xsdt and/or Rsdt
Rsdt = ( RSDT_TABLE * ) ( UINTN ) ( RsdPtr - > RsdtAddress ) ;
Xsdt = ( XSDT_TABLE * ) ( UINTN ) ( RsdPtr - > XsdtAddress ) ;
2020-10-10 15:31:14 +02:00
DBG ( " (Xsdt: %llx, Rsdt: %llx) \n " , ( UINTN ) Xsdt , ( UINTN ) Rsdt ) ;
2019-09-03 11:58:42 +02:00
}
if ( Rsdt = = NULL & & Xsdt = = NULL ) {
DBG ( " No Rsdt and Xsdt - exiting. \n " ) ;
return ;
}
FileNamePrefix = L " " ;
//
// Save Xsdt
//
if ( Xsdt ! = NULL ) {
DBG ( " " ) ;
2020-08-09 17:55:30 +02:00
Status = DumpTable ( ( EFI_ACPI_DESCRIPTION_HEADER * ) Xsdt , " XSDT " , DirName , L " XSDT.aml " _XSW , FileNamePrefix , NULL ) ;
2019-09-03 11:58:42 +02:00
if ( EFI_ERROR ( Status ) ) {
2020-08-25 17:35:19 +02:00
DBG ( " - %s " , efiStrError ( Status ) ) ;
2019-09-03 11:58:42 +02:00
Xsdt = NULL ;
}
DBG ( " \n " ) ;
}
//
// Save Rsdt
//
if ( Rsdt ! = NULL ) {
DBG ( " " ) ;
2020-08-09 17:55:30 +02:00
Status = DumpTable ( ( EFI_ACPI_DESCRIPTION_HEADER * ) Rsdt , " RSDT " , DirName , L " RSDT.aml " _XSW , FileNamePrefix , NULL ) ;
2019-09-03 11:58:42 +02:00
if ( EFI_ERROR ( Status ) ) {
2020-08-25 17:35:19 +02:00
DBG ( " - %s " , efiStrError ( Status ) ) ;
2019-09-03 11:58:42 +02:00
Rsdt = NULL ;
}
DBG ( " \n " ) ;
}
//
// Check once more since they might be invalid
//
if ( Rsdt = = NULL & & Xsdt = = NULL ) {
DBG ( " No Rsdt and Xsdt - exiting. \n " ) ;
return ;
}
2021-09-02 17:43:38 +02:00
UINT32 Count = 0 ;
2019-09-03 11:58:42 +02:00
if ( Xsdt ) {
UINT64 * Ptr , * EndPtr ;
2021-09-02 17:43:38 +02:00
Count = XsdtTableCount ( ) ;
2019-09-03 11:58:42 +02:00
DBG ( " Tables in Xsdt: %d \n " , Count ) ;
if ( Count > 100 ) Count = 100 ; //it's enough
Ptr = XsdtEntryPtrFromIndex ( 0 ) ;
EndPtr = XsdtEntryPtrFromIndex ( Count ) ;
SsdtCount = 0 ;
for ( ; Ptr < EndPtr ; Ptr + + ) {
DBG ( " %d. " , IndexFromXsdtEntryPtr ( Ptr ) ) ;
EFI_ACPI_DESCRIPTION_HEADER * Table = ( EFI_ACPI_DESCRIPTION_HEADER * ) ( UINTN ) ReadUnaligned64 ( Ptr ) ;
if ( ! Table ) {
DBG ( " = 0 \n " ) ;
// skip NULL entry
continue ;
}
if ( EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE = = Table - > Signature ) {
// Fadt - save Dsdt and Facs
2020-08-09 17:55:30 +02:00
Status = DumpTable ( Table , NULL , DirName , L " " _XSW , FileNamePrefix , & SsdtCount ) ;
2019-09-03 11:58:42 +02:00
if ( EFI_ERROR ( Status ) ) {
2020-08-25 17:35:19 +02:00
DBG ( " - %s \n " , efiStrError ( Status ) ) ;
2019-09-03 11:58:42 +02:00
return ;
}
DBG ( " \n " ) ;
EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * Fadt = ( EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * ) Table ;
Status = DumpFadtTables ( Fadt , DirName , FileNamePrefix , & SsdtCount ) ;
if ( EFI_ERROR ( Status ) ) {
return ;
}
} else {
2020-08-09 17:55:30 +02:00
Status = DumpTable ( Table , NULL , DirName , L " " _XSW , FileNamePrefix , & SsdtCount ) ;
2019-09-03 11:58:42 +02:00
if ( EFI_ERROR ( Status ) ) {
2020-08-25 17:35:19 +02:00
DBG ( " - %s \n " , efiStrError ( Status ) ) ;
2019-09-03 11:58:42 +02:00
return ;
}
DBG ( " \n " ) ;
}
}
} // if Xsdt
2021-09-02 17:43:38 +02:00
if ( ! Count & & Rsdt ) {
2019-09-03 11:58:42 +02:00
UINT32 * Ptr , * EndPtr ;
// additional Rsdt tables which are not present in Xsdt will have "RSDT-" prefix, like RSDT-FACS.aml
FileNamePrefix = L " RSDT- " ;
// Take tables from Rsdt
// if saved from Xsdt already, then just print debug
2021-09-02 17:43:38 +02:00
Count = RsdtTableCount ( ) ;
2019-09-03 11:58:42 +02:00
DBG ( " Tables in Rsdt: %d \n " , Count ) ;
if ( Count > 100 ) Count = 100 ; //it's enough
Ptr = RsdtEntryPtrFromIndex ( 0 ) ;
EndPtr = RsdtEntryPtrFromIndex ( Count ) ;
for ( ; Ptr < EndPtr ; Ptr + + ) {
DBG ( " %d. " , IndexFromRsdtEntryPtr ( Ptr ) ) ;
EFI_ACPI_DESCRIPTION_HEADER * Table = ( EFI_ACPI_DESCRIPTION_HEADER * ) ( UINTN ) * Ptr ;
if ( ! Table ) {
DBG ( " = 0 \n " ) ;
// skip NULL entry
continue ;
}
if ( EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE = = Table - > Signature ) {
// Fadt - save Dsdt and Facs
2020-08-09 17:55:30 +02:00
Status = DumpTable ( Table , NULL , DirName , L " " _XSW , FileNamePrefix , & SsdtCount ) ;
2019-09-03 11:58:42 +02:00
if ( EFI_ERROR ( Status ) ) {
2020-08-25 17:35:19 +02:00
DBG ( " - %s \n " , efiStrError ( Status ) ) ;
2019-09-03 11:58:42 +02:00
return ;
}
DBG ( " \n " ) ;
EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * Fadt = ( EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * ) Table ;
Status = DumpFadtTables ( Fadt , DirName , FileNamePrefix , & SsdtCount ) ;
if ( EFI_ERROR ( Status ) ) {
return ;
}
} else {
2020-08-09 17:55:30 +02:00
Status = DumpTable ( Table , NULL , DirName , L " " _XSW , FileNamePrefix , & SsdtCount ) ;
2019-09-03 11:58:42 +02:00
if ( EFI_ERROR ( Status ) ) {
2020-08-25 17:35:19 +02:00
DBG ( " - %s \n " , efiStrError ( Status ) ) ;
2019-09-03 11:58:42 +02:00
return ;
}
DBG ( " \n " ) ;
}
}
} // if Rsdt
}
/** Saves OEM ACPI tables to disk.
* Searches BIOS , then UEFI Sys . Tables for Acpi 2.0 or newer tables , then for Acpi 1.0 tables
* CloverEFI :
* - saves first one found , dump others to log
* UEFI :
* - saves first one found in UEFI Sys . Tables , dump others to log
*
* Dumping of other tables to log can be removed if it turns out that there is no value in doing it .
*/
2020-10-03 19:02:31 +02:00
void SaveOemTables ( )
2019-09-03 11:58:42 +02:00
{
2020-05-15 05:23:33 +02:00
// EFI_STATUS Status;
2020-10-03 19:02:31 +02:00
void * RsdPtr ;
XStringW AcpiOriginPath = L " ACPI \\ origin " _XSW ;
2021-09-28 15:54:31 +02:00
XBool Saved = false ;
2020-08-09 17:55:30 +02:00
CHAR8 * MemLogStart ;
2019-09-03 11:58:42 +02:00
UINTN MemLogStartLen ;
MemLogStartLen = GetMemLogLen ( ) ;
MemLogStart = GetMemLogBuffer ( ) + MemLogStartLen ;
//
// Search in BIOS
// CloverEFI - Save
// UEFI - just print to log
//
// RsdPtr = NULL;
RsdPtr = FindAcpiRsdPtr ( ) ;
if ( RsdPtr ! = NULL ) {
2020-10-10 15:31:14 +02:00
DBG ( " Found BIOS RSDP at %llx \n " , ( UINTN ) RsdPtr ) ;
2019-09-03 11:58:42 +02:00
if ( gFirmwareClover ) {
// Save it
2020-08-09 17:55:30 +02:00
DumpTables ( RsdPtr , AcpiOriginPath . wc_str ( ) ) ;
2021-09-28 10:28:45 +02:00
Saved = true ;
2019-09-03 11:58:42 +02:00
} else {
// just print to log
DumpTables ( RsdPtr , NULL ) ;
}
}
//
// Search Acpi 2.0 or newer in UEFI Sys.Tables
//
RsdPtr = NULL ;
2020-05-15 05:23:33 +02:00
/*Status = */ EfiGetSystemConfigurationTable ( & gEfiAcpi20TableGuid , & RsdPtr ) ;
if ( RsdPtr ! = NULL ) { //it may be EFI_SUCCESS but null pointer
2020-10-10 15:31:14 +02:00
DBG ( " Found UEFI Acpi 2.0 RSDP at %llx \n " , ( UINTN ) RsdPtr ) ;
2019-09-03 11:58:42 +02:00
// if tables already saved, then just print to log
2020-08-09 17:55:30 +02:00
DumpTables ( RsdPtr , Saved ? NULL : AcpiOriginPath . wc_str ( ) ) ;
2021-09-28 10:28:45 +02:00
Saved = true ;
2019-09-03 11:58:42 +02:00
}
//
// Then search Acpi 1.0 UEFI Sys.Tables
//
RsdPtr = NULL ;
/*Status = */ EfiGetSystemConfigurationTable ( & gEfiAcpi10TableGuid , & RsdPtr ) ;
if ( RsdPtr ! = NULL ) {
2020-10-10 15:31:14 +02:00
DBG ( " Found UEFI Acpi 1.0 RSDP at %llx \n " , ( UINTN ) RsdPtr ) ;
2019-09-03 11:58:42 +02:00
// if tables already saved, then just print to log
2020-08-09 17:55:30 +02:00
DumpTables ( RsdPtr , Saved ? NULL : AcpiOriginPath . wc_str ( ) ) ;
2021-09-28 10:28:45 +02:00
// Saved = true;
2019-09-03 11:58:42 +02:00
}
2020-08-09 17:55:30 +02:00
SaveBufferToDisk ( MemLogStart , GetMemLogLen ( ) - MemLogStartLen , AcpiOriginPath . wc_str ( ) , L " DumpLog.txt " ) ;
2019-09-03 11:58:42 +02:00
FreePool ( mSavedTables ) ;
}
2021-09-28 10:28:45 +02:00
void SaveOemDsdt ( XBool FullPatch )
2019-09-03 11:58:42 +02:00
{
EFI_STATUS Status = EFI_NOT_FOUND ;
EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * FadtPointer = NULL ;
EFI_PHYSICAL_ADDRESS dsdt = EFI_SYSTEM_TABLE_MAX_ADDRESS ;
2020-08-09 17:55:30 +02:00
UINTN Pages ;
UINT8 * buffer = NULL ;
UINTN DsdtLen = 0 ;
2020-10-03 19:02:31 +02:00
XStringW OriginDsdt = SWPrintf ( " ACPI \\ origin \\ DSDT.aml " ) ;
2021-02-11 12:41:59 +01:00
XStringW OriginDsdtFixed = SWPrintf ( " ACPI \\ origin \\ DSDT-%x.aml " , gSettings . ACPI . DSDT . FixDsdt ) ;
2020-10-03 19:02:31 +02:00
// constexpr LStringW PathPatched = L"\\EFI\\CL OVER\\ACPI\\patched";
2020-10-17 15:01:33 +02:00
// XStringW PathDsdt;
2020-10-03 19:02:31 +02:00
// XStringW AcpiOemPath = SWPrintf("ACPI\\patched");
2019-09-03 11:58:42 +02:00
2021-02-11 12:41:59 +01:00
// PathDsdt.SWPrintf("\\%ls", gSettings.ACPI.DSDT.FixDsdt.wc_str());
2019-09-03 11:58:42 +02:00
2021-02-11 12:41:59 +01:00
if ( FileExists ( selfOem . getConfigDir ( ) , SWPrintf ( " ACPI \\ patched \\ %ls " , gSettings . ACPI . DSDT . DsdtName . wc_str ( ) ) ) ) {
DBG ( " SaveOemDsdt: DSDT found in Clover volume OEM folder: \\ %ls \\ ACPI \\ patched \\ %ls \n " , selfOem . getConfigDirFullPath ( ) . wc_str ( ) , gSettings . ACPI . DSDT . DsdtName . wc_str ( ) ) ;
Status = egLoadFile ( & selfOem . getConfigDir ( ) , SWPrintf ( " ACPI \\ patched \\ %ls " , gSettings . ACPI . DSDT . DsdtName . wc_str ( ) ) . wc_str ( ) , & buffer , & DsdtLen ) ;
2019-09-03 11:58:42 +02:00
}
2020-10-03 19:02:31 +02:00
// Jief : Do not write outside OemPath
// if (EFI_ERROR(Status) && FileExists(&self.getSelfRootDir(), SWPrintf("%ls%ls", PathPatched.wc_str(), PathDsdt.wc_str()))) {
// DBG("SaveOemDsdt: DSDT found in Clover volume common folder: %ls%ls\n", PathPatched.wc_str(), PathDsdt.wc_str());
// Status = egLoadFile(&self.getSelfRootDir(), SWPrintf("%ls%ls", PathPatched.wc_str(), PathDsdt.wc_str()).wc_str(), &buffer, &DsdtLen);
// }
2019-09-03 11:58:42 +02:00
if ( EFI_ERROR ( Status ) ) {
FadtPointer = GetFadt ( ) ;
if ( FadtPointer = = NULL ) {
DBG ( " Cannot found FADT in BIOS or in UEFI! \n " ) ; //really?!
return ;
}
BiosDsdt = FadtPointer - > Dsdt ;
if ( FadtPointer - > Header . Revision > = EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION & &
FadtPointer - > XDsdt ! = 0 ) {
BiosDsdt = FadtPointer - > XDsdt ;
}
buffer = ( UINT8 * ) ( UINTN ) BiosDsdt ;
}
if ( ! buffer ) {
DBG ( " Cannot found DSDT in BIOS or in files! \n " ) ;
return ;
}
DsdtLen = ( ( EFI_ACPI_DESCRIPTION_HEADER * ) buffer ) - > Length ;
Pages = EFI_SIZE_TO_PAGES ( DsdtLen + DsdtLen / 8 ) ; // take some extra space for patches
Status = gBS - > AllocatePages (
AllocateMaxAddress ,
EfiBootServicesData ,
Pages ,
& dsdt
) ;
//if success insert dsdt pointer into ACPI tables
if ( ! EFI_ERROR ( Status ) )
{
2020-10-03 19:02:31 +02:00
CopyMem ( ( void * ) ( UINTN ) dsdt , buffer , DsdtLen ) ;
2019-09-03 11:58:42 +02:00
buffer = ( UINT8 * ) ( UINTN ) dsdt ;
if ( FullPatch ) {
2020-08-12 17:15:47 +02:00
FixBiosDsdt ( buffer , FadtPointer , NullXString8 ) ;
2019-09-03 11:58:42 +02:00
DsdtLen = ( ( EFI_ACPI_DESCRIPTION_HEADER * ) buffer ) - > Length ;
OriginDsdt = OriginDsdtFixed ;
}
2020-10-17 15:01:33 +02:00
Status = egSaveFile ( & selfOem . getConfigDir ( ) , OriginDsdt . wc_str ( ) , buffer , DsdtLen ) ;
2020-10-03 19:02:31 +02:00
// Jief : do not write outside of OemDir
// if (EFI_ERROR(Status)) {
// Status = egSaveFile(NULL, OriginDsdt.wc_str(), buffer, DsdtLen);
// }
2019-09-03 11:58:42 +02:00
if ( ! EFI_ERROR ( Status ) ) {
2020-10-17 15:01:33 +02:00
MsgLog ( " DSDT saved to %ls \\ %ls \n " , selfOem . getConfigDirFullPath ( ) . wc_str ( ) , OriginDsdt . wc_str ( ) ) ;
2019-09-03 11:58:42 +02:00
} else {
2020-10-17 15:01:33 +02:00
MsgLog ( " Saving DSDT to %ls \\ %ls failed - %s \n " , selfOem . getConfigDirFullPath ( ) . wc_str ( ) , OriginDsdt . wc_str ( ) , efiStrError ( Status ) ) ;
2019-09-03 11:58:42 +02:00
}
gBS - > FreePages ( dsdt , Pages ) ;
}
}
2021-09-28 10:28:45 +02:00
XBool LoadPatchedAML ( const EFI_FILE & dir , const XStringW & acpiOemPath , CONST CHAR16 * PartName , UINTN Pass )
2019-09-03 11:58:42 +02:00
{
// pass1 prefilter based on file names (optimization that avoids loading same files twice)
UINTN Index = IGNORE_INDEX ;
if ( AUTOMERGE_PASS1 = = Pass ) {
Index = IndexFromFileName ( PartName ) ;
2021-02-11 12:41:59 +01:00
// gSettings.ACPI.AutoMerge always true in this case
2019-09-03 11:58:42 +02:00
// file names such as: ECDT.aml, SSDT-0.aml, SSDT-1-CpuPm.aml, attempt merge on pass1
// others: no attempt for merge
// special case for SSDT.aml: no attempt to merge
if ( 0 = = StriCmp ( PartName , L " SSDT.aml " ) | | ( 8 ! = StrLen ( PartName ) & & IGNORE_INDEX = = Index ) ) {
DBG ( " ignore on pass 1 \n " ) ;
2021-09-28 10:28:45 +02:00
return false ;
2019-09-03 11:58:42 +02:00
}
}
UINT8 * buffer = NULL ;
UINTN bufferLen = 0 ;
2020-10-05 09:25:53 +02:00
EFI_STATUS Status = egLoadFile ( & dir , SWPrintf ( " %ls \\ %ls " , acpiOemPath . wc_str ( ) , PartName ) . wc_str ( ) , & buffer , & bufferLen ) ;
2019-09-03 11:58:42 +02:00
if ( ! EFI_ERROR ( Status ) ) {
if ( buffer ) {
EFI_ACPI_DESCRIPTION_HEADER * TableHeader = ( EFI_ACPI_DESCRIPTION_HEADER * ) buffer ;
2021-02-06 18:16:46 +01:00
if ( TableHeader - > Length > 500 * Kilo ) {
2019-09-03 11:58:42 +02:00
DBG ( " wrong table \n " ) ;
2021-09-28 10:28:45 +02:00
return false ;
2019-09-03 11:58:42 +02:00
}
}
DBG ( " size=%lld " , ( UINT64 ) bufferLen ) ;
2021-02-11 12:41:59 +01:00
if ( ! gSettings . ACPI . AutoMerge ) {
2019-09-03 11:58:42 +02:00
// Note: with AutoMerge=false, Pass is only AUTOMERGE_PASS2 here
Status = InsertTable ( buffer , bufferLen ) ;
} else {
Status = ReplaceOrInsertTable ( buffer , bufferLen , Index , Pass ) ;
}
FreePool ( buffer ) ;
}
2020-08-25 17:35:19 +02:00
DBG ( " ... %s \n " , efiStrError ( Status ) ) ;
2019-09-03 11:58:42 +02:00
return ! EFI_ERROR ( Status ) ;
}
# define BVALUE_ATTEMPTED 2 // special value for MenuItem.BValue to avoid excessive log output
2020-10-05 09:25:53 +02:00
void LoadAllPatchedAML ( const XStringW & acpiPathUnderOem , UINTN Pass )
2019-09-03 11:58:42 +02:00
{
2021-02-11 12:41:59 +01:00
if ( ! gSettings . ACPI . AutoMerge & & AUTOMERGE_PASS1 = = Pass ) {
2019-09-03 11:58:42 +02:00
// nothing to do in this case, since AutoMerge=false -> no tables ever merged
return ;
}
2021-03-23 20:59:30 +01:00
if ( ACPIPatchedAML . notEmpty ( ) ) {
2019-09-03 11:58:42 +02:00
DbgHeader ( " ACPIPatchedAML " ) ;
2021-02-11 12:41:59 +01:00
if ( gSettings . ACPI . AutoMerge ) {
2020-03-25 19:32:44 +01:00
DBG ( " AutoMerge pass %llu \n " , Pass ) ;
2019-09-03 11:58:42 +02:00
}
//DBG("Start: Processing Patched AML(s): ");
2021-02-11 12:41:59 +01:00
if ( gSettings . ACPI . SortedACPI . size ( ) ) {
2019-09-03 11:58:42 +02:00
UINTN Index ;
DBG ( " Sorted \n " ) ;
2021-02-11 12:41:59 +01:00
for ( Index = 0 ; Index < gSettings . ACPI . SortedACPI . size ( ) ; Index + + ) {
2021-03-23 20:59:30 +01:00
size_t idx ;
for ( idx = 0 ; idx < ACPIPatchedAML . size ( ) ; + + idx ) {
ACPI_PATCHED_AML & ACPIPatchedAMLTmp = ACPIPatchedAML [ idx ] ;
if ( ACPIPatchedAMLTmp . FileName = = gSettings . ACPI . SortedACPI [ Index ] & & ACPIPatchedAMLTmp . MenuItem . BValue ) {
if ( BVALUE_ATTEMPTED ! = ACPIPatchedAMLTmp . MenuItem . BValue )
DBG ( " Disabled: %s, skip \n " , ACPIPatchedAMLTmp . FileName . c_str ( ) ) ;
ACPIPatchedAMLTmp . MenuItem . BValue = BVALUE_ATTEMPTED ;
2019-09-03 11:58:42 +02:00
break ;
}
}
2021-03-23 20:59:30 +01:00
if ( idx = = ACPIPatchedAML . size ( ) ) { // NULL when not disabled
DBG ( " Inserting table[%llu]:%s from %ls \\ %ls: " , Index , gSettings . ACPI . SortedACPI [ Index ] . c_str ( ) , selfOem . getConfigDirFullPath ( ) . wc_str ( ) , acpiPathUnderOem . wc_str ( ) ) ;
if ( LoadPatchedAML ( selfOem . getConfigDir ( ) , acpiPathUnderOem , XStringW ( gSettings . ACPI . SortedACPI [ Index ] ) . wc_str ( ) , Pass ) ) {
2019-09-03 11:58:42 +02:00
// avoid inserting table again on second pass
2021-03-23 20:59:30 +01:00
for ( idx = 0 ; idx < ACPIPatchedAML . size ( ) ; + + idx ) {
ACPI_PATCHED_AML & temp2 = ACPIPatchedAML [ idx ] ;
if ( temp2 . FileName = = gSettings . ACPI . SortedACPI [ Index ] ) {
temp2 . MenuItem . BValue = BVALUE_ATTEMPTED ;
2019-09-03 11:58:42 +02:00
break ;
}
}
}
}
}
} else {
DBG ( " Unsorted \n " ) ;
2021-03-23 20:59:30 +01:00
for ( size_t idx = 0 ; idx < ACPIPatchedAML . size ( ) ; + + idx ) {
ACPI_PATCHED_AML & ACPIPatchedAMLTmp = ACPIPatchedAML [ idx ] ;
if ( ! ACPIPatchedAMLTmp . MenuItem . BValue ) {
DBG ( " Inserting %s from %ls \\ %ls: " , ACPIPatchedAMLTmp . FileName . c_str ( ) , selfOem . getConfigDirFullPath ( ) . wc_str ( ) , acpiPathUnderOem . wc_str ( ) ) ;
if ( LoadPatchedAML ( selfOem . getConfigDir ( ) , acpiPathUnderOem , XStringW ( ACPIPatchedAMLTmp . FileName ) . wc_str ( ) , Pass ) ) {
2019-09-03 11:58:42 +02:00
// avoid inserting table again on second pass
2021-03-23 20:59:30 +01:00
ACPIPatchedAMLTmp . MenuItem . BValue = BVALUE_ATTEMPTED ;
2019-09-03 11:58:42 +02:00
}
} else {
2021-03-23 20:59:30 +01:00
if ( BVALUE_ATTEMPTED ! = ACPIPatchedAMLTmp . MenuItem . BValue )
DBG ( " Disabled: %s, skip \n " , ACPIPatchedAMLTmp . FileName . c_str ( ) ) ;
ACPIPatchedAMLTmp . MenuItem . BValue = BVALUE_ATTEMPTED ;
2019-09-03 11:58:42 +02:00
}
}
}
//DBG("End: Processing Patched AML(s)\n");
}
}
2020-11-12 22:25:56 +01:00
EFI_STATUS PatchACPI ( IN REFIT_VOLUME * Volume , const MacOsVersion & OSVersion )
2019-09-03 11:58:42 +02:00
{
EFI_STATUS Status = EFI_SUCCESS ;
UINTN Index ;
EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER * RsdPointer = NULL ;
EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * FadtPointer = NULL ;
EFI_ACPI_4_0_FIXED_ACPI_DESCRIPTION_TABLE * newFadt = NULL ;
// EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *Hpet = NULL;
EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE * Facs = NULL ;
EFI_PHYSICAL_ADDRESS dsdt = EFI_SYSTEM_TABLE_MAX_ADDRESS ; //0xFE000000;
EFI_PHYSICAL_ADDRESS BufferPtr ;
SSDT_TABLE * Ssdt = NULL ;
UINT8 * buffer = NULL ;
UINTN bufferLen = 0 ;
2020-10-03 19:02:31 +02:00
// constexpr LStringW PathPatched = L"\\EFI\\CL OVER\\ACPI\\patched";
2020-10-17 15:01:33 +02:00
// XStringW PathDsdt; // = L"\\DSDT.aml";
2020-10-03 19:02:31 +02:00
// CHAR16* PatchedAPIC = L"\\EFI\\CL OVER\\ACPI\\origin\\APIC-p.aml";
2019-09-03 11:58:42 +02:00
UINT32 * rf = NULL ;
UINT64 * xf = NULL ;
UINT64 XDsdt ; //save values if present
UINT64 XFirmwareCtrl ;
2020-10-03 19:02:31 +02:00
// EFI_FILE *RootDir;
2019-09-03 11:58:42 +02:00
UINT32 eCntR ; //, eCntX;
UINT32 * pEntryR ;
CHAR8 * pEntry ;
EFI_ACPI_DESCRIPTION_HEADER * TableHeader ;
// -===== APIC =====-
EFI_ACPI_DESCRIPTION_HEADER * ApicTable ;
// EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *ApicHeader;
EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE * ProcLocalApic ;
EFI_ACPI_2_0_LOCAL_APIC_NMI_STRUCTURE * LocalApicNMI ;
// UINTN ApicLen;
2020-08-09 17:55:30 +02:00
UINTN ApicCPUNum ;
2019-09-03 11:58:42 +02:00
UINT8 * SubTable ;
2021-09-28 15:54:31 +02:00
XBool DsdtLoaded = false ;
XBool NeedUpdate = false ;
2019-09-03 11:58:42 +02:00
OPER_REGION * tmpRegion ;
2020-10-03 19:02:31 +02:00
// XStringW AcpiOemPath = SWPrintf("%ls\\ACPI\\patched", OEMPath.wc_str());
2019-09-03 11:58:42 +02:00
DbgHeader ( " PatchACPI " ) ;
//try to find in SystemTable
for ( Index = 0 ; Index < gST - > NumberOfTableEntries ; Index + + ) {
if ( CompareGuid ( & gST - > ConfigurationTable [ Index ] . VendorGuid , & gEfiAcpi20TableGuid ) ) {
// Acpi 2.0
RsdPointer = ( EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER * ) gST - > ConfigurationTable [ Index ] . VendorTable ;
break ;
}
else if ( CompareGuid ( & gST - > ConfigurationTable [ Index ] . VendorGuid , & gEfiAcpi10TableGuid ) ) {
// Acpi 1.0 - RSDT only
RsdPointer = ( EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER * ) gST - > ConfigurationTable [ Index ] . VendorTable ;
continue ;
}
}
if ( ! RsdPointer ) {
return EFI_UNSUPPORTED ;
}
Rsdt = ( RSDT_TABLE * ) ( UINTN ) RsdPointer - > RsdtAddress ;
2020-10-10 15:31:14 +02:00
// DBG("RSDT 0x%llx\n", Rsdt);
2019-09-03 11:58:42 +02:00
rf = ScanRSDT ( EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE , 0 ) ;
if ( rf ) {
FadtPointer = ( EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * ) ( UINTN ) ( * rf ) ;
2020-10-10 15:31:14 +02:00
// DBG("FADT from RSDT: 0x%llx\n", FadtPointer);
2019-09-03 11:58:42 +02:00
}
Xsdt = NULL ;
if ( RsdPointer - > Revision > = 2 & & ( RsdPointer - > XsdtAddress < ( UINT64 ) ( UINTN ) - 1 ) ) {
Xsdt = ( XSDT_TABLE * ) ( UINTN ) RsdPointer - > XsdtAddress ;
2020-10-10 15:31:14 +02:00
// DBG("XSDT 0x%llx\n", Xsdt);
2019-09-03 11:58:42 +02:00
xf = ScanXSDT ( EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE , 0 ) ;
if ( xf ) {
//Slice - change priority. First Xsdt, second Rsdt
if ( * xf ) {
FadtPointer = ( EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * ) ( UINTN ) ( * xf ) ;
2020-10-10 15:31:14 +02:00
// DBG("FADT from XSDT: 0x%llx\n", FadtPointer);
2019-09-03 11:58:42 +02:00
} else {
* xf = ( UINT64 ) ( UINTN ) FadtPointer ;
// DBG("reuse FADT\n"); //never happens
}
}
}
if ( ! xf & & Rsdt ) {
DBG ( " Xsdt is not found! Creating new one \n " ) ;
//We should make here ACPI20 RSDP with all needed subtables based on ACPI10
BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS ;
Status = gBS - > AllocatePages ( AllocateMaxAddress , EfiACPIReclaimMemory , 1 , & BufferPtr ) ;
if ( ! EFI_ERROR ( Status ) ) {
if ( RsdPointer - > Revision = = 0 ) {
// Acpi 1.0 RsdPtr, but we need Acpi 2.0
EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER * NewRsdPointer ;
DBG ( " RsdPointer is Acpi 1.0 - creating new one Acpi 2.0 \n " ) ;
// add new pointer to the beginning of a new buffer
NewRsdPointer = ( EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER * ) ( UINTN ) BufferPtr ;
// and Xsdt will come after it
BufferPtr + = 0x30 ;
2020-10-10 15:31:14 +02:00
// DBG("::pointers %llx %llx\n", NewRsdPointer, RsdPointer);
2019-09-03 11:58:42 +02:00
// Signature, Checksum, OemId, Reserved/Revision, RsdtAddress
CopyMem ( NewRsdPointer , RsdPointer , sizeof ( EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER ) ) ;
NewRsdPointer - > Revision = 2 ;
NewRsdPointer - > Length = sizeof ( EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER ) ;
RsdPointer = NewRsdPointer ;
2021-09-28 10:28:45 +02:00
NeedUpdate = true ;
2019-09-03 11:58:42 +02:00
// gBS->InstallConfigurationTable(&gEfiAcpiTableGuid, RsdPointer);
// DBG("first install success\n");
// gBS->InstallConfigurationTable(&gEfiAcpi10TableGuid, RsdPointer);
DBG ( " RsdPointer Acpi 2.0 installed \n " ) ;
}
Xsdt = ( XSDT_TABLE * ) ( UINTN ) BufferPtr ;
2020-04-17 14:27:38 +02:00
// DBG("XSDT = 0x%llx\n", uintptr_t(Xsdt));
2019-09-03 11:58:42 +02:00
Xsdt - > Header . Signature = 0x54445358 ; //EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
eCntR = ( Rsdt - > Header . Length - sizeof ( EFI_ACPI_DESCRIPTION_HEADER ) ) / sizeof ( UINT32 ) ;
Xsdt - > Header . Length = eCntR * sizeof ( UINT64 ) + sizeof ( EFI_ACPI_DESCRIPTION_HEADER ) ;
Xsdt - > Header . Revision = 1 ;
CopyMem ( & Xsdt - > Header . OemId , & FadtPointer - > Header . OemId , 6 ) ;
// Xsdt->Header.OemTableId = Rsdt->Header.OemTableId;
CopyMem ( & Xsdt - > Header . OemTableId , & Rsdt - > Header . OemTableId , 8 ) ;
Xsdt - > Header . OemRevision = Rsdt - > Header . OemRevision ;
Xsdt - > Header . CreatorId = Rsdt - > Header . CreatorId ;
Xsdt - > Header . CreatorRevision = Rsdt - > Header . CreatorRevision ;
pEntryR = ( UINT32 * ) ( & ( Rsdt - > Entry ) ) ;
pEntry = ( CHAR8 * ) ( & ( Xsdt - > Entry ) ) ;
DBG ( " RSDT entries = %d \n " , eCntR ) ;
for ( Index = 0 ; Index < eCntR ; Index + + )
{
UINT64 * pEntryX = ( UINT64 * ) pEntry ;
2020-03-25 19:32:44 +01:00
// DBG("RSDT entry = 0x%X\n", *pEntryR);
2019-09-03 11:58:42 +02:00
if ( * pEntryR ! = 0 ) {
* pEntryX = 0 ;
2020-05-01 18:26:28 +02:00
CopyMem ( pEntryX , pEntryR , sizeof ( UINT32 ) ) ;
2019-09-03 11:58:42 +02:00
pEntryR + + ;
pEntry + = sizeof ( UINT64 ) ;
} else {
2020-10-14 09:32:36 +02:00
DBG ( " RSDT entry %llu = 0 ... skip it \n " , Index ) ;
2019-09-03 11:58:42 +02:00
Xsdt - > Header . Length - = sizeof ( UINT64 ) ;
pEntryR + + ;
}
}
}
}
if ( Xsdt ) {
//Now we need no more Rsdt
Rsdt = NULL ;
RsdPointer - > RsdtAddress = 0 ;
//and we want to reallocate Xsdt
BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS ;
Status = gBS - > AllocatePages ( AllocateMaxAddress , EfiACPIReclaimMemory , 1 , & BufferPtr ) ;
if ( ! EFI_ERROR ( Status ) )
{
2020-10-03 19:02:31 +02:00
CopyMem ( ( void * ) ( UINTN ) BufferPtr , Xsdt , Xsdt - > Header . Length ) ;
2019-09-03 11:58:42 +02:00
Xsdt = ( XSDT_TABLE * ) ( UINTN ) BufferPtr ;
}
// DBG("Finishing RsdPointer\n");
RsdPointer - > XsdtAddress = ( UINT64 ) ( UINTN ) Xsdt ;
RsdPointer - > Checksum = 0 ;
RsdPointer - > Checksum = ( UINT8 ) ( 256 - Checksum8 ( ( CHAR8 * ) RsdPointer , 20 ) ) ;
RsdPointer - > ExtendedChecksum = 0 ;
RsdPointer - > ExtendedChecksum = ( UINT8 ) ( 256 - Checksum8 ( ( CHAR8 * ) RsdPointer , RsdPointer - > Length ) ) ;
DBG ( " Xsdt reallocation done \n " ) ;
}
2020-03-25 19:32:44 +01:00
// DBG("FADT pointer = %X\n", (UINTN)FadtPointer);
2019-09-03 11:58:42 +02:00
if ( ! FadtPointer ) {
return EFI_NOT_FOUND ;
}
//Slice - then we do FADT patch no matter if we don't have DSDT.aml
BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS ;
Status = gBS - > AllocatePages ( AllocateMaxAddress , EfiACPIReclaimMemory , 1 , & BufferPtr ) ;
if ( ! EFI_ERROR ( Status ) )
{
UINT32 oldLength = ( ( EFI_ACPI_DESCRIPTION_HEADER * ) FadtPointer ) - > Length ;
newFadt = ( EFI_ACPI_4_0_FIXED_ACPI_DESCRIPTION_TABLE * ) ( UINTN ) BufferPtr ;
2020-03-25 19:32:44 +01:00
DBG ( " old FADT length=%X \n " , oldLength ) ;
2019-09-03 11:58:42 +02:00
CopyMem ( newFadt , FadtPointer , oldLength ) ; //old data
newFadt - > Header . Length = 0xF4 ;
2021-04-03 16:42:49 +02:00
CopyMem ( newFadt - > Header . OemId , AppleBiosVendor . c_str ( ) , 6 ) ;
2019-09-03 11:58:42 +02:00
if ( newFadt - > Header . Revision < EFI_ACPI_4_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION ) {
newFadt - > Header . Revision = EFI_ACPI_4_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION ;
}
newFadt - > Reserved0 = 0 ; //ACPIspec said it should be 0, while 1 is possible, but no more
//should correct headers if needed and if asked
PatchTableHeader ( ( EFI_ACPI_DESCRIPTION_HEADER * ) newFadt ) ;
2021-09-28 10:28:45 +02:00
if ( gSettings . ACPI . smartUPS = = true ) {
2019-09-03 11:58:42 +02:00
newFadt - > PreferredPmProfile = 3 ;
} else {
newFadt - > PreferredPmProfile = gMobile ? 2 : 1 ; //as calculated before
}
2021-03-19 16:35:01 +01:00
if ( GlobalConfig . EnableC6 | | gSettings . ACPI . SSDT . EnableISS ) {
2019-09-03 11:58:42 +02:00
newFadt - > CstCnt = 0x85 ; //as in Mac
}
2021-03-19 16:35:01 +01:00
if ( GlobalConfig . EnableC2 ) newFadt - > PLvl2Lat = 0x65 ;
if ( GlobalConfig . C3Latency > 0 ) {
newFadt - > PLvl3Lat = GlobalConfig . C3Latency ;
} else if ( GlobalConfig . EnableC4 ) {
2019-09-03 11:58:42 +02:00
newFadt - > PLvl3Lat = 0x3E9 ;
}
2021-03-19 16:35:01 +01:00
if ( GlobalConfig . C3Latency = = 0 ) {
GlobalConfig . C3Latency = newFadt - > PLvl3Lat ;
2019-09-03 11:58:42 +02:00
}
newFadt - > IaPcBootArch = 0x3 ;
2021-02-11 12:41:59 +01:00
if ( gSettings . ACPI . NoASPM ) {
2019-09-03 11:58:42 +02:00
newFadt - > IaPcBootArch | = 0x10 ; // disable ASPM
}
newFadt - > Flags | = 0x420 ; //Reset Register Supported and SleepButton active
newFadt - > Flags & = ~ 0x10010 ; //RTC_STS not valid and PowerButton disable
XDsdt = newFadt - > XDsdt ; //save values if present
XFirmwareCtrl = newFadt - > XFirmwareCtrl ;
CopyMem ( & newFadt - > ResetReg , pmBlock , 0x80 ) ;
//but these common values are not specific, so adjust
//ACPIspec said that if Xdsdt !=0 then Dsdt must be =0. But real Mac no! Both values present
if ( BiosDsdt ) {
newFadt - > XDsdt = BiosDsdt ;
newFadt - > Dsdt = ( UINT32 ) BiosDsdt ;
} else if ( newFadt - > Dsdt ) {
newFadt - > XDsdt = ( UINT64 ) ( newFadt - > Dsdt ) ;
} else if ( XDsdt ) {
newFadt - > Dsdt = ( UINT32 ) XDsdt ;
}
if ( newFadt - > FirmwareCtrl ) {
Facs = ( EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE * ) ( UINTN ) newFadt - > FirmwareCtrl ;
newFadt - > XFirmwareCtrl = ( UINT64 ) ( UINTN ) ( Facs ) ;
} else if ( newFadt - > XFirmwareCtrl ) {
newFadt - > FirmwareCtrl = ( UINT32 ) XFirmwareCtrl ;
Facs = ( EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE * ) ( UINTN ) XFirmwareCtrl ;
}
//patch for FACS included here
Facs - > Version = EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION ;
2021-02-02 10:02:21 +01:00
if ( gSettings . Boot . SignatureFixup ) {
2020-03-25 19:32:44 +01:00
DBG ( " SignatureFixup: 0x%X -> 0x%llX \n " , Facs - > HardwareSignature , machineSignature ) ;
2019-09-03 11:58:42 +02:00
Facs - > HardwareSignature = ( UINT32 ) machineSignature ;
} else {
2020-03-25 19:32:44 +01:00
DBG ( " SignatureFixup: 0x%X -> 0x0 \n " , Facs - > HardwareSignature ) ;
2019-09-03 11:58:42 +02:00
Facs - > HardwareSignature = 0x0 ;
}
Facs - > Flags = 0 ; //dont' support S4BIOS, as well as 64bit wake
//
2021-02-11 12:41:59 +01:00
if ( ( gSettings . ACPI . ResetAddr = = 0 ) & & ( ( oldLength < 0x80 ) | | ( newFadt - > ResetReg . Address = = 0 ) ) ) {
2019-09-03 11:58:42 +02:00
newFadt - > ResetReg . Address = 0x64 ;
newFadt - > ResetValue = 0xFE ;
2021-02-11 12:41:59 +01:00
gSettings . ACPI . ResetAddr = 0x64 ;
gSettings . ACPI . ResetVal = 0xFE ;
} else if ( gSettings . ACPI . ResetAddr ! = 0 ) {
newFadt - > ResetReg . Address = gSettings . ACPI . ResetAddr ;
newFadt - > ResetValue = gSettings . ACPI . ResetVal ;
2019-09-03 11:58:42 +02:00
}
newFadt - > XPm1aEvtBlk . Address = ( UINT64 ) ( newFadt - > Pm1aEvtBlk ) ;
newFadt - > XPm1bEvtBlk . Address = ( UINT64 ) ( newFadt - > Pm1bEvtBlk ) ;
newFadt - > XPm1aCntBlk . Address = ( UINT64 ) ( newFadt - > Pm1aCntBlk ) ;
newFadt - > XPm1bCntBlk . Address = ( UINT64 ) ( newFadt - > Pm1bCntBlk ) ;
newFadt - > XPm2CntBlk . Address = ( UINT64 ) ( newFadt - > Pm2CntBlk ) ;
newFadt - > XPmTmrBlk . Address = ( UINT64 ) ( newFadt - > PmTmrBlk ) ;
newFadt - > XGpe0Blk . Address = ( UINT64 ) ( newFadt - > Gpe0Blk ) ;
newFadt - > XGpe1Blk . Address = ( UINT64 ) ( newFadt - > Gpe1Blk ) ;
FadtPointer = ( EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * ) newFadt ;
//We are sure that Fadt is the first entry in RSDT/XSDT table
if ( Rsdt ! = NULL ) {
Rsdt - > Entry = ( UINT32 ) ( UINTN ) newFadt ;
}
if ( Xsdt ! = NULL ) {
Xsdt - > Entry = ( UINT64 ) ( ( UINT32 ) ( UINTN ) newFadt ) ;
}
FixChecksum ( & FadtPointer - > Header ) ;
2021-02-11 12:41:59 +01:00
if ( gSettings . ACPI . SlpSmiEnable ) {
2019-09-03 11:58:42 +02:00
UINT32 * SlpSmiEn = ( UINT32 * ) ( ( UINTN ) ( newFadt - > Pm1aEvtBlk ) + 0x30 ) ;
UINT32 Value = * SlpSmiEn ;
Value & = ~ bit ( 4 ) ;
* SlpSmiEn = Value ;
}
}
//Get regions from BIOS DSDT
2021-02-11 12:41:59 +01:00
if ( ( gSettings . ACPI . DSDT . FixDsdt & FIX_REGIONS ) ! = 0 ) {
2019-09-03 11:58:42 +02:00
GetBiosRegions ( ( UINT8 * ) ( UINTN ) ( newFadt - > Dsdt ) ) ;
}
// DBG("DSDT finding\n");
if ( ! Volume ) {
DBG ( " Volume not found! \n " ) ;
return EFI_NOT_FOUND ;
}
2020-10-03 19:02:31 +02:00
// RootDir = Volume->RootDir;
2019-09-03 11:58:42 +02:00
Status = EFI_NOT_FOUND ;
2020-10-17 15:01:33 +02:00
2021-02-11 12:41:59 +01:00
XStringW acpiPath = SWPrintf ( " ACPI \\ patched \\ %ls " , gSettings . ACPI . DSDT . DsdtName . wc_str ( ) ) ;
2020-10-03 19:02:31 +02:00
2020-10-17 15:01:33 +02:00
if ( selfOem . oemDirExists ( ) ) {
if ( FileExists ( & selfOem . getOemDir ( ) , acpiPath ) ) {
DBG ( " DSDT found in Clover volume OEM folder: %ls \\ %ls \n " , selfOem . getOemFullPath ( ) . wc_str ( ) , acpiPath . wc_str ( ) ) ;
Status = egLoadFile ( & selfOem . getOemDir ( ) , acpiPath . wc_str ( ) , & buffer , & bufferLen ) ;
//REVIEW: memory leak... buffer
}
2019-09-03 11:58:42 +02:00
}
2020-10-14 09:32:36 +02:00
//Slice: the idea was from past
// first priority DSDT.aml from the root of booted volume. It allows to keep different DSDT for different systems
// second priority is DSDT from OEM folder
2021-09-27 08:39:06 +02:00
// third priority is {Clover folder}/ACPI/patched/DSDT*.aml choosen from GUI.
2020-10-14 09:32:36 +02:00
2021-02-11 12:41:59 +01:00
XStringW PathDsdt = SWPrintf ( " \\ %ls " , gSettings . ACPI . DSDT . DsdtName . wc_str ( ) ) ;
2020-10-03 19:02:31 +02:00
if ( EFI_ERROR ( Status ) & & FileExists ( Volume - > RootDir , PathDsdt ) ) {
2019-09-03 11:58:42 +02:00
DBG ( " DSDT found in booted volume \n " ) ;
2020-10-03 19:02:31 +02:00
Status = egLoadFile ( Volume - > RootDir , PathDsdt . wc_str ( ) , & buffer , & bufferLen ) ;
2019-09-03 11:58:42 +02:00
}
2020-10-03 19:02:31 +02:00
// Jief : may I suggest to remove that. Loading from outside of OemPath might be confusing
if ( EFI_ERROR ( Status ) & & FileExists ( & self . getCloverDir ( ) , acpiPath ) ) {
2020-10-17 15:01:33 +02:00
DBG ( " DSDT found in Clover volume: %ls \\ %ls \n " , self . getCloverDirFullPath ( ) . wc_str ( ) , acpiPath . wc_str ( ) ) ;
2020-10-03 19:02:31 +02:00
Status = egLoadFile ( & self . getCloverDir ( ) , acpiPath . wc_str ( ) , & buffer , & bufferLen ) ;
2019-09-03 11:58:42 +02:00
}
//
//apply DSDT loaded from a file into buffer
//else FADT will contain old BIOS DSDT
//
2021-09-28 10:28:45 +02:00
DsdtLoaded = false ;
2019-09-03 11:58:42 +02:00
if ( ! EFI_ERROR ( Status ) ) {
// if we will apply fixes, allocate additional space
bufferLen = bufferLen + bufferLen / 8 ;
dsdt = EFI_SYSTEM_TABLE_MAX_ADDRESS ;
Status = gBS - > AllocatePages (
AllocateMaxAddress ,
EfiACPIReclaimMemory ,
EFI_SIZE_TO_PAGES ( bufferLen ) ,
& dsdt
) ;
//if success insert dsdt pointer into ACPI tables
if ( ! EFI_ERROR ( Status ) ) {
// DBG("page is allocated, write DSDT into\n");
2020-10-03 19:02:31 +02:00
CopyMem ( ( void * ) ( UINTN ) dsdt , buffer , bufferLen ) ;
2020-10-14 09:32:36 +02:00
//once we copied buffer to other place we can free the buffer
2019-09-03 11:58:42 +02:00
FadtPointer - > Dsdt = ( UINT32 ) dsdt ;
FadtPointer - > XDsdt = dsdt ;
FixChecksum ( & FadtPointer - > Header ) ;
2021-09-28 10:28:45 +02:00
DsdtLoaded = true ;
2019-09-03 11:58:42 +02:00
}
}
2020-10-14 09:32:36 +02:00
if ( buffer ) FreePool ( buffer ) ; //the buffer is allocated if egLoadFile() is success. Else the pointer must be nullptr
2019-09-03 11:58:42 +02:00
if ( ! DsdtLoaded ) {
// allocate space for fixes
TableHeader = ( EFI_ACPI_DESCRIPTION_HEADER * ) ( UINTN ) FadtPointer - > Dsdt ;
bufferLen = TableHeader - > Length ;
2020-03-25 19:32:44 +01:00
// DBG("DSDT len = 0x%X", bufferLen);
2019-09-03 11:58:42 +02:00
// bufferLen = bufferLen + bufferLen / 8;
2020-03-25 19:32:44 +01:00
// DBG(" new len = 0x%X\n", bufferLen);
2019-09-03 11:58:42 +02:00
2020-10-14 09:32:36 +02:00
//Slice: new buffer is greater then origin by 12.5%. It is dirty hack but we live with it
// there will be the sense reallocate buffer if one patch requires increasing the buffer
// this is headache to predict how many new bytes we need.
2019-09-03 11:58:42 +02:00
dsdt = EFI_SYSTEM_TABLE_MAX_ADDRESS ;
Status = gBS - > AllocatePages ( AllocateMaxAddress ,
EfiACPIReclaimMemory ,
EFI_SIZE_TO_PAGES ( bufferLen + bufferLen / 8 ) ,
& dsdt ) ;
//if success insert dsdt pointer into ACPI tables
if ( ! EFI_ERROR ( Status ) ) {
2020-10-14 09:32:36 +02:00
CopyMem ( ( void * ) ( UINTN ) dsdt , TableHeader , bufferLen ) ; //can't free TableHeader because we are not allocate it
2019-09-03 11:58:42 +02:00
FadtPointer - > Dsdt = ( UINT32 ) dsdt ;
FadtPointer - > XDsdt = dsdt ;
FixChecksum ( & FadtPointer - > Header ) ;
}
}
2020-05-11 17:44:00 +02:00
// dropDSM = 0xFFFF; //by default we drop all OEM _DSM. They have no sense for us.
2020-05-09 11:15:03 +02:00
// if (defDSM) {
// dropDSM = gSettings.DropOEM_DSM; //if set by user
// }
2019-09-03 11:58:42 +02:00
2021-02-11 12:41:59 +01:00
if ( gSettings . ACPI . DSDT . DebugDSDT ) {
2020-11-06 08:31:30 +01:00
TableHeader = ( EFI_ACPI_DESCRIPTION_HEADER * ) ( UINTN ) FadtPointer - > XDsdt ;
bufferLen = TableHeader - > Length ;
2020-10-17 15:01:33 +02:00
DBG ( " Output DSDT before patch to %ls \\ ACPI \\ origin \\ DSDT-or.aml \n " , selfOem . getConfigDirFullPath ( ) . wc_str ( ) ) ;
Status = egSaveFile ( & selfOem . getConfigDir ( ) , L " ACPI \\ origin \\ DSDT-or.aml " , ( UINT8 * ) ( UINTN ) FadtPointer - > XDsdt , bufferLen ) ;
2019-09-03 11:58:42 +02:00
}
//native DSDT or loaded we want to apply autoFix to this
2021-02-11 12:41:59 +01:00
// if (gSettings.ACPI.DSDT.FixDsdt) { //fix even with zero mask because we want to know PCIRootUID and count(?)
DBG ( " Apply DsdtFixMask=0x%08X \n " , gSettings . ACPI . DSDT . FixDsdt ) ;
2020-05-09 11:15:03 +02:00
// DBG(" drop _DSM mask=0x%04hX\n", dropDSM);
2019-09-03 11:58:42 +02:00
FixBiosDsdt ( ( UINT8 * ) ( UINTN ) FadtPointer - > XDsdt , FadtPointer , OSVersion ) ;
2021-02-11 12:41:59 +01:00
if ( gSettings . ACPI . DSDT . DebugDSDT ) {
2019-09-03 11:58:42 +02:00
for ( Index = 0 ; Index < 60 ; Index + + ) {
2020-10-03 19:02:31 +02:00
XStringW DsdtPatchedName = SWPrintf ( " ACPI \\ origin \\ DSDT-pa%llu.aml " , Index ) ;
2020-10-17 15:01:33 +02:00
if ( ! FileExists ( & selfOem . getConfigDir ( ) , DsdtPatchedName ) ) {
Status = egSaveFile ( & selfOem . getConfigDir ( ) , DsdtPatchedName . wc_str ( ) , ( UINT8 * ) ( UINTN ) FadtPointer - > XDsdt , bufferLen ) ;
2019-09-03 11:58:42 +02:00
if ( ! EFI_ERROR ( Status ) ) {
break ;
}
}
}
if ( EFI_ERROR ( Status ) ) {
2020-08-25 17:35:19 +02:00
DBG ( " ...saving DSDT failed with status=%s \n " , efiStrError ( Status ) ) ;
2019-09-03 11:58:42 +02:00
}
}
// handle unusual situations with XSDT and RSDT
PreCleanupRSDT ( ) ;
PreCleanupXSDT ( ) ;
// XsdtReplaceSizes array is used to keep track of allocations for the merged tables,
// as those tables may need to be freed if patched later.
2020-08-15 15:47:56 +02:00
XsdtReplaceSizes = ( __typeof__ ( XsdtReplaceSizes ) ) AllocateZeroPool ( XsdtTableCount ( ) * sizeof ( * XsdtReplaceSizes ) ) ;
2019-09-03 11:58:42 +02:00
// Load merged ACPI files from ACPI/patched
2020-10-05 09:25:53 +02:00
LoadAllPatchedAML ( L " ACPI \\ patched " _XSW , AUTOMERGE_PASS1 ) ;
2019-09-03 11:58:42 +02:00
// Drop tables
2021-02-11 12:41:59 +01:00
if ( GlobalConfig . ACPIDropTables ) {
2019-09-03 11:58:42 +02:00
ACPI_DROP_TABLE * DropTable ;
DbgHeader ( " ACPIDropTables " ) ;
2021-02-11 12:41:59 +01:00
for ( DropTable = GlobalConfig . ACPIDropTables ; DropTable ; DropTable = DropTable - > Next ) {
2019-09-03 11:58:42 +02:00
if ( DropTable - > MenuItem . BValue ) {
//DBG("Attempting to drop \"%4.4a\" (%8.8X) \"%8.8a\" (%16.16lX) L=%d\n", &(DropTable->Signature), DropTable->Signature, &(DropTable->TableId), DropTable->TableId, DropTable->Length);
DropTableFromXSDT ( DropTable - > Signature , DropTable - > TableId , DropTable - > Length ) ;
DropTableFromRSDT ( DropTable - > Signature , DropTable - > TableId , DropTable - > Length ) ;
}
}
}
2021-03-15 10:02:34 +01:00
if ( GlobalConfig . DropSSDT ) {
2019-09-03 11:58:42 +02:00
DbgHeader ( " DropSSDT " ) ;
//special case if we set into menu drop all SSDT
DropTableFromXSDT ( EFI_ACPI_4_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE , 0 , 0 ) ;
DropTableFromRSDT ( EFI_ACPI_4_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE , 0 , 0 ) ;
}
//It's time to fix headers of all remaining ACPI tables.
// The bug reported by TheRacerMaster and https://alextjam.es/debugging-appleacpiplatform/
// Workaround proposed by cecekpawon, revised by Slice
PatchAllTables ( ) ;
// Load add-on ACPI files from ACPI/patched
2020-10-05 09:25:53 +02:00
LoadAllPatchedAML ( L " ACPI \\ patched " _XSW , AUTOMERGE_PASS2 ) ;
2019-09-03 11:58:42 +02:00
if ( XsdtReplaceSizes ) {
FreePool ( XsdtReplaceSizes ) ;
XsdtReplaceSizes = NULL ;
}
//Slice - this is a time to patch MADT table.
// DBG("Fool proof: size of APIC NMI = %d\n", sizeof(EFI_ACPI_2_0_LOCAL_APIC_NMI_STRUCTURE));
// DBG("----------- size of APIC DESC = %d\n", sizeof(EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER));
// DBG("----------- size of APIC PROC = %d\n", sizeof(EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE));
ApicCPUNum = 0 ;
// 2. For absent NMI subtable
xf = ScanXSDT ( APIC_SIGN , 0 ) ;
if ( xf ) {
ApicTable = ( EFI_ACPI_DESCRIPTION_HEADER * ) ( UINTN ) ( * xf ) ;
// ApicLen = ApicTable->Length;
ProcLocalApic = ( EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE * ) ( UINTN ) ( * xf + sizeof ( EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER ) ) ;
while ( ( ProcLocalApic - > Type = = EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC ) & & ( ProcLocalApic - > Length = = 8 ) ) {
if ( ProcLocalApic - > Flags & EFI_ACPI_4_0_LOCAL_APIC_ENABLED ) {
ApicCPUNum + + ;
}
ProcLocalApic + + ;
if ( ApicCPUNum > 16 ) {
DBG ( " Out of control with CPU numbers \n " ) ;
break ;
}
}
//fool proof
if ( ( ApicCPUNum = = 0 ) | | ( ApicCPUNum > 16 ) ) {
ApicCPUNum = gCPUStructure . Threads ;
}
2020-03-25 19:32:44 +01:00
DBG ( " ApicCPUNum=%llu \n " , ApicCPUNum ) ;
2019-09-03 11:58:42 +02:00
//reallocate table
2021-02-11 12:41:59 +01:00
if ( gSettings . ACPI . PatchNMI ) {
2019-09-03 11:58:42 +02:00
BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS ;
Status = gBS - > AllocatePages ( AllocateMaxAddress , EfiACPIReclaimMemory , 1 , & BufferPtr ) ;
if ( ! EFI_ERROR ( Status ) ) {
//save old table and drop it from XSDT
2020-10-03 19:02:31 +02:00
CopyMem ( ( void * ) ( UINTN ) BufferPtr , ApicTable , ApicTable - > Length ) ;
2019-09-03 11:58:42 +02:00
DropTableFromXSDT ( APIC_SIGN , 0 , 0 ) ;
ApicTable = ( EFI_ACPI_DESCRIPTION_HEADER * ) ( UINTN ) BufferPtr ;
ApicTable - > Revision = EFI_ACPI_4_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION ;
CopyMem ( & ApicTable - > OemId , oemID , 6 ) ;
CopyMem ( & ApicTable - > OemTableId , oemTableID , 8 ) ;
ApicTable - > OemRevision = 0x00000001 ;
CopyMem ( & ApicTable - > CreatorId , creatorID , 4 ) ;
SubTable = ( UINT8 * ) ( ( UINTN ) BufferPtr + sizeof ( EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER ) ) ;
Index = 0 ;
while ( * SubTable ! = EFI_ACPI_4_0_LOCAL_APIC_NMI ) {
DBG ( " Found subtable in MADT: type=%d \n " , * SubTable ) ;
if ( * SubTable = = EFI_ACPI_4_0_PROCESSOR_LOCAL_APIC ) {
ProcLocalApic = ( EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE * ) SubTable ;
2019-09-14 11:31:25 +02:00
// macOS assumes that the first processor from DSDT is always enabled, without checking MADT table
// here we're trying to assign first IDs found in DSDT to enabled processors in MADT, such that macOS assumption to be true
2019-09-03 11:58:42 +02:00
if ( ProcLocalApic - > Flags & EFI_ACPI_4_0_LOCAL_APIC_ENABLED ) {
2019-09-14 11:31:25 +02:00
if ( ProcLocalApic - > AcpiProcessorId ! = acpi_cpu_processor_id [ Index ] ) {
2020-04-17 15:14:24 +02:00
DBG ( " AcpiProcessorId changed: 0x%02hhX to 0x%02hhX \n " , ProcLocalApic - > AcpiProcessorId , acpi_cpu_processor_id [ Index ] ) ;
2019-09-14 11:31:25 +02:00
ProcLocalApic - > AcpiProcessorId = acpi_cpu_processor_id [ Index ] ;
2019-09-03 11:58:42 +02:00
} else {
2020-04-17 15:14:24 +02:00
DBG ( " AcpiProcessorId: 0x%02hhX \n " , ProcLocalApic - > AcpiProcessorId ) ;
2019-09-03 11:58:42 +02:00
}
Index + + ;
}
}
bufferLen = ( UINTN ) SubTable [ 1 ] ;
SubTable + = bufferLen ;
if ( ( ( UINTN ) SubTable - ( UINTN ) BufferPtr ) > = ApicTable - > Length ) {
break ;
}
}
if ( * SubTable = = EFI_ACPI_4_0_LOCAL_APIC_NMI ) {
DBG ( " LocalApicNMI is already present, no patch needed \n " ) ;
} else {
LocalApicNMI = ( EFI_ACPI_2_0_LOCAL_APIC_NMI_STRUCTURE * ) ( ( UINTN ) ApicTable + ApicTable - > Length ) ;
for ( Index = 0 ; Index < ApicCPUNum ; Index + + ) {
LocalApicNMI - > Type = EFI_ACPI_4_0_LOCAL_APIC_NMI ;
LocalApicNMI - > Length = sizeof ( EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCTURE ) ;
2019-09-14 16:02:39 +02:00
LocalApicNMI - > AcpiProcessorId = acpi_cpu_processor_id [ Index ] ;
2019-09-03 11:58:42 +02:00
LocalApicNMI - > Flags = 5 ;
LocalApicNMI - > LocalApicLint = 1 ;
LocalApicNMI + + ;
2019-09-14 16:02:39 +02:00
ApicTable - > Length + = sizeof ( EFI_ACPI_4_0_LOCAL_APIC_NMI_STRUCTURE ) ;
2019-09-03 11:58:42 +02:00
}
DBG ( " ApicTable new Length=%d \n " , ApicTable - > Length ) ;
// insert corrected MADT
}
Status = InsertTable ( ApicTable , ApicTable - > Length ) ;
if ( ! EFI_ERROR ( Status ) ) {
DBG ( " New APIC table successfully inserted \n " ) ;
}
/*
2020-10-03 19:02:31 +02:00
Status = egSaveFile ( & self . getSelfRootDir ( ) , PatchedAPIC , ( UINT8 * ) ApicTable , ApicTable - > Length ) ;
2019-09-03 11:58:42 +02:00
if ( EFI_ERROR ( Status ) ) {
Status = egSaveFile ( NULL , PatchedAPIC , ( UINT8 * ) ApicTable , ApicTable - > Length ) ;
}
if ( ! EFI_ERROR ( Status ) ) {
DBG ( " Patched APIC table saved into efi/clover/acpi/origin/APIC-p.aml \n " ) ;
}
*/
}
}
}
else {
DBG ( " No APIC table Found !!! \n " ) ;
}
if ( gCPUStructure . Threads > = gCPUStructure . Cores ) {
ApicCPUNum = gCPUStructure . Threads ;
} else {
ApicCPUNum = gCPUStructure . Cores ;
}
// }
/*
At this moment we have CPU numbers from DSDT - acpi_cpu_num
and from CPU characteristics gCPUStructure
Also we had the number from APIC table ApicCPUNum
What to choose ?
Since rev745 I will return to acpi_cpu_count global variable
*/
if ( acpi_cpu_count ) {
ApicCPUNum = acpi_cpu_count ;
}
2021-02-11 12:41:59 +01:00
if ( gSettings . ACPI . SSDT . Generate . GeneratePStates | | gSettings . ACPI . SSDT . Generate . GeneratePluginType ) {
2019-09-03 11:58:42 +02:00
Status = EFI_NOT_FOUND ;
2019-09-13 12:45:30 +02:00
Ssdt = generate_pss_ssdt ( ApicCPUNum ) ;
2019-09-03 11:58:42 +02:00
if ( Ssdt ) {
Status = InsertTable ( Ssdt , Ssdt - > Length ) ;
}
if ( EFI_ERROR ( Status ) ) {
2020-08-25 17:35:19 +02:00
DBG ( " GeneratePStates failed: Status=%s \n " , efiStrError ( Status ) ) ;
2019-09-03 11:58:42 +02:00
}
}
2021-02-11 12:41:59 +01:00
if ( gSettings . ACPI . SSDT . Generate . GenerateCStates ) {
2019-09-03 11:58:42 +02:00
Status = EFI_NOT_FOUND ;
2019-09-13 12:45:30 +02:00
Ssdt = generate_cst_ssdt ( FadtPointer , ApicCPUNum ) ;
2019-09-03 11:58:42 +02:00
if ( Ssdt ) {
Status = InsertTable ( Ssdt , Ssdt - > Length ) ;
}
if ( EFI_ERROR ( Status ) ) {
2020-08-25 17:35:19 +02:00
DBG ( " GenerateCStates failed Status=%s \n " , efiStrError ( Status ) ) ;
2019-09-03 11:58:42 +02:00
}
}
// remove NULL entries from RSDT and XSDT
PostCleanupRSDT ( ) ;
PostCleanupXSDT ( ) ;
if ( NeedUpdate ) {
gBS - > InstallConfigurationTable ( & gEfiAcpiTableGuid , RsdPointer ) ;
gBS - > InstallConfigurationTable ( & gEfiAcpi10TableGuid , RsdPointer ) ;
}
//free regions?
while ( gRegions ) {
tmpRegion = gRegions - > next ;
FreePool ( gRegions ) ;
gRegions = tmpRegion ;
}
return EFI_SUCCESS ;
}
/**
* Searches for TableName in PathPatched dirs and loads it
* to Buffer if found . Buffer is allocated here and should be released
* by caller .
*/
EFI_STATUS LoadAcpiTable (
2020-08-09 17:55:30 +02:00
CONST CHAR16 * PathPatched ,
CONST CHAR16 * TableName ,
2019-09-03 11:58:42 +02:00
UINT8 * * Buffer ,
2020-08-09 17:55:30 +02:00
UINTN * BufferLen
2019-09-03 11:58:42 +02:00
)
{
EFI_STATUS Status ;
Status = EFI_NOT_FOUND ;
// checking \EFI\ACPI\patched dir
2020-08-09 17:55:30 +02:00
XStringW TmpStr = SWPrintf ( " %ls \\ %ls " , PathPatched , TableName ) ;
2020-10-03 19:02:31 +02:00
if ( FileExists ( & self . getCloverDir ( ) , TmpStr ) ) {
2020-08-09 17:55:30 +02:00
DBG ( " found %ls \n " , TmpStr . wc_str ( ) ) ;
2020-10-03 19:02:31 +02:00
Status = egLoadFile ( & self . getCloverDir ( ) , TmpStr . wc_str ( ) , Buffer , BufferLen ) ;
2019-09-03 11:58:42 +02:00
}
return Status ;
}
/**
* Searches for DSDT in AcpiOemPath or PathPatched dirs and inserts it
* to FadtPointer if found .
*/
2020-08-09 17:55:30 +02:00
EFI_STATUS LoadAndInjectDSDT ( CONST CHAR16 * PathPatched ,
2019-09-03 11:58:42 +02:00
EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * FadtPointer )
{
EFI_STATUS Status ;
UINT8 * Buffer = NULL ;
UINTN BufferLen = 0 ;
EFI_PHYSICAL_ADDRESS Dsdt ;
// load if exists
2021-02-11 12:41:59 +01:00
Status = LoadAcpiTable ( PathPatched , gSettings . ACPI . DSDT . DsdtName . wc_str ( ) , & Buffer , & BufferLen ) ;
2019-09-03 11:58:42 +02:00
if ( ! EFI_ERROR ( Status ) ) {
// loaded - allocate EfiACPIReclaim
2021-02-11 12:41:59 +01:00
DBG ( " Loaded DSDT at \\ %ls \\ %ls \\ %ls \n " , self . getCloverDirFullPath ( ) . wc_str ( ) , PathPatched , gSettings . ACPI . DSDT . DsdtName . wc_str ( ) ) ;
2019-09-03 11:58:42 +02:00
Dsdt = EFI_SYSTEM_TABLE_MAX_ADDRESS ; //0xFE000000;
Status = gBS - > AllocatePages (
AllocateMaxAddress ,
EfiACPIReclaimMemory ,
EFI_SIZE_TO_PAGES ( BufferLen ) ,
& Dsdt
) ;
if ( ! EFI_ERROR ( Status ) ) {
// copy DSDT into EfiACPIReclaim block
2020-10-03 19:02:31 +02:00
CopyMem ( ( void * ) ( UINTN ) Dsdt , Buffer , BufferLen ) ;
2019-09-03 11:58:42 +02:00
// update FADT
FadtPointer - > Dsdt = ( UINT32 ) Dsdt ;
FadtPointer - > XDsdt = Dsdt ;
FixChecksum ( & FadtPointer - > Header ) ;
2020-10-10 15:31:14 +02:00
DBG ( " DSDT at 0x%llX injected to FADT 0x%llx \n " , Dsdt , ( UINTN ) FadtPointer ) ;
2019-09-03 11:58:42 +02:00
}
2020-10-14 09:32:36 +02:00
if ( Buffer ) FreePool ( Buffer ) ;
2019-09-03 11:58:42 +02:00
}
return Status ;
}
/**
* Searches for TableName in AcpiOemPath or PathPatched dirs and inserts it
* to Rsdt and / or Xsdt ( globals ) if found .
*/
2020-08-09 17:55:30 +02:00
EFI_STATUS LoadAndInjectAcpiTable ( CONST CHAR16 * PathPatched ,
CONST CHAR16 * TableName )
2019-09-03 11:58:42 +02:00
{
EFI_STATUS Status ;
UINT8 * Buffer = NULL ;
UINTN BufferLen = 0 ;
EFI_ACPI_DESCRIPTION_HEADER * TableHeader = NULL ;
// load if exists
Status = LoadAcpiTable ( PathPatched , TableName , & Buffer , & BufferLen ) ;
if ( ! EFI_ERROR ( Status ) ) {
if ( Buffer ) {
// if this is SLIC, then remove previous SLIC if it is there
TableHeader = ( EFI_ACPI_DESCRIPTION_HEADER * ) Buffer ;
if ( TableHeader - > Signature = = SLIC_SIGN ) {
DropTableFromXSDT ( SLIC_SIGN , 0 , 0 ) ;
DropTableFromRSDT ( SLIC_SIGN , 0 , 0 ) ;
}
}
// loaded - insert it into XSDT/RSDT
Status = InsertTable ( Buffer , BufferLen ) ;
if ( ! EFI_ERROR ( Status ) ) {
2020-03-25 19:32:44 +01:00
DBG ( " Table %ls inserted. \n " , TableName ) ;
2019-09-03 11:58:42 +02:00
// if this was SLIC, then update IDs in XSDT/RSDT
if ( TableHeader - > Signature = = SLIC_SIGN ) {
if ( Rsdt ) {
2020-03-25 19:32:44 +01:00
DBG ( " SLIC: Rsdt OEMid '%6.6s', TabId '%8.8s' " , ( CHAR8 * ) & Rsdt - > Header . OemId , ( CHAR8 * ) & Rsdt - > Header . OemTableId ) ;
2019-09-03 11:58:42 +02:00
CopyMem ( & Rsdt - > Header . OemId , & TableHeader - > OemId , 6 ) ;
Rsdt - > Header . OemTableId = TableHeader - > OemTableId ;
2020-03-25 19:32:44 +01:00
DBG ( " to OEMid '%6.6s', TabId '%8.8s' \n " , ( CHAR8 * ) & Rsdt - > Header . OemId , ( CHAR8 * ) & Rsdt - > Header . OemTableId ) ;
2019-09-03 11:58:42 +02:00
}
if ( Xsdt ) {
2020-03-25 19:32:44 +01:00
DBG ( " SLIC: Xsdt OEMid '%6.6s', TabId '%8.8s' " , ( CHAR8 * ) & Xsdt - > Header . OemId , ( CHAR8 * ) & Xsdt - > Header . OemTableId ) ;
2019-09-03 11:58:42 +02:00
CopyMem ( & Xsdt - > Header . OemId , & TableHeader - > OemId , 6 ) ;
Xsdt - > Header . OemTableId = TableHeader - > OemTableId ;
2020-03-25 19:32:44 +01:00
DBG ( " to OEMid '%6.6s', TabId '%8.8s' \n " , ( CHAR8 * ) & Xsdt - > Header . OemId , ( CHAR8 * ) & Xsdt - > Header . OemTableId ) ;
2019-09-03 11:58:42 +02:00
}
}
} else {
2020-08-25 17:35:19 +02:00
DBG ( " Insert return status %s \n " , efiStrError ( Status ) ) ;
2019-09-03 11:58:42 +02:00
}
FreePool ( Buffer ) ;
} // if table loaded
return Status ;
}
/**
* Patches UEFI ACPI tables with tables found in OsSubdir .
*/
2021-09-28 10:28:45 +02:00
EFI_STATUS PatchACPI_OtherOS ( CONST CHAR16 * OsSubdir , XBool DropSSDT )
2019-09-03 11:58:42 +02:00
{
EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER * RsdPointer ;
EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * FadtPointer ;
EFI_STATUS Status ; // = EFI_SUCCESS;
// UINTN Index;
REFIT_DIR_ITER DirIter ;
EFI_FILE_INFO * DirEntry ;
//
// Search for RSDP in UEFI SystemTable/ConfigTable (first Acpi 2.0, then 1.0)
//
RsdPointer = NULL ;
2020-10-03 19:02:31 +02:00
Status = EfiGetSystemConfigurationTable ( & gEfiAcpi20TableGuid , ( void * * ) & RsdPointer ) ;
2019-09-03 11:58:42 +02:00
if ( RsdPointer ! = NULL ) {
2020-03-25 19:32:44 +01:00
DBG ( " OtherOS: Found Acpi 2.0 RSDP 0x%llX \n " , ( uintptr_t ) RsdPointer ) ;
2019-09-03 11:58:42 +02:00
} else {
2020-10-03 19:02:31 +02:00
Status = EfiGetSystemConfigurationTable ( & gEfiAcpi10TableGuid , ( void * * ) & RsdPointer ) ;
2019-09-03 11:58:42 +02:00
if ( RsdPointer ! = NULL ) {
2020-03-25 19:32:44 +01:00
DBG ( " Found Acpi 1.0 RSDP 0x%llX \n " , ( uintptr_t ) RsdPointer ) ;
2019-09-03 11:58:42 +02:00
}
}
// if RSDP not found - quit
if ( ! RsdPointer ) {
2020-05-15 05:23:33 +02:00
return Status ;
2019-09-03 11:58:42 +02:00
}
//
// Find RSDT and/or XSDT
//
Rsdt = ( RSDT_TABLE * ) ( UINTN ) ( RsdPointer - > RsdtAddress ) ;
if ( Rsdt ! = NULL & & Rsdt - > Header . Signature ! = EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE ) {
Rsdt = NULL ;
}
2020-04-28 22:42:53 +02:00
DBG ( " RSDT at 0x%llX \n " , ( UINTN ) Rsdt ) ;
2019-09-03 11:58:42 +02:00
// check for XSDT
Xsdt = NULL ;
if ( RsdPointer - > Revision > = 2 & & ( RsdPointer - > XsdtAddress < ( UINT64 ) ( ( UINTN ) ( - 1 ) ) ) ) {
Xsdt = ( XSDT_TABLE * ) ( UINTN ) RsdPointer - > XsdtAddress ;
if ( Xsdt ! = NULL & & Xsdt - > Header . Signature ! = EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE ) {
Xsdt = NULL ;
}
}
2020-04-28 22:42:53 +02:00
DBG ( " XSDT at 0x%llX \n " , ( UINTN ) Xsdt ) ;
2019-09-03 11:58:42 +02:00
// if RSDT and XSDT not found - quit
if ( Rsdt = = NULL & & Xsdt = = NULL ) {
return EFI_UNSUPPORTED ;
}
//
// Take FADT (FACP) from XSDT or RSDT (always first entry)
//
FadtPointer = NULL ;
if ( Xsdt ) {
FadtPointer = ( EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * ) ( UINTN ) ( Xsdt - > Entry ) ;
} else if ( Rsdt ) {
FadtPointer = ( EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * ) ( UINTN ) ( Rsdt - > Entry ) ;
}
2020-04-28 22:42:53 +02:00
DBG ( " FADT pointer = 0x%llX \n " , ( UINTN ) FadtPointer ) ;
2019-09-03 11:58:42 +02:00
// if not found - quit
if ( FadtPointer = = NULL ) {
return EFI_NOT_FOUND ;
}
//
// Inject/drop tables
//
// prepare dirs that will be searched for custom ACPI tables
2020-08-09 17:55:30 +02:00
XStringW PathPatched ;
2020-10-17 15:01:33 +02:00
if ( selfOem . oemDirExists ( ) ) {
PathPatched = SWPrintf ( " %ls \\ ACPI \\ %ls " , selfOem . getOemPathRelToSelfDir ( ) . wc_str ( ) , OsSubdir ) ;
if ( ! FileExists ( & self . getCloverDir ( ) , PathPatched ) ) {
PathPatched . setEmpty ( ) ;
}
2019-09-03 11:58:42 +02:00
}
2020-10-17 15:01:33 +02:00
if ( PathPatched . isEmpty ( ) ) {
PathPatched = SWPrintf ( " ACPI \\ %ls " , OsSubdir ) ;
if ( ! FileExists ( & self . getCloverDir ( ) , PathPatched ) ) {
DBG ( " Dir ' \\ %ls \\ %ls' not found. No patching will be done. \n " , self . getCloverDirFullPath ( ) . wc_str ( ) , PathPatched . wc_str ( ) ) ;
return EFI_NOT_FOUND ;
}
2019-09-03 11:58:42 +02:00
}
//
// Inject DSDT
//
2020-08-09 17:55:30 +02:00
/* Status = */ LoadAndInjectDSDT ( PathPatched . wc_str ( ) , FadtPointer ) ;
2019-09-03 11:58:42 +02:00
//
// Drop SSDT if requested. Not until now
//
/*
if ( DropSSDT ) {
DropTableFromXSDT ( EFI_ACPI_4_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE , 0 , 0 ) ;
DropTableFromRSDT ( EFI_ACPI_4_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE , 0 , 0 ) ;
}
*/
2021-02-11 12:41:59 +01:00
if ( GlobalConfig . ACPIDropTables ) {
2020-04-20 18:33:42 +02:00
ACPI_DROP_TABLE * DropTable ;
DbgHeader ( " ACPIDropTables " ) ;
2021-02-11 12:41:59 +01:00
for ( DropTable = GlobalConfig . ACPIDropTables ; DropTable ; DropTable = DropTable - > Next ) {
2020-04-20 18:33:42 +02:00
// only for tables that have OtherOS true
if ( DropTable - > OtherOS & & DropTable - > MenuItem . BValue ) {
//DBG("Attempting to drop \"%4.4a\" (%8.8X) \"%8.8a\" (%16.16lX) L=%d\n", &(DropTable->Signature), DropTable->Signature, &(DropTable->TableId), DropTable->TableId, DropTable->Length);
DropTableFromXSDT ( DropTable - > Signature , DropTable - > TableId , DropTable - > Length ) ;
DropTableFromRSDT ( DropTable - > Signature , DropTable - > TableId , DropTable - > Length ) ;
}
}
}
2019-09-03 11:58:42 +02:00
//
// find and inject other ACPI tables
//
2020-10-03 19:02:31 +02:00
DirIterOpen ( & self . getCloverDir ( ) , PathPatched . wc_str ( ) , & DirIter ) ;
2019-09-03 11:58:42 +02:00
while ( DirIterNext ( & DirIter , 2 , L " *.aml " , & DirEntry ) ) {
if ( DirEntry - > FileName [ 0 ] = = L ' . ' ) {
continue ;
}
if ( StrStr ( DirEntry - > FileName , L " DSDT " ) ) {
continue ;
}
2020-08-09 17:55:30 +02:00
LoadAndInjectAcpiTable ( PathPatched . wc_str ( ) , DirEntry - > FileName ) ;
2019-09-03 11:58:42 +02:00
}
/*Status = */ DirIterClose ( & DirIter ) ;
// remove NULL entries from RSDT and XSDT
PostCleanupRSDT ( ) ;
PostCleanupXSDT ( ) ;
return EFI_SUCCESS ;
}