Skip to content

Commit

Permalink
nv2a: implemented NV_PMC_BOOT_1
Browse files Browse the repository at this point in the history
  • Loading branch information
ergo720 committed Mar 22, 2024
1 parent b58b29d commit e2e2031
Show file tree
Hide file tree
Showing 28 changed files with 412 additions and 230 deletions.
1 change: 1 addition & 0 deletions src/hw/cmos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ template<bool log>
void cmos::write(uint32_t addr, const uint8_t data)
{
if constexpr (log) {
uint8_t value = data;
log_io_write();
}

Expand Down
3 changes: 3 additions & 0 deletions src/hw/pci.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ template<bool log>
void pci::write8(uint32_t addr, const uint8_t data)
{
if constexpr (log) {
uint8_t value = data;
log_io_write();
}

Expand Down Expand Up @@ -134,6 +135,7 @@ template<bool log>
void pci::write16(uint32_t addr, const uint16_t data)
{
if constexpr (log) {
uint16_t value = data;
log_io_write();
}

Expand All @@ -145,6 +147,7 @@ template<bool log>
void pci::write32(uint32_t addr, const uint32_t data)
{
if constexpr (log) {
uint32_t value = data;
log_io_write();
}

Expand Down
2 changes: 2 additions & 0 deletions src/hw/pic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ template<bool log>
void pic::write(uint32_t addr, const uint8_t data)
{
if constexpr (log) {
uint8_t value = data;
log_io_write();
}

Expand Down Expand Up @@ -287,6 +288,7 @@ template<bool log>
void pic::write_elcr(uint32_t addr, const uint8_t data)
{
if constexpr (log) {
uint8_t value = data;
log_io_write();
}

Expand Down
18 changes: 8 additions & 10 deletions src/hw/pit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,14 @@ pit::start_timer(uint8_t channel)
cpu_set_timeout(m_machine->get<cpu_t *>(), m_machine->get<cpu>().check_periodic_events(m_chan[channel].last_irq_time));
}

void
pit::write_handler(uint32_t addr, const uint8_t data)
template<bool log>
void pit::write(uint32_t addr, const uint8_t data)
{
if constexpr (log) {
uint8_t value = data;
log_io_write();
}

uint8_t channel = addr & 3;

switch (channel)
Expand Down Expand Up @@ -121,13 +126,6 @@ pit::write_handler(uint32_t addr, const uint8_t data)
}
}

void
pit::write_handler_logger(uint32_t addr, const uint8_t data)
{
log_io_write();
write_handler(addr, data);
}

void
pit::channel_reset(uint8_t channel)
{
Expand All @@ -143,7 +141,7 @@ pit::update_io(bool is_update)
bool log = module_enabled();
if (!LC86_SUCCESS(mem_init_region_io(m_machine->get<cpu_t *>(), 0x40, 4, true,
{
.fnw8 = log ? cpu_write<pit, uint8_t, &pit::write_handler_logger> : cpu_write<pit, uint8_t, &pit::write_handler>
.fnw8 = log ? cpu_write<pit, uint8_t, &pit::write<true>> : cpu_write<pit, uint8_t, &pit::write<false>>
},
this, is_update, is_update))) {
logger_en(error, "Failed to update io ports");
Expand Down
4 changes: 2 additions & 2 deletions src/hw/pit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ class pit {
void reset();
void update_io_logging() { update_io(true); }
uint64_t get_next_irq_time(uint64_t now);
void write_handler(uint32_t addr, const uint8_t data);
void write_handler_logger(uint32_t addr, const uint8_t data);
template<bool log = false>
void write(uint32_t addr, const uint8_t data);

private:
bool update_io(bool is_update);
Expand Down
78 changes: 67 additions & 11 deletions src/hw/video/gpu/pbus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,25 +90,29 @@ nv2a_pci_write(uint8_t *ptr, uint8_t addr, uint8_t data, void *opaque)
return 0; // pass-through the write
}

template<bool should_log>
template<bool should_log, bool is_be>
void pbus::write(uint32_t addr, const uint32_t data)
{
uint32_t value = data;
if constexpr (is_be) {
value = util::byteswap(value);
}
if constexpr (should_log) {
log_io_write();
}

switch (addr)
{
case NV_PBUS_FBIO_RAM:
fbio_ram = data;
fbio_ram = value;
break;

default:
nxbx_fatal("Unhandled write at address 0x%" PRIX32 " with value 0x%" PRIX32, addr, data);
nxbx_fatal("Unhandled write at address 0x%" PRIX32 " with value 0x%" PRIX32, addr, value);
}
}

template<bool should_log>
template<bool should_log, bool is_be>
uint32_t pbus::read(uint32_t addr)
{
uint32_t value = 0;
Expand All @@ -123,30 +127,40 @@ uint32_t pbus::read(uint32_t addr)
nxbx_fatal("Unhandled read at address 0x%" PRIX32, addr);
}

if constexpr (is_be) {
value = util::byteswap(value);
}
if constexpr (should_log) {
log_io_read();
}

return value;
}

template<bool should_log>
template<bool should_log, bool is_be>
void pbus::pci_write(uint32_t addr, const uint32_t data)
{
uint32_t value = data;
if constexpr (is_be) {
value = util::byteswap(value);
}
if constexpr (should_log) {
log_io_write();
}

uint32_t *pci_conf = (uint32_t *)m_pci_conf;
pci_conf[(addr - NV_PBUS_PCI_BASE) / 4] = data;
pci_conf[(addr - NV_PBUS_PCI_BASE) / 4] = value;
}

template<bool should_log>
template<bool should_log, bool is_be>
uint32_t pbus::pci_read(uint32_t addr)
{
uint32_t *pci_conf = (uint32_t *)m_pci_conf;
uint32_t value = pci_conf[(addr - NV_PBUS_PCI_BASE) / 4];

if constexpr (is_be) {
value = util::byteswap(value);
}
if constexpr (should_log) {
log_io_read();
}
Expand All @@ -163,14 +177,56 @@ pbus::pci_init()
m_pci_conf = pci_conf;
}

template<bool is_write, bool is_pci>
auto pbus::get_io_func(bool log, bool is_be)
{
if constexpr (is_pci) {
if constexpr (is_write) {
if (log) {
return is_be ? cpu_write<pbus, uint32_t, &pbus::pci_write<true, true>> : cpu_write<pbus, uint32_t, &pbus::pci_write<true>>;
}
else {
return is_be ? cpu_write<pbus, uint32_t, &pbus::pci_write<false, true>> : cpu_write<pbus, uint32_t, &pbus::pci_write<false>>;
}
}
else {
if (log) {
return is_be ? cpu_read<pbus, uint32_t, &pbus::pci_read<true, true>> : cpu_read<pbus, uint32_t, &pbus::pci_read<true>>;
}
else {
return is_be ? cpu_read<pbus, uint32_t, &pbus::pci_read<false, true>> : cpu_read<pbus, uint32_t, &pbus::pci_read<false>>;
}
}
}
else {
if constexpr (is_write) {
if (log) {
return is_be ? cpu_write<pbus, uint32_t, &pbus::write<true, true>> : cpu_write<pbus, uint32_t, &pbus::write<true>>;
}
else {
return is_be ? cpu_write<pbus, uint32_t, &pbus::write<false, true>> : cpu_write<pbus, uint32_t, &pbus::write<false>>;
}
}
else {
if (log) {
return is_be ? cpu_read<pbus, uint32_t, &pbus::read<true, true>> : cpu_read<pbus, uint32_t, &pbus::read<true>>;
}
else {
return is_be ? cpu_read<pbus, uint32_t, &pbus::read<false, true>> : cpu_read<pbus, uint32_t, &pbus::read<false>>;
}
}
}
}

bool
pbus::update_io(bool is_update)
{
bool log = module_enabled();
bool is_be = m_machine->get<pmc>().endianness & NV_PMC_BOOT_1_ENDIAN24_BIG_MASK;
if (!LC86_SUCCESS(mem_init_region_io(m_machine->get<cpu_t *>(), NV_PBUS_BASE, NV_PBUS_SIZE, false,
{
.fnr32 = log ? cpu_read<pbus, uint32_t, &pbus::read<true>> : cpu_read<pbus, uint32_t, &pbus::read<false>>,
.fnw32 = log ? cpu_write<pbus, uint32_t, &pbus::write<true>> : cpu_write<pbus, uint32_t, &pbus::write<false>>
.fnr32 = get_io_func<false, false>(log, is_be),
.fnw32 = get_io_func<true, false>(log, is_be)
},
this, is_update, is_update))) {
logger_en(error, "Failed to update mmio region");
Expand All @@ -179,8 +235,8 @@ pbus::update_io(bool is_update)

if (!LC86_SUCCESS(mem_init_region_io(m_machine->get<cpu_t *>(), NV_PBUS_PCI_BASE, sizeof(default_pci_configuration), false,
{
.fnr32 = log ? cpu_read<pbus, uint32_t, &pbus::pci_read<true>> : cpu_read<pbus, uint32_t, &pbus::pci_read<false>>,
.fnw32 = log ? cpu_write<pbus, uint32_t, &pbus::pci_write<true>> : cpu_write<pbus, uint32_t, &pbus::pci_write<false>>
.fnr32 = get_io_func<false, true>(log, is_be),
.fnw32 = get_io_func<true, true>(log, is_be)
},
this, is_update, is_update))) {
logger_en(error, "Failed to update pci mmio region");
Expand Down
10 changes: 6 additions & 4 deletions src/hw/video/gpu/pbus.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,19 @@ class pbus {
bool init();
void reset();
void update_io() { update_io(true); }
template<bool log = false>
template<bool log = false, bool is_be = false>
uint32_t read(uint32_t addr);
template<bool log = false>
template<bool log = false, bool is_be = false>
void write(uint32_t addr, const uint32_t data);
template<bool log = false>
template<bool log = false, bool is_be = false>
uint32_t pci_read(uint32_t addr);
template<bool log = false>
template<bool log = false, bool is_be = false>
void pci_write(uint32_t addr, const uint32_t data);

private:
bool update_io(bool is_update);
template<bool is_write, bool is_pci>
auto get_io_func(bool log, bool is_be);
void pci_init();

machine *const m_machine;
Expand Down
36 changes: 22 additions & 14 deletions src/hw/video/gpu/pcrtc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,42 +17,46 @@
#define NV_PCRTC_UNKNOWN0 (NV2A_REGISTER_BASE + 0x00600804)


template<bool log, bool enabled>
template<bool log, bool enabled, bool is_be>
void pcrtc::write(uint32_t addr, const uint32_t data)
{
if constexpr (!enabled) {
return;
}
uint32_t value = data;
if constexpr (is_be) {
value = util::byteswap(value);
}
if constexpr (log) {
log_io_write();
}

switch (addr)
{
case NV_PCRTC_INTR_0:
int_status &= ~data;
int_status &= ~value;
m_machine->get<pmc>().update_irq();
break;

case NV_PCRTC_INTR_EN_0:
int_enabled = data;
int_enabled = value;
m_machine->get<pmc>().update_irq();
break;

case NV_PCRTC_START:
fb_addr = data & 0x7FFFFFC; // fb is 4 byte aligned
fb_addr = value & 0x7FFFFFC; // fb is 4 byte aligned
break;

case NV_PCRTC_UNKNOWN0:
unknown[0] = data;
unknown[0] = value;
break;

default:
nxbx_fatal("Unhandled write at address 0x%" PRIX32 " with value 0x%" PRIX32, addr, data);
nxbx_fatal("Unhandled write at address 0x%" PRIX32 " with value 0x%" PRIX32, addr, value);
}
}

template<bool log, bool enabled>
template<bool log, bool enabled, bool is_be>
uint32_t pcrtc::read(uint32_t addr)
{
if constexpr (!enabled) {
Expand Down Expand Up @@ -83,6 +87,9 @@ uint32_t pcrtc::read(uint32_t addr)
nxbx_fatal("Unhandled read at address 0x%" PRIX32, addr);
}

if constexpr (is_be) {
value = util::byteswap(value);
}
if constexpr (log) {
log_io_read();
}
Expand All @@ -91,15 +98,15 @@ uint32_t pcrtc::read(uint32_t addr)
}

template<bool is_write>
auto pcrtc::get_io_func(bool log, bool enabled)
auto pcrtc::get_io_func(bool log, bool enabled, bool is_be)
{
if constexpr (is_write) {
if (enabled) {
if (log) {
return cpu_write<pcrtc, uint32_t, &pcrtc::write<true>>;
return is_be ? cpu_write<pcrtc, uint32_t, &pcrtc::write<true, true, true>> : cpu_write<pcrtc, uint32_t, &pcrtc::write<true>>;
}
else {
return cpu_write<pcrtc, uint32_t, &pcrtc::write<false>>;
return is_be ? cpu_write<pcrtc, uint32_t, &pcrtc::write<false, true, true>> : cpu_write<pcrtc, uint32_t, &pcrtc::write<false>>;
}
}
else {
Expand All @@ -109,10 +116,10 @@ auto pcrtc::get_io_func(bool log, bool enabled)
else {
if (enabled) {
if (log) {
return cpu_read<pcrtc, uint32_t, &pcrtc::read<true>>;
return is_be ? cpu_read<pcrtc, uint32_t, &pcrtc::read<true, true, true>> : cpu_read<pcrtc, uint32_t, &pcrtc::read<true>>;
}
else {
return cpu_read<pcrtc, uint32_t, &pcrtc::read<false>>;
return is_be ? cpu_read<pcrtc, uint32_t, &pcrtc::read<false, true, true>> : cpu_read<pcrtc, uint32_t, &pcrtc::read<false>>;
}
}
else {
Expand All @@ -126,10 +133,11 @@ pcrtc::update_io(bool is_update)
{
bool log = module_enabled();
bool enabled = m_machine->get<pmc>().engine_enabled & NV_PMC_ENABLE_PCRTC;
bool is_be = m_machine->get<pmc>().endianness & NV_PMC_BOOT_1_ENDIAN24_BIG_MASK;
if (!LC86_SUCCESS(mem_init_region_io(m_machine->get<cpu_t *>(), NV_PCRTC_BASE, NV_PCRTC_SIZE, false,
{
.fnr32 = get_io_func<false>(log, enabled),
.fnw32 = get_io_func<true>(log, enabled)
.fnr32 = get_io_func<false>(log, enabled, is_be),
.fnw32 = get_io_func<true>(log, enabled, is_be)
},
this, is_update, is_update))) {
logger_en(error, "Failed to update mmio region");
Expand Down
6 changes: 3 additions & 3 deletions src/hw/video/gpu/pcrtc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ class pcrtc {
bool init();
void reset();
void update_io() { update_io(true); }
template<bool log = false, bool enabled = true>
template<bool log = false, bool enabled = true, bool is_be = false>
uint32_t read(uint32_t addr);
template<bool log = false, bool enabled = true>
template<bool log = false, bool enabled = true, bool is_be = false>
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);
auto get_io_func(bool log, bool enabled, bool is_be);

friend class pmc;
machine *const m_machine;
Expand Down
Loading

0 comments on commit e2e2031

Please sign in to comment.