diff --git a/core/libs/prx/libSceAgcDriver/Execution/src/Pm4.cpp b/core/libs/prx/libSceAgcDriver/Execution/src/Pm4.cpp index 9dfdfad7b..4b72ec3c5 100644 --- a/core/libs/prx/libSceAgcDriver/Execution/src/Pm4.cpp +++ b/core/libs/prx/libSceAgcDriver/Execution/src/Pm4.cpp @@ -196,6 +196,7 @@ std::string_view UnsupportedReason(std::uint32_t header) { constexpr std::uint32_t DmaSourceCachePolicy = 3u << 13u; constexpr std::uint32_t DmaDestinationCachePolicy = 3u << 25u; +constexpr std::uint32_t WriteDataCachePolicy = 3u << 25u; void Validate(std::span packet, std::uint32_t queue) { require(!packet.empty(), "truncated PM4 header"); @@ -380,7 +381,7 @@ void Validate(std::span packet, std::uint32_t queue) { break; case 0x37: { require(packet.size() >= 5, "WRITE_DATA has no data"); - require((packet[1] & ~0x40110f00u) == 0, "WRITE_DATA engine, cache or reserved fields are not implemented"); + require((packet[1] & ~(0x40110f00u | WriteDataCachePolicy)) == 0, "WRITE_DATA engine or reserved fields are not implemented"); const auto destination = (packet[1] >> 8u) & 0xfu; require(destination == 1 || destination == 2 || (queue != 0 && destination == 5), "WRITE_DATA register or GDS destination is not implemented"); require((packet[2] & 3u) == 0, "misaligned WRITE_DATA destination"); diff --git a/core/libs/prx/libSceAgcDriver/tests/Pm4.cpp b/core/libs/prx/libSceAgcDriver/tests/Pm4.cpp index 4c559fc5f..9195aa78c 100644 --- a/core/libs/prx/libSceAgcDriver/tests/Pm4.cpp +++ b/core/libs/prx/libSceAgcDriver/tests/Pm4.cpp @@ -290,6 +290,9 @@ void testMemory() { check(data[0] == 22 && data[1] == 12, "WRITE_DATA fixed destination failed"); execute(state, makePacket(0x37, {0x40000100, low(data.data()), high(data.data()), 41, 42})); check(data[0] == 41 && data[1] == 42, "WRITE_DATA from the PFP failed"); + execute(state, makePacket(0x37, {0x04100200, low(data.data()), high(data.data()), 61, 62})); + check(data[0] == 61 && data[1] == 62, "WRITE_DATA with a cache policy failed"); + expectFailure([&] { AgcDriver::Pm4::Validate(makePacket(0x37, {0x08000100, low(data.data()), high(data.data()), 71}), 0); }, "reserved"); expectFailure([&] { AgcDriver::Pm4::Validate(makePacket(0x37, {0x80000100, low(data.data()), high(data.data()), 51}), 0); }, "engine"); execute(state, makePacket(0x81, {4, 31, 32})); execute(state, makePacket(0x83, {4, 2, low(data.data()), high(data.data())}));