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