QcomModulePkg: Read HardwareRevision from oem partition

Set "androidboot.hardware.revision", which is automatically
picked up by init, which sets "ro.boot.hardware.revision", which is
used by userspace already.

If HW revision can not be read, fall back to "10000".

Change-Id: Ia73d0e7e1755f2c346a9993eadaf4baf18a0d145
Signed-off-by: Alexander Martinz <amartinz@shiftphones.com>
diff --git a/QcomModulePkg/Include/Library/Board.h b/QcomModulePkg/Include/Library/Board.h
index a5c5ee1..cb206bc 100644
--- a/QcomModulePkg/Include/Library/Board.h
+++ b/QcomModulePkg/Include/Library/Board.h
@@ -92,6 +92,8 @@
 EFI_STATUS BoardInit (VOID);
 
 EFI_STATUS
+BoardHardwareRevision (CHAR8 *StrHardwareRev, UINT32 Len);
+EFI_STATUS
 BoardSerialNum (CHAR8 *StrSerialNum, UINT32 Len);
 UINT32 BoardPlatformRawChipId (VOID);
 CHAR8 *BoardPlatformChipBaseBand (VOID);
diff --git a/QcomModulePkg/Include/Library/Recovery.h b/QcomModulePkg/Include/Library/Recovery.h
index 390e4f5..0f2f774 100644
--- a/QcomModulePkg/Include/Library/Recovery.h
+++ b/QcomModulePkg/Include/Library/Recovery.h
@@ -97,6 +97,8 @@
 ReadFromPartition (EFI_GUID *Ptype, VOID **Msg, UINT32 Size);
 
 EFI_STATUS
+GetOemHardwareRevision (CHAR8 *nv_hwrevision);
+EFI_STATUS
 GetOemSerialNum (CHAR8 *nv_serialnum);
 
 #endif
diff --git a/QcomModulePkg/Include/Library/UpdateCmdLine.h b/QcomModulePkg/Include/Library/UpdateCmdLine.h
index c3a4640..f400b8d 100644
--- a/QcomModulePkg/Include/Library/UpdateCmdLine.h
+++ b/QcomModulePkg/Include/Library/UpdateCmdLine.h
@@ -46,6 +46,7 @@
 
 #define MAX_PATH_SIZE 72
 #define SERIAL_NUM_SIZE 64
+#define HW_REVISION_SIZE 64
 
 typedef struct BootInfo BootInfo;
 
@@ -57,11 +58,13 @@
   UINT32 CmdLineLen;
   UINT32 HaveCmdLine;
   UINT32 PauseAtBootUp;
+  CHAR8 *StrHardwareRev;
   CHAR8 *StrSerialNum;
   CHAR8 *SlotSuffixAscii;
   CHAR8 *ChipBaseBand;
   CHAR8 *DisplayCmdLine;
   CONST CHAR8 *CmdLine;
+  CONST CHAR8 *HardwareRevisionCmdLine;
   CONST CHAR8 *AlarmBootCmdLine;
   CONST CHAR8 *MdtpActiveFlag;
   CONST CHAR8 *BatteryChgPause;
diff --git a/QcomModulePkg/Library/BootLib/Board.c b/QcomModulePkg/Library/BootLib/Board.c
index 31ef3fe..9246c04 100644
--- a/QcomModulePkg/Library/BootLib/Board.c
+++ b/QcomModulePkg/Library/BootLib/Board.c
@@ -571,6 +571,24 @@
 }
 
 EFI_STATUS
+BoardHardwareRevision (CHAR8 *StrHwRevision, UINT32 Len)
+{
+
+  EFI_STATUS Status;
+
+  Status = GetOemHardwareRevision(StrHwRevision);
+  if (Status != EFI_SUCCESS) {
+    /* use fallback hardware revision and mark as success
+     * to proceed bootup */
+    AsciiSPrint (StrHwRevision, Len, "%d", 10000);
+    Status = EFI_SUCCESS;
+  }
+  DEBUG ((EFI_D_ERROR, "Got hardware revision from oem partition: %s\n", StrHwRevision));
+
+  return Status;
+}
+
+EFI_STATUS
 BoardSerialNum (CHAR8 *StrSerialNum, UINT32 Len)
 {
   EFI_STATUS Status = EFI_INVALID_PARAMETER;
diff --git a/QcomModulePkg/Library/BootLib/Recovery.c b/QcomModulePkg/Library/BootLib/Recovery.c
index 065c27c..49207bb 100644
--- a/QcomModulePkg/Library/BootLib/Recovery.c
+++ b/QcomModulePkg/Library/BootLib/Recovery.c
@@ -447,3 +447,49 @@
 
   return Status;
 }
+
+EFI_STATUS
+GetOemHardwareRevision (CHAR8 *nv_hwrevision)
+{
+  CONST CHAR8 *line_ind = "HW:";
+  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_hwrevision, 0x0, sizeof(nv_hwrevision));
+    AsciiStrnCpy((char *)nv_hwrevision, (line_ptr + strlen(line_ind)), READ_OEM_BUF_LEN);
+    for (unsigned char i = 0; i < READ_OEM_BUF_LEN; i++) {
+      if (nv_hwrevision[i] == '\r' || nv_hwrevision[i] == '\n' || nv_hwrevision[i] == ' ') {
+        nv_hwrevision[i] = '\0';
+      }
+    }
+  }
+
+  FreePool (oem_page_buffer);
+  oem_page_buffer = NULL;
+
+  return Status;
+}
diff --git a/QcomModulePkg/Library/BootLib/UpdateCmdLine.c b/QcomModulePkg/Library/BootLib/UpdateCmdLine.c
index ab88a5c..273b78d 100644
--- a/QcomModulePkg/Library/BootLib/UpdateCmdLine.c
+++ b/QcomModulePkg/Library/BootLib/UpdateCmdLine.c
@@ -57,6 +57,7 @@
 STATIC CONST CHAR8 *BatteryChgPause = " androidboot.mode=charger";
 STATIC CONST CHAR8 *MdtpActiveFlag = " mdtp";
 STATIC CONST CHAR8 *AlarmBootCmdLine = " androidboot.alarmboot=true";
+STATIC CONST CHAR8 *HardwareRevisionCmdLine = " androidboot.hardware.revision=";
 STATIC CHAR8 SystemdSlotEnv[] = " systemd.setenv=\"SLOT_SUFFIX=_a\"";
 
 /*Send slot suffix in cmdline with which we have booted*/
@@ -440,6 +441,11 @@
     Param->BootDevBuf = NULL;
   }
 
+  Src = Param->HardwareRevisionCmdLine;
+  AsciiStrCatS (Dst, MaxCmdLineLen, Src);
+  Src = Param->StrHardwareRev;
+  AsciiStrCatS (Dst, MaxCmdLineLen, Src);
+
   Src = Param->UsbSerialCmdLine;
   AsciiStrCatS (Dst, MaxCmdLineLen, Src);
   Src = Param->StrSerialNum;
@@ -572,6 +578,7 @@
   CHAR8 ChipBaseBand[CHIP_BASE_BAND_LEN];
   CHAR8 *BootDevBuf = NULL;
   BOOLEAN BatteryStatus;
+  CHAR8 StrHardwareRev[HW_REVISION_SIZE];
   CHAR8 StrSerialNum[SERIAL_NUM_SIZE];
   BOOLEAN MdtpActive = FALSE;
   UpdateCmdLineParamList Param = {0};
@@ -583,6 +590,12 @@
   UINT32 LEVerityCmdLineLen = 0;
   CHAR8 RootDevStr[BOOT_DEV_NAME_SIZE_MAX];
 
+  Status = BoardHardwareRevision (StrHardwareRev, sizeof (StrHardwareRev));
+  if (Status != EFI_SUCCESS) {
+    DEBUG((EFI_D_ERROR, "Failed to get hardware revision: %r\n", Status));
+    return Status;
+  }
+
   Status = BoardSerialNum (StrSerialNum, sizeof (StrSerialNum));
   if (Status != EFI_SUCCESS) {
     DEBUG ((EFI_D_ERROR, "Error Finding board serial num: %x\n", Status));
@@ -642,6 +655,9 @@
     }
   }
 
+  CmdLineLen += AsciiStrLen (HardwareRevisionCmdLine);
+  CmdLineLen += AsciiStrLen (StrHardwareRev);
+
   CmdLineLen += AsciiStrLen (UsbSerialCmdLine);
   CmdLineLen += AsciiStrLen (StrSerialNum);
 
@@ -748,11 +764,13 @@
   Param.CmdLineLen = CmdLineLen;
   Param.HaveCmdLine = HaveCmdLine;
   Param.PauseAtBootUp = PauseAtBootUp;
+  Param.StrHardwareRev = StrHardwareRev;
   Param.StrSerialNum = StrSerialNum;
   Param.SlotSuffixAscii = SlotSuffixAscii;
   Param.ChipBaseBand = ChipBaseBand;
   Param.DisplayCmdLine = DisplayCmdLine;
   Param.CmdLine = CmdLine;
+  Param.HardwareRevisionCmdLine = HardwareRevisionCmdLine;
   Param.AlarmBootCmdLine = AlarmBootCmdLine;
   Param.MdtpActiveFlag = MdtpActiveFlag;
   Param.BatteryChgPause = BatteryChgPause;