Allow a fixup to be used to deposit a field in a machine-code
instruction. The option shift and length fixup fields indicate the
field being deposited by the fixup.

Signed-off-by: Peter Crosthwaite <peter.crosthwa...@xilinx.com>
---

 hw/arm/boot.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 1241761..840f5da 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -41,6 +41,8 @@ typedef enum {
 typedef struct ARMInsnFixup {
     uint32_t insn;
     FixupType fixup;
+    int shift;
+    int length;
 } ARMInsnFixup;
 
 static const ARMInsnFixup bootloader_aarch64[] = {
@@ -125,6 +127,10 @@ static void write_bootloader(const char *name, hwaddr addr,
     for (i = 0; i < len; i++) {
         uint32_t insn = insns[i].insn;
         FixupType fixup = insns[i].fixup;
+        int shift = insns[i].shift;
+        int length = insns[i].length ? insns[i].length : 32;
+
+        assert(shift + length <= 32);
 
         switch (fixup) {
         case FIXUP_NONE:
@@ -135,7 +141,7 @@ static void write_bootloader(const char *name, hwaddr addr,
         case FIXUP_GIC_CPU_IF:
         case FIXUP_BOOTREG:
         case FIXUP_DSB:
-            insn = fixupcontext[fixup];
+            insn = deposit32(insn, shift, length, fixupcontext[fixup]);
             break;
         default:
             abort();
-- 
2.0.1.1.gfbfc394


Reply via email to