#include <Library/IoLib.h>\r
#include <Library/PrintLib.h>\r
\r
-//\r
-// Size in number of characters of the Linux boot argument\r
-// passing the MAC address to be used by the PCI GigaByte\r
-// Ethernet device : " sky2.mac_address=0x11,0x22,0x33,0x44,0x55,0x66"\r
-//\r
-#define SKY2_MAC_ADDRESS_BOOTARG_LEN 47\r
-\r
//\r
// Hardware platform identifiers\r
//\r
JUNO_R1\r
} JUNO_REVISION;\r
\r
-//\r
-// Function prototypes\r
-//\r
-STATIC EFI_STATUS SetJunoR1DefaultBootEntries (\r
- VOID\r
- );\r
-\r
// This GUID must match the FILE_GUID in ArmPlatformPkg/ArmJunoPkg/AcpiTables/AcpiTables.inf\r
STATIC CONST EFI_GUID mJunoAcpiTableFile = { 0xa1dd808e, 0x1e95, 0x4399, { 0xab, 0xc0, 0x65, 0x3c, 0x82, 0xe8, 0x53, 0x0c } };\r
\r
\r
EFI_EVENT mAcpiRegistration = NULL;\r
\r
-/**\r
- * Build and Set UEFI Variable Boot####\r
- *\r
- * @param BootVariableName Name of the UEFI Variable\r
- * @param Attributes 'Attributes' for the Boot#### variable as per UEFI spec\r
- * @param BootDescription Description of the Boot#### variable\r
- * @param DevicePath EFI Device Path of the EFI Application to boot\r
- * @param OptionalData Parameters to pass to the EFI application\r
- * @param OptionalDataSize Size of the parameters to pass to the EFI application\r
- *\r
- * @return EFI_OUT_OF_RESOURCES A memory allocation failed\r
- * @return Return value of RT.SetVariable\r
- */\r
-STATIC\r
-EFI_STATUS\r
-BootOptionCreate (\r
- IN CHAR16 BootVariableName[9],\r
- IN UINT32 Attributes,\r
- IN CHAR16* BootDescription,\r
- IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,\r
- IN UINT8* OptionalData,\r
- IN UINTN OptionalDataSize\r
- )\r
-{\r
- UINTN VariableSize;\r
- UINT8 *Variable;\r
- UINT8 *VariablePtr;\r
- UINTN FilePathListLength;\r
- UINTN BootDescriptionSize;\r
-\r
- FilePathListLength = GetDevicePathSize (DevicePath);\r
- BootDescriptionSize = StrSize (BootDescription);\r
-\r
- // Each Boot#### variable is built as follow:\r
- // UINT32 Attributes\r
- // UINT16 FilePathListLength\r
- // CHAR16* Description\r
- // EFI_DEVICE_PATH_PROTOCOL FilePathList[]\r
- // UINT8 OptionalData[]\r
- VariableSize = sizeof (UINT32) + sizeof (UINT16) +\r
- BootDescriptionSize + FilePathListLength + OptionalDataSize;\r
- Variable = AllocateZeroPool (VariableSize);\r
- if (Variable == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- // 'Attributes' field\r
- *(UINT32*)Variable = Attributes;\r
- // 'FilePathListLength' field\r
- VariablePtr = Variable + sizeof (UINT32);\r
- *(UINT16*)VariablePtr = FilePathListLength;\r
- // 'Description' field\r
- VariablePtr += sizeof (UINT16);\r
- CopyMem (VariablePtr, BootDescription, BootDescriptionSize);\r
- // 'FilePathList' field\r
- VariablePtr += BootDescriptionSize;\r
- CopyMem (VariablePtr, DevicePath, FilePathListLength);\r
- // 'OptionalData' field\r
- VariablePtr += FilePathListLength;\r
- CopyMem (VariablePtr, OptionalData, OptionalDataSize);\r
-\r
- return gRT->SetVariable (\r
- BootVariableName,\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
- VariableSize, Variable\r
- );\r
-}\r
-\r
/**\r
Notification function of the event defined as belonging to the\r
EFI_END_OF_DXE_EVENT_GROUP_GUID event group that was created in\r
// Set the R1 two boot options if not already done.\r
//\r
if (JunoRevision == JUNO_R1) {\r
- Status = SetJunoR1DefaultBootEntries ();\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
// Enable PCI enumeration\r
PcdSetBool (PcdPciDisableBusEnumeration, FALSE);\r
\r
\r
return Status;\r
}\r
-\r
-/**\r
- * If no boot entry is currently defined, define the two default boot entries\r
- * for Juno R1.\r
- *\r
- * @return EFI_SUCCESS Some boot entries were already defined or\r
- * the default boot entries were set successfully.\r
- * @return EFI_OUT_OF_RESOURCES A memory allocation failed.\r
- * @return EFI_DEVICE_ERROR An UEFI variable could not be saved due to a hardware failure.\r
- * @return EFI_WRITE_PROTECTED An UEFI variable is read-only.\r
- * @return EFI_SECURITY_VIOLATION An UEFI variable could not be written.\r
- */\r
-STATIC\r
-EFI_STATUS\r
-SetJunoR1DefaultBootEntries (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- CONST CHAR16* ExtraBootArgument = L" dtb=r1a57a53.dtb";\r
- UINTN Size;\r
- EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol;\r
- EFI_DEVICE_PATH* BootDevicePath;\r
- UINT32 SysPciGbeL;\r
- UINT32 SysPciGbeH;\r
- CHAR16* DefaultBootArgument;\r
- CHAR16* DefaultBootArgument1;\r
- UINTN DefaultBootArgument1Size;\r
- CHAR16* DefaultBootArgument2;\r
- UINTN DefaultBootArgument2Size;\r
- UINT16 BootOrder[2];\r
-\r
- BootDevicePath = NULL;\r
- DefaultBootArgument1 = NULL;\r
- DefaultBootArgument2 = NULL;\r
-\r
- //\r
- // Because the driver has a dependency on gEfiVariable(Write)ArchProtocolGuid\r
- // (see [Depex] section of the INF file), we know we can safely access the\r
- // UEFI Variable at that stage.\r
- //\r
- Size = 0;\r
- Status = gRT->GetVariable (L"BootOrder", &gEfiGlobalVariableGuid, NULL, &Size, NULL);\r
- if (Status != EFI_NOT_FOUND) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- Status = gBS->LocateProtocol (\r
- &gEfiDevicePathFromTextProtocolGuid,\r
- NULL,\r
- (VOID **)&EfiDevicePathFromTextProtocol\r
- );\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // You must provide an implementation of DevicePathFromTextProtocol\r
- // in your firmware (eg: DevicePathDxe)\r
- //\r
- DEBUG ((EFI_D_ERROR, "Error: Require DevicePathFromTextProtocol\n"));\r
- return Status;\r
- }\r
- //\r
- // We use the same default kernel.\r
- //\r
- BootDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (\r
- (CHAR16*)PcdGetPtr (PcdDefaultBootDevicePath)\r
- );\r
- if (BootDevicePath == NULL) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- DefaultBootArgument = (CHAR16*)PcdGetPtr (PcdDefaultBootArgument);\r
- DefaultBootArgument1Size = StrSize (DefaultBootArgument) +\r
- (SKY2_MAC_ADDRESS_BOOTARG_LEN * sizeof (CHAR16));\r
- DefaultBootArgument2Size = DefaultBootArgument1Size + StrSize (ExtraBootArgument);\r
-\r
- Status = EFI_OUT_OF_RESOURCES;\r
- DefaultBootArgument1 = AllocatePool (DefaultBootArgument1Size);\r
- if (DefaultBootArgument1 == NULL) {\r
- goto Error;\r
- }\r
- DefaultBootArgument2 = AllocatePool (DefaultBootArgument2Size);\r
- if (DefaultBootArgument2 == NULL) {\r
- goto Error;\r
- }\r
-\r
- SysPciGbeL = MmioRead32 (ARM_JUNO_SYS_PCIGBE_L);\r
- SysPciGbeH = MmioRead32 (ARM_JUNO_SYS_PCIGBE_H);\r
-\r
- UnicodeSPrint (\r
- DefaultBootArgument1,\r
- DefaultBootArgument1Size,\r
- L"%s sky2.mac_address=0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x",\r
- DefaultBootArgument,\r
- (SysPciGbeH >> 8 ) & 0xFF, (SysPciGbeH ) & 0xFF,\r
- (SysPciGbeL >> 24) & 0xFF, (SysPciGbeL >> 16) & 0xFF,\r
- (SysPciGbeL >> 8 ) & 0xFF, (SysPciGbeL ) & 0xFF\r
- );\r
-\r
- CopyMem (DefaultBootArgument2, DefaultBootArgument1, DefaultBootArgument1Size);\r
- CopyMem (\r
- (UINT8*)DefaultBootArgument2 + DefaultBootArgument1Size - sizeof (CHAR16),\r
- ExtraBootArgument,\r
- StrSize (ExtraBootArgument)\r
- );\r
-\r
- //\r
- // Create Boot0001 environment variable\r
- //\r
- Status = BootOptionCreate (\r
- L"Boot0001", LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_BOOT,\r
- L"Linux with A57x2", BootDevicePath,\r
- (UINT8*)DefaultBootArgument1, DefaultBootArgument1Size\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ASSERT_EFI_ERROR (Status);\r
- goto Error;\r
- }\r
-\r
- //\r
- // Create Boot0002 environment variable\r
- //\r
- Status = BootOptionCreate (\r
- L"Boot0002", LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_BOOT,\r
- L"Linux with A57x2_A53x4", BootDevicePath,\r
- (UINT8*)DefaultBootArgument2, DefaultBootArgument2Size\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ASSERT_EFI_ERROR (Status);\r
- goto Error;\r
- }\r
-\r
- //\r
- // Add the new Boot Index to the list\r
- //\r
- BootOrder[0] = 1; // Boot0001\r
- BootOrder[1] = 2; // Boot0002\r
- Status = gRT->SetVariable (\r
- L"BootOrder",\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_NON_VOLATILE |\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS |\r
- EFI_VARIABLE_RUNTIME_ACCESS,\r
- sizeof (BootOrder),\r
- BootOrder\r
- );\r
-\r
-Error:\r
- if (BootDevicePath != NULL) {\r
- FreePool (BootDevicePath);\r
- }\r
- if (DefaultBootArgument1 != NULL) {\r
- FreePool (DefaultBootArgument1);\r
- }\r
- if (DefaultBootArgument2 != NULL) {\r
- FreePool (DefaultBootArgument2);\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((\r
- EFI_D_ERROR,\r
- "ArmJunoDxe - The setting of the default boot entries failed - %r\n",\r
- Status\r
- ));\r
- }\r
-\r
- return Status;\r
-}\r