#include "dma_helpers.h" #include "third-party/fmt/format.h" /*! * Make sure that the DMA Transfer is a VIF unpack (copy data to VIF memory) with the given * setup. This is for a transfer with STCYCL followed by UNPACK. */ bool verify_unpack_with_stcycl(const DmaTransfer& transfer, VifCode::Kind unpack_kind, u16 cl, u16 wl, u32 qwc, u32 addr, bool usn, bool flg) { if (transfer.size_bytes != qwc * 16) { fmt::print("verify_unpack: bad size {} vs {}\n", transfer.size_bytes, qwc * 16); return false; } if (transfer.vifcode0().kind != VifCode::Kind::STCYCL) { fmt::print("verify_unpack: bad vifcode 0\n"); return false; } if (transfer.vifcode1().kind != unpack_kind) { fmt::print("verify_unpack: bad vifcode 1\n"); return false; } VifCodeStcycl stcycl(transfer.vifcode0()); VifCodeUnpack unpack(transfer.vifcode1()); if (stcycl.cl != cl || stcycl.wl != wl) { fmt::print("verify_unpack: bad cl/wl {}/{} vs {}/{}\n", stcycl.cl, stcycl.wl, cl, wl); return false; } if (unpack.addr_qw != addr || unpack.use_tops_flag != flg || unpack.is_unsigned != usn) { fmt::print("verify_unpack: bad unpack {}/{}/{} vs {}/{}/{}", unpack.addr_qw, unpack.use_tops_flag, unpack.is_unsigned, addr, flg, usn); return false; } if (transfer.vifcode1().num != qwc) { fmt::print("verify_unpack: bad num {} vs {}\n", transfer.vifcode1().num, qwc); return false; } return true; } /*! * Verify the DMA transfer is a VIF unpack (with STCYCL tag). * Then, unpack the data to dst. */ void unpack_to_stcycl(void* dst, const DmaTransfer& transfer, VifCode::Kind unpack_kind, u16 cl, u16 wl, u32 size_bytes, u32 addr, bool usn, bool flg) { bool ok = verify_unpack_with_stcycl(transfer, unpack_kind, cl, wl, size_bytes / 16, addr, usn, flg); ASSERT(ok); ASSERT((size_bytes & 0xf) == 0); memcpy(dst, transfer.data, size_bytes); } /*! * Make sure that the DMA transfer is a VIF unpack with the given setup. * This is for when there's just an UNPACK. */ bool verify_unpack_no_stcycl(const DmaTransfer& transfer, VifCode::Kind unpack_kind, u32 qwc, u32 addr, bool usn, bool flg) { if (transfer.size_bytes != qwc * 16) { fmt::print("verify_unpack: bad size {} vs {}\n", transfer.size_bytes, qwc * 16); return false; } if (transfer.vifcode0().kind != VifCode::Kind::NOP) { fmt::print("verify_unpack: bad vifcode 0\n"); return false; } if (transfer.vifcode1().kind != unpack_kind) { fmt::print("verify_unpack: bad vifcode 1\n"); return false; } VifCodeUnpack unpack(transfer.vifcode1()); if (unpack.addr_qw != addr || unpack.use_tops_flag != flg || unpack.is_unsigned != usn) { fmt::print("verify_unpack: bad unpack {}/{}/{} vs {}/{}/{}", unpack.addr_qw, unpack.use_tops_flag, unpack.is_unsigned, addr, flg, usn); return false; } if (transfer.vifcode1().num != qwc) { fmt::print("verify_unpack: bad num {} vs {}\n", transfer.vifcode1().num, qwc); return false; } return true; } /*! * Verify the DMA transfer is a VIF unpack (with no STCYCL tag). * Then, unpack the data to dst. */ void unpack_to_no_stcycl(void* dst, const DmaTransfer& transfer, VifCode::Kind unpack_kind, u32 size_bytes, u32 addr, bool usn, bool flg) { bool ok = verify_unpack_no_stcycl(transfer, unpack_kind, size_bytes / 16, addr, usn, flg); ASSERT(ok); ASSERT((size_bytes & 0xf) == 0); memcpy(dst, transfer.data, size_bytes); } void verify_mscal(const DmaTransfer& transfer, int address) { ASSERT(transfer.size_bytes == 0); ASSERT(transfer.vif0() == 0); ASSERT(transfer.vifcode1().kind == VifCode::Kind::MSCAL); ASSERT(transfer.vifcode1().immediate == address); }