mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 13:56:59 +01:00
agc: reserve driver backing before guest direct-memory allocation
This commit is contained in:
+32
-34
@@ -57,7 +57,6 @@ struct DriverDmem {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static DriverDmem g_driver_dmem;
|
static DriverDmem g_driver_dmem;
|
||||||
static int InitializeDmem();
|
|
||||||
static void ReleaseDmem();
|
static void ReleaseDmem();
|
||||||
|
|
||||||
} // namespace Gen5Driver
|
} // namespace Gen5Driver
|
||||||
@@ -82,6 +81,8 @@ void Initialize() {
|
|||||||
auto& video_out = VideoOut::VideoOutInit(width, height, presenter);
|
auto& video_out = VideoOut::VideoOutInit(width, height, presenter);
|
||||||
g_renderer = &presenter.Renderer();
|
g_renderer = &presenter.Renderer();
|
||||||
g_renderer->InitializeGpu(&video_out);
|
g_renderer->InitializeGpu(&video_out);
|
||||||
|
// Native driver module startup reserves its DMEM before the guest can allocate it.
|
||||||
|
EXIT_IF(Gen5Driver::Initialize() != OK);
|
||||||
ShaderInit();
|
ShaderInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,38 +357,6 @@ int KYTY_SYSV_ABI AgcInit(uint32_t* state, uint32_t ver) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("version = %u\n", ver);
|
printf("version = %u\n", ver);
|
||||||
std::scoped_lock lock {Gen5Driver::g_driver_dmem.mutex};
|
|
||||||
if (Gen5Driver::g_driver_dmem.physical_offset >= 0) {
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
if (const auto result = Gen5Driver::InitializeDmem(); result != OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
struct FunctionShaderBindings {
|
|
||||||
uint64_t code;
|
|
||||||
uint32_t user_data[2];
|
|
||||||
};
|
|
||||||
static_assert(sizeof(FunctionShaderBindings) == 16);
|
|
||||||
// Ordered-count queue validator, including its return to the caller.
|
|
||||||
static constexpr std::array<uint32_t, 16> validator {
|
|
||||||
0xbeeb03ff, 0x00000021, 0xb96a1818, 0xbf06106a,
|
|
||||||
0xbf800000, 0x8590807e, 0xb96a0a18, 0xbf066a80,
|
|
||||||
0xbf800000, 0x85ea807e, 0x88ea106a, 0xbf870003,
|
|
||||||
0xbefc03ff, 0x8a6ca000, 0xbf920009, 0xbefd210e,
|
|
||||||
};
|
|
||||||
const auto base = Gen5Driver::DriverDmemBase + Gen5Driver::AgcDmemOffset;
|
|
||||||
const auto function_table = base + 0x60;
|
|
||||||
const auto code_address = base + 0x100; // Shader code requires 256-byte alignment.
|
|
||||||
std::array<FunctionShaderBindings, 8> functions {};
|
|
||||||
functions[2].code = code_address;
|
|
||||||
const std::array<uint32_t, 4> descriptor {
|
|
||||||
static_cast<uint32_t>(function_table),
|
|
||||||
static_cast<uint32_t>(function_table >> 32u) | 0x00100000u,
|
|
||||||
static_cast<uint32_t>(functions.size()), 0x5204u,
|
|
||||||
};
|
|
||||||
std::memcpy(reinterpret_cast<void*>(function_table), functions.data(), sizeof(functions));
|
|
||||||
std::memcpy(reinterpret_cast<void*>(code_address), validator.data(), sizeof(validator));
|
|
||||||
std::memcpy(reinterpret_cast<void*>(base), descriptor.data(), sizeof(descriptor));
|
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@@ -4275,7 +4244,11 @@ namespace Gen5Driver {
|
|||||||
|
|
||||||
LIB_NAME("Graphics5Driver", "Graphics5Driver");
|
LIB_NAME("Graphics5Driver", "Graphics5Driver");
|
||||||
|
|
||||||
static int InitializeDmem() {
|
int Initialize() {
|
||||||
|
std::scoped_lock lock {g_driver_dmem.mutex};
|
||||||
|
if (g_driver_dmem.physical_offset >= 0) {
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
int64_t physical_offset = -1;
|
int64_t physical_offset = -1;
|
||||||
auto result = LibKernel::Memory::KernelAllocateDirectMemory(
|
auto result = LibKernel::Memory::KernelAllocateDirectMemory(
|
||||||
0, LibKernel::Memory::KernelGetDirectMemorySize(), DriverDmemSize, DriverDmemSize,
|
0, LibKernel::Memory::KernelGetDirectMemorySize(), DriverDmemSize, DriverDmemSize,
|
||||||
@@ -4292,6 +4265,31 @@ static int InitializeDmem() {
|
|||||||
}
|
}
|
||||||
EXIT_IF(reinterpret_cast<uint64_t>(address) != DriverDmemBase);
|
EXIT_IF(reinterpret_cast<uint64_t>(address) != DriverDmemBase);
|
||||||
std::memset(address, 0, DriverDmemSize);
|
std::memset(address, 0, DriverDmemSize);
|
||||||
|
struct FunctionShaderBindings {
|
||||||
|
uint64_t code;
|
||||||
|
uint32_t user_data[2];
|
||||||
|
};
|
||||||
|
static_assert(sizeof(FunctionShaderBindings) == 16);
|
||||||
|
// Ordered-count queue validator, including its return to the caller.
|
||||||
|
static constexpr std::array<uint32_t, 16> validator {
|
||||||
|
0xbeeb03ff, 0x00000021, 0xb96a1818, 0xbf06106a,
|
||||||
|
0xbf800000, 0x8590807e, 0xb96a0a18, 0xbf066a80,
|
||||||
|
0xbf800000, 0x85ea807e, 0x88ea106a, 0xbf870003,
|
||||||
|
0xbefc03ff, 0x8a6ca000, 0xbf920009, 0xbefd210e,
|
||||||
|
};
|
||||||
|
const auto base = DriverDmemBase + AgcDmemOffset;
|
||||||
|
const auto function_table = base + 0x60;
|
||||||
|
const auto code_address = base + 0x100; // Shader code requires 256-byte alignment.
|
||||||
|
std::array<FunctionShaderBindings, 8> functions {};
|
||||||
|
functions[2].code = code_address;
|
||||||
|
const std::array<uint32_t, 4> descriptor {
|
||||||
|
static_cast<uint32_t>(function_table),
|
||||||
|
static_cast<uint32_t>(function_table >> 32u) | 0x00100000u,
|
||||||
|
static_cast<uint32_t>(functions.size()), 0x5204u,
|
||||||
|
};
|
||||||
|
std::memcpy(reinterpret_cast<void*>(function_table), functions.data(), sizeof(functions));
|
||||||
|
std::memcpy(reinterpret_cast<void*>(code_address), validator.data(), sizeof(validator));
|
||||||
|
std::memcpy(reinterpret_cast<void*>(base), descriptor.data(), sizeof(descriptor));
|
||||||
g_driver_dmem.physical_offset = physical_offset;
|
g_driver_dmem.physical_offset = physical_offset;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -307,6 +307,8 @@ uint32_t* KYTY_SYSV_ABI AgcDcbSetFlip(CommandBuffer* buf, uint32_t video_out_han
|
|||||||
|
|
||||||
namespace Gen5Driver {
|
namespace Gen5Driver {
|
||||||
|
|
||||||
|
int Initialize();
|
||||||
|
|
||||||
struct Packet {
|
struct Packet {
|
||||||
uint32_t* addr;
|
uint32_t* addr;
|
||||||
uint32_t dw_num;
|
uint32_t dw_num;
|
||||||
|
|||||||
@@ -41903,9 +41903,24 @@ void CheckAgcSystemTable(RenderContext &renderer) {
|
|||||||
0xbf800000, 0x85ea807e, 0x88ea106a, 0xbf870003,
|
0xbf800000, 0x85ea807e, 0x88ea106a, 0xbf870003,
|
||||||
0xbefc03ff, 0x8a6ca000, 0xbf920009, 0xbefd210e};
|
0xbefc03ff, 0x8a6ca000, 0xbf920009, 0xbefd210e};
|
||||||
LibKernel::Memory::InstallGpuResources(&renderer);
|
LibKernel::Memory::InstallGpuResources(&renderer);
|
||||||
|
Require(name, "driver module startup", Gen5Driver::Initialize() == 0,
|
||||||
|
"driver module startup failed before guest initialization");
|
||||||
|
const auto direct_memory_size = LibKernel::Memory::KernelGetDirectMemorySize();
|
||||||
|
int64_t available_offset = -1;
|
||||||
|
size_t available_size = 0;
|
||||||
|
Require(name, "remaining direct pool",
|
||||||
|
LibKernel::Memory::KernelAvailableDirectMemorySize(
|
||||||
|
0, direct_memory_size, 0, &available_offset, &available_size) == 0 &&
|
||||||
|
available_size == direct_memory_size - 0x200000,
|
||||||
|
"driver startup did not reserve its backing in the reported direct pool");
|
||||||
|
int64_t guest_allocation = -1;
|
||||||
|
Require(name, "guest consumes remaining direct pool",
|
||||||
|
LibKernel::Memory::KernelAllocateDirectMemory(
|
||||||
|
0, direct_memory_size, available_size, 0x4000, 0, &guest_allocation) == 0,
|
||||||
|
"guest could not allocate all remaining direct memory");
|
||||||
uint32_t state = 0xabcdef01u;
|
uint32_t state = 0xabcdef01u;
|
||||||
Require(name, "driver startup", Gen5::AgcInit(&state, 13) == 0 && state == 0xabcdef01u,
|
Require(name, "driver startup", Gen5::AgcInit(&state, 13) == 0 && state == 0xabcdef01u,
|
||||||
"Agc startup failed or changed its ignored public state pointer");
|
"Agc startup required free guest memory or changed its ignored public state pointer");
|
||||||
LibKernel::Memory::VirtualQueryInfo mapping{};
|
LibKernel::Memory::VirtualQueryInfo mapping{};
|
||||||
Require(name, "shared driver backing",
|
Require(name, "shared driver backing",
|
||||||
LibKernel::Memory::KernelVirtualQuery(reinterpret_cast<void *>(driver_base), 0,
|
LibKernel::Memory::KernelVirtualQuery(reinterpret_cast<void *>(driver_base), 0,
|
||||||
@@ -41932,10 +41947,14 @@ void CheckAgcSystemTable(RenderContext &renderer) {
|
|||||||
Require(name, "default instrumentation", *instrumentation == 0,
|
Require(name, "default instrumentation", *instrumentation == 0,
|
||||||
"unused vertex validation was enabled at startup");
|
"unused vertex validation was enabled at startup");
|
||||||
*instrumentation = 0x12340000u;
|
*instrumentation = 0x12340000u;
|
||||||
Require(name, "repeat startup", Gen5::AgcInit(nullptr, 13) == 0 &&
|
Require(name, "repeat startup", Gen5Driver::Initialize() == 0 &&
|
||||||
|
Gen5::AgcInit(nullptr, 13) == 0 &&
|
||||||
*instrumentation == 0x12340000u,
|
*instrumentation == 0x12340000u,
|
||||||
"repeat Agc initialization reset existing system state");
|
"repeat Agc initialization reset existing system state");
|
||||||
*instrumentation = 0;
|
*instrumentation = 0;
|
||||||
|
Require(name, "release guest allocation",
|
||||||
|
LibKernel::Memory::KernelCheckedReleaseDirectMemory(guest_allocation, available_size) == 0,
|
||||||
|
"guest allocation release failed");
|
||||||
LibKernel::Memory::InstallGpuResources(nullptr);
|
LibKernel::Memory::InstallGpuResources(nullptr);
|
||||||
std::printf("[host] %-32s ok\n", name);
|
std::printf("[host] %-32s ok\n", name);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user