Skip to content

Commit

Permalink
nv2a: implemented more bits of NV_PMC_ENABLE
Browse files Browse the repository at this point in the history
  • Loading branch information
ergo720 committed Mar 21, 2024
1 parent 7419458 commit b58b29d
Show file tree
Hide file tree
Showing 17 changed files with 293 additions and 58 deletions.
20 changes: 10 additions & 10 deletions src/hw/video/gpu/nv2a.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ nv2a::get_next_update_time(uint64_t now)
void
nv2a::apply_log_settings()
{
m_pmc.update_io_logging();
m_pcrtc.update_io_logging();
m_pramdac.update_io_logging();
m_ptimer.update_io_logging();
m_pfb.update_io_logging();
m_pbus.update_io_logging();
m_pramin.update_io_logging();
m_pfifo.update_io_logging();
m_pvga.update_io_logging();
m_pvideo.update_io_logging();
m_pmc.update_io();
m_pcrtc.update_io();
m_pramdac.update_io();
m_ptimer.update_io();
m_pfb.update_io();
m_pbus.update_io();
m_pramin.update_io();
m_pfifo.update_io();
m_pvga.update_io();
m_pvideo.update_io();
}
2 changes: 1 addition & 1 deletion src/hw/video/gpu/pbus.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class pbus {
pbus(machine *machine) : m_machine(machine), m_pci_conf(nullptr) {}
bool init();
void reset();
void update_io_logging() { update_io(true); }
void update_io() { update_io(true); }
template<bool log = false>
uint32_t read(uint32_t addr);
template<bool log = false>
Expand Down
47 changes: 43 additions & 4 deletions src/hw/video/gpu/pcrtc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@
#define NV_PCRTC_UNKNOWN0 (NV2A_REGISTER_BASE + 0x00600804)


template<bool log>
template<bool log, bool enabled>
void pcrtc::write(uint32_t addr, const uint32_t data)
{
if constexpr (!enabled) {
return;
}
if constexpr (log) {
log_io_write();
}
Expand Down Expand Up @@ -49,9 +52,13 @@ void pcrtc::write(uint32_t addr, const uint32_t data)
}
}

template<bool log>
template<bool log, bool enabled>
uint32_t pcrtc::read(uint32_t addr)
{
if constexpr (!enabled) {
return 0;
}

uint32_t value = 0;

switch (addr)
Expand Down Expand Up @@ -83,14 +90,46 @@ uint32_t pcrtc::read(uint32_t addr)
return value;
}

template<bool is_write>
auto pcrtc::get_io_func(bool log, bool enabled)
{
if constexpr (is_write) {
if (enabled) {
if (log) {
return cpu_write<pcrtc, uint32_t, &pcrtc::write<true>>;
}
else {
return cpu_write<pcrtc, uint32_t, &pcrtc::write<false>>;
}
}
else {
return cpu_write<pcrtc, uint32_t, &pcrtc::write<false, false>>;
}
}
else {
if (enabled) {
if (log) {
return cpu_read<pcrtc, uint32_t, &pcrtc::read<true>>;
}
else {
return cpu_read<pcrtc, uint32_t, &pcrtc::read<false>>;
}
}
else {
return cpu_read<pcrtc, uint32_t, &pcrtc::read<false, false>>;
}
}
}

bool
pcrtc::update_io(bool is_update)
{
bool log = module_enabled();
bool enabled = m_machine->get<pmc>().engine_enabled & NV_PMC_ENABLE_PCRTC;
if (!LC86_SUCCESS(mem_init_region_io(m_machine->get<cpu_t *>(), NV_PCRTC_BASE, NV_PCRTC_SIZE, false,
{
.fnr32 = log ? cpu_read<pcrtc, uint32_t, &pcrtc::read<true>> : cpu_read<pcrtc, uint32_t, &pcrtc::read<false>>,
.fnw32 = log ? cpu_write<pcrtc, uint32_t, &pcrtc::write<true>> : cpu_write<pcrtc, uint32_t, &pcrtc::write<false>>
.fnr32 = get_io_func<false>(log, enabled),
.fnw32 = get_io_func<true>(log, enabled)
},
this, is_update, is_update))) {
logger_en(error, "Failed to update mmio region");
Expand Down
8 changes: 5 additions & 3 deletions src/hw/video/gpu/pcrtc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@ class pcrtc {
pcrtc(machine *machine) : m_machine(machine) {}
bool init();
void reset();
void update_io_logging() { update_io(true); }
template<bool log = false>
void update_io() { update_io(true); }
template<bool log = false, bool enabled = true>
uint32_t read(uint32_t addr);
template<bool log = false>
template<bool log = false, bool enabled = true>
void write(uint32_t addr, const uint32_t data);

private:
bool update_io(bool is_update);
template<bool is_write>
auto get_io_func(bool log, bool enabled);

friend class pmc;
machine *const m_machine;
Expand Down
47 changes: 43 additions & 4 deletions src/hw/video/gpu/pfb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@
#define NV_PFB_NVM (NV2A_REGISTER_BASE + 0x00100214)


template<bool log>
template<bool log, bool enabled>
void pfb::write(uint32_t addr, const uint32_t data)
{
if constexpr (!enabled) {
return;
}
if constexpr (log) {
log_io_write();
}
Expand Down Expand Up @@ -46,9 +49,13 @@ void pfb::write(uint32_t addr, const uint32_t data)
}
}

template<bool log>
template<bool log, bool enabled>
uint32_t pfb::read(uint32_t addr)
{
if constexpr (!enabled) {
return 0;
}

uint32_t value = 0;

switch (addr)
Expand Down Expand Up @@ -80,14 +87,46 @@ uint32_t pfb::read(uint32_t addr)
return value;
}

template<bool is_write>
auto pfb::get_io_func(bool log, bool enabled)
{
if constexpr (is_write) {
if (enabled) {
if (log) {
return cpu_write<pfb, uint32_t, &pfb::write<true>>;
}
else {
return cpu_write<pfb, uint32_t, &pfb::write<false>>;
}
}
else {
return cpu_write<pfb, uint32_t, &pfb::write<false, false>>;
}
}
else {
if (enabled) {
if (log) {
return cpu_read<pfb, uint32_t, &pfb::read<true>>;
}
else {
return cpu_read<pfb, uint32_t, &pfb::read<false>>;
}
}
else {
return cpu_read<pfb, uint32_t, &pfb::read<false, false>>;
}
}
}

bool
pfb::update_io(bool is_update)
{
bool log = module_enabled();
bool enabled = m_machine->get<pmc>().engine_enabled & NV_PMC_ENABLE_PFB;
if (!LC86_SUCCESS(mem_init_region_io(m_machine->get<cpu_t *>(), NV_PFB_BASE, NV_PFB_SIZE, false,
{
.fnr32 = log ? cpu_read<pfb, uint32_t, &pfb::read<true>> : cpu_read<pfb, uint32_t, &pfb::read<false>>,
.fnw32 = log ? cpu_write<pfb, uint32_t, &pfb::write<true>> : cpu_write<pfb, uint32_t, &pfb::write<false>>
.fnr32 = get_io_func<false>(log, enabled),
.fnw32 = get_io_func<true>(log, enabled)
},
this, is_update, is_update))) {
logger_en(error, "Failed to update mmio region");
Expand Down
8 changes: 5 additions & 3 deletions src/hw/video/gpu/pfb.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@ class pfb {
pfb(machine *machine) : m_machine(machine) {}
bool init();
void reset();
void update_io_logging() { update_io(true); }
template<bool log = false>
void update_io() { update_io(true); }
template<bool log = false, bool enabled = true>
uint32_t read(uint32_t addr);
template<bool log = false>
template<bool log = false, bool enabled = true>
void write(uint32_t addr, const uint32_t data);

private:
bool update_io(bool is_update);
template<bool is_write>
auto get_io_func(bool log, bool enabled);

friend class pramin;
machine *const m_machine;
Expand Down
47 changes: 43 additions & 4 deletions src/hw/video/gpu/pfifo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@
#define NV_PFIFO_RAMRO (NV2A_REGISTER_BASE + 0x00002218)


template<bool log>
template<bool log, bool enabled>
void pfifo::write(uint32_t addr, const uint32_t data)
{
if constexpr (!enabled) {
return;
}
if constexpr (log) {
log_io_write();
}
Expand All @@ -41,9 +44,13 @@ void pfifo::write(uint32_t addr, const uint32_t data)
}
}

template<bool log>
template<bool log, bool enabled>
uint32_t pfifo::read(uint32_t addr)
{
if constexpr (!enabled) {
return 0;
}

uint32_t value = 0;

switch (addr)
Expand Down Expand Up @@ -71,14 +78,46 @@ uint32_t pfifo::read(uint32_t addr)
return value;
}

template<bool is_write>
auto pfifo::get_io_func(bool log, bool enabled)
{
if constexpr (is_write) {
if (enabled) {
if (log) {
return cpu_write<pfifo, uint32_t, &pfifo::write<true>>;
}
else {
return cpu_write<pfifo, uint32_t, &pfifo::write<false>>;
}
}
else {
return cpu_write<pfifo, uint32_t, &pfifo::write<false, false>>;
}
}
else {
if (enabled) {
if (log) {
return cpu_read<pfifo, uint32_t, &pfifo::read<true>>;
}
else {
return cpu_read<pfifo, uint32_t, &pfifo::read<false>>;
}
}
else {
return cpu_read<pfifo, uint32_t, &pfifo::read<false, false>>;
}
}
}

bool
pfifo::update_io(bool is_update)
{
bool log = module_enabled();
bool enabled = m_machine->get<pmc>().engine_enabled & NV_PMC_ENABLE_PFIFO;
if (!LC86_SUCCESS(mem_init_region_io(m_machine->get<cpu_t *>(), NV_PFIFO_BASE, NV_PFIFO_SIZE, false,
{
.fnr32 = log ? cpu_read<pfifo, uint32_t, &pfifo::read<true>> : cpu_read<pfifo, uint32_t, &pfifo::read<false>>,
.fnw32 = log ? cpu_write<pfifo, uint32_t, &pfifo::write<true>> : cpu_write<pfifo, uint32_t, &pfifo::write<false>>
.fnr32 = get_io_func<false>(log, enabled),
.fnw32 = get_io_func<true>(log, enabled)
},
this, is_update, is_update))) {
logger_en(error, "Failed to update mmio region");
Expand Down
8 changes: 5 additions & 3 deletions src/hw/video/gpu/pfifo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@ class pfifo {
pfifo(machine *machine) : m_machine(machine) {}
bool init();
void reset();
void update_io_logging() { update_io(true); }
template<bool log = false>
void update_io() { update_io(true); }
template<bool log = false, bool enabled = true>
uint32_t read(uint32_t addr);
template<bool log = false>
template<bool log = false, bool enabled = true>
void write(uint32_t addr, const uint32_t data);

private:
bool update_io(bool is_update);
template<bool is_write>
auto get_io_func(bool log, bool enabled);

machine *const m_machine;
struct {
Expand Down
22 changes: 17 additions & 5 deletions src/hw/video/gpu/pmc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@
#define NV_PMC_INTR_EN_0_INTA_DISABLED 0x00000000
#define NV_PMC_INTR_EN_0_INTA_HARDWARE 0x00000001
#define NV_PMC_INTR_EN_0_INTA_SOFTWARE 0x00000002
#define NV_PMC_ENABLE (NV2A_REGISTER_BASE + 0x00000200)
#define NV_PMC_ENABLE_PTIMER (1 << 16)
#define NV_PMC_ENABLE_PFB (1 << 20)
#define NV_PMC_ENABLE_PCRTC (1 << 24)


template<bool log>
Expand Down Expand Up @@ -76,7 +72,11 @@ void pmc::write(uint32_t addr, const uint32_t data)

case NV_PMC_ENABLE: {
bool has_int_state_changed = false;
uint32_t old_state = engine_enabled;
engine_enabled = data;
if ((data & NV_PMC_ENABLE_PFIFO) == 0) {
m_machine->get<pfifo>().reset();
}
if ((data & NV_PMC_ENABLE_PTIMER) == 0) {
m_machine->get<ptimer>().reset();
has_int_state_changed = true;
Expand All @@ -88,6 +88,17 @@ void pmc::write(uint32_t addr, const uint32_t data)
m_machine->get<pcrtc>().reset();
has_int_state_changed = true;
}
if ((data & NV_PMC_ENABLE_PVIDEO) == 0) {
m_machine->get<pvideo>().reset();
}
if ((old_state ^ engine_enabled) & NV_PMC_ENABLE_MASK) {
m_machine->get<pfifo>().update_io();
m_machine->get<ptimer>().update_io();
m_machine->get<pfb>().update_io();
m_machine->get<pcrtc>().update_io();
m_machine->get<pvideo>().update_io();
mem_init_region_io(m_machine->get<cpu_t *>(), 0, 0, true, {}, m_machine->get<cpu_t *>(), true, 3); // trigger the update in lib86cpu too
}
if (has_int_state_changed) {
update_irq();
}
Expand Down Expand Up @@ -205,10 +216,11 @@ pmc::update_io(bool is_update)
void
pmc::reset()
{
// Values dumped from a Retail 1.0 xbox
endianness = NV_PMC_BOOT_1_ENDIAN0_LITTLE_MASK | NV_PMC_BOOT_1_ENDIAN24_LITTLE_MASK;
int_status = NV_PMC_INTR_0_NOT_PENDING;
int_enabled = NV_PMC_INTR_EN_0_INTA_DISABLED;
engine_enabled = 0;
engine_enabled = NV_PMC_ENABLE_PTIMER | NV_PMC_ENABLE_PFB | NV_PMC_ENABLE_PCRTC;
}

bool
Expand Down
Loading

0 comments on commit b58b29d

Please sign in to comment.