[U-Boot] [PATCH v4 2/9] efi_loader: AArch64: Run EFI payloads in EL2 if U-Boot runs in EL3

york sun york.sun at nxp.com
Wed Jul 20 17:18:46 CEST 2016


On 06/21/2016 10:44 PM, Alexander Graf wrote:
>
>
> On 21.06.16 20:02, york sun wrote:
>> On 06/21/2016 10:55 AM, Alexander Graf wrote:
>>>
>>>
>>>> Am 21.06.2016 um 19:12 schrieb york sun <york.sun at nxp.com>:
>>>>
>>>>> On 06/20/2016 04:07 PM, Alexander Graf wrote:
>>>>> Some boards decided not to run ATF or other secure firmware in EL3, so
>>>>> they instead run U-Boot there. The uEFI spec doesn't know what EL3 is
>>>>> though - it only knows about EL2 and EL1. So if we see that we're running
>>>>> in EL3, let's get into EL2 to make payloads happy.
>>>>>
>>>>> Signed-off-by: Alexander Graf <agraf at suse.de>
>>>>> ---
>>>>>   arch/arm/include/asm/armv8/mmu.h | 19 ++++++++++++-------
>>>>>   cmd/bootefi.c                    | 11 +++++++++++
>>>>>   2 files changed, 23 insertions(+), 7 deletions(-)
>>>>>
>>>>> diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h
>>>>> index 0d08ed3..876a2b2 100644
>>>>> --- a/arch/arm/include/asm/armv8/mmu.h
>>>>> +++ b/arch/arm/include/asm/armv8/mmu.h
>>>>> @@ -116,19 +116,24 @@
>>>>>   static inline void set_ttbr_tcr_mair(int el, u64 table, u64 tcr, u64 attr)
>>>>>   {
>>>>>       asm volatile("dsb sy");
>>>>> -    if (el == 1) {
>>>>> +    switch (el) {
>>>>> +    case 1:
>>>>>           asm volatile("msr ttbr0_el1, %0" : : "r" (table) : "memory");
>>>>>           asm volatile("msr tcr_el1, %0" : : "r" (tcr) : "memory");
>>>>>           asm volatile("msr mair_el1, %0" : : "r" (attr) : "memory");
>>>>> -    } else if (el == 2) {
>>>>> -        asm volatile("msr ttbr0_el2, %0" : : "r" (table) : "memory");
>>>>> -        asm volatile("msr tcr_el2, %0" : : "r" (tcr) : "memory");
>>>>> -        asm volatile("msr mair_el2, %0" : : "r" (attr) : "memory");
>>>>> -    } else if (el == 3) {
>>>>> +        break;
>>>>> +    case 3:
>>>>>           asm volatile("msr ttbr0_el3, %0" : : "r" (table) : "memory");
>>>>>           asm volatile("msr tcr_el3, %0" : : "r" (tcr) : "memory");
>>>>>           asm volatile("msr mair_el3, %0" : : "r" (attr) : "memory");
>>>>> -    } else {
>>>>> +
>>>>> +        /* We may switch to EL2 later, so set those too; fall through */
>>>>> +    case 2:
>>>>> +        asm volatile("msr ttbr0_el2, %0" : : "r" (table) : "memory");
>>>>> +        asm volatile("msr tcr_el2, %0" : : "r" (tcr) : "memory");
>>>>> +        asm volatile("msr mair_el2, %0" : : "r" (attr) : "memory");
>>>>> +        break;
>>>>
>>>>
>>>> This may be problematic. If we use secure memory for EL3, the MMU tables
>>>> have to be within the secure memory. But EL2 will not be able to access
>>>> it. I believe you have verified this patch set actually work. I am
>>>> curious how it work.
>>>
>>> That's a good question. I suppose the default config doesn't actually lock secure memory? Or doesn't go secure at all?
>>>
>>
>> The patch set using this secure memory is still pending. Our internal
>> team has been working on it. So the secure memory has been working. I am
>> sure I have put MMU tables in secure memory. You can verify by running
>> "bdi" command. It will show you the secure memory location. If you don't
>> see it, then you don't have secure memory setup. By default, it is enabled.
>
> Ok, yes, I do see secure memory there.
>
>> I remember I have done a test to access to the secure memory from
>> non-secure master and got an exception.
>>
>> Could your test run at EL2 without a proper MMU table? I don't remember
>> if the core would hang, or continue to run if fetching MMU table fails.
>
> So without this patch, U-Boot would just hang (or probably loop in
> delivering page faults) in the switch to EL2, before we even reach any
> EFI payload. I'm not sure why it does succeed in accessing the page
> tables though if they are indeed in secure memory.
>
> Maybe we should just turn the whole logic upside down. Switch from EL3
> to EL2 in very early init code and get people to just run ATF or some
> other self-contained trusted firmware (maybe even built as part of
> U-Boot) in EL3. Putting all of U-Boot into EL3 doesn't seem to much of a
> good idea either way, as there is a lot of code that has no business at EL3.
>
> Would that approach work for you as well?
>

Alex,

With recent patches merged, I think we have a solution here. You can 
call dcache_enable() after switching to el2 in cmd/bootefi.c. Since MMU 
is not on by default, mmu_setup() will be called. In the weak function, 
you check if (!gd->arch.tlb_fillptr), so no new tables are created. The 
code following will enable MMU for EL2. For platforms with mmu_setup 
(including ls2080a), mmu_setup() will take care of creating new tables 
in non-secure memory. I have verified on LS1043A with new PPA framework.

I can test this for you, if you educate me how to run distro boot. Do I 
need hard drive/image to continue?

York




More information about the U-Boot mailing list