QcomModulePkg: Log the kernel load start and end time

Existing Bootloader code does not log the kernel load
start and kernel load end time in the IMEM region. This
results in incorrect values of kernel load time read
from the kernel.

Fix this issue by storing the kernel load start and end
time in the IMEM region from the bootloader.

Change-Id: Ib79690005732216db06903213e364280fddda44d
Signed-off-by: Shreyas K K <shrekk@codeaurora.org>
diff --git a/QcomModulePkg/Library/BootLib/BootStats.c b/QcomModulePkg/Library/BootLib/BootStats.c
index 1b39339..48b3524 100644
--- a/QcomModulePkg/Library/BootLib/BootStats.c
+++ b/QcomModulePkg/Library/BootLib/BootStats.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017, 2021 The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -39,6 +39,14 @@
 STATIC UINT64 MpmTimerBase;
 STATIC UINT64 BsImemAddress;
 
+/*
+ * With GKI support, the kernel load time will be sum of
+ * GKI kernel load time + Vendor kernel load time.
+ * To account for this, capture the total number of partition
+ * loading that has to be accounted.
+ */
+STATIC UINT32 KernelLoadTime;
+
 void
 BootStatsSetTimeStamp (BS_ENTRY BootStatId)
 {
@@ -83,18 +91,23 @@
       KernelLoadStart = READL (MpmTimerBase);
       DEBUG ((EFI_D_VERBOSE, "BootStats: ID-%d: Kernel Load Start:%u\n",
               BootStatId, KernelLoadStart));
-      return;
     }
 
     if (BootStatId == BS_KERNEL_LOAD_DONE) {
-      BootStatImemAddress =
-          BsImemAddress + (sizeof (UINT32) * BS_KERNEL_LOAD_TIME);
       BootStatClockCount = READL (MpmTimerBase);
       if (BootStatClockCount) {
-        WRITEL (BootStatImemAddress, (BootStatClockCount - KernelLoadStart));
+        KernelLoadTime += BootStatClockCount - KernelLoadStart;
+      }
+      BootStatImemAddress =
+          BsImemAddress + (sizeof (UINT32) * BS_KERNEL_LOAD_TIME);
+      if (BootStatClockCount) {
+        WRITEL (BootStatImemAddress, KernelLoadTime);
+        BootStatImemAddress = BsImemAddress +
+                              (sizeof (UINT32) * BS_KERNEL_LOAD_DONE);
+        WRITEL (BootStatImemAddress, BootStatClockCount);
       }
       DEBUG ((EFI_D_VERBOSE, "BootStats: ID-%d: Kernel Load Done:%u\n",
-              BootStatId, BootStatClockCount));
+            BootStatId, BootStatClockCount));
     } else {
       BootStatImemAddress = BsImemAddress + (sizeof (UINT32) * BootStatId);
       BootStatClockCount = READL (MpmTimerBase);
diff --git a/QcomModulePkg/Library/avb/libavb/avb_slot_verify.c b/QcomModulePkg/Library/avb/libavb/avb_slot_verify.c
index 7967f00..2e70780 100644
--- a/QcomModulePkg/Library/avb/libavb/avb_slot_verify.c
+++ b/QcomModulePkg/Library/avb/libavb/avb_slot_verify.c
@@ -22,7 +22,7 @@
  * SOFTWARE.
  */
 
-/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -59,6 +59,7 @@
 #include "avb_util.h"
 #include "avb_vbmeta_image.h"
 #include "avb_version.h"
+#include "BootStats.h"
 
 /* Maximum allow length (in bytes) of a partition name, including
  * ab_suffix.
@@ -119,6 +120,8 @@
   size_t digest_len;
   const char* found;
   uint64_t image_size;
+  static bool bootImgLoaded = FALSE;
+  static bool vendorBootImgLoaded = FALSE;
 
   if (!avb_hash_descriptor_validate_and_byteswap(
           (const AvbHashDescriptor*)descriptor, &hash_desc)) {
@@ -187,6 +190,13 @@
     goto out;
   }
 
+  if ((Avb_StrnCmp ("boot", part_name, 4) == 0 &&
+      !bootImgLoaded) ||
+      (Avb_StrnCmp ("vendor_boot", part_name, 11) == 0 &&
+      !vendorBootImgLoaded)) {
+    BootStatsSetTimeStamp (BS_KERNEL_LOAD_START);
+  }
+
   io_ret = ops->read_from_partition(
       ops, part_name, 0 /* offset */, image_size, image_buf, &part_num_read);
   if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
@@ -203,6 +213,16 @@
     goto out;
   }
 
+  if (Avb_StrnCmp ("boot", part_name, 4) == 0 &&
+      !bootImgLoaded) {
+    bootImgLoaded = TRUE;
+    BootStatsSetTimeStamp (BS_KERNEL_LOAD_DONE);
+  } else if (Avb_StrnCmp ("vendor_boot", part_name, 11) == 0 &&
+            !vendorBootImgLoaded) {
+    vendorBootImgLoaded = TRUE;
+    BootStatsSetTimeStamp (BS_KERNEL_LOAD_DONE);
+  }
+
   if (Avb_StrnCmp ( (CONST CHAR8*)hash_desc.hash_algorithm, "sha256",
                  avb_strlen ("sha256")) == 0) {
     avb_sha256_init(&sha256_ctx);