Re: [edk2] Adding a memory region to GCD on AARCH64?

2016-06-27 Thread Achin Gupta
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 *) 
> >>> ,
> >>>   ImageHandle,
> >>>   NULL);
> >>>
> >>> The address of the buffer is 0xfbe0 and size is 0x20 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. 

Re: [edk2] Adding a memory region to GCD on AARCH64?

2016-06-23 Thread Laszlo Ersek
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 *) 
>>> ,
>>>   ImageHandle,
>>>   NULL);
>>>
>>> The address of the buffer is 0xfbe0 and size is 0x20 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?

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 

Re: [edk2] Adding a memory region to GCD on AARCH64?

2016-06-23 Thread Achin Gupta
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 *) 
> > ,
> >   ImageHandle,
> >   NULL);
> >
> > The address of the buffer is 0xfbe0 and size is 0x20 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
> >
> > 

Re: [edk2] Adding a memory region to GCD on AARCH64?

2016-06-22 Thread Laszlo Ersek
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 *) ,
>   ImageHandle,
>   NULL);
> 
> The address of the buffer is 0xfbe0 and size is 0x20 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.

The pattern that you use above is valid, but you should use a different
GCD memory type (probably EfiGcdMemoryTypeReserved).

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).

Just my two cents.

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
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
> 

___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel