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.

>
> Just my two cents.

Thanks a lot for your help!

cheers,
Achin

>
> Thanks
> Laszlo
>
> >
> > I have tried ignoring the error returned by AllocateMemorySpace(). This is 
> > under
> > the assumption that AddMemorySpace() must have added it to the translation
> > tables. So the buffer must be accessible even though it is not yet marked as
> > allocated. However, I eventually run into translation faults with this 
> > approach.
> >
> > Can anyone provide some insight? Please let me know if you need any
> > clarifications.
> >
> > Thanks a lot,
> > Achin
> >
> > _______________________________________________
> > edk2-devel mailing list
> > [email protected]
> > https://lists.01.org/mailman/listinfo/edk2-devel
> >
>

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to