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 efi_status_t check_platform_features(void) 18 { 19 u64 tg; 20 21 /* 22 * If we have 48 bits of VA space for TTBR0 mappings, we can map the 23 * UEFI runtime regions 1:1 and so calling SetVirtualAddressMap() is 24 * unnecessary. 25 */ 26 if (VA_BITS_MIN >= 48) 27 efi_novamap = true; 28 29 /* UEFI mandates support for 4 KB granularity, no need to check */ 30 if (IS_ENABLED(CONFIG_ARM64_4K_PAGES)) 31 return EFI_SUCCESS; 32 33 tg = (read_cpuid(ID_AA64MMFR0_EL1) >> ID_AA64MMFR0_EL1_TGRAN_SHIFT) & 0xf; 34 if (tg < ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MIN || tg > ID_AA64MMFR0_EL1_TGRAN_SUPPORTED_MAX) { 35 if (IS_ENABLED(CONFIG_ARM64_64K_PAGES)) 36 efi_err("This 64 KB granular kernel is not supported by your CPU\n"); 37 else 38 efi_err("This 16 KB granular kernel is not supported by your CPU\n"); 39 return EFI_UNSUPPORTED; 40 } 41 return EFI_SUCCESS; 42 } 43 44 void efi_cache_sync_image(unsigned long image_base, 45 unsigned long alloc_size, 46 unsigned long code_size) 47 { 48 u32 ctr = read_cpuid_effective_cachetype(); 49 u64 lsize = 4 << cpuid_feature_extract_unsigned_field(ctr, 50 CTR_EL0_DminLine_SHIFT); 51 52 do { 53 asm("dc civac, %0" :: "r"(image_base)); 54 image_base += lsize; 55 alloc_size -= lsize; 56 } while (alloc_size >= lsize); 57 58 asm("ic ialluis"); 59 dsb(ish); 60 isb(); 61 } 62