1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2013, 2014 Linaro Ltd; <roy.franz@linaro.org> 4 * 5 * This file implements the EFI boot stub for the arm64 kernel. 6 * Adapted from ARM version by Mark Salter <msalter@redhat.com> 7 */ 8 9 10 #include <linux/efi.h> 11 #include <asm/efi.h> 12 #include <asm/memory.h> 13 #include <asm/sysreg.h> 14 15 #include "efistub.h" 16 17 static bool system_needs_vamap(void) 18 { 19 const u8 *type1_family = efi_get_smbios_string(1, family); 20 21 /* 22 * Ampere Altra machines crash in SetTime() if SetVirtualAddressMap() 23 * has not been called prior. 24 */ 25 if (!type1_family || strcmp(type1_family, "Altra")) 26 return false; 27 28 efi_warn("Working around broken SetVirtualAddressMap()\n"); 29 return true; 30 } 31 32 efi_status_t check_platform_features(void) 33 { 34 u64 tg; 35 36 /* 37 * If we have 48 bits of VA space for TTBR0 mappings, we can map the 38 * UEFI runtime regions 1:1 and so calling SetVirtualAddressMap() is 39 * unnecessary. 40 */ 41 if (VA_BITS_MIN >= 48 && !system_needs_vamap()) 42 efi_novamap = true; 43 44 /* UEFI mandates support for 4 KB granularity, no need to check */ 45 if (IS_ENABLED(CONFIG_ARM64_4K_PAGES)) 46 return EFI_SUCCESS; 47 48 tg = (read_cpuid(ID_AA64MMFR0_EL1) >> ID_AA64MMFR0_EL1_TGRAN_SHIFT) & 0xf; 49 if (tg < ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MIN || tg > ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MAX) { 50 if (IS_ENABLED(CONFIG_ARM64_64K_PAGES)) 51 efi_err("This 64 KB granular kernel is not supported by your CPU\n"); 52 else 53 efi_err("This 16 KB granular kernel is not supported by your CPU\n"); 54 return EFI_UNSUPPORTED; 55 } 56 return EFI_SUCCESS; 57 } 58 59 void efi_cache_sync_image(unsigned long image_base, 60 unsigned long alloc_size, 61 unsigned long code_size) 62 { 63 u32 ctr = read_cpuid_effective_cachetype(); 64 u64 lsize = 4 << cpuid_feature_extract_unsigned_field(ctr, 65 CTR_EL0_DminLine_SHIFT); 66 67 do { 68 asm("dc civac, %0" :: "r"(image_base)); 69 image_base += lsize; 70 alloc_size -= lsize; 71 } while (alloc_size >= lsize); 72 73 asm("ic ialluis"); 74 dsb(ish); 75 isb(); 76 } 77