1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright 2012 IBM Corporation 4 * 5 * Author: Ashley Lai <ashleydlai@gmail.com> 6 * Nayna Jain <nayna@linux.vnet.ibm.com> 7 * 8 * Maintained by: <tpmdd-devel@lists.sourceforge.net> 9 * 10 * Read the event log created by the firmware on PPC64 11 */ 12 13 #include <linux/slab.h> 14 #include <linux/of.h> 15 #include <linux/tpm_eventlog.h> 16 17 #include "../tpm.h" 18 #include "common.h" 19 20 int tpm_read_log_of(struct tpm_chip *chip) 21 { 22 struct device_node *np; 23 const u32 *sizep; 24 const u64 *basep; 25 struct tpm_bios_log *log; 26 u32 size; 27 u64 base; 28 29 log = &chip->log; 30 if (chip->dev.parent && chip->dev.parent->of_node) 31 np = chip->dev.parent->of_node; 32 else 33 return -ENODEV; 34 35 if (of_property_read_bool(np, "powered-while-suspended")) 36 chip->flags |= TPM_CHIP_FLAG_ALWAYS_POWERED; 37 38 sizep = of_get_property(np, "linux,sml-size", NULL); 39 basep = of_get_property(np, "linux,sml-base", NULL); 40 if (sizep == NULL && basep == NULL) 41 return -ENODEV; 42 if (sizep == NULL || basep == NULL) 43 return -EIO; 44 45 /* 46 * For both vtpm/tpm, firmware has log addr and log size in big 47 * endian format. But in case of vtpm, there is a method called 48 * sml-handover which is run during kernel init even before 49 * device tree is setup. This sml-handover function takes care 50 * of endianness and writes to sml-base and sml-size in little 51 * endian format. For this reason, vtpm doesn't need conversion 52 * but physical tpm needs the conversion. 53 */ 54 if (of_property_match_string(np, "compatible", "IBM,vtpm") < 0 && 55 of_property_match_string(np, "compatible", "IBM,vtpm20") < 0) { 56 size = be32_to_cpup((__force __be32 *)sizep); 57 base = be64_to_cpup((__force __be64 *)basep); 58 } else { 59 size = *sizep; 60 base = *basep; 61 } 62 63 if (size == 0) { 64 dev_warn(&chip->dev, "%s: Event log area empty\n", __func__); 65 return -EIO; 66 } 67 68 log->bios_event_log = kmemdup(__va(base), size, GFP_KERNEL); 69 if (!log->bios_event_log) 70 return -ENOMEM; 71 72 log->bios_event_log_end = log->bios_event_log + size; 73 74 if (chip->flags & TPM_CHIP_FLAG_TPM2) 75 return EFI_TCG2_EVENT_LOG_FORMAT_TCG_2; 76 return EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2; 77 } 78