123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438 |
- /** @file
- Platform PEI driver
- Copyright (c) 2022 Loongson Technology Corporation Limited. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- @par Glossary:
- - Mem - Memory
- **/
- //
- // The package level header files this module uses
- //
- #include <PiPei.h>
- //
- // The Library classes this module consumes
- //
- #include <Library/DebugLib.h>
- #include <Library/HobLib.h>
- #include <Library/IoLib.h>
- #include <Library/MemoryAllocationLib.h>
- #include <Library/BaseMemoryLib.h>
- #include <Library/PcdLib.h>
- #include <Library/PeimEntryPoint.h>
- #include <Library/PeiServicesLib.h>
- #include <Library/ResourcePublicationLib.h>
- #include <Guid/MemoryTypeInformation.h>
- #include <Library/QemuFwCfgLib.h>
- #include <Library/MmuLib.h>
- #include <Guid/FdtHob.h>
- #include <libfdt.h>
- #include <Ppi/MasterBootMode.h>
- #include "Platform.h"
- /* TODO */
- EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
- { EfiReservedMemoryType, 0x004 },
- { EfiRuntimeServicesData, 0x024 },
- { EfiRuntimeServicesCode, 0x030 },
- { EfiBootServicesCode, 0x180 },
- { EfiBootServicesData, 0xF00 },
- { EfiMaxMemoryType, 0x000 }
- };
- //
- // Module globals
- //
- CONST EFI_PEI_PPI_DESCRIPTOR mPpiListBootMode = {
- (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
- &gEfiPeiMasterBootModePpiGuid,
- NULL
- };
- STATIC EFI_BOOT_MODE mBootMode = BOOT_WITH_FULL_CONFIGURATION;
- /**
- Create Reserved type memory range hand off block.
- @param MemoryBase memory base address.
- @param MemoryLimit memory length.
- @return VOID
- **/
- VOID
- AddReservedMemoryBaseSizeHob (
- EFI_PHYSICAL_ADDRESS MemoryBase,
- UINT64 MemorySize
- )
- {
- BuildResourceDescriptorHob (
- EFI_RESOURCE_MEMORY_RESERVED,
- EFI_RESOURCE_ATTRIBUTE_PRESENT |
- EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
- EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
- EFI_RESOURCE_ATTRIBUTE_TESTED,
- MemoryBase,
- MemorySize
- );
- }
- /**
- Create system type memory range hand off block.
- @param MemoryBase memory base address.
- @param MemoryLimit memory length.
- @return VOID
- **/
- VOID
- AddMemoryBaseSizeHob (
- EFI_PHYSICAL_ADDRESS MemoryBase,
- UINT64 MemorySize
- )
- {
- BuildResourceDescriptorHob (
- EFI_RESOURCE_SYSTEM_MEMORY,
- 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,
- MemoryBase,
- MemorySize
- );
- }
- /**
- Create memory range hand off block.
- @param MemoryBase memory base address.
- @param MemoryLimit memory length.
- @return VOID
- **/
- VOID
- AddMemoryRangeHob (
- EFI_PHYSICAL_ADDRESS MemoryBase,
- EFI_PHYSICAL_ADDRESS MemoryLimit
- )
- {
- AddMemoryBaseSizeHob (MemoryBase, (UINT64) (MemoryLimit - MemoryBase));
- }
- /**
- Create memory type information hand off block.
- @param VOID
- @return VOID
- **/
- VOID
- MemMapInitialization (
- VOID
- )
- {
- DEBUG ((DEBUG_INFO, "==%a==\n", __func__));
- //
- // Create Memory Type Information HOB
- //
- BuildGuidDataHob (
- &gEfiMemoryTypeInformationGuid,
- mDefaultMemoryTypeInformation,
- sizeof (mDefaultMemoryTypeInformation)
- );
- }
- /** Get the UART base address of the console serial-port from the DT.
- This function fetches the node referenced in the "stdout-path"
- property of the "chosen" node and returns the base address of
- the console UART.
- @param [in] Fdt Pointer to a Flattened Device Tree (Fdt).
- @param [out] SerialConsoleAddress If success, contains the base address
- of the console serial-port.
- @retval EFI_SUCCESS The function completed successfully.
- @retval EFI_NOT_FOUND Console serial-port info not found in DT.
- @retval EFI_INVALID_PARAMETER Invalid parameter.
- **/
- STATIC
- EFI_STATUS
- EFIAPI
- GetSerialConsolePortAddress (
- IN CONST VOID *Fdt,
- OUT UINT64 *SerialConsoleAddress
- )
- {
- CONST CHAR8 *Prop;
- INT32 PropSize;
- CONST CHAR8 *Path;
- INT32 PathLen;
- INT32 ChosenNode;
- INT32 SerialConsoleNode;
- INT32 Len;
- CONST CHAR8 *NodeStatus;
- CONST UINT64 *RegProperty;
- if ((Fdt == NULL) || (fdt_check_header (Fdt) != 0)) {
- return EFI_INVALID_PARAMETER;
- }
- // The "chosen" node resides at the root of the DT. Fetch it.
- ChosenNode = fdt_path_offset (Fdt, "/chosen");
- if (ChosenNode < 0) {
- return EFI_NOT_FOUND;
- }
- Prop = fdt_getprop (Fdt, ChosenNode, "stdout-path", &PropSize);
- if (PropSize < 0) {
- return EFI_NOT_FOUND;
- }
- // Determine the actual path length, as a colon terminates the path.
- Path = ScanMem8 (Prop, ':', PropSize);
- if (Path == NULL) {
- PathLen = AsciiStrLen (Prop);
- } else {
- PathLen = Path - Prop;
- }
- // Aliases cannot start with a '/', so it must be the actual path.
- if (Prop[0] == '/') {
- SerialConsoleNode = fdt_path_offset_namelen (Fdt, Prop, PathLen);
- } else {
- // Lookup the alias, as this contains the actual path.
- Path = fdt_get_alias_namelen (Fdt, Prop, PathLen);
- if (Path == NULL) {
- return EFI_NOT_FOUND;
- }
- SerialConsoleNode = fdt_path_offset (Fdt, Path);
- }
- NodeStatus = fdt_getprop (Fdt, SerialConsoleNode, "status", &Len);
- if ((NodeStatus != NULL) && (AsciiStrCmp (NodeStatus, "okay") != 0)) {
- return EFI_NOT_FOUND;
- }
- RegProperty = fdt_getprop (Fdt, SerialConsoleNode, "reg", &Len);
- if (Len != 16) {
- return EFI_INVALID_PARAMETER;
- }
- *SerialConsoleAddress = fdt64_to_cpu (ReadUnaligned64 (RegProperty));
- return EFI_SUCCESS;
- }
- /** Get the Rtc base address from the DT.
- This function fetches the node referenced in the "loongson,ls7a-rtc"
- property of the "reg" node and returns the base address of
- the RTC.
- @param [in] Fdt Pointer to a Flattened Device Tree (Fdt).
- @param [out] RtcBaseAddress If success, contains the base address
- of the Rtc.
- @retval EFI_SUCCESS The function completed successfully.
- @retval EFI_NOT_FOUND RTC info not found in DT.
- @retval EFI_INVALID_PARAMETER Invalid parameter.
- **/
- STATIC
- EFI_STATUS
- EFIAPI
- GetRtcAddress (
- IN CONST VOID *Fdt,
- OUT UINT64 *RtcBaseAddress
- )
- {
- INT32 Node;
- INT32 Prev;
- CONST CHAR8 *Type;
- INT32 Len;
- CONST UINT64 *RegProp;
- EFI_STATUS Status;
- if ((Fdt == NULL) || (fdt_check_header (Fdt) != 0)) {
- return EFI_INVALID_PARAMETER;
- }
- Status = EFI_NOT_FOUND;
- for (Prev = 0;; Prev = Node) {
- Node = fdt_next_node (Fdt, Prev, NULL);
- if (Node < 0) {
- break;
- }
- //
- // Check for memory node
- //
- Type = fdt_getprop (Fdt, Node, "compatible", &Len);
- if ((Type)
- && (AsciiStrnCmp (Type, "loongson,ls7a-rtc", 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 (Fdt, Node, "reg", &Len);
- if ((RegProp != 0)
- && (Len == (2 * sizeof (UINT64))))
- {
- *RtcBaseAddress = SwapBytes64 (RegProp[0]);
- Status = RETURN_SUCCESS;
- DEBUG ((DEBUG_INFO, "%a Len %d RtcBase %llx\n",__func__, Len, *RtcBaseAddress));
- break;
- } else {
- DEBUG ((DEBUG_ERROR, "%a: Failed to parse FDT rtc node\n",
- __FUNCTION__));
- break;
- }
- }
- }
- return Status;
- }
- /**
- Misc Initialization.
- @param VOID
- @return VOID
- **/
- VOID
- MiscInitialization (
- VOID
- )
- {
- DEBUG ((DEBUG_INFO, "==%a==\n", __func__));
- //
- // Creat CPU HOBs.
- //
- BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize));
- }
- /**
- add fdt hand off block.
- @param VOID
- @return VOID
- **/
- VOID
- AddFdtHob (VOID)
- {
- VOID *Base;
- VOID *NewBase;
- UINTN FdtSize;
- UINTN FdtPages;
- UINT64 *FdtHobData;
- UINT64 *UartHobData;
- UINT64 SerialConsoleAddress;
- UINT64 RtcBaseAddress;
- RETURN_STATUS Status;
- Base = (VOID*)(UINTN)PcdGet64 (PcdDeviceTreeBase);
- ASSERT (Base != NULL);
- Status = GetSerialConsolePortAddress (Base, &SerialConsoleAddress);
- if (RETURN_ERROR (Status)) {
- return;
- }
- UartHobData = BuildGuidHob (&gEarly16550UartBaseAddressGuid, sizeof *UartHobData);
- ASSERT (UartHobData != NULL);
- *UartHobData = SerialConsoleAddress;
- Status = GetRtcAddress(Base, &RtcBaseAddress);
- if (RETURN_ERROR (Status)) {
- return;
- }
- Status = PcdSet64S (PcdRtcBaseAddress, RtcBaseAddress);
- if (RETURN_ERROR (Status)) {
- return;
- }
- FdtSize = fdt_totalsize (Base) + PcdGet32 (PcdDeviceTreePadding);
- FdtPages = EFI_SIZE_TO_PAGES (FdtSize);
- NewBase = AllocatePages (FdtPages);
- ASSERT (NewBase != NULL);
- fdt_open_into (Base, NewBase, EFI_PAGES_TO_SIZE (FdtPages));
- FdtHobData = BuildGuidHob (&gFdtHobGuid, sizeof *FdtHobData);
- ASSERT (FdtHobData != NULL);
- *FdtHobData = (UINTN)NewBase;
- }
- /**
- Fetch the size of system memory from QEMU.
- @param VOID
- @return VOID
- **/
- VOID
- SystemMemorySizeInitialization (
- VOID
- )
- {
- UINT64 RamSize;
- RETURN_STATUS PcdStatus;
- QemuFwCfgSelectItem (QemuFwCfgItemRamSize);
- RamSize= QemuFwCfgRead64 ();
- DEBUG ((DEBUG_INFO, "%a: QEMU reports %dM system memory\n", __FUNCTION__,
- RamSize/1024/1024));
- //
- // If the fw_cfg key or fw_cfg entirely is unavailable, no change to PCD.
- //
- if (RamSize == 0) {
- return;
- }
- //
- // Otherwise, set RamSize to PCD.
- //
- PcdStatus = PcdSet64S (PcdRamSize, RamSize);
- ASSERT_RETURN_ERROR (PcdStatus);
- }
- /**
- Perform Platform PEI initialization.
- @param FileHandle Handle of the file being invoked.
- @param PeiServices Describes the list of possible PEI Services.
- @return EFI_SUCCESS The PEIM initialized successfully.
- **/
- EFI_STATUS
- EFIAPI
- InitializePlatform (
- IN EFI_PEI_FILE_HANDLE FileHandle,
- IN CONST EFI_PEI_SERVICES **PeiServices
- )
- {
- EFI_STATUS Status;
- DEBUG ((DEBUG_INFO, "Platform PEIM Loaded\n"));
- Status = PeiServicesSetBootMode (mBootMode);
- ASSERT_EFI_ERROR (Status);
- Status = PeiServicesInstallPpi (&mPpiListBootMode);
- ASSERT_EFI_ERROR (Status);
- SystemMemorySizeInitialization ();
- PublishPeiMemory ();
- PeiFvInitialization ();
- InitializeRamRegions ();
- MemMapInitialization ();
- MiscInitialization ();
- AddFdtHob ();
- ConfigureMmu ();
- return EFI_SUCCESS;
- }
|