From 3a5c61797cf0fdeaab4e2b76b3708b734748520b Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Fri, 2 Sep 2022 23:24:06 +0000 Subject: [PATCH] Revert "PCI fixes" --- devices/common/pci/bandit.cpp | 74 +++++---------- devices/common/pci/pcidevice.cpp | 47 ++++----- devices/floppy/floppyimg.cpp | 9 +- devices/memctrl/mpc106.cpp | 73 +++++--------- devices/memctrl/mpc106.h | 4 +- devices/video/atirage.cpp | 49 ++-------- devices/video/control.cpp | 157 ++++++++++++++----------------- devices/video/control.h | 1 - memaccess.h | 54 ----------- 9 files changed, 159 insertions(+), 309 deletions(-) diff --git a/devices/common/pci/bandit.cpp b/devices/common/pci/bandit.cpp index 5b5df92..6ebd6a1 100644 --- a/devices/common/pci/bandit.cpp +++ b/devices/common/pci/bandit.cpp @@ -81,27 +81,15 @@ uint32_t Bandit::pci_cfg_read(uint32_t reg_offs, uint32_t size) if (reg_offs < 64) { return PCIDevice::pci_cfg_read(reg_offs, size); } - - uint32_t offset = reg_offs & 3; - reg_offs &= ~3; - if (~-size & offset) { - LOG_F( - WARNING, "%s: unaligned read @%02x.%c", - this->name.c_str(), reg_offs + offset, - size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size - ); - } - if (reg_offs == BANDIT_ADDR_MASK) { - return pci_cfg_rev_read(this->addr_mask, offset, size); + switch (reg_offs) { + case BANDIT_ADDR_MASK: + return BYTESWAP_32(this->addr_mask); + default: + LOG_F(WARNING, "%s: reading from unimplemented config register at 0x%X", + this->pci_name.c_str(), reg_offs); } - LOG_F( - WARNING, "%s: reading from unimplemented config register @%02x.%c", - this->name.c_str(), reg_offs + offset, - size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size - ); - return 0; } @@ -112,27 +100,15 @@ void Bandit::pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size) return; } - uint32_t offset = reg_offs & 3; - reg_offs &= ~3; - if (~-size & offset) { - LOG_F( - WARNING, "%s: unaligned write @%02x.%c = %0*x", - this->name.c_str(), reg_offs + offset, - size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, flip_sized(value, size) - ); - } - - if (reg_offs == BANDIT_ADDR_MASK) { - this->addr_mask = pci_cfg_rev_write(this->addr_mask, offset, size, value); + switch (reg_offs) { + case BANDIT_ADDR_MASK: + this->addr_mask = BYTESWAP_32(value); this->verbose_address_space(); - return; + break; + default: + LOG_F(WARNING, "%s: writing to unimplemented config register at 0x%X", + this->pci_name.c_str(), reg_offs); } - - LOG_F( - WARNING, "%s: writing to unimplemented config register @%02x.%c = %0*x", - this->name.c_str(), reg_offs + offset, - size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, flip_sized(value, size) - ); } uint32_t Bandit::read(uint32_t rgn_start, uint32_t offset, int size) @@ -171,10 +147,10 @@ uint32_t Bandit::read(uint32_t rgn_start, uint32_t offset, int size) } if (idsel == BANDIT_ID_SEL) { // access to myself - result = this->pci_cfg_read(reg_offs + (offset & 3), size); + result = this->pci_cfg_read(reg_offs, size); } else { if (this->dev_map.count(idsel)) { - result = this->dev_map[idsel]->pci_cfg_read(reg_offs + (offset & 3), size); + result = this->dev_map[idsel]->pci_cfg_read(reg_offs, size); } else { dev_num = WHAT_BIT_SET(idsel) + 11; LOG_F( @@ -220,7 +196,7 @@ void Bandit::write(uint32_t rgn_start, uint32_t offset, uint32_t value, int size LOG_F( WARNING, "%s: write config cycle type 1 not supported yet %02x:%02x.%x @%02x.%c = %0*x", this->name.c_str(), bus_num, dev_num, fun_num, reg_offs + (offset & 3), - size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, flip_sized(value, size) + size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, value ); return; } @@ -232,24 +208,24 @@ void Bandit::write(uint32_t rgn_start, uint32_t offset, uint32_t value, int size ERROR, "%s: write invalid IDSEL=0x%X config:0x%X ??:??.%x? @%02x?.%c = %0*x", this->name.c_str(), idsel, this->config_addr, fun_num, reg_offs + (offset & 3), - size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, flip_sized(value, size) + size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, value ); return; } if (idsel == BANDIT_ID_SEL) { // access to myself - this->pci_cfg_write(reg_offs + (offset & 3), value, size); + this->pci_cfg_write(reg_offs, value, size); return; } if (this->dev_map.count(idsel)) { - this->dev_map[idsel]->pci_cfg_write(reg_offs + (offset & 3), value, size); + this->dev_map[idsel]->pci_cfg_write(reg_offs, value, size); } else { dev_num = WHAT_BIT_SET(idsel) + 11; LOG_F( ERROR, "%s err: write attempt to non-existing PCI device ??:%02x.%x @%02x.%c = %0*x", this->name.c_str(), dev_num, fun_num, reg_offs + (offset & 3), - size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, flip_sized(value, size) + size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, value ); } } else { @@ -344,7 +320,7 @@ uint32_t Chaos::read(uint32_t rgn_start, uint32_t offset, int size) } if (this->dev_map.count(idsel)) { - result = this->dev_map[idsel]->pci_cfg_read(reg_offs + (offset & 3), size); + result = this->dev_map[idsel]->pci_cfg_read(reg_offs, size); } else { dev_num = WHAT_BIT_SET(idsel) + 11; LOG_F( @@ -382,7 +358,7 @@ void Chaos::write(uint32_t rgn_start, uint32_t offset, uint32_t value, int size) LOG_F( WARNING, "%s: write config cycle type 1 not supported yet %02x:%02x.%x @%02x.%c = %0*x", this->name.c_str(), bus_num, dev_num, fun_num, reg_offs + (offset & 3), - size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, flip_sized(value, size) + size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, value ); return; } @@ -394,19 +370,19 @@ void Chaos::write(uint32_t rgn_start, uint32_t offset, uint32_t value, int size) ERROR, "%s: write invalid IDSEL=0x%X config:0x%X ??:??.%x? @%02x?.%c = %0*x", this->name.c_str(), idsel, this->config_addr, fun_num, reg_offs + (offset & 3), - size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, flip_sized(value, size) + size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, value ); return; } if (this->dev_map.count(idsel)) { - this->dev_map[idsel]->pci_cfg_write(reg_offs + (offset & 3), value, size); + this->dev_map[idsel]->pci_cfg_write(reg_offs, value, size); } else { dev_num = WHAT_BIT_SET(idsel) + 11; LOG_F( ERROR, "%s err: write attempt to non-existing VCI device ??:%02x.%x @%02x.%c = %0*x", this->name.c_str(), dev_num, fun_num, reg_offs + (offset & 3), - size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, flip_sized(value, size) + size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, value ); } } else { diff --git a/devices/common/pci/pcidevice.cpp b/devices/common/pci/pcidevice.cpp index e301e48..41676b8 100644 --- a/devices/common/pci/pcidevice.cpp +++ b/devices/common/pci/pcidevice.cpp @@ -52,16 +52,6 @@ uint32_t PCIDevice::pci_cfg_read(uint32_t reg_offs, uint32_t size) { uint32_t result; - uint32_t offset = reg_offs & 3; - reg_offs &= ~3; - if (~-size & offset) { - LOG_F( - WARNING, "%s: unaligned read @%02x.%c", - this->pci_name.c_str(), reg_offs + offset, - size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size - ); - } - switch (reg_offs) { case PCI_CFG_DEV_ID: result = (this->device_id << 16) | (this->vendor_id); @@ -99,32 +89,31 @@ uint32_t PCIDevice::pci_cfg_read(uint32_t reg_offs, uint32_t size) default: LOG_F( WARNING, "%s: attempt to read from reserved/unimplemented register @%02x.%c", - this->pci_name.c_str(), reg_offs + offset, + this->pci_name.c_str(), reg_offs, size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size ); return 0; } - return pci_cfg_rev_read(result, offset, size); + if (size == 4) { + return BYTESWAP_32(result); + } else { + return read_mem_rev(((uint8_t *)&result) + (reg_offs & 3), size); + } } void PCIDevice::pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size) { uint32_t data; - uint32_t offset = reg_offs & 3; - reg_offs &= ~3; - if (~-size & offset) { - LOG_F( - WARNING, "%s: unaligned write @%02x.%c = %0*x", - this->pci_name.c_str(), reg_offs + offset, - size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, flip_sized(value, size) - ); + if (size == 4) { + data = BYTESWAP_32(value); + } else { + // get current register content as DWORD and update it partially + data = BYTESWAP_32(this->pci_cfg_read(reg_offs, 4)); + write_mem_rev(((uint8_t *)&data) + (reg_offs & 3), value, size); } - // get current register content as DWORD and update it partially - data = pci_cfg_rev_write(size == 4 ? 0 : BYTESWAP_32(this->pci_cfg_read(reg_offs, 4)), offset, size, value); - switch (reg_offs) { case PCI_CFG_STAT_CMD: this->pci_wr_stat(data >> 16); @@ -148,10 +137,10 @@ void PCIDevice::pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size) } break; case PCI_CFG_ROM_BAR: - if ((data & this->exp_bar_cfg) == this->exp_bar_cfg) { - this->exp_rom_bar = (data & (this->exp_bar_cfg | 1)); + if (data == 0xFFFFF800UL) { + this->exp_rom_bar = this->exp_bar_cfg; } else { - this->exp_rom_bar = (data & (this->exp_bar_cfg | 1)); + this->exp_rom_bar = (data & 0xFFFFF801UL); if (this->exp_rom_bar & 1) { this->map_exp_rom_mem(); } else { @@ -167,7 +156,7 @@ void PCIDevice::pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size) LOG_F( WARNING, "%s: attempt to write to reserved/unimplemented register @%02x.%c = %0*x", this->pci_name.c_str(), reg_offs, - size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, flip_sized(value, size) + size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, value ); } } @@ -254,7 +243,7 @@ void PCIDevice::set_bar_value(int bar_num, uint32_t value) { uint32_t bar_cfg = this->bars_cfg[bar_num]; if (bar_cfg & 1) { - this->bars[bar_num] = (value & 0xFFFFFFFCUL) | (bar_cfg & 3); + this->bars[bar_num] = (value & 0xFFFFFFFCUL) | 1; } else { if (bar_cfg & 6) { ABORT_F("Invalid or unsupported PCI space type: %d", (bar_cfg >> 1) & 3); @@ -268,7 +257,7 @@ void PCIDevice::map_exp_rom_mem() { uint32_t rom_addr, rom_size; - rom_addr = this->exp_rom_bar & this->exp_bar_cfg; + rom_addr = this->exp_rom_bar & 0xFFFFF800UL; rom_size = ~this->exp_bar_cfg + 1; if (!this->exp_rom_addr || this->exp_rom_addr != rom_addr) { diff --git a/devices/floppy/floppyimg.cpp b/devices/floppy/floppyimg.cpp index 7298cad..47e1db3 100644 --- a/devices/floppy/floppyimg.cpp +++ b/devices/floppy/floppyimg.cpp @@ -64,7 +64,7 @@ static FlopImgType identify_image(std::ifstream& img_file) } } - return FlopImgType::RAW; + return FlopImgType::UNKNOWN; } static int64_t get_hfs_vol_size(const uint8_t *mdb_data) @@ -133,16 +133,17 @@ int RawFloppyImg::calc_phys_params() } else if (buf[0] == 0xD2 && buf[1] == 0xD7) { // check MFS volume size } else { - LOG_F(WARNING, "RawFloppyImg: unknown volume type!"); + LOG_F(ERROR, "RawFloppyImg: unknown volume type!"); + return -1; } - if (vol_size && (vol_size > this->img_size)) { + if (vol_size > this->img_size) { LOG_F(INFO, "RawFloppyImg: volume size > image size!"); LOG_F(INFO, "Volume size: %llu, Image size: %d", vol_size, this->img_size); return -1; } - // raw images don't include anything other than raw disk data + // raw images don't include anything than raw disk data this->data_size = this->img_size; // guess disk format from image file size diff --git a/devices/memctrl/mpc106.cpp b/devices/memctrl/mpc106.cpp index bfe4d33..7ca2ab4 100644 --- a/devices/memctrl/mpc106.cpp +++ b/devices/memctrl/mpc106.cpp @@ -89,7 +89,7 @@ uint32_t MPC106::read(uint32_t rgn_start, uint32_t offset, int size) { } else { if (offset >= 0x200000) { if (this->config_addr & 0x80) // process only if bit E (enable) is set - return pci_read(offset & 3, size); + return pci_read(size); } } @@ -113,39 +113,39 @@ void MPC106::write(uint32_t rgn_start, uint32_t offset, uint32_t value, int size this->config_addr = value; } else { if (this->config_addr & 0x80) // process only if bit E (enable) is set - return pci_write(offset & 3, value, size); + return pci_write(value, size); } } } -uint32_t MPC106::pci_read(uint32_t offset, uint32_t size) { +uint32_t MPC106::pci_read(uint32_t size) { int bus_num, dev_num, fun_num, reg_offs; - bus_num = (this->config_addr >> 8) & 0xFF; + bus_num = (this->config_addr >> 8) & 0xFF; dev_num = (this->config_addr >> 19) & 0x1F; fun_num = (this->config_addr >> 16) & 0x07; reg_offs = (this->config_addr >> 24) & 0xFC; if (bus_num) { - LOG_F( - ERROR, - "%s err: read attempt from non-local PCI bus, config_addr = %x, offset = %x %02x:%02x.%x @%02x.%c", - this->name.c_str(), this->config_addr, offset, bus_num, dev_num, fun_num, reg_offs, - size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size - ); + LOG_F( + ERROR, + "%s err: read attempt from non-local PCI bus, config_addr = %x %02x:%02x.%x @%02x.%c", + this->name.c_str(), this->config_addr, bus_num, dev_num, fun_num, reg_offs, + size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size + ); return 0xFFFFFFFFUL; // PCI spec §6.1 } if (dev_num == 0 && fun_num == 0) { // dev_num 0 is assigned to myself - return this->pci_cfg_read(reg_offs + offset, size); + return this->pci_cfg_read(reg_offs, size); } else { if (this->dev_map.count(dev_num)) { - return this->dev_map[dev_num]->pci_cfg_read(reg_offs + offset, size); + return this->dev_map[dev_num]->pci_cfg_read(reg_offs, size); } else { LOG_F( ERROR, "%s err: read attempt from non-existing PCI device %02x:%02x.%x @%02x.%c", - this->name.c_str(), bus_num, dev_num, fun_num, reg_offs + offset, + this->name.c_str(), bus_num, dev_num, fun_num, reg_offs, size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size ); return 0xFFFFFFFFUL; // PCI spec §6.1 @@ -155,10 +155,10 @@ uint32_t MPC106::pci_read(uint32_t offset, uint32_t size) { return 0; } -void MPC106::pci_write(uint32_t offset, uint32_t value, uint32_t size) { +void MPC106::pci_write(uint32_t value, uint32_t size) { int bus_num, dev_num, fun_num, reg_offs; - bus_num = (this->config_addr >> 8) & 0xFF; + bus_num = (this->config_addr >> 8) & 0xFF; dev_num = (this->config_addr >> 19) & 0x1F; fun_num = (this->config_addr >> 16) & 0x07; reg_offs = (this->config_addr >> 24) & 0xFC; @@ -166,26 +166,26 @@ void MPC106::pci_write(uint32_t offset, uint32_t value, uint32_t size) { if (bus_num) { LOG_F( ERROR, - "%s err: write attempt to non-local PCI bus, config_addr = %x, offset = %x %02x:%02x.%x @%02x.%c = %0*x", - this->name.c_str(), this->config_addr, offset, bus_num, dev_num, fun_num, reg_offs + offset, - size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, - size * 2, flip_sized(value, size) - ); + "%s err: write attempt to non-local PCI bus, config_addr = %x %02x:%02x.%x @%02x.%c = %0*x", + this->name.c_str(), this->config_addr, bus_num, dev_num, fun_num, reg_offs, + size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, + size * 2, value + ); return; } if (dev_num == 0 && fun_num == 0) { // dev_num 0 is assigned to myself - this->pci_cfg_write(reg_offs + offset, value, size); + this->pci_cfg_write(reg_offs, value, size); } else { if (this->dev_map.count(dev_num)) { - this->dev_map[dev_num]->pci_cfg_write(reg_offs + offset, value, size); + this->dev_map[dev_num]->pci_cfg_write(reg_offs, value, size); } else { LOG_F( ERROR, "%s err: write attempt to non-existing PCI device %02x:%02x.%x @%02x.%c = %0*x", - this->name.c_str(), bus_num, dev_num, fun_num, reg_offs + offset, + this->name.c_str(), bus_num, dev_num, fun_num, reg_offs, size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, - size * 2, flip_sized(value, size) + size * 2, value ); } } @@ -200,17 +200,7 @@ uint32_t MPC106::pci_cfg_read(uint32_t reg_offs, uint32_t size) { return PCIDevice::pci_cfg_read(reg_offs, size); } - uint32_t offset = reg_offs & 3; - reg_offs &= ~3; - if (~-size & offset) { - LOG_F( - WARNING, "%s: unaligned read @%02x.%c", - this->pci_name.c_str(), reg_offs + offset, - size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size - ); - } - - return pci_cfg_rev_read(READ_DWORD_LE_A(&this->my_pci_cfg_hdr[reg_offs]), offset, size); + return read_mem(&this->my_pci_cfg_hdr[reg_offs], size); } void MPC106::pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size) { @@ -223,20 +213,9 @@ void MPC106::pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size) { return; } - uint32_t offset = reg_offs & 3; - reg_offs &= ~3; - if (~-size & offset) { - LOG_F( - WARNING, "%s: unaligned write @%02x.%c = %0*x", - this->pci_name.c_str(), reg_offs + offset, - size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, flip_sized(value, size) - ); - } - // FIXME: implement write-protection for read-only registers - uint32_t *addr = (uint32_t *)&this->my_pci_cfg_hdr[reg_offs]; - WRITE_DWORD_LE_A(addr, pci_cfg_rev_write(READ_DWORD_LE_A(addr), offset, size, value)); + write_mem(&this->my_pci_cfg_hdr[reg_offs], value, size); if (this->my_pci_cfg_hdr[0xF2] & 8) { #ifdef MPC106_DEBUG diff --git a/devices/memctrl/mpc106.h b/devices/memctrl/mpc106.h index 99de748..5d62df2 100644 --- a/devices/memctrl/mpc106.h +++ b/devices/memctrl/mpc106.h @@ -59,8 +59,8 @@ public: protected: /* PCI access */ - uint32_t pci_read(uint32_t offset, uint32_t size); - void pci_write(uint32_t offset, uint32_t value, uint32_t size); + uint32_t pci_read(uint32_t size); + void pci_write(uint32_t value, uint32_t size); /* my own PCI configuration registers access */ uint32_t pci_cfg_read(uint32_t reg_offs, uint32_t size); diff --git a/devices/video/atirage.cpp b/devices/video/atirage.cpp index 3b6a556..5efb89b 100644 --- a/devices/video/atirage.cpp +++ b/devices/video/atirage.cpp @@ -167,25 +167,11 @@ uint32_t ATIRage::pci_cfg_read(uint32_t reg_offs, uint32_t size) return PCIDevice::pci_cfg_read(reg_offs, size); } - uint32_t offset = reg_offs & 3; - reg_offs &= ~3; - if (~-size & offset) { - LOG_F( - WARNING, "%s: unaligned read @%02x.%c", - this->pci_name.c_str(), reg_offs + offset, - size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size - ); - } - switch (reg_offs) { case 0x40: - return pci_cfg_rev_read(this->user_cfg, offset, size); + return this->user_cfg; default: - LOG_F( - WARNING, "%s: reading from unimplemented config register @%02x.%c", - this->pci_name.c_str(), reg_offs + offset, - size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size - ); + LOG_F(WARNING, "ATIRage: reading from unimplemented config register at 0x%X", reg_offs); } return 0; @@ -195,29 +181,14 @@ void ATIRage::pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size) { if (reg_offs < 64) { PCIDevice::pci_cfg_write(reg_offs, value, size); - return; - } - - uint32_t offset = reg_offs & 3; - reg_offs &= ~3; - if (~-size & offset) { - LOG_F( - WARNING, "%s: unaligned write @%02x.%c = %0*x", - this->pci_name.c_str(), reg_offs + offset, - size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, flip_sized(value, size) - ); - } - - switch (reg_offs) { - case 0x40: - this->user_cfg = pci_cfg_rev_write(this->user_cfg, offset, size, value); - break; - default: - LOG_F( - WARNING, "%s: writing to unimplemented config register @%02x.%c = %0*x", - this->pci_name.c_str(), reg_offs + offset, - size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, flip_sized(value, size) - ); + } else { + switch (reg_offs) { + case 0x40: + this->user_cfg = value; + break; + default: + LOG_F(WARNING, "ATIRage: writing to unimplemented config register at 0x%X", reg_offs); + } } } diff --git a/devices/video/control.cpp b/devices/video/control.cpp index cfbcedc..b15b4c2 100644 --- a/devices/video/control.cpp +++ b/devices/video/control.cpp @@ -59,7 +59,6 @@ ControlVideo::ControlVideo() this->vendor_id = PCI_VENDOR_APPLE; this->device_id = 3; this->class_rev = 0; - this->bars_cfg[0] = 0xFFFFFFFFUL; // I/O region (4 bytes but it's weird because bit 1 is set) this->bars_cfg[1] = 0xFFFFF000UL; // base address for the HW registers (4KB) this->bars_cfg[2] = 0xFC000000UL; // base address for the VRAM (64MB) @@ -85,10 +84,6 @@ ControlVideo::ControlVideo() void ControlVideo::notify_bar_change(int bar_num) { switch (bar_num) { - case 0: - this->io_base = this->bars[bar_num] & ~3; - LOG_F(INFO, "Control: I/O space address set to 0x%08X", this->io_base); - break; case 1: if (this->regs_base != (this->bars[bar_num] & 0xFFFFFFF0UL)) { this->regs_base = this->bars[bar_num] & 0xFFFFFFF0UL; @@ -121,22 +116,18 @@ uint32_t ControlVideo::read(uint32_t rgn_start, uint32_t offset, int size) } } - if (rgn_start == this->regs_base) { - switch (offset >> 4) { - case ControlRegs::TEST: - result = this->test; - break; - case ControlRegs::MON_SENSE: - result = this->cur_mon_id << 6; - break; - default: - LOG_F(INFO, "read from 0x%08X:0x%08X", rgn_start, offset); - } - - return BYTESWAP_32(result); + switch (offset >> 4) { + case ControlRegs::TEST: + result = this->test; + break; + case ControlRegs::MON_SENSE: + result = this->cur_mon_id << 6; + break; + default: + LOG_F(INFO, "read from 0x%08X:0x%08X", rgn_start, offset); } - return 0; + return BYTESWAP_32(result); } void ControlVideo::write(uint32_t rgn_start, uint32_t offset, uint32_t value, int size) @@ -150,77 +141,75 @@ void ControlVideo::write(uint32_t rgn_start, uint32_t offset, uint32_t value, in return; } - if (rgn_start == this->regs_base) { - value = BYTESWAP_32(value); + value = BYTESWAP_32(value); - switch (offset >> 4) { - case ControlRegs::VFPEQ: - case ControlRegs::VFP: - case ControlRegs::VAL: - case ControlRegs::VBP: - case ControlRegs::VBPEQ: - case ControlRegs::VSYNC: - case ControlRegs::VHLINE: - case ControlRegs::PIPED: - case ControlRegs::HPIX: - case ControlRegs::HFP: - case ControlRegs::HAL: - case ControlRegs::HBWAY: - case ControlRegs::HSP: - case ControlRegs::HEQ: - case ControlRegs::HLFLN: - case ControlRegs::HSERR: - this->swatch_params[(offset >> 4) - 1] = value; - break; - case ControlRegs::TEST: - if (this->test != value) { - if ((this->test & ~TEST_STROBE) != (value & ~TEST_STROBE)) { - this->test = value; - this->test_shift = 0; - LOG_F(9, "New TEST value: 0x%08X", this->test); - } else { - LOG_F(9, "TEST strobe bit flipped, new value: 0x%08X", value); - this->test = value; - if (++this->test_shift >= 3) { - LOG_F(9, "Received TEST reg value: 0x%08X", this->test & ~TEST_STROBE); - if ((this->test ^ this->prev_test) & 0x400) { - if (this->test & 0x400) { - this->disable_display(); - } else { - this->enable_display(); - } - this->prev_test = this->test; + switch (offset >> 4) { + case ControlRegs::VFPEQ: + case ControlRegs::VFP: + case ControlRegs::VAL: + case ControlRegs::VBP: + case ControlRegs::VBPEQ: + case ControlRegs::VSYNC: + case ControlRegs::VHLINE: + case ControlRegs::PIPED: + case ControlRegs::HPIX: + case ControlRegs::HFP: + case ControlRegs::HAL: + case ControlRegs::HBWAY: + case ControlRegs::HSP: + case ControlRegs::HEQ: + case ControlRegs::HLFLN: + case ControlRegs::HSERR: + this->swatch_params[(offset >> 4) - 1] = value; + break; + case ControlRegs::TEST: + if (this->test != value) { + if ((this->test & ~TEST_STROBE) != (value & ~TEST_STROBE)) { + this->test = value; + this->test_shift = 0; + LOG_F(9, "New TEST value: 0x%08X", this->test); + } else { + LOG_F(9, "TEST strobe bit flipped, new value: 0x%08X", value); + this->test = value; + if (++this->test_shift >= 3) { + LOG_F(9, "Received TEST reg value: 0x%08X", this->test & ~TEST_STROBE); + if ((this->test ^ this->prev_test) & 0x400) { + if (this->test & 0x400) { + this->disable_display(); + } else { + this->enable_display(); } + this->prev_test = this->test; } } } - break; - case ControlRegs::GBASE: - this->fb_base = value; - break; - case ControlRegs::ROW_WORDS: - this->row_words = value; - break; - case ControlRegs::MON_SENSE: - LOG_F(9, "Control: monitor sense written with 0x%X", value); - value = (value >> 3) & 7; - this->cur_mon_id = this->display_id->read_monitor_sense(value & 7, value ^ 7); - break; - case ControlRegs::ENABLE: - this->flags = value; - break; - case ControlRegs::GSC_DIVIDE: - this->clock_divider = value; - break; - case ControlRegs::REFRESH_COUNT: - LOG_F(INFO, "Control: refresh count set to 0x%08X", value); - break; - case ControlRegs::INT_ENABLE: - this->int_enable = value; - break; - default: - LOG_F(INFO, "write 0x%08X to 0x%08X:0x%08X", value, rgn_start, offset); } + break; + case ControlRegs::GBASE: + this->fb_base = value; + break; + case ControlRegs::ROW_WORDS: + this->row_words = value; + break; + case ControlRegs::MON_SENSE: + LOG_F(9, "Control: monitor sense written with 0x%X", value); + value = (value >> 3) & 7; + this->cur_mon_id = this->display_id->read_monitor_sense(value & 7, value ^ 7); + break; + case ControlRegs::ENABLE: + this->flags = value; + break; + case ControlRegs::GSC_DIVIDE: + this->clock_divider = value; + break; + case ControlRegs::REFRESH_COUNT: + LOG_F(INFO, "Control: refresh count set to 0x%08X", value); + break; + case ControlRegs::INT_ENABLE: + this->int_enable = value; + break; + default: + LOG_F(INFO, "write 0x%08X to 0x%08X:0x%08X", value, rgn_start, offset); } } diff --git a/devices/video/control.h b/devices/video/control.h index 89aa376..323d695 100644 --- a/devices/video/control.h +++ b/devices/video/control.h @@ -117,7 +117,6 @@ private: std::unique_ptr vram_ptr; uint32_t vram_size; - uint32_t io_base = 0; uint32_t vram_base = 0; uint32_t regs_base = 0; uint32_t prev_test = 0x433; diff --git a/memaccess.h b/memaccess.h index c90c11c..46bc60c 100644 --- a/memaccess.h +++ b/memaccess.h @@ -177,60 +177,6 @@ inline uint32_t read_mem_rev(const uint8_t* buf, uint32_t size) { } } -/* value is dword from PCI config. MSB..LSB of value is stored in PCI config as 0:LSB..3:MSB. - result is part of value at byte offset from LSB and size bytes (with wrap around) and flipped as required for pci_cfg_read result. */ -inline uint32_t pci_cfg_rev_read(uint32_t value, uint32_t offset, uint32_t size) { - switch (size << 2 | offset) { - case 0x04: return value & 0xff; // 0 - case 0x05: return (value >> 8) & 0xff; // 1 - case 0x06: return (value >> 16) & 0xff; // 2 - case 0x07: return (value >> 24) & 0xff; // 3 - - case 0x08: return ((value & 0xff) << 8) | ((value >> 8) & 0xff); // 0 1 - case 0x09: return ( value & 0xff00) | ((value >> 16) & 0xff); // 1 2 - case 0x0a: return ((value >> 8) & 0xff00) | ((value >> 24) & 0xff); // 2 3 - case 0x0b: return ((value >> 16) & 0xff00) | ( value & 0xff); // 3 0 - - case 0x10: return ((value & 0xff) << 24) | ((value & 0xff00) << 8) | ((value >> 8) & 0xff00) | ((value >> 24) & 0xff); // 0 1 2 3 - case 0x11: return ((value & 0xff00) << 16) | ( value & 0xff0000) | ((value >> 16) & 0xff00) | ( value & 0xff); // 1 2 3 0 - case 0x12: return ((value & 0xff0000) << 8) | ((value >> 8) & 0xff0000) | ((value & 0xff) << 8) | ((value >> 8) & 0xff); // 2 3 0 1 - case 0x13: return ( value & 0xff000000) | ((value & 0xff) << 16) | ( value & 0xff00) | ((value >> 16) & 0xff); // 3 0 1 2 - default: LOG_F(ERROR, "pci_cfg_rev: invalid offset %d for size %d!", offset, size); return 0xffffffff; - } -} - -/* value is dword from PCI config. MSB..LSB of value (3.2.1.0) is stored in PCI config as 0:LSB..3:MSB. - data is flipped bytes (d0.d1.d2.d3, as passed to pci_cfg_write) to be merged into value. - result is part of value at byte offset from LSB and size bytes (with wrap around) modified by data. */ -inline uint32_t pci_cfg_rev_write(uint32_t value, uint32_t offset, uint32_t size, uint32_t data) { - switch (size << 2 | offset) { - case 0x04: return (value & 0xffffff00) | (data & 0xff); // 3 2 1 d0 - case 0x05: return (value & 0xffff00ff) | ((data & 0xff) << 8); // 3 2 d0 0 - case 0x06: return (value & 0xff00ffff) | ((data & 0xff) << 16); // 3 d0 1 0 - case 0x07: return (value & 0x00ffffff) | ((data & 0xff) << 24); // d0 2 1 0 - - case 0x08: return (value & 0xffff0000) | ((data >> 8) & 0xff) | ((data & 0xff) << 8); // 3 2 d1 d0 - case 0x09: return (value & 0xff0000ff) | (data & 0xff00) | ((data & 0xff) << 16); // 3 d1 d0 0 - case 0x0a: return (value & 0x0000ffff) | ((data & 0xff00) << 8) | ((data & 0xff) << 24); // d1 d0 1 0 - case 0x0b: return (value & 0x00ffff00) | ((data & 0xff00) << 16) | (data & 0xff); // d0 2 1 d1 - - case 0x10: return ((data & 0xff) << 24) | ((data & 0xff00) << 8) | ((data >> 8) & 0xff00) | ((data >> 24) & 0xff); // d3 d2 d1 d0 - case 0x11: return ((data & 0xff00) << 16) | ( data & 0xff0000) | ((data >> 16) & 0xff00) | ( data & 0xff); // d2 d1 d0 d3 - case 0x12: return ((data & 0xff0000) << 8) | ((data >> 8) & 0xff0000) | ((data & 0xff) << 8) | ((data >> 8) & 0xff); // d1 d0 d3 d2 - case 0x13: return ( data & 0xff000000) | ((data & 0xff) << 16) | ( data & 0xff00) | ((data >> 16) & 0xff); // d0 d3 d2 d1 - default: LOG_F(ERROR, "pci_cfg_rev: invalid offset %d for size %d!", offset, size); return 0xffffffff; - } -} - -inline uint32_t flip_sized(uint32_t value, uint32_t size) { - switch (size) { - case 1: return value; - case 2: return BYTESWAP_16(value); - case 4: return BYTESWAP_32(value); - default: LOG_F(ERROR, "flip_sized: invalid size %d!", size); return 0xffffffff; - } -} - /* write the specified value of the specified size to memory pointed to by addr, perform necessary byte swapping so that the byte order of the destination remains unchanged. */