[PATCH v2 12/13] armv8: layerscape: relocate spin table if EFI_LOADER is enabled

Michael Walle michael at walle.cc
Tue Jun 2 22:19:23 CEST 2020


Am 2020-06-02 22:00, schrieb Heinrich Schuchardt:
> On 6/1/20 9:53 PM, Michael Walle wrote:
>> On ARM64, a 64kb region is reserved for the runtime services code.
>> Unfortunately, this code overlaps with the spin table code, which also
>> needs to be reserved. Thus now that the code is relocatable, allocate 
>> a
>> new page from EFI, copy the spin table code into it, update any 
>> pointers
>> to the old region and the start the secondary CPUs.
>> 
>> Signed-off-by: Michael Walle <michael at walle.cc>
>> ---
>>  arch/arm/cpu/armv8/fsl-layerscape/mp.c | 36 
>> ++++++++++++++++++++++++++
>>  1 file changed, 36 insertions(+)
>> 
>> diff --git a/arch/arm/cpu/armv8/fsl-layerscape/mp.c 
>> b/arch/arm/cpu/armv8/fsl-layerscape/mp.c
>> index d50c5a437b..bd85351705 100644
>> --- a/arch/arm/cpu/armv8/fsl-layerscape/mp.c
>> +++ b/arch/arm/cpu/armv8/fsl-layerscape/mp.c
>> @@ -79,6 +79,10 @@ int fsl_layerscape_wake_seconday_cores(void)
>>  	u32 cores, cpu_up_mask = 1;
>>  	int i, timeout = 10;
>>  	u64 *table;
>> +#ifdef CONFIG_EFI_LOADER
>> +	u64 reloc_addr = U32_MAX;
>> +	efi_status_t ret;
>> +#endif
>> 
>>  #ifdef COUNTER_FREQUENCY_REAL
>>  	/* update for secondary cores */
>> @@ -87,6 +91,38 @@ int fsl_layerscape_wake_seconday_cores(void)
>>  			   (unsigned long)&__real_cntfrq + 8);
>>  #endif
>> 
>> +#ifdef CONFIG_EFI_LOADER
>> +	/*
>> +	 * EFI will reserve 64kb for its runtime services. This will 
>> probably
>> +	 * overlap with our spin table code, which is why we have to 
>> relocate
>> +	 * it.
>> +	 * Keep this after the __real_cntfrq update, so we have it when we
>> +	 * copy the complete section here.
>> +	 */
>> +	ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
>> +				 EFI_RESERVED_MEMORY_TYPE,
>> +				 efi_size_in_pages(secondary_boot_code_size),
>> +				 &reloc_addr);
>> +	if (ret == EFI_SUCCESS) {
>> +		debug("Relocating spin table from %llx to %llx (size %lx)\n",
>> +		      (u64)secondary_boot_code_start, reloc_addr,
>> +		      secondary_boot_code_size);
>> +		memcpy((void *)reloc_addr, secondary_boot_code_start,
>> +		       secondary_boot_code_size);
>> +		flush_dcache_range(reloc_addr,
>> +				   reloc_addr + secondary_boot_code_size);

dcache flush is done here. but icache is missing, correct.

>> +
>> +		/* set new entry point for secondary cores */
>> +		secondary_boot_addr += (void *)reloc_addr -
>> +				       secondary_boot_code_start;
>> +		flush_dcache_range((unsigned long)&secondary_boot_addr,
>> +				   (unsigned long)&secondary_boot_addr + 8);
> 
> Wouldn't you want to flush the complete target range of memcpy() and
> afterwards call invalidate_icache_all(). At least this is what we do in
> other cases after copying instructions. Cf. efi_runtime_relocate().

see above.

-michael

>> +
>> +		/* this will be used to reserve the memory */
>> +		secondary_boot_code_start = (void *)reloc_addr;
>> +	}
>> +#endif
>> +
>>  	cores = cpu_mask();
>>  	/* Clear spin table so that secondary processors
>>  	 * observe the correct value after waking up from wfe.
>> 


More information about the U-Boot mailing list