2019-02-02 10:41:15 +01:00
// SPDX-License-Identifier: GPL-2.0
2012-09-28 17:57:05 -07:00
/*
* Copyright 2012 Intel Corporation
* Author : Josh Triplett < josh @ joshtriplett . org >
*
* Based on the bgrt driver :
* Copyright 2012 Red Hat , Inc < mjg @ redhat . com >
* Author : Matthew Garrett
*/
2015-10-25 10:26:35 +00:00
# define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2012-09-28 17:57:05 -07:00
# include <linux/kernel.h>
2012-11-23 16:30:07 +00:00
# include <linux/init.h>
2012-09-28 17:57:05 -07:00
# include <linux/acpi.h>
# include <linux/efi.h>
# include <linux/efi-bgrt.h>
2017-01-31 13:21:40 +00:00
struct acpi_table_bgrt bgrt_tab ;
2018-07-03 17:43:10 +02:00
size_t bgrt_image_size ;
2012-09-28 17:57:05 -07:00
struct bmp_header {
u16 id ;
u32 size ;
} __packed ;
2017-01-31 13:21:40 +00:00
void __init efi_bgrt_init ( struct acpi_table_header * table )
2012-09-28 17:57:05 -07:00
{
2015-12-09 15:41:08 -08:00
void * image ;
2012-09-28 17:57:05 -07:00
struct bmp_header bmp_header ;
2017-01-31 13:21:40 +00:00
struct acpi_table_bgrt * bgrt = & bgrt_tab ;
2012-09-28 17:57:05 -07:00
if ( acpi_disabled )
return ;
2017-06-09 08:45:58 +00:00
if ( ! efi_enabled ( EFI_MEMMAP ) )
2017-05-26 12:36:51 +01:00
return ;
2017-01-31 13:21:40 +00:00
if ( table - > length < sizeof ( bgrt_tab ) ) {
2016-05-03 20:29:41 +01:00
pr_notice ( " Ignoring BGRT: invalid length %u (expected %zu) \n " ,
2017-01-31 13:21:40 +00:00
table - > length , sizeof ( bgrt_tab ) ) ;
2012-11-07 16:46:08 +00:00
return ;
2014-07-30 12:23:32 -07:00
}
2017-01-31 13:21:40 +00:00
* bgrt = * ( struct acpi_table_bgrt * ) table ;
2020-01-31 14:06:23 +01:00
/*
* Only version 1 is defined but some older laptops ( seen on Lenovo
* Ivy Bridge models ) have a correct version 1 BGRT table with the
* version set to 0 , so we accept version 0 and 1.
*/
if ( bgrt - > version > 1 ) {
2016-05-03 20:29:41 +01:00
pr_notice ( " Ignoring BGRT: invalid version %u (expected 1) \n " ,
2017-01-31 13:21:40 +00:00
bgrt - > version ) ;
goto out ;
2014-07-30 12:23:32 -07:00
}
2017-01-31 13:21:40 +00:00
if ( bgrt - > image_type ! = 0 ) {
2016-05-03 20:29:41 +01:00
pr_notice ( " Ignoring BGRT: invalid image type %u (expected 0) \n " ,
2017-01-31 13:21:40 +00:00
bgrt - > image_type ) ;
goto out ;
2014-07-30 12:23:32 -07:00
}
2017-01-31 13:21:40 +00:00
if ( ! bgrt - > image_address ) {
2016-05-03 20:29:41 +01:00
pr_notice ( " Ignoring BGRT: null image address \n " ) ;
2017-01-31 13:21:40 +00:00
goto out ;
2014-07-30 12:23:32 -07:00
}
2012-09-28 17:57:05 -07:00
2017-08-25 16:50:19 +01:00
if ( efi_mem_type ( bgrt - > image_address ) ! = EFI_BOOT_SERVICES_DATA ) {
2017-06-09 08:45:58 +00:00
pr_notice ( " Ignoring BGRT: invalid image address \n " ) ;
goto out ;
}
2017-01-31 13:21:40 +00:00
image = early_memremap ( bgrt - > image_address , sizeof ( bmp_header ) ) ;
2012-09-28 17:57:05 -07:00
if ( ! image ) {
2016-05-03 20:29:41 +01:00
pr_notice ( " Ignoring BGRT: failed to map image header memory \n " ) ;
2017-01-31 13:21:40 +00:00
goto out ;
2012-09-28 17:57:05 -07:00
}
2015-12-09 15:41:08 -08:00
memcpy ( & bmp_header , image , sizeof ( bmp_header ) ) ;
2017-01-31 13:21:40 +00:00
early_memunmap ( image , sizeof ( bmp_header ) ) ;
2016-02-01 22:07:03 +00:00
if ( bmp_header . id ! = 0x4d42 ) {
2016-05-03 20:29:41 +01:00
pr_notice ( " Ignoring BGRT: Incorrect BMP magic number 0x%x (expected 0x4d42) \n " ,
2016-02-01 22:07:03 +00:00
bmp_header . id ) ;
2017-01-31 13:21:40 +00:00
goto out ;
2016-02-01 22:07:03 +00:00
}
2012-09-28 17:57:05 -07:00
bgrt_image_size = bmp_header . size ;
2017-01-31 13:21:40 +00:00
efi_mem_reserve ( bgrt - > image_address , bgrt_image_size ) ;
2012-09-28 17:57:05 -07:00
2017-01-31 13:21:40 +00:00
return ;
out :
memset ( bgrt , 0 , sizeof ( bgrt_tab ) ) ;
2012-09-28 17:57:05 -07:00
}