Jump to content

Clover Problems and Solutions


ErmaC
3,206 posts in this topic

Recommended Posts

Perhaps this?

 

  if ((PciRead16 (PCI_ICH_LPC_ADDRESS (0))) != 0x8086) { // Intel ICH device was not found
    AsciiSPrint(InitError, sizeof(InitError), "Intel ICH device was not found.");
  } else if ((PciRead8 (PCI_ICH_LPC_ADDRESS (R_ICH_LPC_ACPI_CNT)) & B_ICH_LPC_ACPI_CNT_ACPI_EN) == 0) { // Check for TSC at LPC (default location)
    if ((PciRead8 (PCI_ICH_SMBUS_ADDRESS (R_ICH_SMBUS_ACPI_CNT)) & B_ICH_SMBUS_ACPI_CNT_ACPI_EN) != 0) { // Check for TSC at SMBUS (Skylake specific)
      TimerAddr = (PciRead16 (PCI_ICH_SMBUS_ADDRESS (R_ICH_SMBUS_ACPI_BASE)) & B_ICH_SMBUS_ACPI_BASE_BAR) + R_ACPI_PM1_TMR;
    } else {
      AsciiSPrint(InitError, sizeof(InitError), "ACPI I/O space is not enabled.");
    }
  } else if ((TimerAddr = ((PciRead16 (PCI_ICH_LPC_ADDRESS (R_ICH_LPC_ACPI_BASE))) & B_ICH_LPC_ACPI_BASE_BAR) + R_ACPI_PM1_TMR) == 0) { // Timer address can't be obtained
    AsciiSPrint(InitError, sizeof(InitError), "Timer address can't be obtained.");
  } else {
    // Check that Timer is advancing
    AcpiTick0 = IoRead32 (TimerAddr);
    gBS->Stall(1000); // 1ms
    AcpiTick1 = IoRead32(TimerAddr);
    if (AcpiTick0 == AcpiTick1) { // Timer is not advancing
      TimerAddr = 0; // Flag it as not working
      AsciiSPrint(InitError, sizeof(InitError), "Timer is not advancing.");
    }
  }

Sorry, you are right. I will commit your solution. But where did you get this constants?

Compiling build tools with gcc6 via brew works but introduces other errors in build

 

edit:

that's compiling with gcc5.3.0 for Clover....

 

edit2:

To do that cd edk2

make -C BaseTools CC=gcc-6

As far as I remember you are creator of CloverGrowerElite. Where can I download it?

Link to comment
Share on other sites

@RehabMan Did you test the Reloc block size idea? An Oz user PM'd me, having had the same issue, and said that disabling SIP works... sounds like Apple f*cked something up or they want to tease us with SIP.

I'm running with the modified OsxAptioFixDrv-64.efi (currently have mine set at 256mb, as someone requested it).

 

But I run with CsrActiveConfig=0x67. SIP has no value for me, so I keep it disabled.

 

The 128mb OsxAptioFixDrv-64.efi has been confirmed working for several. For one, 0x67 did not work and 128mb AptioFix required. For another, 128mb AptioFix did not work and 0x67 required (still waiting for feedback on 256mb).

 

Go figure...

 

Apple probably wants to keep us guessing...

Link to comment
Share on other sites

Tbh, dmazar in all honor, AptioFix needs a rewrite quite badly. Today I had an idea on how to completely get rid of reloc-block vs no-reloc-block, but I could not confirm by testing and I might (as usually :) ) have some flaw in my idea.

My idea was to override AllocatePages to call gBS.AllocatePages. If the error code indicates the area is already occupied, use gBS.AllocatePool to allocate the data anywhere and add the original allocation request + the new, temp. address to an array. When the kernel is started, skip through the array and copy stuff from the old to the new address.

To end up with a clean solution, we should also override GetMemoryMap to return the map as if the allocation was successful (i.e. mark the data that blocked our allocation as conventional memory and add the boot.efi entries).

 

Any thoughts?

 

EDIT: For the Fix stuff (fix the addresses of the relocated data), one would need to check which data chunk it was in and then get the "RelocBase" per-case by calcing the diff of the old and the new address, I guess...

EDIT2: Ok, we cannot use AllocatePool because the data should be allocated < 4GB (32-bit addresses)... easy fix, use AllocatePages with 4GB as max addr ;)

Link to comment
Share on other sites

Tbh, dmazar in all honor, AptioFix needs a rewrite quite badly. Today I had an idea on how to completely get rid of reloc-block vs no-reloc-block, but I could not confirm by testing and I might (as usually :) ) have some flaw in my idea.

My idea was to override AllocatePages to call gBS.AllocatePages. If the error code indicates the area is already occupied, use gBS.AllocatePool to allocate the data anywhere and add the original allocation request + the new, temp. address to an array. When the kernel is started, skip through the array and copy stuff from the old to the new address.

To end up with a clean solution, we should also override GetMemoryMap to return the map as if the allocation was successful (i.e. mark the data that blocked our allocation as conventional memory and add the boot.efi entries).

 

Any thoughts?

 

EDIT: For the Fix stuff (fix the addresses of the relocated data), one would need to check which data chunk it was in and then get the "RelocBase" per-case by calcing the diff of the old and the new address, I guess...

Wish I knew more about what's really going on here...

 

From your previous reply (#328), I'm getting the impression that this relocation block is used to force future allocations into a different range of addresses? It seems that would make it rather system dependent...

Link to comment
Share on other sites

@RehabMan Yes, with the relocation block, all allocations (of fixed addresses) are 'shifted' by the RelocBase.

@STLVNUB I refactored the definitions from the SMBIOS Protocol header to the IndustryStandard header... Clover's 'SmbiosA.h' has the same header guard macro as the original, so it overrides it and that creates the error. So, do it properly and extract the Apple types into a second file (so you have MdePkg'S SmBios.h and AppleSmBios.h in Clover), or update SmbiosA. :)

Link to comment
Share on other sites

@Download-Fritz: How does this look? I moved the Apple/OEM-specific types to AppleSmBios.h. Seems to compile and work fine.

 

Exactly how I wanted to do it for ApplePkg... and might eventually do. :)

 

EDIT: If you want to make it even cleaner, prefix Apple tables with 'APPLE_', that way you can be sure it won't ever conflict with anything else.

 

EDIT2: So, I started with some code for the new AptioFix technique. Overriding AllocatePages, first the hibernation image check is done (unchanged). Next, if it is not a hibernate-wake and if a fixed-address allocation from boot.efi fails, a buffer with Destination (where boot.efi originally wanted the data), Source (where the data is relocated) and some data for later cosmetic use is (Re)Allocated from BootServices Pool memory. Next, an allocation with AllocatePagesFromTop is made (4GB top) for the data boot.efi wants, the relocation data is stored in one entry of the buffer and the new address is returned.

 

On ExitBootServices(), now it's checking if the counter variable for the relocations is greater than zero to overwrite the Kernel Entry, as we don't need the overwrite if we need no copying back.

 

Along the entire control flow, I replaced the usages of gRelocBase with per-block calculations, calculating the Destination from the Source address by getting the relocation information entry from the previously allocated buffer, check the bounds and if contained, return Destination - Source. This is an INT32, which could be positive or negative, but is negative in all normal cases (as boot.efi does not (yet) allocate > 4GB). Currently I cast the input address from UINT32 to INT64 and add the RelocBase, so in theory positive bases shall work, and cast that back to UINT32 (boot.efi/kernel currently use 32-bit addressing only).

 

Tomorrow I will look at the Kernel Overwrite as it is the last fundamental piece to make it work. Till now I obviously couldn't test stuff and this is all raw code.

 

Please comment if someone has better ideas, practices or whatever. :)

 

EDIT3: Does anyone remember, why hibernation is not possible with AptioFix1?

  • Like 4
Link to comment
Share on other sites

As suggested, reverted edk2 back to r20288 and was able to build Clover on both my desktop (10.9.5, Xcode 6.2) and my laptop (10.11.4, Xcode 7.3). The Apple's compiler changes have nothing to do with the recent build issues, it's all the edk2 base.

  • Like 1
Link to comment
Share on other sites

[...] Today I had an idea on how to completely get rid of reloc-block vs no-reloc-block, but I could not confirm by testing and I might (as usually :) ) have some flaw in my idea.

My idea was to override AllocatePages to call gBS.AllocatePages. If the error code indicates the area is already occupied, use gBS.AllocatePool to allocate the data anywhere and add the original allocation request + the new, temp. address to an array. When the kernel is started, skip through the array and copy stuff from the old to the new address.

To end up with a clean solution, we should also override GetMemoryMap to return the map as if the allocation was successful (i.e. mark the data that blocked our allocation as conventional memory and add the boot.efi entries).

 

Any thoughts?

 

EDIT: For the Fix stuff (fix the addresses of the relocated data), one would need to check which data chunk it was in and then get the "RelocBase" per-case by calcing the diff of the old and the new address, I guess...

EDIT2: Ok, we cannot use AllocatePool because the data should be allocated < 4GB (32-bit addresses)... easy fix, use AllocatePages with 4GB as max addr ;)

 

Finally had an ideas on how to handle the case that RT data is in a block the boot.efi wants to reserve.

 

1) Relocate the boot.efi datablock as described above.

2) Reserve memory blocks for the RT data relocation.

3) Override GetMemoryMap. When it is called by boot.efi, remove the RT flag/type from the conflicting block. boot.efi will later map the reserved block from above.

​4) Override SetVirtualAddressMap. When called by boot.efi, mod the Memory Map it provides to replace the addresses of the new RT block (buffers from 2) with the old ones. This will make ConvertPointer() calls work for the RT drivers. Copy RT data blocks to the new location, as all pointers will already be updated.

5) Overwrite the kernel entry (as done currently and in my proposal) to copy the RT code blocks from the conflicting block to the new block (this late, in case something has changed).

6) Move the relocated boot.efi data block into its proper location.

 

By now, if the RT block belongs to a UEFI spec-compliant non-SMM driver, everything should be fine.

 

Possible issues:

1) If it was a SMM block, stuff will be screwed because SMM drivers continue to access memory in physical address mode and thus the pointers it uses will never be updated.

 

Please comment. ;)

 

EDIT1: Updated steps 4 and 5.

  • Like 1
Link to comment
Share on other sites

I corrected Smbios problem in Clover 3379. Now it is compatible with EDK2-20404.

 

'+#ifndef SMBIOS_TYPE'

 

ifndef does not work on C types per specification, only on preprocessor macros, and thus this will cause issues for compilers that actually care for standards. Why don't you apply the changes by TheRacterMaster?

Link to comment
Share on other sites

EDK2 problem is indeed solved, however, now I have this (Clover 3380):

Traceback (most recent call last):
  File "/Volumes/Valinor/Hackintosh/CloverGrowerPro/edk2/BaseTools/BinWrappers/PosixLike/../../Source/Python/build/build.py", line 41, in <module>
    from AutoGen.AutoGen import *
  File "/Volumes/Valinor/Hackintosh/CloverGrowerPro/edk2/BaseTools/Source/Python/AutoGen/AutoGen.py", line 22, in <module>
    import GenC
  File "/Volumes/Valinor/Hackintosh/CloverGrowerPro/edk2/BaseTools/Source/Python/AutoGen/GenC.py", line 871
    AutoGenH.Append('#define %s  LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))
           ^
IndentationError: expected an indented block
Cloverx64 release  ERROR!!
Link to comment
Share on other sites

'+#ifndef SMBIOS_TYPE'

 

ifndef does not work on C types per specification, only on preprocessor macros, and thus this will cause issues for compilers that actually care for standards. Why don't you apply the changes by TheRacterMaster?

SMBIOS_TYPE is not C type, it is preprocessor macro.

 

A solution by TheRacerMaster may be better, I just had no much time to explore it.

Link to comment
Share on other sites

SMBIOS_TYPE is not C type, it is preprocessor macro.

 

No, it is a C type.

 

EDK2:  'typedef UINT8 SMBIOS_TYPE;' (line 121, https://github.com/tianocore/edk2/blob/master/MdePkg/Include/IndustryStandard/SmBios.h)

Clover: 'typedef UINT8  SMBIOS_TYPE;' (line 28, https://sourceforge.net/p/cloverefiboot/code/3379/tree//Include/IndustryStandard/SmbiosA.h)

  • Like 1
Link to comment
Share on other sites

×
×
  • Create New...