mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-14 05:46:50 +07:00
248fbcd5ae
It's totally legitimate, per the ACPI spec, for the firmware to set the BGRT 'status' field to zero to indicate that the BGRT image isn't being displayed, and we shouldn't be printing an error message in that case because it's just noise for users. So swap pr_err() for pr_debug(). However, Josh points that out it still makes sense to test the validity of the upper 7 bits of the 'status' field, since they're marked as "reserved" in the spec and must be zero. If firmware violates this it really *is* an error. Reported-by: Tom Yan <tom.ty89@gmail.com> Tested-by: Tom Yan <tom.ty89@gmail.com> Signed-off-by: Matt Fleming <matt.fleming@intel.com> Reviewed-by: Josh Triplett <josh@joshtriplett.org> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Matthew Garrett <mjg59@srcf.ucam.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/1438936621-5215-2-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar <mingo@kernel.org>
111 lines
2.7 KiB
C
111 lines
2.7 KiB
C
/*
|
|
* 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
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*/
|
|
#include <linux/kernel.h>
|
|
#include <linux/init.h>
|
|
#include <linux/acpi.h>
|
|
#include <linux/efi.h>
|
|
#include <linux/efi-bgrt.h>
|
|
|
|
struct acpi_table_bgrt *bgrt_tab;
|
|
void *__initdata bgrt_image;
|
|
size_t __initdata bgrt_image_size;
|
|
|
|
struct bmp_header {
|
|
u16 id;
|
|
u32 size;
|
|
} __packed;
|
|
|
|
void __init efi_bgrt_init(void)
|
|
{
|
|
acpi_status status;
|
|
void __iomem *image;
|
|
bool ioremapped = false;
|
|
struct bmp_header bmp_header;
|
|
|
|
if (acpi_disabled)
|
|
return;
|
|
|
|
status = acpi_get_table("BGRT", 0,
|
|
(struct acpi_table_header **)&bgrt_tab);
|
|
if (ACPI_FAILURE(status))
|
|
return;
|
|
|
|
if (bgrt_tab->header.length < sizeof(*bgrt_tab)) {
|
|
pr_err("Ignoring BGRT: invalid length %u (expected %zu)\n",
|
|
bgrt_tab->header.length, sizeof(*bgrt_tab));
|
|
return;
|
|
}
|
|
if (bgrt_tab->version != 1) {
|
|
pr_err("Ignoring BGRT: invalid version %u (expected 1)\n",
|
|
bgrt_tab->version);
|
|
return;
|
|
}
|
|
if (bgrt_tab->status & 0xfe) {
|
|
pr_err("Ignoring BGRT: reserved status bits are non-zero %u\n",
|
|
bgrt_tab->status);
|
|
return;
|
|
}
|
|
if (bgrt_tab->status != 1) {
|
|
pr_debug("Ignoring BGRT: invalid status %u (expected 1)\n",
|
|
bgrt_tab->status);
|
|
return;
|
|
}
|
|
if (bgrt_tab->image_type != 0) {
|
|
pr_err("Ignoring BGRT: invalid image type %u (expected 0)\n",
|
|
bgrt_tab->image_type);
|
|
return;
|
|
}
|
|
if (!bgrt_tab->image_address) {
|
|
pr_err("Ignoring BGRT: null image address\n");
|
|
return;
|
|
}
|
|
|
|
image = efi_lookup_mapped_addr(bgrt_tab->image_address);
|
|
if (!image) {
|
|
image = early_ioremap(bgrt_tab->image_address,
|
|
sizeof(bmp_header));
|
|
ioremapped = true;
|
|
if (!image) {
|
|
pr_err("Ignoring BGRT: failed to map image header memory\n");
|
|
return;
|
|
}
|
|
}
|
|
|
|
memcpy_fromio(&bmp_header, image, sizeof(bmp_header));
|
|
if (ioremapped)
|
|
early_iounmap(image, sizeof(bmp_header));
|
|
bgrt_image_size = bmp_header.size;
|
|
|
|
bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL | __GFP_NOWARN);
|
|
if (!bgrt_image) {
|
|
pr_err("Ignoring BGRT: failed to allocate memory for image (wanted %zu bytes)\n",
|
|
bgrt_image_size);
|
|
return;
|
|
}
|
|
|
|
if (ioremapped) {
|
|
image = early_ioremap(bgrt_tab->image_address,
|
|
bmp_header.size);
|
|
if (!image) {
|
|
pr_err("Ignoring BGRT: failed to map image memory\n");
|
|
kfree(bgrt_image);
|
|
bgrt_image = NULL;
|
|
return;
|
|
}
|
|
}
|
|
|
|
memcpy_fromio(bgrt_image, image, bgrt_image_size);
|
|
if (ioremapped)
|
|
early_iounmap(image, bmp_header.size);
|
|
}
|