transfer_memory.cpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // Copyright 2019 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include "core/hle/kernel/errors.h"
  5. #include "core/hle/kernel/kernel.h"
  6. #include "core/hle/kernel/process.h"
  7. #include "core/hle/kernel/shared_memory.h"
  8. #include "core/hle/kernel/transfer_memory.h"
  9. #include "core/hle/result.h"
  10. namespace Kernel {
  11. TransferMemory::TransferMemory(KernelCore& kernel) : Object{kernel} {}
  12. TransferMemory::~TransferMemory() = default;
  13. SharedPtr<TransferMemory> TransferMemory::Create(KernelCore& kernel, VAddr base_address, u64 size,
  14. MemoryPermission permissions) {
  15. SharedPtr<TransferMemory> transfer_memory{new TransferMemory(kernel)};
  16. transfer_memory->base_address = base_address;
  17. transfer_memory->memory_size = size;
  18. transfer_memory->owner_permissions = permissions;
  19. transfer_memory->owner_process = kernel.CurrentProcess();
  20. return transfer_memory;
  21. }
  22. const u8* TransferMemory::GetPointer() const {
  23. return backing_block.get()->data();
  24. }
  25. u64 TransferMemory::GetSize() const {
  26. return memory_size;
  27. }
  28. ResultCode TransferMemory::MapMemory(VAddr address, u64 size, MemoryPermission permissions) {
  29. if (memory_size != size) {
  30. return ERR_INVALID_SIZE;
  31. }
  32. if (owner_permissions != permissions) {
  33. return ERR_INVALID_STATE;
  34. }
  35. if (is_mapped) {
  36. return ERR_INVALID_STATE;
  37. }
  38. backing_block = std::make_shared<PhysicalMemory>(size);
  39. const auto map_state = owner_permissions == MemoryPermission::None
  40. ? MemoryState::TransferMemoryIsolated
  41. : MemoryState::TransferMemory;
  42. auto& vm_manager = owner_process->VMManager();
  43. const auto map_result = vm_manager.MapMemoryBlock(address, backing_block, 0, size, map_state);
  44. if (map_result.Failed()) {
  45. return map_result.Code();
  46. }
  47. is_mapped = true;
  48. return RESULT_SUCCESS;
  49. }
  50. ResultCode TransferMemory::UnmapMemory(VAddr address, u64 size) {
  51. if (memory_size != size) {
  52. return ERR_INVALID_SIZE;
  53. }
  54. auto& vm_manager = owner_process->VMManager();
  55. const auto result = vm_manager.UnmapRange(address, size);
  56. if (result.IsError()) {
  57. return result;
  58. }
  59. is_mapped = false;
  60. return RESULT_SUCCESS;
  61. }
  62. } // namespace Kernel