diff --git a/Docs/Configuration.pdf b/Docs/Configuration.pdf index a252e540..57725ef8 100644 Binary files a/Docs/Configuration.pdf and b/Docs/Configuration.pdf differ diff --git a/Docs/Configuration.tex b/Docs/Configuration.tex index 2d911612..1acc065f 100755 --- a/Docs/Configuration.tex +++ b/Docs/Configuration.tex @@ -762,7 +762,7 @@ for extensive messages that should not appear in NVRAM log that is heavily limit When trying to find the problematic change it is useful to rely on \href{https://git-scm.com/docs/git-bisect}{\texttt{git-bisect}} functionality. -There also are some unnoficial resources that provide per-commit binary +There also are some unofficial resources that provide per-commit binary builds of OpenCore, like \href{https://dortania.github.io/builds}{Dortania}. \section{ACPI}\label{acpi} @@ -2298,20 +2298,20 @@ blocking. \textbf{Description}: Prefer specified kernel architecture (\texttt{Auto}, \texttt{i386}, \texttt{i386-user32}, \texttt{x86\_64}) when available. - On macOS 10.7 and earlier XNU kernel may not boot with the usual \texttt{x86\_64} architecture, - and the exact choice depends on many factors including boot arguments, SMBIOS, and operating - system type. This setting will use the specified architecture to boot macOS when it is supported - by the macOS and the configuration: + On macOS 10.7 and earlier XNU kernel can boot with architectures different from + the usual \texttt{x86\_64}. This setting will use the specified architecture to boot + macOS when it is supported by the macOS and the configuration: \begin{itemize} \tightlist \item \texttt{Auto} --- Choose the preferred architecture automatically. \item \texttt{i386} --- Use \texttt{i386} (32-bit) kernel when available. \item \texttt{i386-user32} --- Use \texttt{i386} (32-bit) kernel when available - and force the use of 32-bit userspace even on 64-bit capable processors - (similar to \texttt{-legacy} boot argument). This mode is relevant for older Pentium - processors with \texttt{x86\_64} support but without \texttt{SSSE3}, which - on macOS 10.6 will result in some applications crashing. + and force the use of 32-bit userspace on 64-bit capable processors. + On macOS 64-bit capable processors are assumed to support \texttt{SSSE3}. + This is not the case for older 64-bit capable Pentium processors, which + cause some applications to crash on macOS~10.6. The behaviour corresponds + to \texttt{-legacy} kernel boot argument. \item \texttt{x86\_64} --- Use \texttt{x86\_64} (64-bit) kernel when available. \end{itemize} @@ -2321,28 +2321,41 @@ blocking. \tightlist \item \texttt{arch} argument in image arguments (e.g. when launched via UEFI Shell) or in \texttt{boot-args} variable overrides any compatibility - checks and forces the specified architecture, ending this algorithm. + checks and forces the specified architecture, completing this algorithm. \item OpenCore build architecture restricts capabilities to \texttt{i386} - and \texttt{i386-user32} mode in 32-bit firmware variant. + and \texttt{i386-user32} mode for the 32-bit firmware variant. \item Determined EfiBoot version restricts architecture choice: \begin{itemize} \item 10.4-10.5 --- \texttt{i386} or \texttt{i386-user32} \item 10.6-10.7 --- \texttt{i386}, \texttt{i386-user32}, or \texttt{x86\_64} \item 10.8 or newer --- \texttt{x86\_64} \end{itemize} - \item \texttt{CPUID} capabilities restrict capabilities to - \texttt{i386-user32} if \texttt{SSSE3} is not available - and \texttt{KernelArch} is set to \texttt{Auto}. - \item SMBIOS model information and EfiBoot version restrict - architecture choice and define architecture preference for client - and server operating systems according to the table below. - \item \texttt{KernelArch} setting updates architecture preference - for both client and server operating systems if the architecture - is supported and \texttt{KernelArch} is not \texttt{Auto}. - \item EfiBoot decides on server boot picking either server - or client preference. + \item If \texttt{KernelArch} is set to \texttt{Auto} and \texttt{SSSE3} + is not supported by the CPU, capabilities are restricted to \texttt{i386-user32} + if supported by EfiBoot. + \item Board identifier (from SMBIOS) based on EfiBoot version + disables \texttt{x86\_64} support on an unsupported model + if any \texttt{i386} variant is supported. \texttt{Auto} + is not consulted here as the list is not overridable in EfiBoot. + \item \texttt{KernelArch} restricts the support to the explicitly + specified architecture (when not set to \texttt{Auto}) if + the architecture remains present in the capabilities. + \item The best supported architecture is chosen in this order: + \texttt{x86\_64}, \texttt{i386}, \texttt{i386-user32}. \end{enumerate} + Unlike macOS~10.7, where select boards identifiers are treated as the \texttt{i386} + only machines, and macOS~10.5 or earlier, where \texttt{x86\_64} is not supported + by the macOS kernel, macOS~10.6 is very special. The architecture choice on macOS~10.6 + depends on many factors including not only the board identifier, but also macOS + product type (client vs server), macOS point release, and RAM amount. The detection + of them all is complicated and not practical, because several point releases had genuine + bugs and failed to properly perform the server detection in the first place. + For this reason OpenCore on macOS~10.6 will fallback to \texttt{x86\_64} + architecture whenever it is supported by the board at all, just like on macOS~10.7. + As a reference here is the 64-bit Mac model compatibility corresponding to actual + EfiBoot behaviour on macOS 10.6.8 and 10.7.5. + \begin{center} \begin{tabular}{|p{0.9in}|c|c|c|c|} \hline @@ -2365,15 +2378,6 @@ blocking. \end{tabular} \end{center} - \emph{Note 1}: Unlike 10.7 and newer, on 10.6 many models support 64-bit - kernel loading but have it disabled by default. Information about 10.6 - 64-bit Mac model compatibility is incorrect on Apple support website - and does not correspond to actual EfiBoot behaviour. - - \emph{Note 2}: Older 10.6 server versions will start in client mode due - to a bug in EfiBoot. Consider using this preference to workaround - the issue. - \item \texttt{KernelCache}\\ \textbf{Type}: \texttt{plist\ string}\\ diff --git a/Docs/Differences/Differences.pdf b/Docs/Differences/Differences.pdf index 7712e500..14b764e2 100644 Binary files a/Docs/Differences/Differences.pdf and b/Docs/Differences/Differences.pdf differ diff --git a/Docs/Differences/Differences.tex b/Docs/Differences/Differences.tex index fe3a16f7..9c47aeaf 100644 --- a/Docs/Differences/Differences.tex +++ b/Docs/Differences/Differences.tex @@ -1,7 +1,7 @@ \documentclass[]{article} %DIF LATEXDIFF DIFFERENCE FILE -%DIF DEL PreviousConfiguration.tex Tue Aug 25 23:11:15 2020 -%DIF ADD ../Configuration.tex Tue Aug 25 23:11:15 2020 +%DIF DEL PreviousConfiguration.tex Sat Aug 8 20:55:30 2020 +%DIF ADD ../Configuration.tex Sat Aug 29 16:17:38 2020 \usepackage{lmodern} \usepackage{amssymb,amsmath} @@ -663,14 +663,19 @@ one should also install \href{https://www.nasm.us}{NASM} and The latest Xcode version is recommended for use despite the toolchain name. Example command sequence may look as follows: -\begin{lstlisting}[caption=Compilation Commands, label=compile, style=ocbash] -git clone --recursive --depth=1 https://github.com/acidanthera/audk UDK +\DIFmodbegin +\begin{lstlisting}[caption=Compilation Commands, label=compile, style=ocbash,alsolanguage=DIFcode] +%DIF < git clone --recursive --depth=1 https://github.com/acidanthera/audk UDK +%DIF > git clone --depth=1 https://github.com/acidanthera/audk UDK cd UDK -git clone https://github.com/acidanthera/OpenCorePkg +%DIF < git clone https://github.com/acidanthera/OpenCorePkg +%DIF > git submodule update --init --recommend-shallow +%DIF > git clone --depth=1 https://github.com/acidanthera/OpenCorePkg source edksetup.sh make -C BaseTools build -a X64 -b RELEASE -t XCODE5 -p OpenCorePkg/OpenCorePkg.dsc \end{lstlisting} +\DIFmodend For IDE usage Xcode projects are available in the root of the repositories. Another approach could be \href{https://www.sublimetext.com}{Sublime Text} with @@ -824,7 +829,7 @@ for extensive messages that should not appear in NVRAM log that is heavily limit When trying to find the problematic change it is useful to rely on \href{https://git-scm.com/docs/git-bisect}{\texttt{git-bisect}} functionality. -\DIFaddbegin \DIFadd{There also are some unnoficial resources that provide per-commit binary +\DIFaddbegin \DIFadd{There also are some unofficial resources that provide per-commit binary builds of OpenCore, like }\href{https://dortania.github.io/builds}{Dortania}\DIFadd{. }\DIFaddend @@ -2366,36 +2371,70 @@ blocking. \textbf{\DIFadd{Type}}\DIFadd{: }\texttt{\DIFadd{plist\ string}}\\ \textbf{\DIFadd{Failsafe}}\DIFadd{: }\texttt{\DIFadd{Auto}}\\ \textbf{\DIFadd{Description}}\DIFadd{: Prefer specified kernel architecture (}\texttt{\DIFadd{Auto}}\DIFadd{, }\texttt{\DIFadd{i386}}\DIFadd{, - }\texttt{\DIFadd{x86\_64}}\DIFadd{) when available. + }\texttt{\DIFadd{i386-user32}}\DIFadd{, }\texttt{\DIFadd{x86\_64}}\DIFadd{) when available. } - \DIFadd{On macOS 10.7 and earlier XNU kernel may not boot with the usual }\texttt{\DIFadd{x86\_64}} \DIFadd{architecture, - and the exact choice depends on many factors including boot arguments, SMBIOS, and operating - system type. This setting will use the specified architecture to boot macOS when it is supported - by the macOS and the configuration. Below is the algorithm determining the kernel architecture. + \DIFadd{On macOS 10.7 and earlier XNU kernel can boot with architectures different from + the usual }\texttt{\DIFadd{x86\_64}}\DIFadd{. This setting will use the specified architecture to boot + macOS when it is supported by the macOS and the configuration: +} + + \begin{itemize} + \tightlist + \item \texttt{\DIFadd{Auto}} \DIFadd{--- Choose the preferred architecture automatically. + }\item \texttt{\DIFadd{i386}} \DIFadd{--- Use }\texttt{\DIFadd{i386}} \DIFadd{(32-bit) kernel when available. + }\item \texttt{\DIFadd{i386-user32}} \DIFadd{--- Use }\texttt{\DIFadd{i386}} \DIFadd{(32-bit) kernel when available + and force the use of 32-bit userspace on 64-bit capable processors. + On macOS 64-bit capable processors are assumed to support }\texttt{\DIFadd{SSSE3}}\DIFadd{. + This is not the case for older 64-bit capable Pentium processors, which + cause some applications to crash on macOS~10.6. The behaviour corresponds + to }\texttt{\DIFadd{-legacy}} \DIFadd{kernel boot argument. + }\item \texttt{\DIFadd{x86\_64}} \DIFadd{--- Use }\texttt{\DIFadd{x86\_64}} \DIFadd{(64-bit) kernel when available. + }\end{itemize} + + \DIFadd{Below is the algorithm determining the kernel architecture. } \begin{enumerate} \tightlist \item \texttt{\DIFadd{arch}} \DIFadd{argument in image arguments (e.g. when launched - via UEFI Shell) or in }\texttt{\DIFadd{boot-args}} \DIFadd{variable override any compatibility - checks and force the specified architecture. + via UEFI Shell) or in }\texttt{\DIFadd{boot-args}} \DIFadd{variable overrides any compatibility + checks and forces the specified architecture, completing this algorithm. + }\item \DIFadd{OpenCore build architecture restricts capabilities to }\texttt{\DIFadd{i386}} + \DIFadd{and }\texttt{\DIFadd{i386-user32}} \DIFadd{mode for the 32-bit firmware variant. }\item \DIFadd{Determined EfiBoot version restricts architecture choice: }\begin{itemize} - \item \DIFadd{10.4-10.5 --- }\texttt{\DIFadd{i386}} - \item \DIFadd{10.6-10.7 --- }\texttt{\DIFadd{i386}} \DIFadd{or }\texttt{\DIFadd{x86\_64}} + \item \DIFadd{10.4-10.5 --- }\texttt{\DIFadd{i386}} \DIFadd{or }\texttt{\DIFadd{i386-user32}} + \item \DIFadd{10.6-10.7 --- }\texttt{\DIFadd{i386}}\DIFadd{, }\texttt{\DIFadd{i386-user32}}\DIFadd{, or }\texttt{\DIFadd{x86\_64}} \item \DIFadd{10.8 or newer --- }\texttt{\DIFadd{x86\_64}} \end{itemize} - \item \DIFadd{SMBIOS model information and EfiBoot version restrict - architecture choice and define architecture preference for client - and server operating systems according to the table below. - }\item \texttt{\DIFadd{KernelArch}} \DIFadd{setting updates architecture preference - for both client and server operating systems if the architecture - is supported and }\texttt{\DIFadd{KernelArch}} \DIFadd{is not }\texttt{\DIFadd{Auto}}\DIFadd{. - }\item \DIFadd{EfiBoot decides on server boot picking either server - or client preference. + \item \DIFadd{If }\texttt{\DIFadd{KernelArch}} \DIFadd{is set to }\texttt{\DIFadd{Auto}} \DIFadd{and }\texttt{\DIFadd{SSSE3}} + \DIFadd{is not supported by the CPU, capabilities are restricted to }\texttt{\DIFadd{i386-user32}} + \DIFadd{if supported by EfiBoot. + }\item \DIFadd{Board identifier (from SMBIOS) based on EfiBoot version + disables }\texttt{\DIFadd{x86\_64}} \DIFadd{support on an unsupported model + if any }\texttt{\DIFadd{i386}} \DIFadd{variant is supported. }\texttt{\DIFadd{Auto}} + \DIFadd{is not consulted here as the list is not overridable in EfiBoot. + }\item \texttt{\DIFadd{KernelArch}} \DIFadd{restricts the support to the explicitly + specified architecture (when not set to }\texttt{\DIFadd{Auto}}\DIFadd{) if + the architecture remains present in the capabilities. + }\item \DIFadd{The best supported architecture is chosen in this order: + }\texttt{\DIFadd{x86\_64}}\DIFadd{, }\texttt{\DIFadd{i386}}\DIFadd{, }\texttt{\DIFadd{i386-user32}}\DIFadd{. }\end{enumerate} + \DIFadd{Unlike macOS~10.7, where select boards identifiers are treated as the }\texttt{\DIFadd{i386}} + \DIFadd{only machines, and macOS~10.5 or earlier, where }\texttt{\DIFadd{x86\_64}} \DIFadd{is not supported + by the macOS kernel, macOS~10.6 is very special. The architecture choice on macOS~10.6 + depends on many factors including not only the board identifier, but also macOS + product type (client vs server), macOS point release, and RAM amount. The detection + of them all is complicated and not practical, because several point releases had genuine + bugs and failed to properly perform the server detection in the first place. + For this reason OpenCore on macOS~10.6 will fallback to }\texttt{\DIFadd{x86\_64}} + \DIFadd{architecture whenever it is supported by the board at all, just like on macOS~10.7. + As a reference here is the 64-bit Mac model compatibility corresponding to actual + EfiBoot behaviour on macOS 10.6.8 and 10.7.5. +} + \begin{center} \begin{tabular}{|p{0.9in}|c|c|c|c|} \hline @@ -2418,17 +2457,6 @@ blocking. \end{tabular} \end{center} - \emph{\DIFadd{Note 1}}\DIFadd{: Unlike 10.7 and newer, on 10.6 many models support 64-bit - kernel loading but have it disabled by default. Information about 10.6 - 64-bit Mac model compatibility is incorrect on Apple support website - and does not correspond to actual EfiBoot behaviour. -} - - \emph{\DIFadd{Note 2}}\DIFadd{: Older 10.6 server versions will start in client mode due - to a bug in EfiBoot. Consider using this preference to workaround - the issue. -} - \item \texttt{\DIFadd{KernelCache}}\\ \textbf{\DIFadd{Type}}\DIFadd{: }\texttt{\DIFadd{plist\ string}}\\ @@ -4857,7 +4885,7 @@ similar to the builtin text interface. OpenCanopy requires graphical resources located in \texttt{Resources} directory to run. Sample resources (fonts and images) can be found in -\href{https://github.com/acidanthera/OcBinaryData}{OcBinaryData repository}. You can find customised icons over the internet +\href{https://github.com/acidanthera/OcBinaryData}{OcBinaryData repository}. You can find customised icons over the internet (e.g. \href{https://github.com/blackosx/OpenCanopyIcons}{here} or \href{https://applelife.ru/threads/kastomizacija-opencanopy.2945020/}{there}). OpenCanopy provides full support for \texttt{PickerAttributes} and offers a configurable diff --git a/Docs/Errata/Errata.pdf b/Docs/Errata/Errata.pdf index 5950c565..ea168acb 100644 Binary files a/Docs/Errata/Errata.pdf and b/Docs/Errata/Errata.pdf differ diff --git a/Include/Acidanthera/Library/OcBootManagementLib.h b/Include/Acidanthera/Library/OcBootManagementLib.h index e9bfa55a..2fef7bde 100755 --- a/Include/Acidanthera/Library/OcBootManagementLib.h +++ b/Include/Acidanthera/Library/OcBootManagementLib.h @@ -1142,6 +1142,24 @@ OcAppendArgumentToCmd ( IN CONST UINTN ArgumentLength ); +/** + Append 1 or more arguments to Loaded Image protocol. + + @param[in,out] LoadedImage Loaded Image protocol instance. + @param[in] Arguments Argument array. + @param[in] ArgumentCount Number of arguments in the array. + @param[in] Replace Whether to append to existing arguments or replace. + + @retval TRUE on success. +**/ +BOOLEAN +OcAppendArgumentsToLoadedImage ( + IN OUT EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN CONST CHAR8 **Arguments, + IN UINT32 ArgumentCount, + IN BOOLEAN Replace + ); + /** Perform NVRAM UEFI variable deletion. **/ diff --git a/Include/Acidanthera/Library/OcMacInfoLib.h b/Include/Acidanthera/Library/OcMacInfoLib.h index 0407709a..a72bcd03 100644 --- a/Include/Acidanthera/Library/OcMacInfoLib.h +++ b/Include/Acidanthera/Library/OcMacInfoLib.h @@ -101,6 +101,8 @@ GetMacInfo ( @param[in] ProductName Product to get information for. @param[in] KernelVersion Kernel version. + + @retval TRUE if supported. **/ BOOLEAN IsMacModel64BitCompatible ( diff --git a/Library/OcBootManagementLib/BootArguments.c b/Library/OcBootManagementLib/BootArguments.c index c0b8c84a..0f472370 100644 --- a/Library/OcBootManagementLib/BootArguments.c +++ b/Library/OcBootManagementLib/BootArguments.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -187,6 +188,79 @@ OcAppendArgumentToCmd ( return TRUE; } +BOOLEAN +OcAppendArgumentsToLoadedImage ( + IN OUT EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN CONST CHAR8 **Arguments, + IN UINT32 ArgumentCount, + IN BOOLEAN Replace + ) +{ + UINT32 Index; + UINTN ArgumentLength; + UINTN TotalLength; + CHAR16 *NewArguments; + CHAR16 *Walker; + + ASSERT (LoadedImage != NULL); + ASSERT (Arguments != NULL); + ASSERT (ArgumentCount > 0); + + TotalLength = 0; + + // + // Count length including spaces between or '\0' for the last argument. + // + for (Index = 0; Index < ArgumentCount; ++Index) { + ArgumentLength = AsciiStrSize (Arguments[Index]); + if (OcOverflowAddUN (TotalLength, ArgumentLength, &TotalLength)) { + return FALSE; + } + } + + if (OcOverflowMulUN (TotalLength, sizeof (CHAR16), &TotalLength)) { + return FALSE; + } + + Replace |= LoadedImage->LoadOptionsSize < sizeof (CHAR16); + if (!Replace + && OcOverflowTriAddUN (TotalLength, sizeof (CHAR16), LoadedImage->LoadOptionsSize, &TotalLength)) { + return FALSE; + } + + NewArguments = AllocatePool (TotalLength); + if (NewArguments == NULL) { + return FALSE; + } + + Walker = NewArguments; + for (Index = 0; Index < ArgumentCount; ++Index) { + if (Index != 0) { + *Walker++ = ' '; + } + + ArgumentLength = AsciiStrLen (Arguments[Index]); + AsciiStrToUnicodeStrS ( + Arguments[Index], + Walker, + ArgumentLength + 1 + ); + Walker += ArgumentLength; + } + + if (!Replace) { + *Walker++ = ' '; + CopyMem (Walker, LoadedImage->LoadOptions, LoadedImage->LoadOptionsSize); + Walker += LoadedImage->LoadOptionsSize / sizeof (CHAR16); + *Walker++ = '\0'; + } + + LoadedImage->LoadOptions = NewArguments; + LoadedImage->LoadOptionsSize = TotalLength; + + return TRUE; +} + BOOLEAN OcCheckArgumentFromEnv ( IN EFI_LOADED_IMAGE *LoadedImage OPTIONAL, diff --git a/Library/OcBootManagementLib/DefaultEntryChoice.c b/Library/OcBootManagementLib/DefaultEntryChoice.c index 8be01690..99866ba8 100644 --- a/Library/OcBootManagementLib/DefaultEntryChoice.c +++ b/Library/OcBootManagementLib/DefaultEntryChoice.c @@ -958,7 +958,6 @@ InternalLoadBootEntry ( VOID *EntryData; UINT32 EntryDataSize; CONST CHAR8 *Args; - UINT32 ArgsLen; ASSERT (BootEntry != NULL); // @@ -1058,18 +1057,17 @@ InternalLoadBootEntry ( if (BootEntry->LoadOptions == NULL && (BootEntry->Type & OC_BOOT_APPLE_ANY) != 0) { Args = Context->AppleBootArgs; - ArgsLen = (UINT32) AsciiStrLen (Args); } else { Args = BootEntry->LoadOptions; - ArgsLen = BootEntry->LoadOptionsSize; - ASSERT (ArgsLen == ((Args == NULL) ? 0 : (UINT32) AsciiStrLen (Args))); } - if (ArgsLen > 0) { - LoadedImage->LoadOptions = AsciiStrCopyToUnicode (Args, ArgsLen); - if (LoadedImage->LoadOptions != NULL) { - LoadedImage->LoadOptionsSize = ArgsLen * sizeof (CHAR16) + sizeof (CHAR16); - } + if (Args != NULL && Args[0] != '\0') { + OcAppendArgumentsToLoadedImage ( + LoadedImage, + &Args, + 1, + TRUE + ); } if (BootEntry->Type == OC_BOOT_EXTERNAL_OS || BootEntry->Type == OC_BOOT_EXTERNAL_TOOL) { diff --git a/Platform/OpenCore/OpenCoreKernel.c b/Platform/OpenCore/OpenCoreKernel.c index 35c11701..32ea871b 100644 --- a/Platform/OpenCore/OpenCoreKernel.c +++ b/Platform/OpenCore/OpenCoreKernel.c @@ -48,8 +48,12 @@ OcKernelConfigureCapabilities ( { CONST CHAR8 *KernelArch; CHAR8 *AppleArchValue; + CONST CHAR8 *NewArguments[2]; + UINT32 ArgumentCount; + UINT32 RequestedArch; BOOLEAN HasAppleArch; - BOOLEAN Automatic; + BOOLEAN SnowLeo64; + BOOLEAN Lion64; // // Reset to the default value. @@ -76,7 +80,7 @@ OcKernelConfigureCapabilities ( &AppleArchValue ); - if (AppleArchValue) { + if (HasAppleArch) { mUse32BitKernel = AsciiStrCmp (AppleArchValue, "i386") == 0; DEBUG ((DEBUG_INFO, "OC: Arch %a overrides capabilities %u\n", AppleArchValue, Capabilities)); FreePool (AppleArchValue); @@ -84,22 +88,94 @@ OcKernelConfigureCapabilities ( } // - // FIXME: The rest is not complete. + // Determine requested arch. // - KernelArch = OC_BLOB_GET (&mOcConfiguration->Kernel.Scheme.KernelArch); - Automatic = KernelArch[0] == '\0' || AsciiStrCmp (KernelArch, "Auto") == 0; + if (AsciiStrCmp (KernelArch, "x86_64") == 0) { + RequestedArch = OC_KERN_CAPABILITY_K64_U64; + } else if (AsciiStrCmp (KernelArch, "i386") == 0) { + RequestedArch = OC_KERN_CAPABILITY_K32_U64; + } else if (AsciiStrCmp (KernelArch, "i386-user32") == 0) { + RequestedArch = OC_KERN_CAPABILITY_K32_U32; + } else { + RequestedArch = 0; + } + + // + // Determine the current operating system. + // + SnowLeo64 = (Capabilities & (OC_KERN_CAPABILITY_K32_U32 | OC_KERN_CAPABILITY_K32_U64 | OC_KERN_CAPABILITY_K64_U64)) + == (OC_KERN_CAPABILITY_K32_U32 | OC_KERN_CAPABILITY_K32_U64 | OC_KERN_CAPABILITY_K64_U64); + Lion64 = (Capabilities & (OC_KERN_CAPABILITY_K32_U32 | OC_KERN_CAPABILITY_K32_U64 | OC_KERN_CAPABILITY_K64_U64)) + == (OC_KERN_CAPABILITY_K32_U64 | OC_KERN_CAPABILITY_K64_U64); // // In automatic mode, if we do not support SSSE3 and can downgrade to U32, do it. // - if (Automatic && (Capabilities & OC_KERN_CAPABILITY_K32_U32) != 0 - && (Capabilities & (OC_KERN_CAPABILITY_K32_U64 | OC_KERN_CAPABILITY_K64_U64)) != 0 - && (mOcCpuInfo->Features & CPUID_FEATURE_SSSE3) == 0) { + if (RequestedArch == 0 + && (mOcCpuInfo->Features & CPUID_FEATURE_SSSE3) == 0 + && (Capabilities & OC_KERN_CAPABILITY_K32_U32) != 0 + && (Capabilities & (OC_KERN_CAPABILITY_K32_U64 | OC_KERN_CAPABILITY_K64_U64)) != 0) { DEBUG ((DEBUG_INFO, "OC: Missing SSSE3 disables U64 capabilities %u\n", Capabilities)); Capabilities &= ~(OC_KERN_CAPABILITY_K32_U64 | OC_KERN_CAPABILITY_K64_U64); } + // + // If we support K64 mode, check whether the board supports it. + // + if ((Capabilities & OC_KERN_CAPABILITY_K64_U64) != 0 + && !OcPlatformIs64BitSupported (SnowLeo64 ? KERNEL_VERSION_SNOW_LEOPARD_MIN : KERNEL_VERSION_LION_MIN)) { + Capabilities &= ~(OC_KERN_CAPABILITY_K64_U64); + } + + // + // If we are not choosing the architecture automatically, try to use the requested one. + // Otherwise try best available. + // + if (RequestedArch != 0 && (Capabilities & RequestedArch) != 0) { + Capabilities = RequestedArch; + } else if ((Capabilities & OC_KERN_CAPABILITY_K64_U64) != 0) { + Capabilities = OC_KERN_CAPABILITY_K64_U64; + } else if ((Capabilities & OC_KERN_CAPABILITY_K32_U64) != 0) { + Capabilities = OC_KERN_CAPABILITY_K32_U64; + } else if ((Capabilities & OC_KERN_CAPABILITY_K32_U32) != 0) { + Capabilities = OC_KERN_CAPABILITY_K32_U32; + } else { + ASSERT (FALSE); + } + + // + // Pass arch argument when we are: + // - SnowLeo64 and try to boot x86_64. + // - SnowLeo64 or Lion64 and try to boot i386. + // + ArgumentCount = 0; + if (Capabilities == OC_KERN_CAPABILITY_K64_U64 && SnowLeo64) { + NewArguments[ArgumentCount++] = "arch=x86_64"; + } else if (Capabilities != OC_KERN_CAPABILITY_K64_U64 && (SnowLeo64 || Lion64)) { + NewArguments[ArgumentCount++] = "arch=i386"; + } + + // + // Pass legacy argument when we are booting i386. + // + if (Capabilities == OC_KERN_CAPABILITY_K32_U32 + && OcCheckArgumentFromEnv (LoadedImage, gRT->GetVariable, "-legacy", L_STR_LEN ("-legacy"), NULL)) { + NewArguments[ArgumentCount++] = "-legacy"; + } + + // + // Update argument list. + // + if (ArgumentCount > 0) { + OcAppendArgumentsToLoadedImage ( + LoadedImage, + &NewArguments[0], + ArgumentCount, + FALSE + ); + } + // // If we do not support K64 for this target, force 32. //