| 
									
										
										
										
											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 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 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>
 | 
					
						
							| 
									
										
										
										
											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>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct acpi_table_bgrt *bgrt_tab; | 
					
						
							| 
									
										
										
										
											2012-11-23 16:30:07 +00:00
										 |  |  | void *__initdata bgrt_image; | 
					
						
							|  |  |  | size_t __initdata bgrt_image_size; | 
					
						
							| 
									
										
										
										
											2012-09-28 17:57:05 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | struct bmp_header { | 
					
						
							|  |  |  | 	u16 id; | 
					
						
							|  |  |  | 	u32 size; | 
					
						
							|  |  |  | } __packed; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-23 16:30:07 +00:00
										 |  |  | void __init efi_bgrt_init(void) | 
					
						
							| 
									
										
										
										
											2012-09-28 17:57:05 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	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; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-07 16:46:08 +00:00
										 |  |  | 	if (bgrt_tab->header.length < sizeof(*bgrt_tab)) | 
					
						
							|  |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2014-02-13 17:17:54 +00:00
										 |  |  | 	if (bgrt_tab->version != 1 || bgrt_tab->status != 1) | 
					
						
							| 
									
										
										
										
											2012-09-28 17:57:05 -07:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	if (bgrt_tab->image_type != 0 || !bgrt_tab->image_address) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	image = efi_lookup_mapped_addr(bgrt_tab->image_address); | 
					
						
							|  |  |  | 	if (!image) { | 
					
						
							| 
									
										
										
										
											2014-01-14 12:40:09 +00:00
										 |  |  | 		image = early_memremap(bgrt_tab->image_address, | 
					
						
							|  |  |  | 				       sizeof(bmp_header)); | 
					
						
							| 
									
										
										
										
											2012-09-28 17:57:05 -07:00
										 |  |  | 		ioremapped = true; | 
					
						
							|  |  |  | 		if (!image) | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memcpy_fromio(&bmp_header, image, sizeof(bmp_header)); | 
					
						
							|  |  |  | 	if (ioremapped) | 
					
						
							| 
									
										
										
										
											2014-01-14 12:40:09 +00:00
										 |  |  | 		early_iounmap(image, sizeof(bmp_header)); | 
					
						
							| 
									
										
										
										
											2012-09-28 17:57:05 -07:00
										 |  |  | 	bgrt_image_size = bmp_header.size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL); | 
					
						
							|  |  |  | 	if (!bgrt_image) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (ioremapped) { | 
					
						
							| 
									
										
										
										
											2014-01-14 12:40:09 +00:00
										 |  |  | 		image = early_memremap(bgrt_tab->image_address, | 
					
						
							|  |  |  | 				       bmp_header.size); | 
					
						
							| 
									
										
										
										
											2012-09-28 17:57:05 -07:00
										 |  |  | 		if (!image) { | 
					
						
							|  |  |  | 			kfree(bgrt_image); | 
					
						
							|  |  |  | 			bgrt_image = NULL; | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memcpy_fromio(bgrt_image, image, bgrt_image_size); | 
					
						
							|  |  |  | 	if (ioremapped) | 
					
						
							| 
									
										
										
										
											2014-01-14 12:40:09 +00:00
										 |  |  | 		early_iounmap(image, bmp_header.size); | 
					
						
							| 
									
										
										
										
											2012-09-28 17:57:05 -07:00
										 |  |  | } |