123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481 |
- /** @file
- *
- * Copyright (c) 2016, Hisilicon Limited. All rights reserved.
- * Copyright (c) 2016, Linaro Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-2-Clause-Patent
- *
- **/
- #include <Uefi.h>
- #include <Library/ArmArchTimer.h>
- #include <Library/BaseLib.h>
- #include <libfdt.h>
- #include <Library/IoLib.h>
- #include <Library/DebugLib.h>
- #include <Library/UefiBootServicesTableLib.h>
- #include <Library/FdtUpdateLib.h>
- #include <PlatformArch.h>
- #include <Library/PcdLib.h>
- #include <Library/PlatformSysCtrlLib.h>
- #include <Library/MemoryAllocationLib.h>
- #include <Protocol/HisiBoardNicProtocol.h>
- #include <Library/UefiRuntimeServicesTableLib.h>
- #include <Library/OemMiscLib.h>
- typedef union AA_DAW
- {
- /* Define the struct bits */
- struct
- {
- unsigned int sysdaw_id : 7 ; /* [6:0] */
- unsigned int interleave_en : 1 ; /* [7] */
- unsigned int sysdaw_size : 4 ; /* [11:8] */
- unsigned int reserved : 4 ; /* [15:12] */
- unsigned int sysdaw_addr : 16 ; /* [31:16] */
- } bits;
- /* Define an unsigned member */
- unsigned int u32;
- } AA_DAW_U;
- MAC_ADDRESS gMacAddress[1];
- CHAR8 *EthName[8]=
- {
- "ethernet@0","ethernet@1",
- "ethernet@2","ethernet@3",
- "ethernet@4","ethernet@5",
- "ethernet@6","ethernet@7"
- };
- UINT8 DawNum[4] = {0, 0, 0, 0};
- PHY_MEM_REGION *NodemRegion[4] = {NULL, NULL, NULL, NULL};
- UINTN NumaPages[4] = {0, 0, 0, 0};
- CHAR8 *NumaNodeName[4]=
- {
- "p0-ta","p0-tc",
- "p1-ta","p1-tc",
- };
- STATIC
- BOOLEAN
- IsMemMapRegion (
- IN EFI_MEMORY_TYPE MemoryType
- )
- {
- switch(MemoryType)
- {
- case EfiRuntimeServicesCode:
- case EfiRuntimeServicesData:
- case EfiConventionalMemory:
- case EfiACPIReclaimMemory:
- case EfiACPIMemoryNVS:
- case EfiLoaderCode:
- case EfiLoaderData:
- case EfiBootServicesCode:
- case EfiBootServicesData:
- case EfiPalCode:
- return TRUE;
- default:
- return FALSE;
- }
- }
- EFI_STATUS
- GetMacAddress (UINT32 Port)
- {
- EFI_MAC_ADDRESS Mac;
- EFI_STATUS Status;
- HISI_BOARD_NIC_PROTOCOL *OemNic = NULL;
- Status = gBS->LocateProtocol(&gHisiBoardNicProtocolGuid, NULL, (VOID **)&OemNic);
- if(EFI_ERROR(Status))
- {
- DEBUG((EFI_D_ERROR, "[%a]:[%dL] LocateProtocol failed %r\n", __FUNCTION__, __LINE__, Status));
- return Status;
- }
- Status = OemNic->GetMac(&Mac, Port);
- if(EFI_ERROR(Status))
- {
- DEBUG((EFI_D_ERROR, "[%a]:[%dL] GetMac failed %r\n", __FUNCTION__, __LINE__, Status));
- return Status;
- }
- gMacAddress[0].data0=Mac.Addr[0];
- gMacAddress[0].data1=Mac.Addr[1];
- gMacAddress[0].data2=Mac.Addr[2];
- gMacAddress[0].data3=Mac.Addr[3];
- gMacAddress[0].data4=Mac.Addr[4];
- gMacAddress[0].data5=Mac.Addr[5];
- DEBUG((EFI_D_INFO, "Port%d:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
- Port,gMacAddress[0].data0,gMacAddress[0].data1,gMacAddress[0].data2,
- gMacAddress[0].data3,gMacAddress[0].data4,gMacAddress[0].data5));
- return EFI_SUCCESS;
- }
- STATIC
- EFI_STATUS
- DelPhyhandleUpdateMacAddress(IN VOID* Fdt)
- {
- UINT8 port;
- INTN ethernetnode;
- INTN node;
- INTN Error;
- struct fdt_property *m_prop;
- int m_oldlen;
- EFI_STATUS Status = EFI_SUCCESS;
- EFI_STATUS GetMacStatus = EFI_SUCCESS;
- node = fdt_subnode_offset(Fdt, 0, "soc");
- if (node < 0)
- {
- DEBUG ((EFI_D_ERROR, "can not find soc root node\n"));
- return EFI_INVALID_PARAMETER;
- }
- else
- {
- for( port=0; port<8; port++ )
- {
- GetMacStatus= GetMacAddress(port);
- ethernetnode = fdt_subnode_offset(Fdt, node,EthName[port]);
- if(!EFI_ERROR(GetMacStatus))
- {
- if (ethernetnode < 0)
- {
- DEBUG ((EFI_D_WARN, "Can not find ethernet@%d node\n",port));
- DEBUG ((EFI_D_WARN, "Suppose port %d is not enabled.\n", port));
- continue;
- }
- m_prop = fdt_get_property_w(Fdt, ethernetnode, "local-mac-address", &m_oldlen);
- if(m_prop)
- {
- Error = fdt_delprop(Fdt, ethernetnode, "local-mac-address");
- if (Error)
- {
- DEBUG ((EFI_D_ERROR, "ERROR:fdt_delprop() Local-mac-address: %a\n", fdt_strerror (Error)));
- Status = EFI_INVALID_PARAMETER;
- }
- Error = fdt_setprop(Fdt, ethernetnode, "local-mac-address",gMacAddress,sizeof(MAC_ADDRESS));
- if (Error)
- {
- DEBUG ((EFI_D_ERROR, "ERROR:fdt_setprop():local-mac-address %a\n", fdt_strerror (Error)));
- Status = EFI_INVALID_PARAMETER;
- }
- }
- }
- }
- }
- return Status;
- }
- STATIC
- EFI_STATUS
- UpdateRefClk (IN VOID* Fdt)
- {
- INTN node;
- INTN Error;
- struct fdt_property *m_prop;
- int m_oldlen;
- UINTN ArchTimerFreq = 0;
- UINT32 Data;
- CONST CHAR8 *Property = "clock-frequency";
- ArmArchTimerReadReg (CntFrq, &ArchTimerFreq);
- if (!ArchTimerFreq) {
- DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Get timer frequency failed!\n", __FUNCTION__, __LINE__));
- return EFI_INVALID_PARAMETER;
- }
- node = fdt_subnode_offset(Fdt, 0, "soc");
- if (node < 0) {
- DEBUG ((DEBUG_ERROR, "can not find soc node\n"));
- return EFI_INVALID_PARAMETER;
- }
- node = fdt_subnode_offset(Fdt, node, "refclk");
- if (node < 0) {
- DEBUG ((DEBUG_ERROR, "can not find refclk node\n"));
- return EFI_INVALID_PARAMETER;
- }
- m_prop = fdt_get_property_w(Fdt, node, Property, &m_oldlen);
- if(!m_prop) {
- DEBUG ((DEBUG_ERROR, "[%a]:[%dL] Can't find property %a\n", __FUNCTION__, __LINE__, Property));
- return EFI_INVALID_PARAMETER;
- }
- Error = fdt_delprop(Fdt, node, Property);
- if (Error) {
- DEBUG ((DEBUG_ERROR, "ERROR: fdt_delprop() %a: %a\n", Property, fdt_strerror (Error)));
- return EFI_INVALID_PARAMETER;
- }
- // UINT32 is enough for refclk data length
- Data = (UINT32) ArchTimerFreq;
- Data = cpu_to_fdt32 (Data);
- Error = fdt_setprop(Fdt, node, Property, &Data, sizeof(Data));
- if (Error) {
- DEBUG ((DEBUG_ERROR, "ERROR:fdt_setprop() %a: %a\n", Property, fdt_strerror (Error)));
- return EFI_INVALID_PARAMETER;
- }
- DEBUG ((DEBUG_INFO, "Update refclk successfully.\n"));
- return EFI_SUCCESS;
- }
- INTN
- GetMemoryNode(VOID* Fdt)
- {
- INTN node;
- int m_oldlen;
- struct fdt_property *m_prop;
- INTN Error = 0;
- node = fdt_subnode_offset(Fdt, 0, "memory");
- if (node < 0)
- {
- // Create the memory node
- node = fdt_add_subnode(Fdt, 0, "memory");
- if(node < 0)
- {
- DEBUG((EFI_D_ERROR, "[%a]:[%dL] fdt add subnode error\n", __FUNCTION__, __LINE__));
- return node;
- }
- }
- //find the memory node property
- m_prop = fdt_get_property_w(Fdt, node, "memory", &m_oldlen);
- if(m_prop)
- {
- Error = fdt_delprop(Fdt, node, "reg");
- if (Error)
- {
- DEBUG ((EFI_D_ERROR, "ERROR:fdt_delprop(): %a\n", fdt_strerror (Error)));
- node = -1;
- return node;
- }
- }
- return node;
- }
- EFI_STATUS UpdateMemoryNode(VOID* Fdt)
- {
- INTN Error = 0;
- EFI_STATUS Status = EFI_SUCCESS;
- UINT32 Index = 0;
- UINT32 MemIndex;
- INTN node;
- EFI_MEMORY_DESCRIPTOR *MemoryMap;
- EFI_MEMORY_DESCRIPTOR *MemoryMapPtr;
- EFI_MEMORY_DESCRIPTOR *MemoryMapPtrCurrent;
- UINTN MemoryMapSize;
- UINTN Pages0 = 0;
- UINTN Pages1 = 0;
- UINTN MapKey;
- UINTN DescriptorSize;
- UINT32 DescriptorVersion;
- PHY_MEM_REGION *mRegion;
- UINTN MemoryMapLastEndAddress ;
- UINTN MemoryMapcontinuousStartAddress ;
- UINTN MemoryMapCurrentStartAddress;
- BOOLEAN FindMemoryRegionFlag = FALSE;
- node = GetMemoryNode(Fdt);
- if (node < 0)
- {
- DEBUG((EFI_D_ERROR, "Can not find memory node\n"));
- return EFI_NOT_FOUND;
- }
- MemoryMap = NULL;
- MemoryMapSize = 0;
- MemIndex = 0;
- Status = gBS->GetMemoryMap (&MemoryMapSize, MemoryMap, &MapKey, &DescriptorSize, &DescriptorVersion);
- if (Status == EFI_BUFFER_TOO_SMALL)
- {
- // The UEFI specification advises to allocate more memory for the MemoryMap buffer between successive
- // calls to GetMemoryMap(), since allocation of the new buffer may potentially increase memory map size.
- Pages0 = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;
- MemoryMap = AllocatePages (Pages0);
- if (MemoryMap == NULL)
- {
- Status = EFI_OUT_OF_RESOURCES;
- return Status;
- }
- Status = gBS->GetMemoryMap (&MemoryMapSize, MemoryMap, &MapKey, &DescriptorSize, &DescriptorVersion);
- if (EFI_ERROR(Status))
- {
- DEBUG ((EFI_D_ERROR, "FdtUpdateLib GetMemoryMap Error\n"));
- FreePages (MemoryMap, Pages0);
- return Status;
- }
- }
- else
- {
- DEBUG ((EFI_D_ERROR, "FdtUpdateLib GetmemoryMap Status: %r\n",Status));
- return EFI_ABORTED;
- }
- mRegion = NULL;
- Pages1 = EFI_SIZE_TO_PAGES (sizeof(PHY_MEM_REGION) *( MemoryMapSize / DescriptorSize));
- mRegion = (PHY_MEM_REGION*)AllocatePool(Pages1);
- if (mRegion == NULL)
- {
- Status = EFI_OUT_OF_RESOURCES;
- FreePages (MemoryMap, Pages0);
- return Status;
- }
- MemoryMapPtr = MemoryMap;
- MemoryMapPtrCurrent = MemoryMapPtr;
- MemoryMapLastEndAddress = 0;
- MemoryMapcontinuousStartAddress = 0;
- MemoryMapCurrentStartAddress = 0;
- for (Index = 0; Index < (MemoryMapSize / DescriptorSize); Index++)
- {
- MemoryMapPtrCurrent = (EFI_MEMORY_DESCRIPTOR*)((UINTN)MemoryMapPtr + Index*DescriptorSize);
- MemoryMapCurrentStartAddress = (UINTN)MemoryMapPtrCurrent->PhysicalStart;
- if (!IsMemMapRegion ((EFI_MEMORY_TYPE)MemoryMapPtrCurrent->Type))
- {
- continue;
- }
- else
- {
- FindMemoryRegionFlag = TRUE;
- if(MemoryMapCurrentStartAddress != MemoryMapLastEndAddress)
- {
- mRegion[MemIndex].BaseHigh= cpu_to_fdt32(MemoryMapcontinuousStartAddress>>32);
- mRegion[MemIndex].BaseLow=cpu_to_fdt32(MemoryMapcontinuousStartAddress);
- mRegion[MemIndex].LengthHigh= cpu_to_fdt32((MemoryMapLastEndAddress-MemoryMapcontinuousStartAddress)>>32);
- mRegion[MemIndex].LengthLow=cpu_to_fdt32(MemoryMapLastEndAddress-MemoryMapcontinuousStartAddress);
- MemIndex+=1;
- MemoryMapcontinuousStartAddress=MemoryMapCurrentStartAddress;
- }
- }
- MemoryMapLastEndAddress = (UINTN)(MemoryMapPtrCurrent->PhysicalStart + MemoryMapPtrCurrent->NumberOfPages * EFI_PAGE_SIZE);
- }
- if (FindMemoryRegionFlag)
- {
- mRegion[MemIndex].BaseHigh = cpu_to_fdt32(MemoryMapcontinuousStartAddress>>32);
- mRegion[MemIndex].BaseLow = cpu_to_fdt32(MemoryMapcontinuousStartAddress);
- mRegion[MemIndex].LengthHigh = cpu_to_fdt32((MemoryMapLastEndAddress-MemoryMapcontinuousStartAddress)>>32);
- mRegion[MemIndex].LengthLow = cpu_to_fdt32(MemoryMapLastEndAddress-MemoryMapcontinuousStartAddress);
- }
- Error = fdt_setprop(Fdt, node, "reg",mRegion,sizeof(PHY_MEM_REGION) *(MemIndex+1));
- FreePool (mRegion);
- FreePages (MemoryMap, Pages0);
- if (Error)
- {
- DEBUG ((EFI_D_ERROR, "ERROR:fdt_setprop(): %a\n", fdt_strerror (Error)));
- Status = EFI_INVALID_PARAMETER;
- return Status;
- }
- return Status;
- }
- EFI_STATUS
- UpdateNumaNode(VOID* Fdt)
- {
- //TODO: Need to update numa node
- return EFI_SUCCESS;
- }
- /*
- * Entry point for fdtupdate lib.
- */
- EFI_STATUS EFIFdtUpdate(UINTN FdtFileAddr)
- {
- INTN Error;
- VOID* Fdt;
- UINT32 Size;
- UINTN NewFdtBlobSize;
- UINTN NewFdtBlobBase;
- EFI_STATUS Status = EFI_SUCCESS;
- EFI_STATUS UpdateNumaStatus = EFI_SUCCESS;
- Error = fdt_check_header ((VOID*)(FdtFileAddr));
- if (0 != Error)
- {
- DEBUG ((EFI_D_ERROR,"ERROR: Device Tree header not valid (%a)\n", fdt_strerror(Error)));
- return EFI_INVALID_PARAMETER;
- }
- Size = (UINTN)fdt_totalsize ((VOID*)(UINTN)(FdtFileAddr));
- NewFdtBlobSize = Size + ADD_FILE_LENGTH;
- Fdt = (VOID*)(UINTN)FdtFileAddr;
- Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, EFI_SIZE_TO_PAGES(NewFdtBlobSize), &NewFdtBlobBase);
- if (EFI_ERROR (Status))
- {
- return EFI_OUT_OF_RESOURCES;
- }
- Error = fdt_open_into(Fdt,(VOID*)(UINTN)(NewFdtBlobBase), (NewFdtBlobSize));
- if (Error) {
- DEBUG ((EFI_D_ERROR, "ERROR:fdt_open_into(): %a\n", fdt_strerror (Error)));
- Status = EFI_INVALID_PARAMETER;
- goto EXIT;
- }
- Fdt = (VOID*)(UINTN)NewFdtBlobBase;
- Status = DelPhyhandleUpdateMacAddress(Fdt);
- if (EFI_ERROR (Status))
- {
- DEBUG ((EFI_D_ERROR, "DelPhyhandleUpdateMacAddress fail:\n"));
- Status = EFI_SUCCESS;
- }
- Status = UpdateRefClk (Fdt);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "UpdateiRefClk fail.\n"));
- }
- Status = UpdateMemoryNode(Fdt);
- if (EFI_ERROR (Status))
- {
- DEBUG ((EFI_D_ERROR, "UpdateMemoryNode Error\n"));
- goto EXIT;
- }
- UpdateNumaStatus = UpdateNumaNode(Fdt);
- if (EFI_ERROR (UpdateNumaStatus))
- {
- DEBUG ((EFI_D_ERROR, "Update NumaNode fail\n"));
- }
- gBS->CopyMem(((VOID*)(UINTN)(FdtFileAddr)),((VOID*)(UINTN)(NewFdtBlobBase)),NewFdtBlobSize);
- EXIT:
- gBS->FreePages(NewFdtBlobBase,EFI_SIZE_TO_PAGES(NewFdtBlobSize));
- return Status;
- }
|