Writes UINTN data to memory address. This routine is called by the EBC data movement instructions that write to memory. Since these writes may be to the stack, which looks like (high address on top) this, [EBC entry point arguments] [VM stack] [EBC stack] we need to detect all attempts to write to the EBC entry point argument stack area and adjust the address (which w
| 4866 | |
| 4867 | **/ |
| 4868 | EFI_STATUS |
| 4869 | VmWriteMemN ( |
| 4870 | IN VM_CONTEXT *VmPtr, |
| 4871 | IN UINTN Addr, |
| 4872 | IN UINTN Data |
| 4873 | ) |
| 4874 | { |
| 4875 | EFI_STATUS Status; |
| 4876 | UINTN Index; |
| 4877 | |
| 4878 | Status = EFI_SUCCESS; |
| 4879 | |
| 4880 | // |
| 4881 | // Convert the address if it's in the stack gap |
| 4882 | // |
| 4883 | Addr = ConvertStackAddr (VmPtr, Addr); |
| 4884 | |
| 4885 | // |
| 4886 | // Do a simple write if aligned |
| 4887 | // |
| 4888 | if (IS_ALIGNED (Addr, sizeof (UINTN))) { |
| 4889 | *(UINTN *) Addr = Data; |
| 4890 | } else { |
| 4891 | for (Index = 0; Index < sizeof (UINTN) / sizeof (UINT32); Index++) { |
| 4892 | MemoryFence (); |
| 4893 | Status = VmWriteMem32 (VmPtr, Addr + Index * sizeof (UINT32), (UINT32) Data); |
| 4894 | MemoryFence (); |
| 4895 | Data = (UINTN) RShiftU64 ((UINT64)Data, 32); |
| 4896 | } |
| 4897 | } |
| 4898 | |
| 4899 | return Status; |
| 4900 | } |
| 4901 | |
| 4902 | |
| 4903 | /** |
no test coverage detected