mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-01-13 18:30:44 +00:00
bandit: implement Aspen style PCI bridge.
This commit is contained in:
parent
dcdfaabedf
commit
e7da98b6bd
@ -161,7 +161,7 @@ uint32_t BanditHost::read(uint32_t rgn_start, uint32_t offset, int size)
|
|||||||
return 0xFFFFFFFFUL; // PCI spec §6.1
|
return 0xFFFFFFFFUL; // PCI spec §6.1
|
||||||
|
|
||||||
case 2: // CONFIG_ADDR
|
case 2: // CONFIG_ADDR
|
||||||
return BYTESWAP_32(this->config_addr);
|
return (this->is_aspen) ? this->config_addr : BYTESWAP_32(this->config_addr);
|
||||||
|
|
||||||
default: // I/O space
|
default: // I/O space
|
||||||
return pci_io_read_broadcast(offset, size);
|
return pci_io_read_broadcast(offset, size);
|
||||||
@ -193,7 +193,10 @@ void BanditHost::write(uint32_t rgn_start, uint32_t offset, uint32_t value, int
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // CONFIG_ADDR
|
case 2: // CONFIG_ADDR
|
||||||
this->config_addr = BYTESWAP_32(value);
|
if (this->is_aspen)
|
||||||
|
this->config_addr = value;
|
||||||
|
else
|
||||||
|
BYTESWAP_32(value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: // I/O space
|
default: // I/O space
|
||||||
@ -218,20 +221,23 @@ inline void BanditHost::cfg_setup(uint32_t offset, int size, int &bus_num,
|
|||||||
}
|
}
|
||||||
details.flags = PCI_CONFIG_TYPE_0;
|
details.flags = PCI_CONFIG_TYPE_0;
|
||||||
bus_num = 0; // use dummy value for bus number
|
bus_num = 0; // use dummy value for bus number
|
||||||
uint32_t idsel = this->config_addr & 0xFFFFF800U;
|
if (is_aspen)
|
||||||
if (!SINGLE_BIT_SET(idsel)) {
|
dev_num = (this->config_addr >> 11) + 11; // IDSEL = 1 << (dev_num + 11)
|
||||||
for (dev_num = -1, idsel = this->config_addr; idsel; idsel >>= 1, dev_num++) {}
|
else {
|
||||||
LOG_F(ERROR, "%s: config_addr 0x%08x does not contain valid IDSEL",
|
uint32_t idsel = this->config_addr & 0xFFFFF800U;
|
||||||
this->name.c_str(), (uint32_t)this->config_addr);
|
if (!SINGLE_BIT_SET(idsel)) {
|
||||||
device = NULL;
|
for (dev_num = -1, idsel = this->config_addr; idsel; idsel >>= 1, dev_num++) {}
|
||||||
return;
|
LOG_F(ERROR, "%s: config_addr 0x%08x does not contain valid IDSEL",
|
||||||
|
this->name.c_str(), (uint32_t)this->config_addr);
|
||||||
|
device = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dev_num = WHAT_BIT_SET(idsel);
|
||||||
}
|
}
|
||||||
dev_num = WHAT_BIT_SET(idsel);
|
|
||||||
device = pci_find_device(dev_num, fun_num);
|
device = pci_find_device(dev_num, fun_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
int BanditHost::device_postinit()
|
int BanditHost::device_postinit() {
|
||||||
{
|
|
||||||
std::string pci_dev_name;
|
std::string pci_dev_name;
|
||||||
|
|
||||||
static const std::map<std::string, int> pci_slots1 = {
|
static const std::map<std::string, int> pci_slots1 = {
|
||||||
@ -303,6 +309,23 @@ Chaos::Chaos(std::string name) : BanditHost(0)
|
|||||||
mem_ctrl->add_mmio_region(0xF0000000UL, 0x01000000, this);
|
mem_ctrl->add_mmio_region(0xF0000000UL, 0x01000000, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AspenPci::AspenPci(std::string name) : BanditHost(1) {
|
||||||
|
this->name = name;
|
||||||
|
|
||||||
|
supports_types(HWCompType::PCI_HOST);
|
||||||
|
|
||||||
|
this->is_aspen = true;
|
||||||
|
|
||||||
|
MemCtrlBase *mem_ctrl = dynamic_cast<MemCtrlBase *>
|
||||||
|
(gMachineObj->get_comp_by_type(HWCompType::MEM_CTRL));
|
||||||
|
|
||||||
|
// add memory mapped I/O region for Aspen PCI control registers
|
||||||
|
// This region has the following layout:
|
||||||
|
// base_addr + 0x800000 --> CONFIG_ADDR
|
||||||
|
// base_addr + 0xC00000 --> CONFIG_DATA
|
||||||
|
mem_ctrl->add_mmio_region(0xF2000000UL, 0x01000000, this);
|
||||||
|
}
|
||||||
|
|
||||||
static const PropMap Bandit1_Properties = {
|
static const PropMap Bandit1_Properties = {
|
||||||
{"pci_A1",
|
{"pci_A1",
|
||||||
new StrProperty("")},
|
new StrProperty("")},
|
||||||
@ -346,7 +369,12 @@ static const DeviceDescription Chaos_Descriptor = {
|
|||||||
Chaos::create, {}, Chaos_Properties
|
Chaos::create, {}, Chaos_Properties
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_DEVICE(Bandit1, Bandit1_Descriptor);
|
static const DeviceDescription AspenPci1_Descriptor = {
|
||||||
REGISTER_DEVICE(Bandit2, Bandit2_Descriptor);
|
AspenPci::create, {}, Bandit1_Properties
|
||||||
REGISTER_DEVICE(PsxPci1, PsxPci1_Descriptor);
|
};
|
||||||
REGISTER_DEVICE(Chaos, Chaos_Descriptor);
|
|
||||||
|
REGISTER_DEVICE(Bandit1, Bandit1_Descriptor);
|
||||||
|
REGISTER_DEVICE(Bandit2, Bandit2_Descriptor);
|
||||||
|
REGISTER_DEVICE(PsxPci1, PsxPci1_Descriptor);
|
||||||
|
REGISTER_DEVICE(AspenPci1, AspenPci1_Descriptor);
|
||||||
|
REGISTER_DEVICE(Chaos, Chaos_Descriptor);
|
||||||
|
@ -85,6 +85,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
uint32_t config_addr;
|
uint32_t config_addr;
|
||||||
int bridge_num;
|
int bridge_num;
|
||||||
|
bool is_aspen = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void cfg_setup(uint32_t offset, int size, int &bus_num, int &dev_num,
|
void cfg_setup(uint32_t offset, int size, int &bus_num, int &dev_num,
|
||||||
@ -134,8 +135,8 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t base_addr;
|
|
||||||
std::unique_ptr<BanditPciDevice> my_pci_device;
|
std::unique_ptr<BanditPciDevice> my_pci_device;
|
||||||
|
uint32_t base_addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -151,4 +152,17 @@ public:
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Aspen PCI Bridge HLE emulation class.
|
||||||
|
*/
|
||||||
|
class AspenPci : public BanditHost {
|
||||||
|
public:
|
||||||
|
AspenPci(std::string name);
|
||||||
|
~AspenPci() = default;
|
||||||
|
|
||||||
|
static std::unique_ptr<HWComponent> create() {
|
||||||
|
return std::unique_ptr<AspenPci>(new AspenPci("Aspen-PCI1"));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
#endif // BANDIT_PCI_H
|
#endif // BANDIT_PCI_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user