59 #define KMSG_COMPONENT "SFI"
60 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
63 #include <linux/kernel.h>
64 #include <linux/module.h>
65 #include <linux/errno.h>
66 #include <linux/types.h>
70 #include <linux/slab.h>
74 #define ON_SAME_PAGE(addr1, addr2) \
75 (((unsigned long)(addr1) & PAGE_MASK) == \
76 ((unsigned long)(addr2) & PAGE_MASK))
77 #define TABLE_ON_PAGE(page, table, size) (ON_SAME_PAGE(page, table) && \
78 ON_SAME_PAGE(page, table + size))
120 static void sfi_print_table_header(
unsigned long long pa,
123 pr_info(
"%4.4s %llX, %04X (v%d %6.6s %8.8s)\n",
137 u8 *puchar = (
u8 *)table;
141 if (length > 0x100000) {
142 pr_err(
"Invalid table length 0x%x\n", length);
147 checksum += *puchar++;
150 pr_err(
"Checksum %2.2X should be %2.2X\n",
151 table->
csum, table->
csum - checksum);
172 th = (
void *)syst_va + (pa - syst_pa);
183 return sfi_map_memory(pa, length);
196 sizeof(*th) : th->
len);
241 sfi_print_table_header(pa, th);
242 if (sfi_verify_table(th))
245 if (!sfi_table_check_key(th, key))
265 for (i = 0; i < tbl_cnt; i++) {
267 if (!IS_ERR(th) && th)
298 ret = handler(table);
311 static int __init sfi_parse_syst(
void)
322 for (i = 0; i < tbl_cnt; i++) {
340 static __init int sfi_find_syst(
void)
346 start = sfi_map_memory(SFI_SYST_SEARCH_BEGIN, len);
350 for (offset = 0; offset < len; offset += 16) {
353 syst_hdr = start +
offset;
361 sfi_print_table_header(SFI_SYST_SEARCH_BEGIN + offset,
364 if (sfi_verify_table(syst_hdr))
371 pr_info(
"SYST 0x%llx + 0x%x crosses page\n",
372 syst_pa, syst_hdr->
len);
377 syst_pa = SFI_SYST_SEARCH_BEGIN +
offset;
378 sfi_unmap_memory(start, len);
382 sfi_unmap_memory(start, len);
386 static struct kobject *sfi_kobj;
387 static struct kobject *tables_kobj;
391 loff_t offset,
size_t count)
413 syst_va, syst_va->header.len);
429 if (!th || !th->
sig[0]) {
437 tbl_attr->
attr.size = 0;
438 tbl_attr->
attr.read = sfi_table_show;
439 tbl_attr->
attr.attr.name = tbl_attr->
name;
440 tbl_attr->
attr.attr.mode = 0400;
453 static int __init sfi_sysfs_init(
void)
474 for (i = 0; i < tbl_cnt; i++)
480 pr_info(
"SFI sysfs interfaces init success\n");
492 pr_info(
"Simple Firmware Interface v0.81 http://simplefirmware.org\n");
507 length = syst_va->header.len;
512 syst_va = sfi_map_memory(syst_pa, length);