Hi Laszlo, On Thu, Jun 23, 2016 at 04:38:03PM +0200, Laszlo Ersek wrote: > On 06/23/16 16:19, Achin Gupta wrote: > > Hi Laszlo, > > > > On Wed, Jun 22, 2016 at 09:56:11PM +0200, Laszlo Ersek wrote: > >> On 06/22/16 20:53, Achin Gupta wrote: > >>> Hi All, > >>> > >>> I having some trouble trying an experiment on the AARCH64 Base FVP with > >>> UEFI and > >>> ARM Trusted Firmware. There is a buffer that is allocated by the latter > >>> in DRAM > >>> with TZC-400 attributes that allow non-secure access. Its extents are made > >>> available to a UEFI DXE driver through an SMC. AFAIU, it should be added > >>> to the > >>> UEFI memory map/EL2 translation tables and subsequently allocated before > >>> it can > >>> be used. > >>> > >>> To add it to the memory map, I successfully call AddMemorySpace() GCD > >>> service as > >>> follows: > >>> > >>> Status = gDS->AddMemorySpace(EfiGcdMemoryTypeSystemMemory, > >>> (EFI_PHYSICAL_ADDRESS) mNsBufferAddress, > >>> mNsBufferMaxSize, > >>> EFI_MEMORY_WB | EFI_MEMORY_XP); > >>> > >>> To allocate this buffer, I call AllocateMemorySpace GCD service > >>> immediately > >>> after AddMemorySpace() as follows: > >>> > >>> Status = gDS->AllocateMemorySpace(EfiGcdAllocateAddress, > >>> EfiGcdMemoryTypeSystemMemory, > >>> EFI_PAGE_SHIFT, > >>> mNsBufferMaxSize, > >>> (EFI_PHYSICAL_ADDRESS *) > >>> &mNsBufferAddress, > >>> ImageHandle, > >>> NULL); > >>> > >>> The address of the buffer is 0xfbe00000 and size is 0x200000 i.e. it is > >>> aligned > >>> to the page boundary. This call fails with EFI_NOT_FOUND. I am unable to > >>> figure > >>> out what is going wrong. Am I using these interfaces in their intended > >>> way? > >> > >> I recall the following from the relevant volume of the PI spec (please > >> look it up and double check it): when you add memory space of type > >> EfiGcdMemoryTypeSystemMemory, it is immediately absorbed by the pool / > >> page UEFI memory allocation services, for their internal management. So > >> after you add this, you can't allocate memory *space* of > >> EfiGcdMemoryTypeSystemMemory. If you want to allocate system memory, > >> just use the AllocatePool() / AllocatePages() boot services. > > > > Makes sense. The spec. says that the new memory range may be automatically > > allocated for use by UEFI memory services. The EDK2 implementation always > > does > > this in CoreAddMemorySpace() in MdeModulePkg/Core/Dxe/Gcd/Gcd.c. > > > >> > >> The pattern that you use above is valid, but you should use a different > >> GCD memory type (probably EfiGcdMemoryTypeReserved). > > > > I have not tried this memory type. I think there is a more basic problem. > > Please > > see below! > > > >> > >> If you definitely need "system memory" (= plain memory) to reside at > >> this address, and want to allocate it right after adding it to the > >> global coherency domain as EfiGcdMemoryTypeSystemMemory, then allocate > >> it with the AllocatePages() boot service, setting the first argument > >> (--> EFI_ALLOCATE_TYPE) to AllocateAddress (--> attempt to allocate at > >> the fixed address). > > > > I gave this a try since a similar approach has been followed in some ARM > > platform code. However, it does not make a difference. I run into a Level 2 > > translation fault as soon as I try to access the buffer. I have disabled > > cache > > state modelling so there are no TLBs or caches. So the translation fault is > > likely to be 'cause of an invalid/missing page table descriptor. . > > > > I think I am missing something obvious being a UEFI newbie. There are three > > steps that need to be undertaken in order to access this buffer. > > > > 1. Add an identity mapped entry corresponding to the buffer in the > > translation > > tables of the exception level UEFI is executing in (EL2 in my case). > > > > 2. Add this buffer in the UEFI memory map so that it can either be consumed > > by > > the memory allocation services or reserved. > > > > 3. Allocate this buffer using its physical address so that it is not > > allocated > > to another driver. > > > > I was under the impression that gDS->AddMemorySpace() will perform both > > steps > > 1. and 2. However looking at the behaviour and the code, it seems that it > > does > > only 2. > > > > Is it at all possible to do 1. after the translation tables have been > > created > > and the MMU initialised in the PEI phase. This essentially means adding > > entries > > to live translation tables. Is this expected to be done through architecture > > specific mechanisms rather than the GCD services. > > Is the base address of the new memory area above any other address that > you access otherwise?
Yes it is. It is still a region in DRAM. But it has been accessed before. > > I'm not sure about the aarch64 specifics here, but from my OvmfPkg > experience, I recall this: when you are about to enter the DXE phase, > the DXE IPL PEIM allocates memory from the permanent PEI RAM for page > tables, and builds the entire identity mapping that is supposed to be > relied on throughout DXE and BDS. How high this mapping extends is > governed by the CPU HOB that the HOB producer phase (~= PEI phase) produces. > > In edk2 this HOB is generally produced with the BuildCpuHob() library > call (see "MdePkg/Include/Library/HobLib.h") in one of the platform PEIMs. > > So, the CPU HOB should reflect the number of "value bits" of the > physical addresses that are expected to be accessed. For example, it has > to consider any 64-bit PCI MMIO aperture as well. > > If your new area falls outside of the address space that is "announced" > by the CPU HOB, that would be consistent with the failure you're seeing, > in my opinion. I remember vaguely that the number of address bits being passed by the CPU HOB is 64 on aarch64. The area does lie within the address space. AFAIU, the bottomline is that at least on aarch64, 1. cannot be done after the initial identity mapped page tables have been created during the PEI phase. I had to add a static mapping to the platform memory map which is consumed by a ARM platform specific PEIM to create the page tables. The region became a part of the UEFI memory map as a result. So I did not have to use the GCD services from within my driver. I got mislead by the name and description of the gDS->AllocateMemorySpace() function. I needed something like a AddMemoryRegion() function in the CPU Architectural protocol. A call to this function should precede a call to gDS->AllocateMemorySpace(). That does not exist at the moment. Thanks a lot! Achin > > Thanks > Laszlo > _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

