Chameleon

Issue 21: EFI64 does not work well with netbook

Reported by neo lnx, Apr 26, 2010

When switching from Chameleon2rc3 to the Chameleon2rc4 (and the last 
svn release). The netbook (running i386 mode) with 10.6.3 didn't 
work very well with new EFI64 scheme. At least two issues have been 
spotted:

1) Failed to automatically create "options" child under 
IODeviceTree, thus vanilla AppleHDA creates error logs.

2) "unable to determine UUID for host. Error: 35" fix does 
not work anymore.

Using quick and dirty hack of fake_efi.c, i.e. changing EFI64 back 
to EFI32, the issues went away. Thus it is related to EFI64.

Hopefully, the new release will support both EFI32 and EFI64.

Comment 1 by ryu k, Apr 30, 2010

Hi,I did same workaround.

To enable EFI64 on recent kernel, cpu must have EM64 feature.

see ->
http://www.opensource.apple.com/source/xnu/xnu-1504.3.12/osfmk/i386/A
T386/model_dep.c:efi_set_tables_64()

        if (!cpu_mode_is64bit()) {
            kprintf("Skipping 64-bit EFI runtime services for 
32-bit legacy mode\n");			
            break;
        }

Code breaks above line, so don't publish 
"runtime-services" property.
cause
-> Can't load AppleEFIRuntime -> Can't load AppleEFINVRAM
cause
-> lack of /options and UUID fix.

Cpus doesn't have EM64(atom, CoreSolo and duo ) still need EM32.

I tried kernel patch to avoid above break, but no luck.

In Chameleon's code, condition is !(Platform.CPU.Features & 
CPU_FEATURE_EM64T ).

Comment 2 by Azimutz, May 10, 2010

Hi guys,
can you test the attached file? EMT64 is always detected on my 
Pentium D, even booting with "legacy" kernel, so i can't 
test it. If i "force" EFI32 i get kp pointing to 
AppleEFINVRAM & AppleEFIRuntime.
This sets EFI64 on my cpu, so i guess it will work fine for you 
guys!?

Comment 3 by ryu k, May 10, 2010

Hi, Azimutz.

It's not so simple.
We must use EFI_SYSTEM_TABLE_32 structure with "EFI32"

Below is my "EFI32" patch.

To implement both EFI64 and EFI32 in one source code
needs some consideration.

--- trunk/i386/libsaio/fake_efi.c	2010-04-22 20:38:07.000000000 
+0900
+++ src/i386/libsaio/fake_efi.c	2010-04-24 14:32:41.000000000 +0900
@@ -67,10 +67,11 @@
 








/*==========================================================================
  * Function to map 32 bit physical address to 64 bit virtual 
address
  */
-static uint64_t ptov64(uint32_t addr)
-{
-  return ((uint64_t)addr | 0xFFFFFF8000000000ULL);
-}
+//static uint64_t ptov64(uint32_t addr)
+//{
+//  return ((uint64_t)addr | 0xFFFFFF8000000000ULL);
+//}
+#define ptov64(x) x
 
 
 








/*==========================================================================
@@ -100,15 +101,15 @@
  */
 struct fake_efi_pages
 {
-    EFI_SYSTEM_TABLE_64 efiSystemTable;
-    EFI_RUNTIME_SERVICES_64 efiRuntimeServices;
-    EFI_CONFIGURATION_TABLE_64 
efiConfigurationTable[MAX_CONFIGURATION_TABLE_ENTRIES];
+    EFI_SYSTEM_TABLE_32 efiSystemTable;
+    EFI_RUNTIME_SERVICES_32 efiRuntimeServices;
+    EFI_CONFIGURATION_TABLE_32 
efiConfigurationTable[MAX_CONFIGURATION_TABLE_ENTRIES];
     EFI_CHAR16 
firmwareVendor[sizeof(FIRMWARE_VENDOR)/sizeof(EFI_CHAR16)];
     uint8_t 
voidret_instructions[sizeof(VOIDRET_INSTRUCTIONS)/sizeof(uint8_t)];
     uint8_t 
unsupportedret_instructions[sizeof(UNSUPPORTEDRET_INSTRUCTIONS)/sizeo
f(uint8_t)];
 };
 
-EFI_SYSTEM_TABLE_64 *gST = NULL;
+EFI_SYSTEM_TABLE_32 *gST = NULL;
 Node *gEfiConfigurationTableNode = NULL;
 
 extern EFI_STATUS addConfigurationTable(EFI_GUID const *pGuid, void 
*table, char const *alias)
@@ -124,8 +125,8 @@
     if(table != NULL)
     {
     	/* FIXME
-        ((EFI_CONFIGURATION_TABLE_64 
*)gST->ConfigurationTable)[i].VendorGuid = *pGuid;
-        ((EFI_CONFIGURATION_TABLE_64 
*)gST->ConfigurationTable)[i].VendorTable = (EFI_PTR64)table;
+        ((EFI_CONFIGURATION_TABLE_32 
*)gST->ConfigurationTable)[i].VendorGuid = *pGuid;
+        ((EFI_CONFIGURATION_TABLE_32 
*)gST->ConfigurationTable)[i].VendorTable = (EFI_PTR32)table;
 
         ++gST->NumberOfTableEntries;
 		  */
@@ -146,7 +147,7 @@
     return EFI_UNSUPPORTED;
 }
 
-static inline void fixupEfiSystemTableCRC32(EFI_SYSTEM_TABLE_64 
*efiSystemTable)
+static inline void fixupEfiSystemTableCRC32(EFI_SYSTEM_TABLE_32 
*efiSystemTable)
 {
     efiSystemTable->Hdr.CRC32 = 0;
     efiSystemTable->Hdr.CRC32 = crc32(0L, efiSystemTable, 
efiSystemTable->Hdr.HeaderSize);
@@ -176,10 +177,10 @@
 
     /* 
-------------------------------------------------------------------- 
*/
     /* System table */
-    EFI_SYSTEM_TABLE_64 *efiSystemTable = gST = 
&fakeEfiPages->efiSystemTable;
+    EFI_SYSTEM_TABLE_32 *efiSystemTable = gST = 
&fakeEfiPages->efiSystemTable;
     efiSystemTable->Hdr.Signature = EFI_SYSTEM_TABLE_SIGNATURE;
     efiSystemTable->Hdr.Revision = EFI_SYSTEM_TABLE_REVISION;
-    efiSystemTable->Hdr.HeaderSize = 
sizeof(EFI_SYSTEM_TABLE_64);
+    efiSystemTable->Hdr.HeaderSize = 
sizeof(EFI_SYSTEM_TABLE_32);
     efiSystemTable->Hdr.CRC32 = 0; /* Initialize to zero and 
then do CRC32 */
     efiSystemTable->Hdr.Reserved = 0;
 
@@ -216,10 +217,10 @@
 
     /* 
-------------------------------------------------------------------- 
*/
     /* Runtime services */
-    EFI_RUNTIME_SERVICES_64 *efiRuntimeServices = 
&fakeEfiPages->efiRuntimeServices;
+    EFI_RUNTIME_SERVICES_32 *efiRuntimeServices = 
&fakeEfiPages->efiRuntimeServices;
     efiRuntimeServices->Hdr.Signature = 
EFI_RUNTIME_SERVICES_SIGNATURE;
     efiRuntimeServices->Hdr.Revision = 
EFI_RUNTIME_SERVICES_REVISION;
-    efiRuntimeServices->Hdr.HeaderSize = 
sizeof(EFI_RUNTIME_SERVICES_64);
+    efiRuntimeServices->Hdr.HeaderSize = 
sizeof(EFI_RUNTIME_SERVICES_32);
     efiRuntimeServices->Hdr.CRC32 = 0;
     efiRuntimeServices->Hdr.Reserved = 0;
 
@@ -254,7 +255,7 @@
     /* 
-------------------------------------------------------------------- 
*/
     /* Finish filling in the rest of the boot args that we need. */
     bootArgs->efiSystemTable = (uint32_t)efiSystemTable;
-    bootArgs->efiMode = kBootArgsEfiMode64;
+    bootArgs->efiMode = kBootArgsEfiMode32;
 
     /* The bootArgs structure as a whole is bzero'd so we don't 
need to fill in
      * things like efiRuntimeServices* and what not.
@@ -315,7 +316,7 @@
 static const char const FIRMWARE_REVISION_PROP[] = 
"firmware-revision";
 static const char const FIRMWARE_ABI_PROP[] = 
"firmware-abi";
 static const char const FIRMWARE_VENDOR_PROP[] = 
"firmware-vendor";
-static const char const FIRMWARE_ABI_PROP_VALUE[] = 
"EFI64";
+static const char const FIRMWARE_ABI_PROP_VALUE[] = 
"EFI32";
 static const char const SYSTEM_ID_PROP[] = "system-id";
 static const char const SYSTEM_SERIAL_PROP[] = 
"SystemSerialNumber";
 static const char const SYSTEM_TYPE_PROP[] = 
"system-type";
@@ -520,6 +521,10 @@
         // Generate efi device strings 
 	setupEfiDevices();
 	
 	// Initialize the base table
 	setupEfiTables();

Comment 4 by Azimutz, May 10, 2010

Ok, i see.. there's much more to it! That's probably why i get the 
kp setting EFI32.. need to change the rest of the stuff too. I was 
finding it "too easy"!! :P
That stuff was confusing me as i was pretty sure it worked before.
Thanks for the answer and sorry for the "noob" post.. i'm 
learning, so this stuff is a "bit" over my knowledge. 
Anyway, going to take a better look at it, at least to get a better 
knowledge of the code involved.

See ya later.

Comment 5 by Azimutz, May 17, 2010

Well guys, no good news here, just confirmations.
I still can't test this properly because EMT64 is always detected on 
my cpu. The closest i can get to a cpu without EMT64 is by running a 
"legacy" kernel and i can do that even with EFI64; setting 
EFI32 does not solve the problems mentioned, be it by changing only 
"static const char const FIRMWARE_ABI_PROP_VALUE[]" or by 
reverting everything like it was on RC3. Even setting the UUID with 
"SystemId" key doesn't work, i always get the default 
UUID.
At least, now i understand the problem and symptoms.
Thanks for posting this.. if i find something will remember to post 
here.

Comment 6 by Azimutz, Jul 25, 2010

Hi guys, anyone around? :)
Been testing a solution for this during the past 3 or 4 weeks and it 
seems like a good time to post it, with all the activity going on.
This just changes between old EFI32 settings and new EFI64 ones, 
according to kernel architecture in use. CPU's whit 64 bit 
instructions will use EFI64 on pre 10.6 systems by default, which 
seems to cause no problem; both EFI32/64 can be used by these CPU's 
when booting i386 arch.
Hope this helps, at least as a catalyst for this issue to be fixed 
soon :)

Comment 7 by Tamás Kosárszky, Jul 26, 2010

Hey Azimutz!

Thx for the patch. I will take a look at it as soon as i can :)

Comment 8 by Tamás Kosárszky, Jul 26, 2010

Status: Accepted

Comment 9 by Azimutz, Jul 26, 2010

Thanks Tamás :)

this one almost cracked my poor newbie brain. Was about to pm you to 
point it out.

Talk to you later...

Comment 10 by Evan Lojewski, Jul 27, 2010

I have had (almost) the exact same patch in my branch for quite some 
time.
http://forge.voodooprojects.org/p/chameleon/source/tree/HEAD/branches
/meklort/i386/libsaio/fake_efi.c

I've been using it myself for a while too.

Comment 11 by Azimutz, Jul 27, 2010

Hi Evan :)

Yep, if you are talking about the first one i submitted on comment 
#2, they are the same! Only diff is on the naming we used on 
FIRMWARE_ABI. I haven't seen your code at that time (at least that 
part); when i saw it later here on the repo, i found it so funny 
that i started to use your naming on that :)

But, that stuff all alone doesn't fix the problem. The latest i 
posted (#6) is very diff.

Comment 12 by Evan Lojewski, Jul 27, 2010

Ah, I'll take a look and see what other changes you've made as well.

Comment 13 by Tamás Kosárszky, Aug 30, 2010

Azimutz:

How about this commit? :)

http://forge.voodooprojects.org/p/chameleon/source/commit/450/

Comment 14 by Azimutz, Aug 30, 2010

Zef,

simply beautiful :)

Hey, be careful with the "selected volume" path; this was 
the one that killed my patience to keep it! I'll get back to this 
stuff, but last time i tested it, the damn thing insisted on loading 
smbios.plist from bt(0,0) (disk0s2, Snow install) instead of the 
selected volume, e.g. disk0s4 the Leo install. The weird thing is 
that this only happened with /Extra/... path on 
setupSmbiosConfigFile(); the exact same algo worked fine on the 
other functions were used.

Comment 15 by Tamás Kosárszky, Aug 30, 2010

Status: Fixed

Created: 8 years 3 months ago by neo lnx

Updated: 7 years 11 months ago

Status: Fixed

Followed by: 3 persons

Labels:
Priority:Medium
Type:Defect