blob: af347c190819d98aa4ce7aa81a3df7b4a8f786f3 [file] [log] [blame]
Thomas Gleixner2874c5f2019-05-27 08:55:01 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Ashley Laic5df3922012-08-14 18:35:32 -05002/*
3 * Copyright 2012 IBM Corporation
4 *
Ashley Lai1a0f1b22014-12-04 21:01:51 -06005 * Author: Ashley Lai <ashleydlai@gmail.com>
Nayna Jain02ae13822016-11-14 05:00:54 -05006 * Nayna Jain <nayna@linux.vnet.ibm.com>
Ashley Laic5df3922012-08-14 18:35:32 -05007 *
8 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
9 *
10 * Read the event log created by the firmware on PPC64
Ashley Laic5df3922012-08-14 18:35:32 -050011 */
12
13#include <linux/slab.h>
14#include <linux/of.h>
Thiebaud Weksteenfd3ec362017-09-20 10:13:36 +020015#include <linux/tpm_eventlog.h>
Ashley Laic5df3922012-08-14 18:35:32 -050016
Thiebaud Weksteen0bfb2372018-04-12 12:13:48 +020017#include "../tpm.h"
Thiebaud Weksteen75d647f2018-04-12 12:13:50 +020018#include "common.h"
Ashley Laic5df3922012-08-14 18:35:32 -050019
Nayna Jain02ae13822016-11-14 05:00:54 -050020int tpm_read_log_of(struct tpm_chip *chip)
Ashley Laic5df3922012-08-14 18:35:32 -050021{
22 struct device_node *np;
23 const u32 *sizep;
Hon Ching \(Vicky\) Lod72c39112015-06-17 18:17:09 -040024 const u64 *basep;
Nayna Jain748935e2016-11-14 05:00:52 -050025 struct tpm_bios_log *log;
Nayna Jaine46e22f2017-01-23 02:26:26 -050026 u32 size;
27 u64 base;
Ashley Laic5df3922012-08-14 18:35:32 -050028
Nayna Jain748935e2016-11-14 05:00:52 -050029 log = &chip->log;
Jason Gunthorpe0cf577a2016-11-19 11:18:28 -070030 if (chip->dev.parent && chip->dev.parent->of_node)
Nayna Jained4fdb42016-11-14 05:00:55 -050031 np = chip->dev.parent->of_node;
Colin Ian King79eec5b2016-11-15 13:27:22 +000032 else
Ashley Laic5df3922012-08-14 18:35:32 -050033 return -ENODEV;
Ashley Laic5df3922012-08-14 18:35:32 -050034
Enric Balletbo i Serrab5d0ebc2017-06-27 12:27:24 +020035 if (of_property_read_bool(np, "powered-while-suspended"))
36 chip->flags |= TPM_CHIP_FLAG_ALWAYS_POWERED;
37
Ashley Laic5df3922012-08-14 18:35:32 -050038 sizep = of_get_property(np, "linux,sml-size", NULL);
Jason Gunthorpe0cf577a2016-11-19 11:18:28 -070039 basep = of_get_property(np, "linux,sml-base", NULL);
40 if (sizep == NULL && basep == NULL)
41 return -ENODEV;
42 if (sizep == NULL || basep == NULL)
Nayna Jain5efae7d2016-11-14 05:00:56 -050043 return -EIO;
44
Nayna Jaine46e22f2017-01-23 02:26:26 -050045 /*
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) {
Thiebaud Weksteen09dd1442018-04-25 15:26:41 +020055 size = be32_to_cpup((__force __be32 *)sizep);
56 base = be64_to_cpup((__force __be64 *)basep);
Nayna Jaine46e22f2017-01-23 02:26:26 -050057 } else {
58 size = *sizep;
59 base = *basep;
60 }
61
62 if (size == 0) {
Nayna Jain5efae7d2016-11-14 05:00:56 -050063 dev_warn(&chip->dev, "%s: Event log area empty\n", __func__);
64 return -EIO;
Ashley Laic5df3922012-08-14 18:35:32 -050065 }
66
Ji-Hun Kim69798912018-05-09 09:12:36 +090067 log->bios_event_log = kmemdup(__va(base), size, GFP_KERNEL);
Nayna Jain5efae7d2016-11-14 05:00:56 -050068 if (!log->bios_event_log)
Ashley Laic5df3922012-08-14 18:35:32 -050069 return -ENOMEM;
Ashley Laic5df3922012-08-14 18:35:32 -050070
Nayna Jaine46e22f2017-01-23 02:26:26 -050071 log->bios_event_log_end = log->bios_event_log + size;
Ashley Laic5df3922012-08-14 18:35:32 -050072
Thiebaud Weksteen58cc1e42017-09-20 10:13:40 +020073 if (chip->flags & TPM_CHIP_FLAG_TPM2)
74 return EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
75 return EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
Ashley Laic5df3922012-08-14 18:35:32 -050076}