atimach64gx: Add io_access_allowed.

This method is used by both pci_io_read and pci_io_write to determine if ISA type I/O access is allowed.
The SPARSE_IO_BASE I/O address is defined. This I/O range is not defined by an I/O BAR.
This commit is contained in:
joevt 2024-02-27 21:27:56 -08:00 committed by dingusdev
parent a11770961e
commit 00f917f52e
2 changed files with 22 additions and 8 deletions

View File

@ -248,32 +248,45 @@ static const uint32_t io_idx_to_reg_offset[32] = {
ATI_CRTC_H_TOTAL_DISP,
};
enum {
SPARSE_IO_BASE = 0x2EC
};
bool AtiMach64Gx::io_access_allowed(uint32_t offset) {
if ((offset & 0xFFFF03FC) == SPARSE_IO_BASE) {
if (this->command & 1) {
return true;
}
LOG_F(WARNING, "ATI I/O space disabled in the command reg");
}
return false;
}
bool AtiMach64Gx::pci_io_read(uint32_t offset, uint32_t size, uint32_t* res)
{
*res = 0;
// check for valid I/O base and I/O access permission
if ((offset & 0x3FC) != 0x2EC || !(this->command & 1)) {
if (!this->io_access_allowed(offset)) {
return false;
}
uint32_t result = 0;
// convert ISA-style I/O address to MMIO register offset
offset = io_idx_to_reg_offset[(offset >> 10) & 0x1F] * 4 + (offset & 3);
// CONFIG_CNTL is accessible from I/O space only
if ((offset >> 2) == ATI_CONFIG_CNTL) {
*res = read_mem(((uint8_t *)&this->config_cntl) + (offset & 3), size);
result = read_mem(((uint8_t *)&this->config_cntl) + (offset & 3), size);
} else {
*res = BYTESWAP_SIZED(this->read_reg(offset, size), size);
result = BYTESWAP_SIZED(this->read_reg(offset, size), size);
}
*res = result;
return true;
}
bool AtiMach64Gx::pci_io_write(uint32_t offset, uint32_t value, uint32_t size)
{
// check for valid I/O base and I/O access permission
if ((offset & 0x3FC) != 0x2EC || !(this->command & 1)) {
if (!this->io_access_allowed(offset)) {
return false;
}

View File

@ -57,6 +57,7 @@ protected:
void notify_bar_change(int bar_num);
const char* get_reg_name(uint32_t reg_offset);
const char* rgb514_get_reg_name(uint32_t reg_offset);
bool io_access_allowed(uint32_t offset);
uint32_t read_reg(uint32_t reg_offset, uint32_t size);
void write_reg(uint32_t reg_offset, uint32_t value, uint32_t size);
void enable_crtc_internal();