mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 21:37:52 -07:00
Merge pull request #7253 from booto/fifo_reg
CP: some bits in some of the HI registers cannot be set
This commit is contained in:
commit
6a22f1b3e0
@ -140,52 +140,63 @@ void Init()
|
|||||||
|
|
||||||
void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
{
|
{
|
||||||
|
constexpr u16 WMASK_NONE = 0x0000;
|
||||||
|
constexpr u16 WMASK_ALL = 0xffff;
|
||||||
|
constexpr u16 WMASK_LO_ALIGN_32BIT = 0xffe0;
|
||||||
|
const u16 WMASK_HI_RESTRICT = SConfig::GetInstance().bWii ? 0x1fff : 0x03ff;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
u32 addr;
|
u32 addr;
|
||||||
u16* ptr;
|
u16* ptr;
|
||||||
bool readonly;
|
bool readonly;
|
||||||
bool writes_align_to_32_bytes;
|
// FIFO mmio regs in the range [cc000020-cc00003e] have certain bits that always read as 0
|
||||||
|
// For _LO registers in this range, only bits 0xffe0 can be set
|
||||||
|
// For _HI registers in this range, only bits 0x03ff can be set on GCN and 0x1fff on Wii
|
||||||
|
u16 wmask;
|
||||||
} directly_mapped_vars[] = {
|
} directly_mapped_vars[] = {
|
||||||
{FIFO_TOKEN_REGISTER, &m_tokenReg},
|
{FIFO_TOKEN_REGISTER, &m_tokenReg, false, WMASK_ALL},
|
||||||
|
|
||||||
// Bounding box registers are read only.
|
// Bounding box registers are read only.
|
||||||
{FIFO_BOUNDING_BOX_LEFT, &m_bboxleft, true},
|
{FIFO_BOUNDING_BOX_LEFT, &m_bboxleft, true, WMASK_NONE},
|
||||||
{FIFO_BOUNDING_BOX_RIGHT, &m_bboxright, true},
|
{FIFO_BOUNDING_BOX_RIGHT, &m_bboxright, true, WMASK_NONE},
|
||||||
{FIFO_BOUNDING_BOX_TOP, &m_bboxtop, true},
|
{FIFO_BOUNDING_BOX_TOP, &m_bboxtop, true, WMASK_NONE},
|
||||||
{FIFO_BOUNDING_BOX_BOTTOM, &m_bboxbottom, true},
|
{FIFO_BOUNDING_BOX_BOTTOM, &m_bboxbottom, true, WMASK_NONE},
|
||||||
|
{FIFO_BASE_LO, MMIO::Utils::LowPart(&fifo.CPBase), false, WMASK_LO_ALIGN_32BIT},
|
||||||
// Some FIFO addresses need to be aligned on 32 bytes on write - only
|
{FIFO_BASE_HI, MMIO::Utils::HighPart(&fifo.CPBase), false, WMASK_HI_RESTRICT},
|
||||||
// the high part can be written directly without a mask.
|
{FIFO_END_LO, MMIO::Utils::LowPart(&fifo.CPEnd), false, WMASK_LO_ALIGN_32BIT},
|
||||||
{FIFO_BASE_LO, MMIO::Utils::LowPart(&fifo.CPBase), false, true},
|
{FIFO_END_HI, MMIO::Utils::HighPart(&fifo.CPEnd), false, WMASK_HI_RESTRICT},
|
||||||
{FIFO_BASE_HI, MMIO::Utils::HighPart(&fifo.CPBase)},
|
{FIFO_HI_WATERMARK_LO, MMIO::Utils::LowPart(&fifo.CPHiWatermark), false,
|
||||||
{FIFO_END_LO, MMIO::Utils::LowPart(&fifo.CPEnd), false, true},
|
WMASK_LO_ALIGN_32BIT},
|
||||||
{FIFO_END_HI, MMIO::Utils::HighPart(&fifo.CPEnd)},
|
{FIFO_HI_WATERMARK_HI, MMIO::Utils::HighPart(&fifo.CPHiWatermark), false, WMASK_HI_RESTRICT},
|
||||||
{FIFO_HI_WATERMARK_LO, MMIO::Utils::LowPart(&fifo.CPHiWatermark)},
|
{FIFO_LO_WATERMARK_LO, MMIO::Utils::LowPart(&fifo.CPLoWatermark), false,
|
||||||
{FIFO_HI_WATERMARK_HI, MMIO::Utils::HighPart(&fifo.CPHiWatermark)},
|
WMASK_LO_ALIGN_32BIT},
|
||||||
{FIFO_LO_WATERMARK_LO, MMIO::Utils::LowPart(&fifo.CPLoWatermark)},
|
{FIFO_LO_WATERMARK_HI, MMIO::Utils::HighPart(&fifo.CPLoWatermark), false, WMASK_HI_RESTRICT},
|
||||||
{FIFO_LO_WATERMARK_HI, MMIO::Utils::HighPart(&fifo.CPLoWatermark)},
|
|
||||||
// FIFO_RW_DISTANCE has some complex read code different for
|
// FIFO_RW_DISTANCE has some complex read code different for
|
||||||
// single/dual core.
|
// single/dual core.
|
||||||
{FIFO_WRITE_POINTER_LO, MMIO::Utils::LowPart(&fifo.CPWritePointer), false, true},
|
{FIFO_WRITE_POINTER_LO, MMIO::Utils::LowPart(&fifo.CPWritePointer), false,
|
||||||
{FIFO_WRITE_POINTER_HI, MMIO::Utils::HighPart(&fifo.CPWritePointer)},
|
WMASK_LO_ALIGN_32BIT},
|
||||||
|
{FIFO_WRITE_POINTER_HI, MMIO::Utils::HighPart(&fifo.CPWritePointer), false,
|
||||||
|
WMASK_HI_RESTRICT},
|
||||||
// FIFO_READ_POINTER has different code for single/dual core.
|
// FIFO_READ_POINTER has different code for single/dual core.
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto& mapped_var : directly_mapped_vars)
|
for (auto& mapped_var : directly_mapped_vars)
|
||||||
{
|
{
|
||||||
u16 wmask = mapped_var.writes_align_to_32_bytes ? 0xFFE0 : 0xFFFF;
|
|
||||||
mmio->Register(base | mapped_var.addr, MMIO::DirectRead<u16>(mapped_var.ptr),
|
mmio->Register(base | mapped_var.addr, MMIO::DirectRead<u16>(mapped_var.ptr),
|
||||||
mapped_var.readonly ? MMIO::InvalidWrite<u16>() :
|
mapped_var.readonly ? MMIO::InvalidWrite<u16>() :
|
||||||
MMIO::DirectWrite<u16>(mapped_var.ptr, wmask));
|
MMIO::DirectWrite<u16>(mapped_var.ptr, mapped_var.wmask));
|
||||||
}
|
}
|
||||||
|
|
||||||
mmio->Register(
|
mmio->Register(base | FIFO_BP_LO, MMIO::DirectRead<u16>(MMIO::Utils::LowPart(&fifo.CPBreakpoint)),
|
||||||
base | FIFO_BP_LO, MMIO::DirectRead<u16>(MMIO::Utils::LowPart(&fifo.CPBreakpoint)),
|
MMIO::ComplexWrite<u16>([WMASK_LO_ALIGN_32BIT](u32, u16 val) {
|
||||||
MMIO::ComplexWrite<u16>([](u32, u16 val) { WriteLow(fifo.CPBreakpoint, val & 0xffe0); }));
|
WriteLow(fifo.CPBreakpoint, val & WMASK_LO_ALIGN_32BIT);
|
||||||
|
}));
|
||||||
mmio->Register(base | FIFO_BP_HI,
|
mmio->Register(base | FIFO_BP_HI,
|
||||||
MMIO::DirectRead<u16>(MMIO::Utils::HighPart(&fifo.CPBreakpoint)),
|
MMIO::DirectRead<u16>(MMIO::Utils::HighPart(&fifo.CPBreakpoint)),
|
||||||
MMIO::ComplexWrite<u16>([](u32, u16 val) { WriteHigh(fifo.CPBreakpoint, val); }));
|
MMIO::ComplexWrite<u16>([WMASK_HI_RESTRICT](u32, u16 val) {
|
||||||
|
WriteHigh(fifo.CPBreakpoint, val & WMASK_HI_RESTRICT);
|
||||||
|
}));
|
||||||
|
|
||||||
// Timing and metrics MMIOs are stubbed with fixed values.
|
// Timing and metrics MMIOs are stubbed with fixed values.
|
||||||
struct
|
struct
|
||||||
@ -250,7 +261,8 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
|||||||
fifo.CPBase + 32);
|
fifo.CPBase + 32);
|
||||||
}) :
|
}) :
|
||||||
MMIO::DirectRead<u16>(MMIO::Utils::LowPart(&fifo.CPReadWriteDistance)),
|
MMIO::DirectRead<u16>(MMIO::Utils::LowPart(&fifo.CPReadWriteDistance)),
|
||||||
MMIO::DirectWrite<u16>(MMIO::Utils::LowPart(&fifo.CPReadWriteDistance), 0xFFE0));
|
MMIO::DirectWrite<u16>(MMIO::Utils::LowPart(&fifo.CPReadWriteDistance),
|
||||||
|
WMASK_LO_ALIGN_32BIT));
|
||||||
mmio->Register(base | FIFO_RW_DISTANCE_HI,
|
mmio->Register(base | FIFO_RW_DISTANCE_HI,
|
||||||
IsOnThread() ?
|
IsOnThread() ?
|
||||||
MMIO::ComplexRead<u16>([](u32) {
|
MMIO::ComplexRead<u16>([](u32) {
|
||||||
@ -261,8 +273,8 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
|||||||
fifo.CPBase + 32);
|
fifo.CPBase + 32);
|
||||||
}) :
|
}) :
|
||||||
MMIO::DirectRead<u16>(MMIO::Utils::HighPart(&fifo.CPReadWriteDistance)),
|
MMIO::DirectRead<u16>(MMIO::Utils::HighPart(&fifo.CPReadWriteDistance)),
|
||||||
MMIO::ComplexWrite<u16>([](u32, u16 val) {
|
MMIO::ComplexWrite<u16>([WMASK_HI_RESTRICT](u32, u16 val) {
|
||||||
WriteHigh(fifo.CPReadWriteDistance, val);
|
WriteHigh(fifo.CPReadWriteDistance, val & WMASK_HI_RESTRICT);
|
||||||
Fifo::SyncGPU(Fifo::SyncGPUReason::Other);
|
Fifo::SyncGPU(Fifo::SyncGPUReason::Other);
|
||||||
if (fifo.CPReadWriteDistance == 0)
|
if (fifo.CPReadWriteDistance == 0)
|
||||||
{
|
{
|
||||||
@ -275,20 +287,21 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
|||||||
}
|
}
|
||||||
Fifo::RunGpu();
|
Fifo::RunGpu();
|
||||||
}));
|
}));
|
||||||
mmio->Register(base | FIFO_READ_POINTER_LO,
|
mmio->Register(
|
||||||
IsOnThread() ?
|
base | FIFO_READ_POINTER_LO,
|
||||||
MMIO::DirectRead<u16>(MMIO::Utils::LowPart(&fifo.SafeCPReadPointer)) :
|
IsOnThread() ? MMIO::DirectRead<u16>(MMIO::Utils::LowPart(&fifo.SafeCPReadPointer)) :
|
||||||
MMIO::DirectRead<u16>(MMIO::Utils::LowPart(&fifo.CPReadPointer)),
|
MMIO::DirectRead<u16>(MMIO::Utils::LowPart(&fifo.CPReadPointer)),
|
||||||
MMIO::DirectWrite<u16>(MMIO::Utils::LowPart(&fifo.CPReadPointer), 0xFFE0));
|
MMIO::DirectWrite<u16>(MMIO::Utils::LowPart(&fifo.CPReadPointer), WMASK_LO_ALIGN_32BIT));
|
||||||
mmio->Register(base | FIFO_READ_POINTER_HI,
|
mmio->Register(
|
||||||
IsOnThread() ?
|
base | FIFO_READ_POINTER_HI,
|
||||||
MMIO::DirectRead<u16>(MMIO::Utils::HighPart(&fifo.SafeCPReadPointer)) :
|
IsOnThread() ? MMIO::DirectRead<u16>(MMIO::Utils::HighPart(&fifo.SafeCPReadPointer)) :
|
||||||
MMIO::DirectRead<u16>(MMIO::Utils::HighPart(&fifo.CPReadPointer)),
|
MMIO::DirectRead<u16>(MMIO::Utils::HighPart(&fifo.CPReadPointer)),
|
||||||
IsOnThread() ? MMIO::ComplexWrite<u16>([](u32, u16 val) {
|
IsOnThread() ?
|
||||||
WriteHigh(fifo.CPReadPointer, val);
|
MMIO::ComplexWrite<u16>([WMASK_HI_RESTRICT](u32, u16 val) {
|
||||||
fifo.SafeCPReadPointer = fifo.CPReadPointer;
|
WriteHigh(fifo.CPReadPointer, val & WMASK_HI_RESTRICT);
|
||||||
}) :
|
fifo.SafeCPReadPointer = fifo.CPReadPointer;
|
||||||
MMIO::DirectWrite<u16>(MMIO::Utils::HighPart(&fifo.CPReadPointer)));
|
}) :
|
||||||
|
MMIO::DirectWrite<u16>(MMIO::Utils::HighPart(&fifo.CPReadPointer), WMASK_HI_RESTRICT));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GatherPipeBursted()
|
void GatherPipeBursted()
|
||||||
|
Loading…
Reference in New Issue
Block a user