pcihost: pull common code from Grackle.

This commit is contained in:
Maxim Poliakovski 2022-01-16 21:30:43 +01:00
parent 36fa53e8c1
commit 289df32817
4 changed files with 57 additions and 52 deletions

View File

@ -0,0 +1,31 @@
#include <devices/common/pci/pcidevice.h>
#include <devices/common/pci/pcihost.h>
#include <devices/memctrl/memctrlbase.h>
#include <machines/machinebase.h>
#include <cinttypes>
bool PCIHost::pci_register_device(int dev_num, PCIDevice* dev_instance)
{
// return false if dev_num already registered
if (this->dev_map.count(dev_num))
return false;
this->dev_map[dev_num] = dev_instance;
dev_instance->set_host(this);
if (dev_instance->supports_io_space()) {
this->io_space_devs.push_back(dev_instance);
}
return true;
}
bool PCIHost::pci_register_mmio_region(uint32_t start_addr, uint32_t size, PCIDevice* obj)
{
MemCtrlBase *mem_ctrl = dynamic_cast<MemCtrlBase *>
(gMachineObj->get_comp_by_type(HWCompType::MEM_CTRL));
// FIXME: add sanity checks!
return mem_ctrl->add_mmio_region(start_addr, size, obj);
}

View File

@ -23,13 +23,26 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#define PCI_HOST_H
#include <cinttypes>
#include <unordered_map>
#include <vector>
class PCIDevice; // forward declaration to prevent errors
class PCIHost {
public:
virtual bool pci_register_device(int dev_num, PCIDevice* dev_instance) = 0;
virtual bool pci_register_mmio_region(uint32_t start_addr, uint32_t size, PCIDevice* obj) = 0;
PCIHost() {
this->dev_map.clear();
io_space_devs.clear();
};
~PCIHost() = default;
virtual bool pci_register_device(int dev_num, PCIDevice* dev_instance);
virtual bool pci_register_mmio_region(uint32_t start_addr, uint32_t size, PCIDevice* obj);
protected:
std::unordered_map<int, PCIDevice*> dev_map;
std::vector<PCIDevice*> io_space_devs;
};
#endif /* PCI_HOST_H */

View File

@ -1,6 +1,6 @@
/*
DingusPPC - The Experimental PowerPC Macintosh emulator
Copyright (C) 2018-21 divingkatae and maximum
Copyright (C) 2018-22 divingkatae and maximum
(theweirdo) spatium
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
@ -19,10 +19,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/** MPC106 (Grackle) emulation
Author: Max Poliakovski
*/
/** MPC106 (Grackle) emulation. */
#include <devices/common/hwcomponent.h>
#include <devices/common/mmiodevice.h>
@ -36,7 +33,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <loguru.hpp>
MPC106::MPC106() : MemCtrlBase(), PCIDevice("Grackle PCI host bridge") {
MPC106::MPC106() : MemCtrlBase(), PCIDevice("Grackle PCI host bridge"), PCIHost()
{
this->name = "Grackle";
supports_types(HWCompType::MEM_CTRL | HWCompType::MMIO_DEV |
@ -47,13 +45,6 @@ MPC106::MPC106() : MemCtrlBase(), PCIDevice("Grackle PCI host bridge") {
/* add memory mapped I/O region for MPC106 registers */
add_mmio_region(0xFEC00000, 0x300000, this);
this->pci_0_bus.clear();
this->io_space_devs.clear();
}
MPC106::~MPC106() {
this->pci_0_bus.clear();
}
uint32_t MPC106::read(uint32_t reg_start, uint32_t offset, int size) {
@ -120,8 +111,8 @@ uint32_t MPC106::pci_read(uint32_t size) {
if (dev_num == 0 && fun_num == 0) { // dev_num 0 is assigned to myself
return this->pci_cfg_read(reg_offs, size);
} else {
if (this->pci_0_bus.count(dev_num)) {
return this->pci_0_bus[dev_num]->pci_cfg_read(reg_offs, size);
if (this->dev_map.count(dev_num)) {
return this->dev_map[dev_num]->pci_cfg_read(reg_offs, size);
} else {
LOG_F(
ERROR,
@ -155,8 +146,8 @@ void MPC106::pci_write(uint32_t value, uint32_t size) {
if (dev_num == 0 && fun_num == 0) { // dev_num 0 is assigned to myself
this->pci_cfg_write(reg_offs, value, size);
} else {
if (this->pci_0_bus.count(dev_num)) {
this->pci_0_bus[dev_num]->pci_cfg_write(reg_offs, value, size);
if (this->dev_map.count(dev_num)) {
this->dev_map[dev_num]->pci_cfg_write(reg_offs, value, size);
} else {
LOG_F(
ERROR,
@ -192,26 +183,6 @@ void MPC106::pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size) {
}
}
bool MPC106::pci_register_device(int dev_num, PCIDevice* dev_instance) {
if (this->pci_0_bus.count(dev_num)) // is dev_num already registered?
return false;
this->pci_0_bus[dev_num] = dev_instance;
dev_instance->set_host(this);
if (dev_instance->supports_io_space()) {
this->io_space_devs.push_back(dev_instance);
}
return true;
}
bool MPC106::pci_register_mmio_region(uint32_t start_addr, uint32_t size, PCIDevice* obj) {
// FIXME: add sanity checks!
return this->add_mmio_region(start_addr, size, obj);
}
void MPC106::setup_ram() {
uint32_t mem_start, mem_end, ext_mem_start, ext_mem_end, bank_start, bank_end;
uint32_t ram_size = 0;

View File

@ -1,6 +1,6 @@
/*
DingusPPC - The Experimental PowerPC Macintosh emulator
Copyright (C) 2018-21 divingkatae and maximum
Copyright (C) 2018-22 divingkatae and maximum
(theweirdo) spatium
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
@ -18,9 +18,8 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/** MPC106 (Grackle) emulation
Author: Max Poliakovski
/** MPC106 (Grackle) emulation
Grackle IC is a combined memory and PCI controller manufactured by Motorola.
It's the central device in the Gossamer architecture.
@ -47,14 +46,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
class MPC106 : public MemCtrlBase, public PCIDevice, public PCIHost {
public:
MPC106();
~MPC106();
~MPC106() = default;
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);
/* PCI host bridge API */
bool pci_register_device(int dev_num, PCIDevice* dev_instance);
protected:
/* PCI access */
uint32_t pci_read(uint32_t size);
@ -68,8 +64,6 @@ protected:
return true;
};
bool pci_register_mmio_region(uint32_t start_addr, uint32_t size, PCIDevice* obj);
void setup_ram(void);
private:
@ -159,10 +153,6 @@ private:
};
uint32_t config_addr;
// uint32_t config_data;
std::unordered_map<int, PCIDevice*> pci_0_bus;
std::vector<PCIDevice*> io_space_devs;
};
#endif