UINTN Bytes;\r
UINT64 *Register;\r
UINT8 OpCode, SignByte;\r
+ UINTN Address;\r
\r
Bytes = 0;\r
\r
}\r
break;\r
\r
+ //\r
+ // MMIO write (MOV moffsetX, aX)\r
+ //\r
+ case 0xA2:\r
+ Bytes = 1;\r
+ //\r
+ // fall through\r
+ //\r
+ case 0xA3:\r
+ Bytes = ((Bytes != 0) ? Bytes :\r
+ (InstructionData->DataSize == Size16Bits) ? 2 :\r
+ (InstructionData->DataSize == Size32Bits) ? 4 :\r
+ (InstructionData->DataSize == Size64Bits) ? 8 :\r
+ 0);\r
+\r
+ InstructionData->ImmediateSize = (UINTN) (1 << InstructionData->AddrSize);\r
+ InstructionData->End += InstructionData->ImmediateSize;\r
+\r
+ //\r
+ // This code is X64 only, so a possible 8-byte copy to a UINTN is ok.\r
+ // Use a STATIC_ASSERT to be certain the code is being built as X64.\r
+ //\r
+ STATIC_ASSERT (\r
+ sizeof (UINTN) == sizeof (UINT64),\r
+ "sizeof (UINTN) != sizeof (UINT64), this file must be built as X64"\r
+ );\r
+\r
+ Address = 0;\r
+ CopyMem (\r
+ &Address,\r
+ InstructionData->Immediate,\r
+ InstructionData->ImmediateSize\r
+ );\r
+\r
+ Status = ValidateMmioMemory (Ghcb, Address, Bytes);\r
+ if (Status != 0) {\r
+ return Status;\r
+ }\r
+\r
+ ExitInfo1 = Address;\r
+ ExitInfo2 = Bytes;\r
+ CopyMem (Ghcb->SharedBuffer, &Regs->Rax, Bytes);\r
+\r
+ Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;\r
+ VmgSetOffsetValid (Ghcb, GhcbSwScratch);\r
+ Status = VmgExit (Ghcb, SVM_EXIT_MMIO_WRITE, ExitInfo1, ExitInfo2);\r
+ if (Status != 0) {\r
+ return Status;\r
+ }\r
+ break;\r
+\r
//\r
// MMIO write (MOV reg/memX, immX)\r
//\r
CopyMem (Register, Ghcb->SharedBuffer, Bytes);\r
break;\r
\r
+ //\r
+ // MMIO read (MOV aX, moffsetX)\r
+ //\r
+ case 0xA0:\r
+ Bytes = 1;\r
+ //\r
+ // fall through\r
+ //\r
+ case 0xA1:\r
+ Bytes = ((Bytes != 0) ? Bytes :\r
+ (InstructionData->DataSize == Size16Bits) ? 2 :\r
+ (InstructionData->DataSize == Size32Bits) ? 4 :\r
+ (InstructionData->DataSize == Size64Bits) ? 8 :\r
+ 0);\r
+\r
+ InstructionData->ImmediateSize = (UINTN) (1 << InstructionData->AddrSize);\r
+ InstructionData->End += InstructionData->ImmediateSize;\r
+\r
+ //\r
+ // This code is X64 only, so a possible 8-byte copy to a UINTN is ok.\r
+ // Use a STATIC_ASSERT to be certain the code is being built as X64.\r
+ //\r
+ STATIC_ASSERT (\r
+ sizeof (UINTN) == sizeof (UINT64),\r
+ "sizeof (UINTN) != sizeof (UINT64), this file must be built as X64"\r
+ );\r
+\r
+ Address = 0;\r
+ CopyMem (\r
+ &Address,\r
+ InstructionData->Immediate,\r
+ InstructionData->ImmediateSize\r
+ );\r
+\r
+ Status = ValidateMmioMemory (Ghcb, Address, Bytes);\r
+ if (Status != 0) {\r
+ return Status;\r
+ }\r
+\r
+ ExitInfo1 = Address;\r
+ ExitInfo2 = Bytes;\r
+\r
+ Ghcb->SaveArea.SwScratch = (UINT64) Ghcb->SharedBuffer;\r
+ VmgSetOffsetValid (Ghcb, GhcbSwScratch);\r
+ Status = VmgExit (Ghcb, SVM_EXIT_MMIO_READ, ExitInfo1, ExitInfo2);\r
+ if (Status != 0) {\r
+ return Status;\r
+ }\r
+\r
+ if (Bytes == 4) {\r
+ //\r
+ // Zero-extend for 32-bit operation\r
+ //\r
+ Regs->Rax = 0;\r
+ }\r
+ CopyMem (&Regs->Rax, Ghcb->SharedBuffer, Bytes);\r
+ break;\r
+\r
//\r
// MMIO read w/ zero-extension ((MOVZX regX, reg/memX)\r
//\r
break;\r
\r
default:\r
+ DEBUG ((DEBUG_ERROR, "Invalid MMIO opcode (%x)\n", OpCode));\r
Status = GP_EXCEPTION;\r
ASSERT (FALSE);\r
}\r