Просмотр исходного кода

nvdrv: Change InitializeEx to AllocAsEx

Wee also report the correct "big page size" now in GetVARegions & fix up the struct for IoctlAllocAsEx
Chloe Marcec 5 лет назад
Родитель
Сommit
875183e7c5

+ 33 - 16
src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp

@@ -39,7 +39,7 @@ NvResult nvhost_as_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input,
         case 0x8:
             return GetVARegions(input, output);
         case 0x9:
-            return InitalizeEx(input, output);
+            return AllocAsEx(input, output);
         case 0x14:
             return Remap(input, output);
         default:
@@ -78,11 +78,16 @@ NvResult nvhost_as_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input, std:
     return NvResult::NotImplemented;
 }
 
-NvResult nvhost_as_gpu::InitalizeEx(const std::vector<u8>& input, std::vector<u8>& output) {
-    IoctlInitalizeEx params{};
+NvResult nvhost_as_gpu::AllocAsEx(const std::vector<u8>& input, std::vector<u8>& output) {
+    IoctlAllocAsEx params{};
     std::memcpy(&params, input.data(), input.size());
 
     LOG_WARNING(Service_NVDRV, "(STUBBED) called, big_page_size=0x{:X}", params.big_page_size);
+    if (params.big_page_size == 0) {
+        params.big_page_size = DEFAULT_BIG_PAGE_SIZE;
+    }
+
+    big_page_size = params.big_page_size;
 
     return NvResult::Success;
 }
@@ -276,13 +281,18 @@ NvResult nvhost_as_gpu::GetVARegions(const std::vector<u8>& input, std::vector<u
                 params.buf_size);
 
     params.buf_size = 0x30;
-    params.regions[0].offset = 0x04000000;
-    params.regions[0].page_size = 0x1000;
-    params.regions[0].pages = 0x3fbfff;
 
-    params.regions[1].offset = 0x04000000;
-    params.regions[1].page_size = 0x10000;
-    params.regions[1].pages = 0x1bffff;
+    params.small = IoctlVaRegion{
+        .offset = 0x04000000,
+        .page_size = DEFAULT_SMALL_PAGE_SIZE,
+        .pages = 0x3fbfff,
+    };
+
+    params.big = IoctlVaRegion{
+        .offset = 0x04000000,
+        .page_size = big_page_size,
+        .pages = 0x1bffff,
+    };
 
     // TODO(ogniK): This probably can stay stubbed but should add support way way later
 
@@ -299,18 +309,25 @@ NvResult nvhost_as_gpu::GetVARegions(const std::vector<u8>& input, std::vector<u
                 params.buf_size);
 
     params.buf_size = 0x30;
-    params.regions[0].offset = 0x04000000;
-    params.regions[0].page_size = 0x1000;
-    params.regions[0].pages = 0x3fbfff;
 
-    params.regions[1].offset = 0x04000000;
-    params.regions[1].page_size = 0x10000;
-    params.regions[1].pages = 0x1bffff;
+    params.small = IoctlVaRegion{
+        .offset = 0x04000000,
+        .page_size = 0x1000,
+        .pages = 0x3fbfff,
+    };
+
+    params.big = IoctlVaRegion{
+        .offset = 0x04000000,
+        .page_size = big_page_size,
+        .pages = 0x1bffff,
+    };
 
     // TODO(ogniK): This probably can stay stubbed but should add support way way later
 
     std::memcpy(output.data(), &params, output.size());
-    std::memcpy(inline_output.data(), &params.regions, inline_output.size());
+    std::memcpy(inline_output.data(), &params.small, sizeof(IoctlVaRegion));
+    std::memcpy(inline_output.data() + sizeof(IoctlVaRegion), &params.big, sizeof(IoctlVaRegion));
+
     return NvResult::Success;
 }
 

+ 16 - 11
src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h

@@ -16,6 +16,9 @@
 
 namespace Service::Nvidia::Devices {
 
+constexpr u32 DEFAULT_BIG_PAGE_SIZE = 1 << 16;
+constexpr u32 DEFAULT_SMALL_PAGE_SIZE = 1 << 12;
+
 class nvmap;
 
 enum class AddressSpaceFlags : u32 {
@@ -76,16 +79,16 @@ private:
         bool is_allocated{};
     };
 
-    struct IoctlInitalizeEx {
-        u32_le big_page_size{}; // depends on GPU's available_big_page_sizes; 0=default
-        s32_le as_fd{};         // ignored; passes 0
-        u32_le flags{};         // passes 0
-        u32_le reserved{};      // ignored; passes 0
-        u64_le unk0{};
-        u64_le unk1{};
-        u64_le unk2{};
+    struct IoctlAllocAsEx {
+        u32_le flags{}; // usually passes 1
+        s32_le as_fd{}; // ignored; passes 0
+        u32_le big_page_size{};
+        u32_le reserved{}; // ignored; passes 0
+        u64_le va_range_start{};
+        u64_le va_range_end{};
+        u64_le va_range_split{};
     };
-    static_assert(sizeof(IoctlInitalizeEx) == 40, "IoctlInitalizeEx is incorrect size");
+    static_assert(sizeof(IoctlAllocAsEx) == 40, "IoctlAllocAsEx is incorrect size");
 
     struct IoctlAllocSpace {
         u32_le pages{};
@@ -149,14 +152,16 @@ private:
         u64_le buf_addr{}; // (contained output user ptr on linux, ignored)
         u32_le buf_size{}; // forced to 2*sizeof(struct va_region)
         u32_le reserved{};
-        IoctlVaRegion regions[2]{};
+        IoctlVaRegion small{};
+        IoctlVaRegion big{};
     };
     static_assert(sizeof(IoctlGetVaRegions) == 16 + sizeof(IoctlVaRegion) * 2,
                   "IoctlGetVaRegions is incorrect size");
 
     s32 channel{};
+    u32 big_page_size{DEFAULT_BIG_PAGE_SIZE};
 
-    NvResult InitalizeEx(const std::vector<u8>& input, std::vector<u8>& output);
+    NvResult AllocAsEx(const std::vector<u8>& input, std::vector<u8>& output);
     NvResult AllocateSpace(const std::vector<u8>& input, std::vector<u8>& output);
     NvResult Remap(const std::vector<u8>& input, std::vector<u8>& output);
     NvResult MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);