// SPDX-License-Identifier: GPL-2.0 /* * Author: Yun Liu * Huacai Chen * Copyright (C) 2020-2022 Loongson Technology Corporation Limited */ #include #include #include "efistub.h" extern int kernel_asize; extern int kernel_fsize; extern int kernel_offset; extern int kernel_entry; efi_status_t handle_kernel_image(unsigned long *image_addr, unsigned long *image_size, unsigned long *reserve_addr, unsigned long *reserve_size, efi_loaded_image_t *image, efi_handle_t image_handle) { int nr_pages = round_up(kernel_asize, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE; efi_physical_addr_t kernel_addr = EFI_KIMG_PREFERRED_ADDRESS; efi_status_t status; /* * Allocate space for the kernel image at the preferred offset. This is * the only location in memory from where we can execute the image, so * no point in falling back to another allocation. */ status = efi_bs_call(allocate_pages, EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, nr_pages, &kernel_addr); if (status != EFI_SUCCESS) return status; *image_addr = EFI_KIMG_PREFERRED_ADDRESS; *image_size = kernel_asize; memcpy((void *)EFI_KIMG_PREFERRED_ADDRESS, (void *)&kernel_offset - kernel_offset, kernel_fsize); return status; } unsigned long kernel_entry_address(void) { unsigned long base = (unsigned long)&kernel_offset - kernel_offset; return (unsigned long)&kernel_entry - base + VMLINUX_LOAD_ADDRESS; }