QcomModulePkg: Read SerialNumber from oem partition

This change reads the serial number from "oem" partition
and passes it on to the system.

If the serial number can not be read from "oem" partition,
it falls back to calculate a serial number based on UFS storage.

Change-Id: I8f48ab166330e56efc1bc7603da51fab172de5ad
Signed-off-by: Alexander Martinz <amartinz@shiftphones.com>
diff --git a/QcomModulePkg/Include/Library/Recovery.h b/QcomModulePkg/Include/Library/Recovery.h
index e2f1302..390e4f5 100644
--- a/QcomModulePkg/Include/Library/Recovery.h
+++ b/QcomModulePkg/Include/Library/Recovery.h
@@ -33,6 +33,9 @@
 
 #define FFBM_MODE_BUF_SIZE 8
 
+#define READ_OEM_BUF_SIZE 512
+#define READ_OEM_BUF_LEN  24
+
 #define RECOVERY_BOOT_RECOVERY "boot-recovery"
 #define RECOVERY_BOOT_FASTBOOT "boot-fastboot"
 
@@ -92,4 +95,8 @@
 SetSnapshotMergeStatus (VirtualAbMergeStatus MergeStatus);
 EFI_STATUS
 ReadFromPartition (EFI_GUID *Ptype, VOID **Msg, UINT32 Size);
+
+EFI_STATUS
+GetOemSerialNum (CHAR8 *nv_serialnum);
+
 #endif
diff --git a/QcomModulePkg/Library/BootLib/Board.c b/QcomModulePkg/Library/BootLib/Board.c
index c354f45..31ef3fe 100644
--- a/QcomModulePkg/Library/BootLib/Board.c
+++ b/QcomModulePkg/Library/BootLib/Board.c
@@ -29,6 +29,7 @@
 #include "AutoGen.h"
 #include <Board.h>
 #include <Library/BootImage.h>
+#include <Library/Recovery.h>
 #include <Library/UpdateDeviceTree.h>
 #include <Protocol/EFICardInfo.h>
 #include <Protocol/EFIPlatformInfoTypes.h>
@@ -597,6 +598,12 @@
     return Status;
   }
 
+  Status = GetOemSerialNum (StrSerialNum);
+  if (Status == EFI_SUCCESS) {
+    DEBUG ((EFI_D_ERROR, "Got serial number from oem partition: %s\n", StrSerialNum));
+    return Status;
+  }
+
   if (CardInfo->GetCardInfo (CardInfo, &CardInfoData) == EFI_SUCCESS) {
     if (Type == UFS) {
       Status = gBS->CalculateCrc32 (CardInfoData.product_serial_num,
diff --git a/QcomModulePkg/Library/BootLib/Recovery.c b/QcomModulePkg/Library/BootLib/Recovery.c
index b61acc4..065c27c 100644
--- a/QcomModulePkg/Library/BootLib/Recovery.c
+++ b/QcomModulePkg/Library/BootLib/Recovery.c
@@ -401,3 +401,49 @@
 
   return Status;
 }
+
+EFI_STATUS
+GetOemSerialNum (CHAR8 *nv_serialnum)
+{
+  CONST CHAR8 *line_ind = "SN:";
+  CHAR8 *oem_page_buffer = NULL;
+  CHAR8 *line_ptr = NULL;
+  EFI_STATUS Status;
+  EFI_GUID Ptype = gEfiOemPartitionGuid;
+  MemCardType CardType = UNKNOWN;
+
+  CardType = CheckRootDeviceType ();
+  if (CardType == NAND) {
+    Status = GetNandOemPartiGuid (&Ptype);
+    if (Status != EFI_SUCCESS) {
+      return Status;
+    }
+  }
+
+  Status = ReadFromPartition (&Ptype, (VOID **)&oem_page_buffer, READ_OEM_BUF_SIZE);
+  if (Status != EFI_SUCCESS) {
+    DEBUG ((EFI_D_ERROR, "Error Reading OEM info from oem: %r\n", Status));
+    return Status;
+  }
+
+  oem_page_buffer[READ_OEM_BUF_SIZE - 1] = '\0';
+  //DEBUG ((EFI_D_ERROR, "Read OEM data: %s\n", oem_page_buffer));
+
+  line_ptr = AsciiStrStr(oem_page_buffer, line_ind);
+  if (line_ptr == NULL) {
+    Status = EFI_NOT_FOUND;
+  } else {
+    memset(nv_serialnum, 0x0, sizeof(nv_serialnum));
+    AsciiStrnCpy((char *)nv_serialnum, (line_ptr + strlen(line_ind)), READ_OEM_BUF_LEN);
+    for (unsigned char i = 0; i < READ_OEM_BUF_LEN; i++) {
+      if (nv_serialnum[i] == '\r' || nv_serialnum[i] == '\n' || nv_serialnum[i] == ' ') {
+        nv_serialnum[i] = '\0';
+      }
+    }
+  }
+
+  FreePool (oem_page_buffer);
+  oem_page_buffer = NULL;
+
+  return Status;
+}