1 /* 2 * coreboot_table.c 3 * 4 * Module providing coreboot table access. 5 * 6 * Copyright 2017 Google Inc. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License v2.0 as published by 10 * the Free Software Foundation. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 */ 17 18 #include <linux/err.h> 19 #include <linux/init.h> 20 #include <linux/io.h> 21 #include <linux/kernel.h> 22 #include <linux/module.h> 23 24 #include "coreboot_table.h" 25 26 struct coreboot_table_entry { 27 u32 tag; 28 u32 size; 29 }; 30 31 static struct coreboot_table_header __iomem *ptr_header; 32 33 /* 34 * This function parses the coreboot table for an entry that contains the base 35 * address of the given entry tag. The coreboot table consists of a header 36 * directly followed by a number of small, variable-sized entries, which each 37 * contain an identifying tag and their length as the first two fields. 38 */ 39 int coreboot_table_find(int tag, void *data, size_t data_size) 40 { 41 struct coreboot_table_header header; 42 struct coreboot_table_entry entry; 43 void *ptr_entry; 44 int i; 45 46 if (!ptr_header) 47 return -EPROBE_DEFER; 48 49 memcpy_fromio(&header, ptr_header, sizeof(header)); 50 51 if (strncmp(header.signature, "LBIO", sizeof(header.signature))) { 52 pr_warn("coreboot_table: coreboot table missing or corrupt!\n"); 53 return -ENODEV; 54 } 55 56 ptr_entry = (void *)ptr_header + header.header_bytes; 57 58 for (i = 0; i < header.table_entries; i++) { 59 memcpy_fromio(&entry, ptr_entry, sizeof(entry)); 60 if (entry.tag == tag) { 61 if (data_size < entry.size) 62 return -EINVAL; 63 64 memcpy_fromio(data, ptr_entry, entry.size); 65 66 return 0; 67 } 68 69 ptr_entry += entry.size; 70 } 71 72 return -ENOENT; 73 } 74 EXPORT_SYMBOL(coreboot_table_find); 75 76 int coreboot_table_init(void __iomem *ptr) 77 { 78 ptr_header = ptr; 79 80 return 0; 81 } 82 EXPORT_SYMBOL(coreboot_table_init); 83 84 int coreboot_table_exit(void) 85 { 86 if (ptr_header) 87 iounmap(ptr_header); 88 89 return 0; 90 } 91 EXPORT_SYMBOL(coreboot_table_exit); 92 93 MODULE_AUTHOR("Google, Inc."); 94 MODULE_LICENSE("GPL"); 95