1732ea9dbSArd Biesheuvel // SPDX-License-Identifier: GPL-2.0
2732ea9dbSArd Biesheuvel 
3732ea9dbSArd Biesheuvel #include <linux/efi.h>
4732ea9dbSArd Biesheuvel #include <asm/efi.h>
5732ea9dbSArd Biesheuvel 
6732ea9dbSArd Biesheuvel #include "efistub.h"
7732ea9dbSArd Biesheuvel 
8732ea9dbSArd Biesheuvel /*
9732ea9dbSArd Biesheuvel  * There are two ways of populating the core kernel's struct screen_info via the stub:
10732ea9dbSArd Biesheuvel  * - using a configuration table, like below, which relies on the EFI init code
11732ea9dbSArd Biesheuvel  *   to locate the table and copy the contents;
12732ea9dbSArd Biesheuvel  * - by linking directly to the core kernel's copy of the global symbol.
13732ea9dbSArd Biesheuvel  *
14732ea9dbSArd Biesheuvel  * The latter is preferred because it makes the EFIFB earlycon available very
15732ea9dbSArd Biesheuvel  * early, but it only works if the EFI stub is part of the core kernel image
16732ea9dbSArd Biesheuvel  * itself. The zboot decompressor can only use the configuration table
17732ea9dbSArd Biesheuvel  * approach.
18732ea9dbSArd Biesheuvel  */
19732ea9dbSArd Biesheuvel 
20732ea9dbSArd Biesheuvel static efi_guid_t screen_info_guid = LINUX_EFI_SCREEN_INFO_TABLE_GUID;
21732ea9dbSArd Biesheuvel 
22*fc3608aaSArd Biesheuvel struct screen_info *__alloc_screen_info(void)
23732ea9dbSArd Biesheuvel {
24732ea9dbSArd Biesheuvel 	struct screen_info *si;
25732ea9dbSArd Biesheuvel 	efi_status_t status;
26732ea9dbSArd Biesheuvel 
27732ea9dbSArd Biesheuvel 	status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY,
28732ea9dbSArd Biesheuvel 			     sizeof(*si), (void **)&si);
29732ea9dbSArd Biesheuvel 
30732ea9dbSArd Biesheuvel 	if (status != EFI_SUCCESS)
31732ea9dbSArd Biesheuvel 		return NULL;
32732ea9dbSArd Biesheuvel 
33732ea9dbSArd Biesheuvel 	status = efi_bs_call(install_configuration_table,
34732ea9dbSArd Biesheuvel 			     &screen_info_guid, si);
35732ea9dbSArd Biesheuvel 	if (status == EFI_SUCCESS)
36732ea9dbSArd Biesheuvel 		return si;
37732ea9dbSArd Biesheuvel 
38732ea9dbSArd Biesheuvel 	efi_bs_call(free_pool, si);
39732ea9dbSArd Biesheuvel 	return NULL;
40732ea9dbSArd Biesheuvel }
41732ea9dbSArd Biesheuvel 
42732ea9dbSArd Biesheuvel void free_screen_info(struct screen_info *si)
43732ea9dbSArd Biesheuvel {
44732ea9dbSArd Biesheuvel 	if (!si)
45732ea9dbSArd Biesheuvel 		return;
46732ea9dbSArd Biesheuvel 
47732ea9dbSArd Biesheuvel 	efi_bs_call(install_configuration_table, &screen_info_guid, NULL);
48732ea9dbSArd Biesheuvel 	efi_bs_call(free_pool, si);
49732ea9dbSArd Biesheuvel }
50