mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-12-25 18:29:49 +00:00
bandit: add Chaos support.
This commit is contained in:
parent
ea0fb3b410
commit
e3900b9062
@ -231,8 +231,106 @@ void Bandit::verbose_address_space()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Chaos::Chaos(std::string name) : PCIHost()
|
||||||
|
{
|
||||||
|
supports_types(HWCompType::PCI_HOST);
|
||||||
|
|
||||||
|
MemCtrlBase *mem_ctrl = dynamic_cast<MemCtrlBase *>
|
||||||
|
(gMachineObj->get_comp_by_type(HWCompType::MEM_CTRL));
|
||||||
|
|
||||||
|
// add memory mapped I/O region for Chaos control registers
|
||||||
|
// This region has the following layout:
|
||||||
|
// base_addr + 0x800000 --> CONFIG_ADDR
|
||||||
|
// base_addr + 0xC00000 --> CONFIG_DATA
|
||||||
|
mem_ctrl->add_mmio_region(0xF0000000UL, 0x01000000, this);
|
||||||
|
|
||||||
|
this->name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Chaos::read(uint32_t reg_start, uint32_t offset, int size)
|
||||||
|
{
|
||||||
|
int fun_num;
|
||||||
|
uint8_t reg_offs;
|
||||||
|
uint32_t result, idsel;
|
||||||
|
|
||||||
|
if (offset & BANDIT_CONFIG_SPACE) {
|
||||||
|
if (offset & 0x00400000) {
|
||||||
|
idsel = (this->config_addr >> 11) & 0x1FFFFFU;
|
||||||
|
fun_num = (this->config_addr >> 8) & 7;
|
||||||
|
reg_offs = this->config_addr & 0xFCU;
|
||||||
|
|
||||||
|
if (!SINGLE_BIT_SET(idsel)) {
|
||||||
|
LOG_F(ERROR, "%s: invalid IDSEL=0x%X passed", this->name.c_str(), idsel);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->dev_map.count(idsel)) {
|
||||||
|
result = this->dev_map[idsel]->pci_cfg_read(reg_offs, size);
|
||||||
|
} else {
|
||||||
|
LOG_F(
|
||||||
|
ERROR,
|
||||||
|
"%s err: read attempt from non-existing VCI device %d \n",
|
||||||
|
this->name.c_str(),
|
||||||
|
idsel);
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = this->config_addr;
|
||||||
|
}
|
||||||
|
} else { // I/O space access
|
||||||
|
LOG_F(ERROR, "%s: I/O space not supported", this->name.c_str());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Chaos::write(uint32_t reg_start, uint32_t offset, uint32_t value, int size)
|
||||||
|
{
|
||||||
|
int fun_num;
|
||||||
|
uint8_t reg_offs;
|
||||||
|
uint32_t idsel;
|
||||||
|
|
||||||
|
if (offset & BANDIT_CONFIG_SPACE) {
|
||||||
|
if (offset & 0x00400000) {
|
||||||
|
// access to the CONFIG_DATA pseudo-register causes a Config Cycle
|
||||||
|
if (this->config_addr & BANDIT_CAR_TYPE) {
|
||||||
|
LOG_F(WARNING, "%s: config cycle type 1 not supported yet", this->name.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
idsel = (this->config_addr >> 11) & 0x1FFFFFU;
|
||||||
|
fun_num = (this->config_addr >> 8) & 7;
|
||||||
|
reg_offs = this->config_addr & 0xFCU;
|
||||||
|
|
||||||
|
if (!SINGLE_BIT_SET(idsel)) {
|
||||||
|
LOG_F(ERROR, "%s: invalid IDSEL=0x%X passed", this->name.c_str(), idsel);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->dev_map.count(idsel)) {
|
||||||
|
this->dev_map[idsel]->pci_cfg_write(reg_offs, value, size);
|
||||||
|
} else {
|
||||||
|
LOG_F(
|
||||||
|
ERROR,
|
||||||
|
"%s err: write attempt to non-existing VCI device %d \n",
|
||||||
|
this->name.c_str(),
|
||||||
|
idsel);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this->config_addr = BYTESWAP_32(value);
|
||||||
|
}
|
||||||
|
} else { // I/O space access
|
||||||
|
LOG_F(ERROR, "%s: I/O space not supported", this->name.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const DeviceDescription Bandit1_Descriptor = {
|
static const DeviceDescription Bandit1_Descriptor = {
|
||||||
Bandit::create_first, {}, {}
|
Bandit::create_first, {}, {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const DeviceDescription Chaos_Descriptor = {
|
||||||
|
Chaos::create, {}, {}
|
||||||
|
};
|
||||||
|
|
||||||
REGISTER_DEVICE(Bandit1, Bandit1_Descriptor);
|
REGISTER_DEVICE(Bandit1, Bandit1_Descriptor);
|
||||||
|
REGISTER_DEVICE(Chaos, Chaos_Descriptor);
|
||||||
|
@ -29,6 +29,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
#define BANDIT_PCI_H
|
#define BANDIT_PCI_H
|
||||||
|
|
||||||
#include <devices/common/hwcomponent.h>
|
#include <devices/common/hwcomponent.h>
|
||||||
|
#include <devices/common/mmiodevice.h>
|
||||||
#include <devices/common/pci/pcidevice.h>
|
#include <devices/common/pci/pcidevice.h>
|
||||||
#include <devices/common/pci/pcihost.h>
|
#include <devices/common/pci/pcihost.h>
|
||||||
|
|
||||||
@ -56,7 +57,7 @@ public:
|
|||||||
|
|
||||||
static std::unique_ptr<HWComponent> create_first() {
|
static std::unique_ptr<HWComponent> create_first() {
|
||||||
return std::unique_ptr<Bandit>(new Bandit(1, "Bandit-PCI1"));
|
return std::unique_ptr<Bandit>(new Bandit(1, "Bandit-PCI1"));
|
||||||
}
|
};
|
||||||
|
|
||||||
uint32_t pci_cfg_read(uint32_t reg_offs, uint32_t size);
|
uint32_t pci_cfg_read(uint32_t reg_offs, uint32_t size);
|
||||||
void pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size);
|
void pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size);
|
||||||
@ -74,4 +75,27 @@ private:
|
|||||||
uint32_t addr_mask;
|
uint32_t addr_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Chaos is a custom ARBus-to-PCI bridge that provides a specialized
|
||||||
|
PCI-like bus for video called VCI. This 64-bit bus runs at the same
|
||||||
|
frequency as the CPU bus (40-50 MHz) and provides an interface
|
||||||
|
between video input/output devices and the CPU bus.
|
||||||
|
*/
|
||||||
|
class Chaos : public PCIHost, public MMIODevice {
|
||||||
|
public:
|
||||||
|
Chaos(std::string name);
|
||||||
|
~Chaos() = default;
|
||||||
|
|
||||||
|
static std::unique_ptr<HWComponent> create() {
|
||||||
|
return std::unique_ptr<Chaos>(new Chaos("VCI0"));
|
||||||
|
};
|
||||||
|
|
||||||
|
// MMIODevice methods
|
||||||
|
uint32_t read(uint32_t reg_start, uint32_t offset, int size);
|
||||||
|
void write(uint32_t reg_start, uint32_t offset, uint32_t value, int size);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string name;
|
||||||
|
uint32_t config_addr;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // BANDIT_PCI_H
|
#endif // BANDIT_PCI_H
|
||||||
|
Loading…
Reference in New Issue
Block a user