mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-12-27 00:29:18 +00:00
atirage: PCI BAR changes.
- Add BAR 2 decode. This BAR isn't actually used by Mac OS X, but decode it anyway just in case. - Support updating of BARs (using change_one_bar method).
This commit is contained in:
parent
9c48c296c8
commit
eef6d267c3
@ -124,12 +124,10 @@ ATIRage::ATIRage(uint16_t dev_id)
|
||||
this->class_rev = (0x030000 << 8) | asic_id;
|
||||
this->min_gnt = 8;
|
||||
this->irq_pin = 1;
|
||||
|
||||
this->setup_bars({
|
||||
{0, 0xFF000000UL}, // declare main aperture (16MB)
|
||||
{1, 0xFFFFFF01UL}, // declare I/O region (256 bytes)
|
||||
{2, 0xFFFFF000UL} // declare register aperture (4KB)
|
||||
});
|
||||
for (int i = 0; i < this->aperture_count; i++) {
|
||||
this->bars_cfg[i] = (uint32_t)(-this->aperture_size[i] | this->aperture_flag[i]);
|
||||
}
|
||||
this->finish_config_bars();
|
||||
|
||||
this->pci_notify_bar_change = [this](int bar_num) {
|
||||
this->notify_bar_change(bar_num);
|
||||
@ -146,23 +144,31 @@ ATIRage::ATIRage(uint16_t dev_id)
|
||||
this->regs[ATI_GP_IO] = ((mon_code & 6) << 11) | ((mon_code & 1) << 8);
|
||||
}
|
||||
|
||||
void ATIRage::change_one_bar(uint32_t &aperture, uint32_t aperture_size, uint32_t aperture_new, int bar_num) {
|
||||
if (aperture != aperture_new) {
|
||||
if (aperture)
|
||||
this->host_instance->pci_unregister_mmio_region(aperture, aperture_size, this);
|
||||
|
||||
aperture = aperture_new;
|
||||
if (aperture)
|
||||
this->host_instance->pci_register_mmio_region(aperture, aperture_size, this);
|
||||
|
||||
LOG_F(INFO, "%s: aperture[%d] set to 0x%08X", this->name.c_str(), bar_num, aperture);
|
||||
}
|
||||
}
|
||||
|
||||
void ATIRage::notify_bar_change(int bar_num)
|
||||
{
|
||||
switch (bar_num) {
|
||||
case 0:
|
||||
if (this->aperture_base != (this->bars[bar_num] & 0xFFFFFFF0UL)) {
|
||||
this->aperture_base = this->bars[0] & 0xFFFFFFF0UL;
|
||||
this->host_instance->pci_register_mmio_region(this->aperture_base,
|
||||
APERTURE_SIZE - this->vram_size, this);
|
||||
LOG_F(INFO, "ATIRage: aperture address set to 0x%08X", this->aperture_base);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
this->io_base = this->bars[1] & ~3;
|
||||
LOG_F(INFO, "ATIRage: I/O space address set to 0x%08X", this->io_base);
|
||||
change_one_bar(this->aperture_base[bar_num], this->aperture_size[bar_num] - this->vram_size, this->bars[bar_num] & ~15, bar_num);
|
||||
break;
|
||||
case 2:
|
||||
LOG_F(INFO, "ATIRage: register aperture address set to 0x%08X", this->bars[2]);
|
||||
change_one_bar(this->aperture_base[bar_num], this->aperture_size[bar_num], this->bars[bar_num] & ~15, bar_num);
|
||||
break;
|
||||
case 1:
|
||||
this->aperture_base[1] = this->bars[bar_num] & ~3;
|
||||
LOG_F(INFO, "%s: I/O space address set to 0x%08X", this->name.c_str(), this->aperture_base[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -383,7 +389,7 @@ void ATIRage::write_reg(uint32_t reg_offset, uint32_t value, uint32_t size) {
|
||||
}
|
||||
|
||||
bool ATIRage::io_access_allowed(uint32_t offset) {
|
||||
if (offset >= this->io_base && offset < (this->io_base + 0x100)) {
|
||||
if (offset >= this->aperture_base[1] && offset < (this->aperture_base[1] + 0x100)) {
|
||||
if (this->command & 1) {
|
||||
return true;
|
||||
}
|
||||
@ -392,65 +398,85 @@ bool ATIRage::io_access_allowed(uint32_t offset) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool ATIRage::pci_io_read(uint32_t offset, uint32_t size, uint32_t* res) {
|
||||
if (!this->io_access_allowed(offset)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*res = BYTESWAP_SIZED(this->read_reg(offset - this->io_base, size), size);
|
||||
*res = BYTESWAP_SIZED(this->read_reg(offset - this->aperture_base[1], size), size);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ATIRage::pci_io_write(uint32_t offset, uint32_t value, uint32_t size) {
|
||||
if (!this->io_access_allowed(offset)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->write_reg(offset - this->io_base, BYTESWAP_SIZED(value, size), size);
|
||||
this->write_reg(offset - this->aperture_base[1], BYTESWAP_SIZED(value, size), size);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ATIRage::read(uint32_t rgn_start, uint32_t offset, int size)
|
||||
{
|
||||
if (offset < this->vram_size) { // little-endian VRAM region
|
||||
return read_mem(&this->vram_ptr[offset], size);
|
||||
}
|
||||
else if (offset >= BE_FB_OFFSET) { // big-endian VRAM region
|
||||
return read_mem(&this->vram_ptr[offset - BE_FB_OFFSET], size);
|
||||
}
|
||||
else if (offset >= MM_REGS_0_OFF) { // memory-mapped registers, block 0
|
||||
return BYTESWAP_SIZED(this->read_reg(offset & 0x3FF, size), size);
|
||||
}
|
||||
else if (offset >= MM_REGS_1_OFF) { // memory-mapped registers, block 1
|
||||
return BYTESWAP_SIZED(this->read_reg((offset & 0x3FF) + 0x400, size), size);
|
||||
}
|
||||
else {
|
||||
LOG_F(WARNING, "ATI Rage: read attempt from unmapped aperture region at 0x%08X", offset);
|
||||
if (rgn_start == this->aperture_base[0] && offset < this->aperture_size[0]) {
|
||||
if (offset < this->vram_size) { // little-endian VRAM region
|
||||
return read_mem(&this->vram_ptr[offset], size);
|
||||
}
|
||||
if (offset >= BE_FB_OFFSET) { // big-endian VRAM region
|
||||
return read_mem(&this->vram_ptr[offset - BE_FB_OFFSET], size);
|
||||
}
|
||||
//if (!bit_set(this->regs[ATI_BUS_CNTL], ATI_BUS_APER_REG_DIS)) {
|
||||
if (offset >= MM_REGS_0_OFF) { // memory-mapped registers, block 0
|
||||
return BYTESWAP_SIZED(this->read_reg(offset & 0x3FF, size), size);
|
||||
}
|
||||
if (offset >= MM_REGS_1_OFF
|
||||
//&& bit_set(this->regs[ATI_BUS_CNTL], ATI_BUS_EXT_REG_EN)
|
||||
) { // memory-mapped registers, block 1
|
||||
return BYTESWAP_SIZED(this->read_reg((offset & 0x3FF) + 0x400, size), size);
|
||||
}
|
||||
//}
|
||||
LOG_F(WARNING, "%s: read unmapped aperture[0] region %08x.%c", this->name.c_str(), offset, SIZE_ARG(size));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rgn_start == this->aperture_base[2] && offset < this->aperture_size[2]) {
|
||||
LOG_F(WARNING, "%s: read unmapped aperture[2] region %08x.%c", this->name.c_str(), offset, SIZE_ARG(size));
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOG_F(WARNING, "%s: read unmapped aperture region %08x.%c", this->name.c_str(), offset, SIZE_ARG(size));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ATIRage::write(uint32_t rgn_start, uint32_t offset, uint32_t value, int size)
|
||||
{
|
||||
if (offset < this->vram_size) { // little-endian VRAM region
|
||||
write_mem(&this->vram_ptr[offset], value, size);
|
||||
if (rgn_start == this->aperture_base[0] && offset < this->aperture_size[0]) {
|
||||
if (offset < this->vram_size) { // little-endian VRAM region
|
||||
return write_mem(&this->vram_ptr[offset], value, size);
|
||||
}
|
||||
if (offset >= BE_FB_OFFSET) { // big-endian VRAM region
|
||||
return write_mem(&this->vram_ptr[offset & (BE_FB_OFFSET - 1)], value, size);
|
||||
}
|
||||
//if (!bit_set(this->regs[ATI_BUS_CNTL], ATI_BUS_APER_REG_DIS)) {
|
||||
if (offset >= MM_REGS_0_OFF) { // memory-mapped registers, block 0
|
||||
return this->write_reg(offset & 0x3FF, BYTESWAP_SIZED(value, size), size);
|
||||
}
|
||||
if (offset >= MM_REGS_1_OFF
|
||||
//&& bit_set(this->regs[ATI_BUS_CNTL], ATI_BUS_EXT_REG_EN)
|
||||
) { // memory-mapped registers, block 1
|
||||
return this->write_reg((offset & 0x3FF) + 0x400, BYTESWAP_SIZED(value, size), size);
|
||||
}
|
||||
//}
|
||||
LOG_F(WARNING, "%s: write unmapped aperture[0] region %08x.%c = %0*x", this->name.c_str(), offset, SIZE_ARG(size), size * 2, value);
|
||||
return;
|
||||
}
|
||||
else if (offset >= BE_FB_OFFSET) { // big-endian VRAM region
|
||||
write_mem(&this->vram_ptr[offset & (BE_FB_OFFSET - 1)], value, size);
|
||||
}
|
||||
else if (offset >= MM_REGS_0_OFF) { // memory-mapped registers, block 0
|
||||
this->write_reg(offset & 0x3FF, BYTESWAP_SIZED(value, size), size);
|
||||
}
|
||||
else if (offset >= MM_REGS_1_OFF) { // memory-mapped registers, block 1
|
||||
this->write_reg((offset & 0x3FF) + 0x400, BYTESWAP_SIZED(value, size), size);
|
||||
}
|
||||
else {
|
||||
LOG_F(WARNING, "ATI Rage: write attempt to unmapped aperture region at 0x%08X", offset);
|
||||
|
||||
if (rgn_start == this->aperture_base[2] && offset < this->aperture_size[2]) {
|
||||
LOG_F(WARNING, "%s: write unmapped aperture[2] region %08x.%c = %0*x", this->name.c_str(), offset, SIZE_ARG(size), size * 2, value);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_F(WARNING, "%s: write unmapped aperture region %08x.%c = %0*x", this->name.c_str(), offset, SIZE_ARG(size), size * 2, value);
|
||||
}
|
||||
|
||||
float ATIRage::calc_pll_freq(int scale, int fb_div) {
|
||||
|
@ -81,6 +81,8 @@ protected:
|
||||
void get_cursor_position(int& x, int& y);
|
||||
|
||||
private:
|
||||
void change_one_bar(uint32_t &aperture, uint32_t aperture_size, uint32_t aperture_new, int bar_num);
|
||||
|
||||
uint32_t regs[512] = {}; // internal registers
|
||||
uint8_t plls[64] = {}; // internal PLL registers
|
||||
|
||||
@ -90,10 +92,17 @@ private:
|
||||
std::unique_ptr<uint8_t[]> vram_ptr;
|
||||
uint32_t vram_size;
|
||||
|
||||
uint32_t aperture_base = 0;
|
||||
uint32_t io_base = 0;
|
||||
// config 0x40
|
||||
uint8_t user_cfg = 8;
|
||||
|
||||
// main aperture (16MB)
|
||||
// I/O region (256 bytes)
|
||||
// register aperture (4KB)
|
||||
uint32_t aperture_count = 3;
|
||||
uint32_t aperture_base[3] = { 0, 0, 0 };
|
||||
uint32_t aperture_size[3] = { 0x1000000, 0x100, 0x1000 };
|
||||
uint32_t aperture_flag[3] = { 0, 1, 0 };
|
||||
|
||||
std::unique_ptr<DisplayID> disp_id;
|
||||
|
||||
// DAC interface state
|
||||
|
Loading…
Reference in New Issue
Block a user