1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright 2012 IBM Corporation
5 * Author: Ashley Lai <ashleydlai@gmail.com>
6 * Nayna Jain <nayna@linux.vnet.ibm.com>
8 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
10 * Read the event log created by the firmware on PPC64
13 #include <linux/device.h>
14 #include <linux/slab.h>
16 #include <linux/ioport.h>
18 #include <linux/of_address.h>
19 #include <linux/of_reserved_mem.h>
20 #include <linux/tpm_eventlog.h>
25 static int tpm_read_log_memory_region(struct tpm_chip
*chip
)
27 struct device_node
*node
;
31 node
= of_parse_phandle(chip
->dev
.parent
->of_node
, "memory-region", 0);
35 rc
= of_address_to_resource(node
, 0, &res
);
40 chip
->log
.bios_event_log
= devm_memremap(&chip
->dev
, res
.start
, resource_size(&res
),
42 if (IS_ERR(chip
->log
.bios_event_log
))
45 chip
->log
.bios_event_log_end
= chip
->log
.bios_event_log
+ resource_size(&res
);
47 return chip
->flags
& TPM_CHIP_FLAG_TPM2
? EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
:
48 EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
;
51 int tpm_read_log_of(struct tpm_chip
*chip
)
53 struct device_node
*np
;
56 struct tpm_bios_log
*log
;
61 if (chip
->dev
.parent
&& chip
->dev
.parent
->of_node
)
62 np
= chip
->dev
.parent
->of_node
;
66 if (of_property_read_bool(np
, "powered-while-suspended"))
67 chip
->flags
|= TPM_CHIP_FLAG_ALWAYS_POWERED
;
69 sizep
= of_get_property(np
, "linux,sml-size", NULL
);
70 basep
= of_get_property(np
, "linux,sml-base", NULL
);
71 if (sizep
== NULL
&& basep
== NULL
)
72 return tpm_read_log_memory_region(chip
);
73 if (sizep
== NULL
|| basep
== NULL
)
77 * For both vtpm/tpm, firmware has log addr and log size in big
78 * endian format. But in case of vtpm, there is a method called
79 * sml-handover which is run during kernel init even before
80 * device tree is setup. This sml-handover function takes care
81 * of endianness and writes to sml-base and sml-size in little
82 * endian format. For this reason, vtpm doesn't need conversion
83 * but physical tpm needs the conversion.
85 if (of_property_match_string(np
, "compatible", "IBM,vtpm") < 0 &&
86 of_property_match_string(np
, "compatible", "IBM,vtpm20") < 0) {
87 size
= be32_to_cpup((__force __be32
*)sizep
);
88 base
= be64_to_cpup((__force __be64
*)basep
);
95 dev_warn(&chip
->dev
, "%s: Event log area empty\n", __func__
);
99 log
->bios_event_log
= devm_kmemdup(&chip
->dev
, __va(base
), size
, GFP_KERNEL
);
100 if (!log
->bios_event_log
)
103 log
->bios_event_log_end
= log
->bios_event_log
+ size
;
105 if (chip
->flags
& TPM_CHIP_FLAG_TPM2
)
106 return EFI_TCG2_EVENT_LOG_FORMAT_TCG_2
;
107 return EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
;