public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Etienne Carriere" <etienne.carriere@linaro.org>
To: devel@edk2.groups.io
Cc: Etienne Carriere <etienne.carriere@linaro.org>
Subject: [PATCH 3/5] GenGv: Arm: support images entered in Thumb mode
Date: Sun, 14 Mar 2021 21:06:26 +0100	[thread overview]
Message-ID: <c9fad981b16eca5c709b7ca472129e99cc56b055.1615752383.git.etienne.carriere@linaro.org> (raw)
In-Reply-To: <5a0fdcf767151d786afd8d14bff57cf6fdb8fefc.1615752383.git.etienne.carriere@linaro.org>
In-Reply-To: <5a0fdcf767151d786afd8d14bff57cf6fdb8fefc.1615752383.git.etienne.carriere@linaro.org>

Change GenFv for Arm architecture to generate a specific jump
instruction as image entry instruction when the target entry label
is assembled with Thumb instruction set. This is possible since
SecCoreEntryAddress value fetched from the PE32 as its LSBit set when
the entry instruction executes in Thumb mode.

Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
---
 BaseTools/Source/C/GenFv/GenFvInternalLib.c | 39 ++++++++++++++++-----
 1 file changed, 30 insertions(+), 9 deletions(-)

diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
index 6e296b8ad6..1b12cb9165 100644
--- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c
+++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
@@ -34,9 +34,28 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include "FvLib.h"
 #include "PeCoffLib.h"
 
-#define ARMT_UNCONDITIONAL_JUMP_INSTRUCTION       0xEB000000
 #define ARM64_UNCONDITIONAL_JUMP_INSTRUCTION      0x14000000
 
+//
+// Arm instruction to jump to Fv enry instruction in Arm or Thumb mode.
+// From ARM Arch Ref Manual versions b/c/d, section A8.8.25 BL, BLX (immediate)
+// BLX (encoding A2) branches to offset in Thumb instruction set mode.
+// BL (encoding A1) branches to offset in Arm instruction set mode.
+//
+#define ARM_JUMP_OFFSET_MAX             0xffffff
+#define ARM_JUMP_TO_ARM(Offset)         (0xeb000000 | ((Offset - 8) >> 2))
+
+#define _ARM_JUMP_TO_THUMB(Imm32)       (0xfa000000 | \
+                                         (((Imm32) & (1 << 1)) << (24 - 1)) | \
+                                         (((Imm32) >> 2) & 0x7fffff))
+#define ARM_JUMP_TO_THUMB(Offset)       _ARM_JUMP_TO_THUMB((Offset) - 8)
+
+//
+// Arm instruction to retrun from exception (MOVS PC, LR)
+//
+#define ARM_RETURN_FROM_EXCEPTION       0xE1B0F07E
+
+
 BOOLEAN mArm = FALSE;
 BOOLEAN mRiscV = FALSE;
 STATIC UINT32   MaxFfsAlignment = 0;
@@ -2203,23 +2222,25 @@ Returns:
     // if we found an SEC core entry point then generate a branch instruction
     // to it and populate a debugger SWI entry as well
     if (UpdateVectorSec) {
+      UINT32                    EntryOffset;
 
       VerboseMsg("UpdateArmResetVectorIfNeeded updating ARM SEC vector");
 
-      // B SecEntryPoint - signed_immed_24 part +/-32MB offset
-      // on ARM, the PC is always 8 ahead, so we're not really jumping from the base address, but from base address + 8
-      ResetVector[0] = (INT32)(SecCoreEntryAddress - FvInfo->BaseAddress - 8) >> 2;
+      EntryOffset = (INT32)(SecCoreEntryAddress - FvInfo->BaseAddress);
 
-      if (ResetVector[0] > 0x00FFFFFF) {
-        Error(NULL, 0, 3000, "Invalid", "SEC Entry point must be within 32MB of the start of the FV");
+      if (EntryOffset > ARM_JUMP_OFFSET_MAX) {
+          Error(NULL, 0, 3000, "Invalid", "SEC Entry point offset above 1MB of the start of the FV");
         return EFI_ABORTED;
       }
 
-      // Add opcode for an unconditional branch with no link. i.e.: " B SecEntryPoint"
-      ResetVector[0] |= ARMT_UNCONDITIONAL_JUMP_INSTRUCTION;
+      if (SecCoreEntryAddress & 1) {
+        ResetVector[0] = ARM_JUMP_TO_THUMB(EntryOffset);
+      } else {
+        ResetVector[0] = ARM_JUMP_TO_ARM(EntryOffset);
+      }
 
       // SWI handler movs   pc,lr. Just in case a debugger uses SWI
-      ResetVector[2] = 0xE1B0F07E;
+      ResetVector[2] = ARM_RETURN_FROM_EXCEPTION;
 
       // Place holder to support a common interrupt handler from ROM.
       // Currently not supported. For this to be used the reset vector would not be in this FV
-- 
2.17.1


  parent reply	other threads:[~2021-03-14 20:06 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-14 20:06 [PATCH 1/5] ArmPkg/IndustryStandard: 32b/64b agnostic FF-A and Mm SVC IDs Etienne Carriere
2021-03-14 20:06 ` [PATCH 2/5] ArmPkg: prepare 32bit ARM build of StandaloneMmPkg Etienne Carriere
2021-03-14 20:06 ` Etienne Carriere [this message]
2021-03-14 20:06 ` [PATCH 4/5] StandaloneMmPkg: fix pointer/int casts against 32bit architectures Etienne Carriere
2021-03-14 20:06 ` [PATCH 5/5] StandaloneMmPkg: build for 32bit arm machines Etienne Carriere
  -- strict thread matches above, loose matches on Subject: below --
2021-05-04 15:20 [PATCH 0/5] Arm 32bit support in StandaloveMm Etienne Carriere
2021-05-04 15:20 ` [PATCH 3/5] GenGv: Arm: support images entered in Thumb mode Etienne Carriere
2021-05-10 15:54   ` Ard Biesheuvel
2021-05-11 19:13   ` Sami Mujawar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c9fad981b16eca5c709b7ca472129e99cc56b055.1615752383.git.etienne.carriere@linaro.org \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox