/** Return the Virtual Memory Map of your platform This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform. @param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to- Virtual Memory mapping. This array must be ended by a zero-filled entry **/ VOID ArmPlatformGetVirtualMemoryMap ( IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap ) { ARM_MEMORY_REGION_ATTRIBUTES CacheAttributes; UINTN Index = 0; ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable; ASSERT(VirtualMemoryMap != NULL); VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages(EFI_SIZE_TO_PAGES (sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS)); if (VirtualMemoryTable == NULL) { return; } if (FeaturePcdGet(PcdCacheEnable) == TRUE) { CacheAttributes = DDR_ATTRIBUTES_CACHED; } else { CacheAttributes = DDR_ATTRIBUTES_UNCACHED; } // ReMap (Either NOR Flash or DRAM) VirtualMemoryTable[Index].PhysicalBase = FixedPcdGet64 (PcdSystemMemoryBase); VirtualMemoryTable[Index].VirtualBase = FixedPcdGet64 (PcdSystemMemoryBase); VirtualMemoryTable[Index].Length = FixedPcdGet64 (PcdSystemMemorySize); VirtualMemoryTable[Index].Attributes = CacheAttributes; // SOC Registers. L3 interconnects VirtualMemoryTable[++Index].PhysicalBase = SOC_REGISTERS_L3_PHYSICAL_BASE; VirtualMemoryTable[Index].VirtualBase = SOC_REGISTERS_L3_PHYSICAL_BASE; VirtualMemoryTable[Index].Length = SOC_REGISTERS_L3_PHYSICAL_LENGTH; VirtualMemoryTable[Index].Attributes = SOC_REGISTERS_L3_ATTRIBUTES; // SOC Registers. L4 interconnects VirtualMemoryTable[++Index].PhysicalBase = SOC_REGISTERS_L4_PHYSICAL_BASE; VirtualMemoryTable[Index].VirtualBase = SOC_REGISTERS_L4_PHYSICAL_BASE; VirtualMemoryTable[Index].Length = SOC_REGISTERS_L4_PHYSICAL_LENGTH; VirtualMemoryTable[Index].Attributes = SOC_REGISTERS_L4_ATTRIBUTES; // End of Table VirtualMemoryTable[++Index].PhysicalBase = 0; VirtualMemoryTable[Index].VirtualBase = 0; VirtualMemoryTable[Index].Length = 0; VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0; ASSERT((Index + 1) == MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS); *VirtualMemoryMap = VirtualMemoryTable; }
EFI_STATUS EFIAPI EarlyConfigEntry ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { DEBUG((EFI_D_ERROR,"SMMU CONFIG.........")); SmmuConfigForOS(); DEBUG((EFI_D_ERROR,"Done\n")); DEBUG((EFI_D_ERROR,"ITS CONFIG.........")); ITSCONFIG(); DEBUG((EFI_D_ERROR,"Done\n")); DEBUG((EFI_D_ERROR,"AP CONFIG.........")); MmioWrite64(FixedPcdGet64(PcdMailBoxAddress), 0x0); (void)WriteBackInvalidateDataCacheRange((VOID *) FixedPcdGet64(PcdMailBoxAddress), 8); asm("DSB SY"); asm("ISB"); CoreSelectBoot(); DEBUG((EFI_D_ERROR,"Done\n")); DEBUG((EFI_D_ERROR,"MN CONFIG.........")); MN_CONFIG (); DEBUG((EFI_D_ERROR,"Done\n")); DEBUG((EFI_D_ERROR,"RTC CONFIG.........")); MmioWrite32(0xA00021F0, 0xF); DEBUG((EFI_D_ERROR,"Done\n")); DEBUG((EFI_D_ERROR,"Tsensor CONFIG.........")); MmioWrite32(0x80010000 + 0x5000, 0x1); *(volatile UINT32*)0xA0000A8C = 0x1f; DEBUG((EFI_D_ERROR,"Done\n")); DEBUG((EFI_D_ERROR,"Timer CONFIG.........")); PlatformTimerStart (); DEBUG((EFI_D_ERROR,"Done\n")); return EFI_SUCCESS; }
VOID UartInit ( VOID ) { UINTN Uart = FixedPcdGet32(PcdOmap35xxConsoleUart); UINT32 UartBaseAddress = UartBase(Uart); // Set MODE_SELECT=DISABLE before trying to initialize or modify DLL, DLH registers. MmioWrite32 (UartBaseAddress + UART_MDR1_REG, UART_MDR1_MODE_SELECT_DISABLE); // Put device in configuration mode. MmioWrite32 (UartBaseAddress + UART_LCR_REG, UART_LCR_DIV_EN_ENABLE); // Programmable divisor N = 48Mhz/16/115200 = 26 MmioWrite32 (UartBaseAddress + UART_DLL_REG, 3000000/FixedPcdGet64 (PcdUartDefaultBaudRate)); // low divisor MmioWrite32 (UartBaseAddress + UART_DLH_REG, 0); // high divisor // Enter into UART operational mode. MmioWrite32 (UartBaseAddress + UART_LCR_REG, UART_LCR_DIV_EN_DISABLE | UART_LCR_CHAR_LENGTH_8); // Force DTR and RTS output to active MmioWrite32 (UartBaseAddress + UART_MCR_REG, UART_MCR_RTS_FORCE_ACTIVE | UART_MCR_DTR_FORCE_ACTIVE); // Clear & enable fifos MmioWrite32 (UartBaseAddress + UART_FCR_REG, UART_FCR_TX_FIFO_CLEAR | UART_FCR_RX_FIFO_CLEAR | UART_FCR_FIFO_ENABLE); // Restore MODE_SELECT MmioWrite32 (UartBaseAddress + UART_MDR1_REG, UART_MDR1_MODE_SELECT_UART_16X); }
/** Initialize controllers that must setup in the normal world This function is called by the ArmPlatformPkg/Pei or ArmPlatformPkg/Pei/PlatformPeim in the PEI phase. **/ RETURN_STATUS ArmPlatformInitialize ( IN UINTN MpId ) { RETURN_STATUS Status; UINT64 BaudRate; UINT32 ReceiveFifoDepth; EFI_PARITY_TYPE Parity; UINT8 DataBits; EFI_STOP_BITS_TYPE StopBits; Status = RETURN_SUCCESS; // // Initialize the Serial Debug UART // if (FixedPcdGet64 (PcdSerialDbgRegisterBase)) { ReceiveFifoDepth = 0; // Use the default value for FIFO depth Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity); DataBits = FixedPcdGet8 (PcdUartDefaultDataBits); StopBits = (EFI_STOP_BITS_TYPE)FixedPcdGet8 (PcdUartDefaultStopBits); BaudRate = (UINTN)FixedPcdGet64 (PcdSerialDbgUartBaudRate); Status = PL011UartInitializePort ( (UINTN)FixedPcdGet64 (PcdSerialDbgRegisterBase), FixedPcdGet32 (PcdSerialDbgUartClkInHz), &BaudRate, &ReceiveFifoDepth, &Parity, &DataBits, &StopBits ); } return Status; }
/** Main entry for this driver. @param ImageHandle Image handle this driver. @param SystemTable Pointer to SystemTable. @retval EFI_SUCESS This function always complete successfully. **/ EFI_STATUS EFIAPI PlatfomrSmbiosDriverEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_SMBIOS_HANDLE SmbiosHandle; SMBIOS_STRUCTURE_POINTER Smbios; // Phase 0 - Patch table to make SMBIOS 2.7 structures smaller to conform // to an early version of the specification. // Phase 1 - Initialize SMBIOS tables from template Status = SmbiosLibInitializeFromTemplate (gSmbiosTemplate); ASSERT_EFI_ERROR (Status); // Phase 2 - Patch SMBIOS table entries Smbios.Hdr = SmbiosLibGetRecord (EFI_SMBIOS_TYPE_BIOS_INFORMATION, 0, &SmbiosHandle); if (Smbios.Type0 != NULL) { // 64K * (n+1) bytes Smbios.Type0->BiosSize = (UINT8)DivU64x32 (FixedPcdGet64 (PcdEmuFirmwareFdSize), 64*1024) - 1; SmbiosLibUpdateUnicodeString ( SmbiosHandle, Smbios.Type0->BiosVersion, (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString) ); SmbiosLibUpdateUnicodeString ( SmbiosHandle, Smbios.Type0->BiosReleaseDate, (CHAR16 *) PcdGetPtr (PcdFirmwareReleaseDateString) ); } // Phase 3 - Create tables from scratch // Create Type 13 record from EFI Variables // Do we need this record for EFI as the info is availible from EFI varaibles // Also language types don't always match between EFI and SMBIOS // CreateSmbiosLanguageInformation (1, gSmbiosLangToEfiLang); CreatePlatformSmbiosMemoryRecords (); return EFI_SUCCESS; }
VOID PciExBarInitialization ( VOID ) { union { UINT64 Uint64; UINT32 Uint32[2]; } PciExBarBase; // // We only support the 256MB size for the MMCONFIG area: // 256 buses * 32 devices * 8 functions * 4096 bytes config space. // // The masks used below enforce the Q35 requirements that the MMCONFIG area // be (a) correctly aligned -- here at 256 MB --, (b) located under 64 GB. // // Note that (b) also ensures that the minimum address width we have // determined in AddressWidthInitialization(), i.e., 36 bits, will suffice // for DXE's page tables to cover the MMCONFIG area. // PciExBarBase.Uint64 = FixedPcdGet64 (PcdPciExpressBaseAddress); ASSERT ((PciExBarBase.Uint32[1] & MCH_PCIEXBAR_HIGHMASK) == 0); ASSERT ((PciExBarBase.Uint32[0] & MCH_PCIEXBAR_LOWMASK) == 0); // // Clear the PCIEXBAREN bit first, before programming the high register. // PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW), 0); // // Program the high register. Then program the low register, setting the // MMCONFIG area size and enabling decoding at once. // PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_HIGH), PciExBarBase.Uint32[1]); PciWrite32 ( DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW), PciExBarBase.Uint32[0] | MCH_PCIEXBAR_BUS_FF | MCH_PCIEXBAR_EN ); }
EFI_STATUS MapFd0 ( IN CHAR8 *FileName, IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress, OUT UINT64 *Length ) { int fd; void *res, *res2, *res3; UINTN FileSize; UINTN FvSize; void *EmuMagicPage; fd = open (FileName, O_RDWR); if (fd < 0) { return EFI_NOT_FOUND; } FileSize = lseek (fd, 0, SEEK_END); FvSize = FixedPcdGet64 (PcdEmuFlashFvRecoverySize); // Assume start of FD is Recovery FV, and make it write protected res = mmap ( (void *)(UINTN)FixedPcdGet64 (PcdEmuFlashFvRecoveryBase), FvSize, PROT_READ | PROT_EXEC, MAP_PRIVATE, fd, 0 ); if (res == MAP_FAILED) { perror ("MapFd0() Failed res ="); close (fd); return EFI_DEVICE_ERROR; } else if (res != (void *)(UINTN)FixedPcdGet64 (PcdEmuFlashFvRecoveryBase)) { // We could not load at the build address, so we need to allow writes munmap (res, FvSize); res = mmap ( (void *)(UINTN)FixedPcdGet64 (PcdEmuFlashFvRecoveryBase), FvSize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0 ); if (res == MAP_FAILED) { perror ("MapFd0() Failed res ="); close (fd); return EFI_DEVICE_ERROR; } } // Map the rest of the FD as read/write res2 = mmap ( (void *)(UINTN)(FixedPcdGet64 (PcdEmuFlashFvRecoveryBase) + FvSize), FileSize - FvSize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, fd, FvSize ); close (fd); if (res2 == MAP_FAILED) { perror ("MapFd0() Failed res2 ="); return EFI_DEVICE_ERROR; } // // If enabled use the magic page to communicate between modules // This replaces the PI PeiServicesTable pointer mechanism that // deos not work in the emulator. It also allows the removal of // writable globals from SEC, PEI_CORE (libraries), PEIMs // EmuMagicPage = (void *)(UINTN)FixedPcdGet64 (PcdPeiServicesTablePage); if (EmuMagicPage != NULL) { res3 = mmap ( (void *)EmuMagicPage, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0 ); if (res3 != EmuMagicPage) { printf ("MapFd0(): Could not allocate PeiServicesTablePage @ %lx\n", (long unsigned int)EmuMagicPage); return EFI_DEVICE_ERROR; } } *Length = (UINT64) FileSize; *BaseAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) res; return EFI_SUCCESS; }
/** Initialize the system (or sometimes called permanent) memory This memory is generally represented by the DRAM. This function is called from InitializeMemory() in MemoryInitPeim, in the PEI phase. **/ VOID ArmPlatformInitializeSystemMemory ( VOID ) { VOID *DeviceTreeBase; INT32 Node, Prev; UINT64 NewBase; UINT64 NewSize; CONST CHAR8 *Type; INT32 Len; CONST UINT64 *RegProp; NewBase = 0; NewSize = 0; DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress); ASSERT (DeviceTreeBase != NULL); // // Make sure we have a valid device tree blob // ASSERT (fdt_check_header (DeviceTreeBase) == 0); // // Look for a memory node // for (Prev = 0;; Prev = Node) { Node = fdt_next_node (DeviceTreeBase, Prev, NULL); if (Node < 0) { break; } // // Check for memory node // Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len); if (Type && AsciiStrnCmp (Type, "memory", Len) == 0) { // // Get the 'reg' property of this node. For now, we will assume // two 8 byte quantities for base and size, respectively. // RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len); if (RegProp != 0 && Len == (2 * sizeof (UINT64))) { NewBase = fdt64_to_cpu (ReadUnaligned64 (RegProp)); NewSize = fdt64_to_cpu (ReadUnaligned64 (RegProp + 1)); // // Make sure the start of DRAM matches our expectation // ASSERT (FixedPcdGet64 (PcdSystemMemoryBase) == NewBase); PcdSet64 (PcdSystemMemorySize, NewSize); DEBUG ((EFI_D_INFO, "%a: System RAM @ 0x%lx - 0x%lx\n", __FUNCTION__, NewBase, NewBase + NewSize - 1)); } else { DEBUG ((EFI_D_ERROR, "%a: Failed to parse FDT memory node\n", __FUNCTION__)); } break; } } // // We need to make sure that the machine we are running on has at least // 128 MB of memory configured, and is currently executing this binary from // NOR flash. This prevents a device tree image in DRAM from getting // clobbered when our caller installs permanent PEI RAM, before we have a // chance of marking its location as reserved or copy it to a freshly // allocated block in the permanent PEI RAM in the platform PEIM. // ASSERT (NewSize >= SIZE_128MB); ASSERT ( (((UINT64)PcdGet64 (PcdFdBaseAddress) + (UINT64)PcdGet32 (PcdFdSize)) <= NewBase) || ((UINT64)PcdGet64 (PcdFdBaseAddress) >= (NewBase + NewSize))); }
/** @file Sample to provide TempRamInitParams data. Copyright (c) 2014, Intel Corporation. All rights reserved.<BR> This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php. THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include <Library/PcdLib.h> GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 TempRamInitParams[4] = { ((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchAddress) + FixedPcdGet32 (PcdFlashMicroCodeOffset)), ((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchRegionSize) - FixedPcdGet32 (PcdFlashMicroCodeOffset)), FixedPcdGet32 (PcdFlashCodeCacheAddress), FixedPcdGet32 (PcdFlashCodeCacheSize) };
STATIC PLATFORM_SERIAL_CONSOLE mSerialConsole = { // // VENDOR_DEVICE_PATH SerialDxe // { { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, DP_NODE_LEN (VENDOR_DEVICE_PATH) }, SERIAL_DXE_FILE_GUID }, // // UART_DEVICE_PATH Uart // { { MESSAGING_DEVICE_PATH, MSG_UART_DP, DP_NODE_LEN (UART_DEVICE_PATH) }, 0, // Reserved FixedPcdGet64 (PcdUartDefaultBaudRate), // BaudRate FixedPcdGet8 (PcdUartDefaultDataBits), // DataBits FixedPcdGet8 (PcdUartDefaultParity), // Parity FixedPcdGet8 (PcdUartDefaultStopBits) // StopBits }, // // VENDOR_DEFINED_DEVICE_PATH Vt100 // { { MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, DP_NODE_LEN (VENDOR_DEFINED_DEVICE_PATH) }, EFI_VT_100_GUID },
VOID PrePiMain ( IN UINTN UefiMemoryBase, IN UINTN StacksBase, IN UINT64 StartTimeStamp ) { EFI_HOB_HANDOFF_INFO_TABLE* HobList; ARM_MP_CORE_INFO_PPI* ArmMpCoreInfoPpi; UINTN ArmCoreCount; ARM_CORE_INFO* ArmCoreInfoTable; EFI_STATUS Status; CHAR8 Buffer[100]; UINTN CharCount; UINTN StacksSize; // If ensure the FD is either part of the System Memory or totally outside of the System Memory (XIP) ASSERT (IS_XIP() || ((FixedPcdGet64 (PcdFdBaseAddress) >= FixedPcdGet64 (PcdSystemMemoryBase)) && ((UINT64)(FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= (UINT64)mSystemMemoryEnd))); // Initialize the architecture specific bits ArchInitialize (); // Initialize the Serial Port SerialPortInitialize (); CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"UEFI firmware (version %s built at %a on %a)\n\r", (CHAR16*)PcdGetPtr(PcdFirmwareVersionString), __TIME__, __DATE__); SerialPortWrite ((UINT8 *) Buffer, CharCount); // Initialize the Debug Agent for Source Level Debugging InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL); SaveAndSetDebugTimerInterrupt (TRUE); // Declare the PI/UEFI memory region HobList = HobConstructor ( (VOID*)UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize), (VOID*)UefiMemoryBase, (VOID*)StacksBase // The top of the UEFI Memory is reserved for the stacks ); PrePeiSetHobList (HobList); // Initialize MMU and Memory HOBs (Resource Descriptor HOBs) Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)); ASSERT_EFI_ERROR (Status); // Create the Stacks HOB (reserve the memory for all stacks) if (ArmIsMpCore ()) { StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize) + ((FixedPcdGet32 (PcdCoreCount) - 1) * FixedPcdGet32 (PcdCPUCoreSecondaryStackSize)); } else { StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize); } BuildStackHob (StacksBase, StacksSize); //TODO: Call CpuPei as a library BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize)); if (ArmIsMpCore ()) { // Only MP Core platform need to produce gArmMpCoreInfoPpiGuid Status = GetPlatformPpi (&gArmMpCoreInfoPpiGuid, (VOID**)&ArmMpCoreInfoPpi); // On MP Core Platform we must implement the ARM MP Core Info PPI (gArmMpCoreInfoPpiGuid) ASSERT_EFI_ERROR (Status); // Build the MP Core Info Table ArmCoreCount = 0; Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable); if (!EFI_ERROR(Status) && (ArmCoreCount > 0)) { // Build MPCore Info HOB BuildGuidDataHob (&gArmMpCoreInfoGuid, ArmCoreInfoTable, sizeof (ARM_CORE_INFO) * ArmCoreCount); } } // Set the Boot Mode SetBootMode (ArmPlatformGetBootMode ()); // Initialize Platform HOBs (CpuHob and FvHob) Status = PlatformPeim (); ASSERT_EFI_ERROR (Status); // Now, the HOB List has been initialized, we can register performance information PERF_START (NULL, "PEI", NULL, StartTimeStamp); // SEC phase needs to run library constructors by hand. ExtractGuidedSectionLibConstructor (); LzmaDecompressLibConstructor (); // Build HOBs to pass up our version of stuff the DXE Core needs to save space BuildPeCoffLoaderHob (); BuildExtractSectionHob ( &gLzmaCustomDecompressGuid, LzmaGuidedSectionGetInfo, LzmaGuidedSectionExtraction ); // Assume the FV that contains the SEC (our code) also contains a compressed FV. Status = DecompressFirstFv (); ASSERT_EFI_ERROR (Status); // Load the DXE Core and transfer control to it Status = LoadDxeCoreFromFv (NULL, 0); ASSERT_EFI_ERROR (Status); }
INTN EFIAPI main ( IN INTN Argc, IN CHAR8 **Argv, IN CHAR8 **Envp ) /*++ Routine Description: Main entry point to SEC for WinNt. This is a Windows program Arguments: Argc - Number of command line arguments Argv - Array of command line argument strings Envp - Array of environment variable strings Returns: 0 - Normal exit 1 - Abnormal exit --*/ { EFI_STATUS Status; HANDLE Token; TOKEN_PRIVILEGES TokenPrivileges; VOID *TemporaryRam; UINT32 TemporaryRamSize; VOID *EmuMagicPage; UINTN Index; UINTN Index1; CHAR16 *FileName; CHAR16 *FileNamePtr; BOOLEAN Done; EFI_PEI_FILE_HANDLE FileHandle; VOID *SecFile; CHAR16 *MemorySizeStr; CHAR16 *FirmwareVolumesStr; UINT32 ProcessAffinityMask; UINT32 SystemAffinityMask; INT32 LowBit; // // Enable the privilege so that RTC driver can successfully run SetTime() // OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &Token); if (LookupPrivilegeValue(NULL, SE_TIME_ZONE_NAME, &TokenPrivileges.Privileges[0].Luid)) { TokenPrivileges.PrivilegeCount = 1; TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(Token, FALSE, &TokenPrivileges, 0, (PTOKEN_PRIVILEGES) NULL, 0); } MemorySizeStr = (CHAR16 *) PcdGetPtr (PcdEmuMemorySize); FirmwareVolumesStr = (CHAR16 *) PcdGetPtr (PcdEmuFirmwareVolume); SecPrint ("\nEDK II WIN Host Emulation Environment from http://www.tianocore.org/edk2/\n"); // // Determine the first thread available to this process. // if (GetProcessAffinityMask (GetCurrentProcess (), &ProcessAffinityMask, &SystemAffinityMask)) { LowBit = (INT32)LowBitSet32 (ProcessAffinityMask); if (LowBit != -1) { // // Force the system to bind the process to a single thread to work // around odd semaphore type crashes. // SetProcessAffinityMask (GetCurrentProcess (), (INTN)(BIT0 << LowBit)); } } // // Make some Windows calls to Set the process to the highest priority in the // idle class. We need this to have good performance. // SetPriorityClass (GetCurrentProcess (), IDLE_PRIORITY_CLASS); SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST); SecInitializeThunk (); // // PPIs pased into PEI_CORE // AddThunkPpi (EFI_PEI_PPI_DESCRIPTOR_PPI, &gEmuThunkPpiGuid, &mSecEmuThunkPpi); // // Emulator Bus Driver Thunks // AddThunkProtocol (&mWinNtWndThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuGop), TRUE); AddThunkProtocol (&mWinNtFileSystemThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuFileSystem), TRUE); AddThunkProtocol (&mWinNtBlockIoThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuVirtualDisk), TRUE); // // Allocate space for gSystemMemory Array // gSystemMemoryCount = CountSeparatorsInString (MemorySizeStr, '!') + 1; gSystemMemory = calloc (gSystemMemoryCount, sizeof (NT_SYSTEM_MEMORY)); if (gSystemMemory == NULL) { SecPrint ("ERROR : Can not allocate memory for %S. Exiting.\n", MemorySizeStr); exit (1); } // // Allocate space for gSystemMemory Array // gFdInfoCount = CountSeparatorsInString (FirmwareVolumesStr, '!') + 1; gFdInfo = calloc (gFdInfoCount, sizeof (NT_FD_INFO)); if (gFdInfo == NULL) { SecPrint ("ERROR : Can not allocate memory for %S. Exiting.\n", FirmwareVolumesStr); exit (1); } // // Setup Boot Mode. // SecPrint (" BootMode 0x%02x\n", PcdGet32 (PcdEmuBootMode)); // // Allocate 128K memory to emulate temp memory for PEI. // on a real platform this would be SRAM, or using the cache as RAM. // Set TemporaryRam to zero so WinNtOpenFile will allocate a new mapping // TemporaryRamSize = TEMPORARY_RAM_SIZE; TemporaryRam = VirtualAlloc (NULL, (SIZE_T) (TemporaryRamSize), MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (TemporaryRam == NULL) { SecPrint ("ERROR : Can not allocate enough space for SecStack\n"); exit (1); } SetMem32 (TemporaryRam, TemporaryRamSize, PcdGet32 (PcdInitValueInTempStack)); SecPrint (" OS Emulator passing in %u KB of temp RAM at 0x%08lx to SEC\n", TemporaryRamSize / SIZE_1KB, TemporaryRam ); // // If enabled use the magic page to communicate between modules // This replaces the PI PeiServicesTable pointer mechanism that // deos not work in the emulator. It also allows the removal of // writable globals from SEC, PEI_CORE (libraries), PEIMs // EmuMagicPage = (VOID *)(UINTN)(FixedPcdGet64 (PcdPeiServicesTablePage) & MAX_UINTN); if (EmuMagicPage != NULL) { UINT64 Size; Status = WinNtOpenFile ( NULL, SIZE_4KB, 0, &EmuMagicPage, &Size ); if (EFI_ERROR (Status)) { SecPrint ("ERROR : Could not allocate PeiServicesTablePage @ %p\n", EmuMagicPage); return EFI_DEVICE_ERROR; } } // // Open All the firmware volumes and remember the info in the gFdInfo global // Meanwhile, find the SEC Core. // FileNamePtr = AllocateCopyPool (StrSize (FirmwareVolumesStr), FirmwareVolumesStr); if (FileNamePtr == NULL) { SecPrint ("ERROR : Can not allocate memory for firmware volume string\n"); exit (1); } for (Done = FALSE, Index = 0, SecFile = NULL; !Done; Index++) { FileName = FileNamePtr; for (Index1 = 0; (FileNamePtr[Index1] != '!') && (FileNamePtr[Index1] != 0); Index1++) ; if (FileNamePtr[Index1] == 0) { Done = TRUE; } else { FileNamePtr[Index1] = '\0'; FileNamePtr = &FileNamePtr[Index1 + 1]; } // // Open the FD and remember where it got mapped into our processes address space // Status = WinNtOpenFile ( FileName, 0, OPEN_EXISTING, &gFdInfo[Index].Address, &gFdInfo[Index].Size ); if (EFI_ERROR (Status)) { SecPrint ("ERROR : Can not open Firmware Device File %S (0x%X). Exiting.\n", FileName, Status); exit (1); } SecPrint (" FD loaded from %S\n", FileName); if (SecFile == NULL) { // // Assume the beginning of the FD is an FV and look for the SEC Core. // Load the first one we find. // FileHandle = NULL; Status = PeiServicesFfsFindNextFile ( EFI_FV_FILETYPE_SECURITY_CORE, (EFI_PEI_FV_HANDLE)gFdInfo[Index].Address, &FileHandle ); if (!EFI_ERROR (Status)) { Status = PeiServicesFfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SecFile); if (!EFI_ERROR (Status)) { SecPrint (" contains SEC Core"); } } } SecPrint ("\n"); } // // Calculate memory regions and store the information in the gSystemMemory // global for later use. The autosizing code will use this data to // map this memory into the SEC process memory space. // for (Index = 0, Done = FALSE; !Done; Index++) { // // Save the size of the memory and make a Unicode filename SystemMemory00, ... // gSystemMemory[Index].Size = _wtoi (MemorySizeStr) * SIZE_1MB; // // Find the next region // for (Index1 = 0; MemorySizeStr[Index1] != '!' && MemorySizeStr[Index1] != 0; Index1++) ; if (MemorySizeStr[Index1] == 0) { Done = TRUE; } MemorySizeStr = MemorySizeStr + Index1 + 1; } SecPrint ("\n"); // // Hand off to SEC Core // SecLoadSecCore ((UINTN)TemporaryRam, TemporaryRamSize, gFdInfo[0].Address, gFdInfo[0].Size, SecFile); // // If we get here, then the SEC Core returned. This is an error as SEC should // always hand off to PEI Core and then on to DXE Core. // SecPrint ("ERROR : SEC returned\n"); exit (1); }
*/ { GICC_ENTRY (0, GET_MPID (0, 0), 92, 25, 0), GICC_ENTRY (1, GET_MPID (0, 1), 93, 25, 0), GICC_ENTRY (2, GET_MPID (0, 2), 94, 25, 0), GICC_ENTRY (3, GET_MPID (0, 3), 95, 25, 0), GICC_ENTRY (4, GET_MPID (1, 0), 96, 25, 0), GICC_ENTRY (5, GET_MPID (1, 1), 97, 25, 0), GICC_ENTRY (6, GET_MPID (1, 2), 98, 25, 0), GICC_ENTRY (7, GET_MPID (1, 3), 99, 25, 0) }, // GIC Distributor Info { FixedPcdGet64 (PcdGicDistributorBase), // UINT64 PhysicalBaseAddress 0, // UINT32 SystemVectorBase 3 // UINT8 GicVersion }, /// GIC Re-Distributor Info { // UINT64 DiscoveryRangeBaseAddress FixedPcdGet64 (PcdGicRedistributorsBase), // UINT32 DiscoveryRangeLength 0x00200000 }, // Generic Timer Info { // The physical base address for the counter control frame
/** Returns the Virtual Memory Map of the platform. This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform. @param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to-Virtual Memory mapping. This array must be ended by a zero-filled entry. **/ VOID ArmPlatformGetVirtualMemoryMap ( IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap ) { UINTN Index; ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable; EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes; ResourceAttributes = EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE | EFI_RESOURCE_ATTRIBUTE_TESTED; BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, ResourceAttributes, FixedPcdGet64 (PcdDramBlock2Base), FixedPcdGet64 (PcdDramBlock2Size)); ASSERT (VirtualMemoryMap != NULL); Index = 0; VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages (EFI_SIZE_TO_PAGES (sizeof (ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS)); if (VirtualMemoryTable == NULL) { return; } // Expansion AXI - SMC Chip Select 0 (NOR Flash) VirtualMemoryTable[Index].PhysicalBase = SGI_EXP_SMC_CS0_BASE; VirtualMemoryTable[Index].VirtualBase = SGI_EXP_SMC_CS0_BASE; VirtualMemoryTable[Index].Length = SIZE_64MB; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // Expansion AXI - SMC Chip Select 1 (NOR Flash) VirtualMemoryTable[++Index].PhysicalBase = SGI_EXP_SMC_CS1_BASE; VirtualMemoryTable[Index].VirtualBase = SGI_EXP_SMC_CS1_BASE; VirtualMemoryTable[Index].Length = SIZE_64MB; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // Expansion AXI - SMSC 91X (Ethernet) VirtualMemoryTable[++Index].PhysicalBase = SGI_EXP_SMSC91X_BASE; VirtualMemoryTable[Index].VirtualBase = SGI_EXP_SMSC91X_BASE; VirtualMemoryTable[Index].Length = SGI_EXP_SMSC91X_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // Expansion AXI - System Peripherals VirtualMemoryTable[++Index].PhysicalBase = SGI_EXP_SYS_PERIPH_BASE; VirtualMemoryTable[Index].VirtualBase = SGI_EXP_SYS_PERIPH_BASE; VirtualMemoryTable[Index].Length = SGI_EXP_SYS_PERIPH_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // Sub System Peripherals - Generic Watchdog VirtualMemoryTable[++Index].PhysicalBase = SGI_SUBSYS_GENERIC_WDOG_BASE; VirtualMemoryTable[Index].VirtualBase = SGI_SUBSYS_GENERIC_WDOG_BASE; VirtualMemoryTable[Index].Length = SGI_SUBSYS_GENERIC_WDOG_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // Sub System Peripherals - GIC-600 VirtualMemoryTable[++Index].PhysicalBase = SGI_SUBSYS_GENERIC_GIC_BASE; VirtualMemoryTable[Index].VirtualBase = SGI_SUBSYS_GENERIC_GIC_BASE; VirtualMemoryTable[Index].Length = SGI_SUBSYS_GENERIC_GIC_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // Expansion AXI - Platform Peripherals - HDLCD1 VirtualMemoryTable[++Index].PhysicalBase = SGI_EXP_PLAT_PERIPH_HDLCD1_BASE; VirtualMemoryTable[Index].VirtualBase = SGI_EXP_PLAT_PERIPH_HDLCD1_BASE; VirtualMemoryTable[Index].Length = SGI_EXP_PLAT_PERIPH_HDLCD1_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // Expansion AXI - Platform Peripherals - UART1 VirtualMemoryTable[++Index].PhysicalBase = SGI_EXP_PLAT_PERIPH_UART1_BASE; VirtualMemoryTable[Index].VirtualBase = SGI_EXP_PLAT_PERIPH_UART1_BASE; VirtualMemoryTable[Index].Length = SGI_EXP_PLAT_PERIPH_UART1_SZ; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // DDR - (2GB - 16MB) VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdSystemMemoryBase); VirtualMemoryTable[Index].VirtualBase = PcdGet64 (PcdSystemMemoryBase); VirtualMemoryTable[Index].Length = PcdGet64 (PcdSystemMemorySize); VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK; // DDR - Second Block VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdDramBlock2Base); VirtualMemoryTable[Index].VirtualBase = PcdGet64 (PcdDramBlock2Base); VirtualMemoryTable[Index].Length = PcdGet64 (PcdDramBlock2Size); VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK; // PCI Configuration Space VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdPciExpressBaseAddress); VirtualMemoryTable[Index].VirtualBase = PcdGet64 (PcdPciExpressBaseAddress); VirtualMemoryTable[Index].Length = (FixedPcdGet32 (PcdPciBusMax) - FixedPcdGet32 (PcdPciBusMin) + 1) * SIZE_1MB; VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // MM Memory Space VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdMmBufferBase); VirtualMemoryTable[Index].VirtualBase = PcdGet64 (PcdMmBufferBase); VirtualMemoryTable[Index].Length = PcdGet64 (PcdMmBufferSize); VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED; // End of Table VirtualMemoryTable[++Index].PhysicalBase = 0; VirtualMemoryTable[Index].VirtualBase = 0; VirtualMemoryTable[Index].Length = 0; VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0; ASSERT ((Index + 1) <= MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS); *VirtualMemoryMap = VirtualMemoryTable; }
VOID ApicTableUpdate ( IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader, IN OUT EFI_ACPI_TABLE_VERSION *Version ) /*++ Routine Description: Update the processors information in the APIC table Arguments: Table - The table to be set Version - Version to publish Returns: None --*/ { EFI_STATUS Status; EFI_MP_SERVICES_PROTOCOL *MpService; UINT8 *CurrPtr; UINT8 *EndPtr; UINT8 CurrIoApic; UINT8 CurrProcessor; UINTN NumberOfCPUs; UINTN NumberOfEnabledCPUs; UINTN BufferSize; EFI_PROCESSOR_INFORMATION MpContext; ACPI_APIC_STRUCTURE_PTR *ApicPtr; CurrIoApic = 0; CurrProcessor = 0; // // Find the MP Protocol. This is an MP platform, so MP protocol must be // there. // Status = gBS->LocateProtocol ( &gEfiMpServiceProtocolGuid, NULL, (VOID**)&MpService ); if (EFI_ERROR (Status)) { // // Failed to get MP information, doesn't publish the invalid table // *Version = EFI_ACPI_TABLE_VERSION_NONE; return; } // // Determine the number of processors // MpService->GetNumberOfProcessors ( MpService, &NumberOfCPUs, &NumberOfEnabledCPUs ); CurrPtr = (UINT8*) &(TableHeader[1]); CurrPtr = CurrPtr + 8; // Size of Local APIC Address & Flag EndPtr = (UINT8*) TableHeader; EndPtr = EndPtr + TableHeader->Length; while (CurrPtr < EndPtr) { ApicPtr = (ACPI_APIC_STRUCTURE_PTR*) CurrPtr; switch (ApicPtr->AcpiApicCommon.Type) { case EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC: BufferSize = sizeof (EFI_PROCESSOR_INFORMATION); ApicPtr->AcpiLocalApic.Flags = 0; ApicPtr->AcpiLocalApic.ApicId = 0; Status = MpService->GetProcessorInfo ( MpService, CurrProcessor, &MpContext ); if (!EFI_ERROR (Status)) { if (MpContext.StatusFlag & PROCESSOR_ENABLED_BIT) { ApicPtr->AcpiLocalApic.Flags = EFI_ACPI_3_0_LOCAL_APIC_ENABLED; } ApicPtr->AcpiLocalApic.ApicId = (UINT8)MpContext.ProcessorId; } CurrProcessor++; break; case EFI_ACPI_1_0_IO_APIC: // // IO APIC entries can be patched here // if (CurrIoApic == 0) { // // Update SOC internel IOAPIC base // ApicPtr->AcpiIoApic.IoApicId = PcdGet8 (PcdIoApicSettingIoApicId); ApicPtr->AcpiIoApic.IoApicAddress = (UINT32)FixedPcdGet64(PcdIoApicBaseAddress); ApicPtr->AcpiIoApic.GlobalSystemInterruptBase = 0; } else { // // Porting is required to update other IOAPIC entries if available // ASSERT (0); } CurrIoApic++; break; default: break; }; CurrPtr = CurrPtr + ApicPtr->AcpiApicCommon.Length; } }
VOID MemMapInitialization ( VOID ) { // // Create Memory Type Information HOB // BuildGuidDataHob ( &gEfiMemoryTypeInformationGuid, mDefaultMemoryTypeInformation, sizeof(mDefaultMemoryTypeInformation) ); // // Add PCI IO Port space available for PCI resource allocations. // BuildResourceDescriptorHob ( EFI_RESOURCE_IO, EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED, PcdGet64 (PcdPciIoBase), PcdGet64 (PcdPciIoSize) ); // // Video memory + Legacy BIOS region // AddIoMemoryRangeHob (0x0A0000, BASE_1MB); if (!mXen) { UINT32 TopOfLowRam; UINT64 PciExBarBase; UINT32 PciBase; UINT32 PciSize; TopOfLowRam = GetSystemMemorySizeBelow4gb (); PciExBarBase = 0; if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) { // // The MMCONFIG area is expected to fall between the top of low RAM and // the base of the 32-bit PCI host aperture. // PciExBarBase = FixedPcdGet64 (PcdPciExpressBaseAddress); ASSERT (TopOfLowRam <= PciExBarBase); ASSERT (PciExBarBase <= MAX_UINT32 - SIZE_256MB); PciBase = (UINT32)(PciExBarBase + SIZE_256MB); } else { PciBase = (TopOfLowRam < BASE_2GB) ? BASE_2GB : TopOfLowRam; } // // address purpose size // ------------ -------- ------------------------- // max(top, 2g) PCI MMIO 0xFC000000 - max(top, 2g) // 0xFC000000 gap 44 MB // 0xFEC00000 IO-APIC 4 KB // 0xFEC01000 gap 1020 KB // 0xFED00000 HPET 1 KB // 0xFED00400 gap 111 KB // 0xFED1C000 gap (PIIX4) / RCRB (ICH9) 16 KB // 0xFED20000 gap 896 KB // 0xFEE00000 LAPIC 1 MB // PciSize = 0xFC000000 - PciBase; AddIoMemoryBaseSizeHob (PciBase, PciSize); PcdSet64 (PcdPciMmio32Base, PciBase); PcdSet64 (PcdPciMmio32Size, PciSize); AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB); AddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB); if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) { AddIoMemoryBaseSizeHob (ICH9_ROOT_COMPLEX_BASE, SIZE_16KB); // // Note: there should be an // // AddIoMemoryBaseSizeHob (PciExBarBase, SIZE_256MB); // // call below, just like the one above for RCBA. However, Linux insists // that the MMCONFIG area be marked in the E820 or UEFI memory map as // "reserved memory" -- Linux does not content itself with a simple gap // in the memory map wherever the MCFG ACPI table points to. // // This appears to be a safety measure. The PCI Firmware Specification // (rev 3.1) says in 4.1.2. "MCFG Table Description": "The resources can // *optionally* be returned in [...] EFIGetMemoryMap as reserved memory // [...]". (Emphasis added here.) // // Normally we add memory resource descriptor HOBs in // QemuInitializeRam(), and pre-allocate from those with memory // allocation HOBs in InitializeRamRegions(). However, the MMCONFIG area // is most definitely not RAM; so, as an exception, cover it with // uncacheable reserved memory right here. // AddReservedMemoryBaseSizeHob (PciExBarBase, SIZE_256MB, FALSE); BuildMemoryAllocationHob (PciExBarBase, SIZE_256MB, EfiReservedMemoryType); } AddIoMemoryBaseSizeHob (PcdGet32(PcdCpuLocalApicBaseAddress), SIZE_1MB); } }
STATIC UINT64 SerialPortGetBaseAddress ( VOID ) { UINT64 BaudRate; UINT32 ReceiveFifoDepth; EFI_PARITY_TYPE Parity; UINT8 DataBits; EFI_STOP_BITS_TYPE StopBits; VOID *DeviceTreeBase; INT32 Node, Prev; INT32 Len; CONST CHAR8 *Compatible; CONST CHAR8 *NodeStatus; CONST CHAR8 *CompatibleItem; CONST UINT64 *RegProperty; UINTN UartBase; RETURN_STATUS Status; DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress); if ((DeviceTreeBase == NULL) || (fdt_check_header (DeviceTreeBase) != 0)) { return 0; } // // Enumerate all FDT nodes looking for a PL011 and capture its base address // for (Prev = 0;; Prev = Node) { Node = fdt_next_node (DeviceTreeBase, Prev, NULL); if (Node < 0) { break; } Compatible = fdt_getprop (DeviceTreeBase, Node, "compatible", &Len); if (Compatible == NULL) { continue; } // // Iterate over the NULL-separated items in the compatible string // for (CompatibleItem = Compatible; CompatibleItem < Compatible + Len; CompatibleItem += 1 + AsciiStrLen (CompatibleItem)) { if (AsciiStrCmp (CompatibleItem, "arm,pl011") == 0) { NodeStatus = fdt_getprop (DeviceTreeBase, Node, "status", &Len); if (NodeStatus != NULL && AsciiStrCmp (NodeStatus, "okay") != 0) { continue; } RegProperty = fdt_getprop (DeviceTreeBase, Node, "reg", &Len); if (Len != 16) { return 0; } UartBase = (UINTN)fdt64_to_cpu (ReadUnaligned64 (RegProperty)); BaudRate = (UINTN)FixedPcdGet64 (PcdUartDefaultBaudRate); ReceiveFifoDepth = 0; // Use the default value for Fifo depth Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity); DataBits = FixedPcdGet8 (PcdUartDefaultDataBits); StopBits = (EFI_STOP_BITS_TYPE) FixedPcdGet8 (PcdUartDefaultStopBits); Status = PL011UartInitializePort ( UartBase, FixedPcdGet32 (PL011UartClkInHz), &BaudRate, &ReceiveFifoDepth, &Parity, &DataBits, &StopBits ); if (!EFI_ERROR (Status)) { return UartBase; } } } } return 0; }
STATIC PCI_ROOT_BRIDGE mRootBridge = { 0, // Segment 0, // Supports 0, // Attributes TRUE, // DmaAbove4G FALSE, // NoExtendedConfigSpace FALSE, // ResourceAssigned EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | // AllocationAttributes EFI_PCI_HOST_BRIDGE_MEM64_DECODE, { // Bus FixedPcdGet32 (PcdPciBusMin), FixedPcdGet32 (PcdPciBusMax) }, { // Io FixedPcdGet64 (PcdPciIoBase), FixedPcdGet64 (PcdPciIoBase) + FixedPcdGet64 (PcdPciIoSize) - 1 }, { // Mem FixedPcdGet32 (PcdPciMmio32Base), FixedPcdGet32 (PcdPciMmio32Base) + FixedPcdGet32 (PcdPciMmio32Size) - 1 }, { // MemAbove4G FixedPcdGet64 (PcdPciMmio64Base), FixedPcdGet64 (PcdPciMmio64Base) + FixedPcdGet64 (PcdPciMmio64Size) - 1 }, { // PMem MAX_UINT64, 0 }, { // PMemAbove4G