summaryrefslogtreecommitdiff
path: root/mali_kbase/backend/gpu/mali_kbase_pm_event_log.c
diff options
context:
space:
mode:
authorSean Callanan <spyffe@google.com>2022-03-29 15:59:11 -0700
committerSean Callanan <spyffe@google.com>2022-05-06 03:21:47 +0000
commit3c79757bf266237988f266bbe282c65f3f2b2e71 (patch)
tree56e4effdf2d33fab9a9a4d0d0e8b815c4bcbdbb1 /mali_kbase/backend/gpu/mali_kbase_pm_event_log.c
parent24f884bf5e86175b0da95df93f2f5764ce6dfb99 (diff)
downloadgpu-3c79757bf266237988f266bbe282c65f3f2b2e71.tar.gz
mali_kbase: platform: Add PM event log to SSCD
Add a PM event log recording state transitions. This log can be read in ramdumps, and is also included in SSCDs. Bug: 221885391 Test: Trigger SSCD, check core dump sections Signed-off-by: Sean Callanan <spyffe@google.com> Change-Id: I79151064e1b5075bc07caa261eff0fbc6e8778ec
Diffstat (limited to 'mali_kbase/backend/gpu/mali_kbase_pm_event_log.c')
-rw-r--r--mali_kbase/backend/gpu/mali_kbase_pm_event_log.c108
1 files changed, 108 insertions, 0 deletions
diff --git a/mali_kbase/backend/gpu/mali_kbase_pm_event_log.c b/mali_kbase/backend/gpu/mali_kbase_pm_event_log.c
new file mode 100644
index 0000000..b752af8
--- /dev/null
+++ b/mali_kbase/backend/gpu/mali_kbase_pm_event_log.c
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+/*
+ *
+ * (C) COPYRIGHT 2022 Google LLC. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation, and any use by you of this program is subject to the terms
+ * of such GNU license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you can access it online at
+ * http://www.gnu.org/licenses/gpl-2.0.html.
+ *
+ */
+
+#include <backend/gpu/mali_kbase_pm_event_log.h>
+
+static inline u32 kbase_pm_next_log_event(
+ struct kbase_pm_event_log *log)
+{
+ u32 ret = log->last_event;
+ ++ret;
+ ret %= EVENT_LOG_MAX;
+ log->last_event = ret;
+ return ret;
+}
+
+struct kbase_pm_event_log_event *kbase_pm_add_log_event(
+ struct kbase_device *kbdev)
+{
+ struct kbase_pm_event_log *log = &kbdev->pm.backend.event_log;
+ struct kbase_pm_event_log_event *ret = NULL;
+
+ lockdep_assert_held(&kbdev->hwaccess_lock);
+ ret = &log->events[kbase_pm_next_log_event(log)];
+
+ memset(ret, 0, sizeof(*ret));
+ ret->timestamp = ktime_get();
+ return ret;
+}
+
+/**
+ * struct kbase_pm_event_log_metadata - Info about the event log.
+ *
+ * @magic: always 'kpel', helps find the log in memory dumps
+ * @version: updated whenever the binary layout changes
+ * @events_address: the memory address of the log, or in a file the offset
+ * from the start of the metadata to the log
+ * @num_events: the capacity of the event log
+ * @event_stride: distance between log entries, to aid in parsing if only some
+ * entry types are supported by the parser
+ **/
+struct kbase_pm_event_log_metadata {
+ char magic[4];
+ u8 version;
+ u64 events_address;
+ u32 num_events;
+ u32 event_stride;
+} __attribute__((packed));
+
+static struct kbase_pm_event_log_metadata global_event_log_metadata;
+
+void kbase_pm_init_event_log(struct kbase_device *kbdev)
+{
+ struct kbase_pm_event_log_metadata *md =
+ &global_event_log_metadata;
+ kbdev->pm.backend.event_log.last_event = -1;
+ md->magic[0] = 'k';
+ md->magic[1] = 'p';
+ md->magic[2] = 'e';
+ md->magic[3] = 'l';
+ md->version = 1;
+ md->num_events = EVENT_LOG_MAX;
+ md->events_address = (u64)kbdev->pm.backend.event_log.events;
+ md->event_stride = ((u8*)&kbdev->pm.backend.event_log.events[1] -
+ (u8*)&kbdev->pm.backend.event_log.events[0]);
+}
+
+u64 kbase_pm_max_event_log_size(struct kbase_device *kbdev)
+{
+ return sizeof(struct kbase_pm_event_log_metadata)
+ + sizeof(kbdev->pm.backend.event_log.events);
+}
+
+int kbase_pm_copy_event_log(struct kbase_device *kbdev,
+ void *buffer, u64 size)
+{
+ lockdep_assert_held(&kbdev->hwaccess_lock);
+ if (size < kbase_pm_max_event_log_size(kbdev)) {
+ return -EINVAL;
+ }
+ memcpy(buffer, &global_event_log_metadata,
+ sizeof(global_event_log_metadata));
+ memcpy(((u8*)buffer) + sizeof(global_event_log_metadata),
+ &kbdev->pm.backend.event_log.events,
+ sizeof(kbdev->pm.backend.event_log.events));
+ ((struct kbase_pm_event_log_metadata*)buffer)->events_address =
+ sizeof(struct kbase_pm_event_log_metadata);
+
+ return 0;
+}
+