/******************************************************************************* Copyright (C) 2016 Marvell International Ltd. SPDX-License-Identifier: BSD-2-Clause-Patent *******************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include "Armada7k8kLibMem.h" // The total number of descriptors, including the final "end-of-table" descriptor. #define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 16 // DDR attributes #define DDR_ATTRIBUTES_CACHED ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK #define DDR_ATTRIBUTES_UNCACHED ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED STATIC ARM_MEMORY_REGION_DESCRIPTOR mVirtualMemoryTable[MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS]; // Obtain DRAM size basing on register values filled by early firmware. STATIC UINT64 GetDramSize ( IN OUT UINT64 *MemSize ) { #if defined(MDE_CPU_AARCH64) ARM_SMC_ARGS SmcRegs = {0}; EFI_STATUS Status; SmcRegs.Arg0 = MV_SMC_ID_DRAM_SIZE; Status = ArmadaSoCAp8xxBaseGet (&SmcRegs.Arg1, 0); if (EFI_ERROR (Status)) { return Status; } ArmCallSmc (&SmcRegs); *MemSize = SmcRegs.Arg0; #else // // Use fixed value, as currently there is no support // in Armada early firmware for 32-bit SMC // *MemSize = FixedPcdGet64 (PcdSystemMemorySize); #endif return EFI_SUCCESS; } /** 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 ) { UINTN Index = 0; UINT64 MemSize; UINT64 MemLowSize; UINT64 MemHighStart; UINT64 MemHighSize; UINT64 ConfigSpaceBaseAddr; UINTN PcieControllerCount; UINTN PcieIndex; MV_PCIE_CONTROLLER CONST *PcieControllers; EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes; EFI_STATUS Status; ASSERT (VirtualMemoryMap != NULL); ConfigSpaceBaseAddr = FixedPcdGet64 (PcdConfigSpaceBaseAddress); // Obtain total memory size from the hardware. Status = GetDramSize (&MemSize); if (EFI_ERROR (Status)) { MemSize = FixedPcdGet64 (PcdSystemMemorySize); DEBUG ((DEBUG_ERROR, "Limit total memory size to %d MB\n", MemSize / 1024 / 1024)); } if (DRAM_REMAP_ENABLED) { MemLowSize = MIN (DRAM_REMAP_TARGET, MemSize); MemHighStart = (UINT64)DRAM_REMAP_TARGET + DRAM_REMAP_SIZE; MemHighSize = MemSize - MemLowSize; } else { MemLowSize = MIN (ConfigSpaceBaseAddr, MemSize); } ResourceAttributes = ( EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | 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 (PcdSystemMemoryBase), MemLowSize ); // DDR mVirtualMemoryTable[Index].PhysicalBase = FixedPcdGet64 (PcdSystemMemoryBase); mVirtualMemoryTable[Index].VirtualBase = FixedPcdGet64 (PcdSystemMemoryBase); mVirtualMemoryTable[Index].Length = MemLowSize; mVirtualMemoryTable[Index].Attributes = DDR_ATTRIBUTES_CACHED; // SoC MMIO configuration space mVirtualMemoryTable[++Index].PhysicalBase = ConfigSpaceBaseAddr; mVirtualMemoryTable[Index].VirtualBase = ConfigSpaceBaseAddr; mVirtualMemoryTable[Index].Length = SIZE_4GB - ConfigSpaceBaseAddr; mVirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; // PCIE ECAM Status = ArmadaBoardPcieControllerGet (&PcieControllers, &PcieControllerCount); ASSERT_EFI_ERROR (Status); for (PcieIndex = 0; PcieIndex < PcieControllerCount; PcieIndex++) { mVirtualMemoryTable[++Index].PhysicalBase = PcieControllers[PcieIndex].ConfigSpaceAddress; mVirtualMemoryTable[Index].VirtualBase = PcieControllers[PcieIndex].ConfigSpaceAddress; mVirtualMemoryTable[Index].Length = (PcieControllers[PcieIndex].ConfigSpaceSize == 0) ? SIZE_256MB : PcieControllers[PcieIndex].ConfigSpaceSize; mVirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE; } if (MemSize > MemLowSize) { // // If we have more than MemLowSize worth of DRAM, the remainder will be // mapped at the top of the remapped window. // mVirtualMemoryTable[++Index].PhysicalBase = MemHighStart; mVirtualMemoryTable[Index].VirtualBase = MemHighStart; mVirtualMemoryTable[Index].Length = MemHighSize; mVirtualMemoryTable[Index].Attributes = DDR_ATTRIBUTES_CACHED; BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, ResourceAttributes, MemHighStart, MemHighSize ); } // End of Table mVirtualMemoryTable[++Index].PhysicalBase = 0; mVirtualMemoryTable[Index].VirtualBase = 0; mVirtualMemoryTable[Index].Length = 0; mVirtualMemoryTable[Index].Attributes = 0; ASSERT((Index + 1) <= MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS); *VirtualMemoryMap = mVirtualMemoryTable; }