mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-01-11 05:29:43 +00:00
Introduce base class HWComponent.
This commit is contained in:
parent
822f6cafd2
commit
d53400ebae
57
devices/hwcomponent.h
Normal file
57
devices/hwcomponent.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
DingusPPC - The Experimental PowerPC Macintosh emulator
|
||||
Copyright (C) 2018-20 divingkatae and maximum
|
||||
(theweirdo) spatium
|
||||
|
||||
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#ifndef HW_COMPONENT_H
|
||||
#define HW_COMPONENT_H
|
||||
|
||||
#include <string>
|
||||
|
||||
/** types of different HW components */
|
||||
enum HWCompType : int {
|
||||
UNKNOWN = 0, /* unknown component type */
|
||||
MEM_CTRL = 10, /* memory controller */
|
||||
ROM = 20, /* read-only memory */
|
||||
RAM = 30, /* random access memory */
|
||||
MMIO_DEV = 40, /* memory mapped I/O device */
|
||||
PCI_HOST = 50, /* PCI host */
|
||||
PCI_DEV = 51, /* PCI device */
|
||||
I2C_HOST = 60, /* I2C host */
|
||||
I2C_DEV = 61, /* I2C device */
|
||||
ADB_HOST = 70, /* ADB host */
|
||||
ADB_DEV = 71, /* ADB device */
|
||||
};
|
||||
|
||||
|
||||
/** Abstract base class for HW components. */
|
||||
class HWComponent {
|
||||
public:
|
||||
virtual ~HWComponent() = default;
|
||||
|
||||
virtual std::string get_name(void) { return this->name; };
|
||||
virtual void set_name(std::string name) { this->name = name; };
|
||||
|
||||
virtual bool supports_type(HWCompType type) = 0;
|
||||
|
||||
protected:
|
||||
std::string name;
|
||||
};
|
||||
|
||||
#endif /* HW_COMPONENT_H */
|
@ -23,6 +23,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#define MACHINE_ID_H
|
||||
|
||||
#include <cinttypes>
|
||||
#include "hwcomponent.h"
|
||||
#include "mmiodevice.h"
|
||||
|
||||
/**
|
||||
@ -46,6 +47,10 @@ public:
|
||||
GossamerID(const uint16_t id) { this->id = id, this->name = "Machine-id"; };
|
||||
~GossamerID() = default;
|
||||
|
||||
bool supports_type(HWCompType type) {
|
||||
return type == HWCompType::MMIO_DEV;
|
||||
};
|
||||
|
||||
uint32_t read(uint32_t offset, int size) {
|
||||
return ((!offset && size == 2) ? this->id : 0); };
|
||||
|
||||
|
@ -52,6 +52,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#define MACIO_H
|
||||
|
||||
#include <cinttypes>
|
||||
#include "hwcomponent.h"
|
||||
#include "pcidevice.h"
|
||||
#include "memctrlbase.h"
|
||||
#include "mmiodevice.h"
|
||||
@ -86,11 +87,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
class HeathrowIC : public PCIDevice
|
||||
{
|
||||
public:
|
||||
using PCIDevice::name;
|
||||
|
||||
HeathrowIC();
|
||||
~HeathrowIC();
|
||||
|
||||
bool supports_type(HWCompType type) { return type == HWCompType::MMIO_DEV; };
|
||||
|
||||
void set_host(PCIHost *host_instance) {this->host_instance = host_instance;};
|
||||
|
||||
/* PCI device methods */
|
||||
|
@ -27,12 +27,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#include "memctrlbase.h"
|
||||
|
||||
|
||||
MemCtrlBase::MemCtrlBase(std::string name)
|
||||
{
|
||||
this->name = name;
|
||||
}
|
||||
|
||||
|
||||
MemCtrlBase::~MemCtrlBase()
|
||||
{
|
||||
for (auto ® : mem_regions) {
|
||||
|
@ -25,7 +25,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#include <cinttypes>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "mmiodevice.h"
|
||||
|
||||
enum RangeType {
|
||||
@ -49,7 +48,7 @@ typedef struct AddressMapEntry {
|
||||
/** Base class for memory controllers. */
|
||||
class MemCtrlBase {
|
||||
public:
|
||||
MemCtrlBase(std::string name);
|
||||
MemCtrlBase() = default;
|
||||
virtual ~MemCtrlBase();
|
||||
virtual bool add_rom_region(uint32_t start_addr, uint32_t size);
|
||||
virtual bool add_ram_region(uint32_t start_addr, uint32_t size);
|
||||
@ -62,9 +61,8 @@ public:
|
||||
AddressMapEntry *find_range(uint32_t addr);
|
||||
|
||||
protected:
|
||||
bool add_mem_region(uint32_t start_addr, uint32_t size, uint32_t dest_addr, uint32_t type, uint8_t init_val);
|
||||
|
||||
std::string name;
|
||||
bool add_mem_region(uint32_t start_addr, uint32_t size, uint32_t dest_addr,
|
||||
uint32_t type, uint8_t init_val);
|
||||
|
||||
private:
|
||||
std::vector<uint8_t *> mem_regions;
|
||||
|
@ -24,16 +24,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include <cinttypes>
|
||||
#include <string>
|
||||
#include "hwcomponent.h"
|
||||
|
||||
/** Abstract class representing a simple, memory-mapped I/O device */
|
||||
class MMIODevice {
|
||||
class MMIODevice : public HWComponent {
|
||||
public:
|
||||
virtual uint32_t read(uint32_t offset, int size) = 0;
|
||||
virtual void write(uint32_t offset, uint32_t value, int size) = 0;
|
||||
virtual ~MMIODevice() = default;
|
||||
|
||||
protected:
|
||||
std::string name;
|
||||
};
|
||||
|
||||
#endif /* MMIO_DEVICE_H */
|
||||
|
@ -32,11 +32,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#include "memreadwrite.h"
|
||||
#include "memctrlbase.h"
|
||||
#include "mmiodevice.h"
|
||||
#include "hwcomponent.h"
|
||||
#include "mpc106.h"
|
||||
|
||||
|
||||
MPC106::MPC106() : MemCtrlBase("Grackle"), PCIDevice("Grackle PCI host bridge")
|
||||
MPC106::MPC106() : MemCtrlBase(), PCIDevice("Grackle PCI host bridge")
|
||||
{
|
||||
this->name = "Grackle";
|
||||
|
||||
/* add memory mapped I/O region for MPC106 registers */
|
||||
add_mmio_region(0xFEC00000, 0x300000, this);
|
||||
|
||||
@ -48,6 +51,16 @@ MPC106::~MPC106()
|
||||
this->pci_0_bus.clear();
|
||||
}
|
||||
|
||||
bool MPC106::supports_type(HWCompType type)
|
||||
{
|
||||
if (type == HWCompType::MEM_CTRL || type == HWCompType::MMIO_DEV ||
|
||||
type == HWCompType::PCI_HOST || type == HWCompType::PCI_DEV) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t MPC106::read(uint32_t offset, int size)
|
||||
{
|
||||
if (offset >= 0x200000) {
|
||||
|
@ -37,6 +37,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include <cinttypes>
|
||||
#include <unordered_map>
|
||||
#include "hwcomponent.h"
|
||||
#include "memctrlbase.h"
|
||||
#include "mmiodevice.h"
|
||||
#include "pcidevice.h"
|
||||
@ -46,10 +47,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
class MPC106 : public MemCtrlBase, public PCIDevice, public PCIHost
|
||||
{
|
||||
public:
|
||||
using MemCtrlBase::name;
|
||||
|
||||
MPC106();
|
||||
~MPC106();
|
||||
|
||||
bool supports_type(HWCompType type);
|
||||
|
||||
uint32_t read(uint32_t offset, int size);
|
||||
void write(uint32_t offset, uint32_t value, int size);
|
||||
|
||||
|
@ -37,7 +37,7 @@ enum {
|
||||
|
||||
class PCIDevice : public MMIODevice {
|
||||
public:
|
||||
PCIDevice(std::string name) {this->name = name;};
|
||||
PCIDevice(std::string name) { this->pci_name = name; };
|
||||
virtual ~PCIDevice() = default;
|
||||
|
||||
/* configuration space access methods */
|
||||
@ -47,7 +47,7 @@ public:
|
||||
virtual void set_host(PCIHost *host_instance) = 0;
|
||||
|
||||
protected:
|
||||
std::string name; // human-readable device name
|
||||
std::string pci_name; // human-readable device name
|
||||
PCIHost *host_instance; // host bridge instance to call back
|
||||
uint32_t base_addr; // base address register 0
|
||||
};
|
||||
|
@ -35,6 +35,8 @@ using namespace std;
|
||||
|
||||
ViaCuda::ViaCuda()
|
||||
{
|
||||
this->name = "ViaCuda";
|
||||
|
||||
/* FIXME: is this the correct
|
||||
VIA initialization? */
|
||||
this->via_regs[VIA_A] = 0x80;
|
||||
|
@ -42,11 +42,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
firmware using bit banging (https://en.wikipedia.org/wiki/Bit_banging).
|
||||
*/
|
||||
|
||||
#include "nvram.h"
|
||||
|
||||
#ifndef VIACUDA_H
|
||||
#define VIACUDA_H
|
||||
|
||||
#include "hwcomponent.h"
|
||||
#include "nvram.h"
|
||||
|
||||
/** VIA register offsets. */
|
||||
enum {
|
||||
VIA_B = 0x00, /* input/output register B */
|
||||
@ -99,12 +100,16 @@ enum {
|
||||
};
|
||||
|
||||
|
||||
class ViaCuda
|
||||
class ViaCuda : public HWComponent
|
||||
{
|
||||
public:
|
||||
ViaCuda();
|
||||
~ViaCuda();
|
||||
|
||||
bool supports_type(HWCompType type) {
|
||||
return (type == HWCompType::ADB_HOST || type == HWCompType::I2C_HOST);
|
||||
};
|
||||
|
||||
uint8_t read(int reg);
|
||||
void write(int reg, uint8_t value);
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <string>
|
||||
#include <thirdparty/loguru.hpp>
|
||||
#include "machinebase.h"
|
||||
#include "devices/hwcomponent.h"
|
||||
|
||||
std::unique_ptr<MachineBase> gMachineObj = 0;
|
||||
|
||||
@ -12,7 +13,6 @@ MachineBase::MachineBase(std::string name)
|
||||
|
||||
/* initialize internal maps */
|
||||
this->comp_map.clear();
|
||||
this->name_to_type.clear();
|
||||
this->aliases.clear();
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ MachineBase::~MachineBase()
|
||||
this->comp_map.clear();
|
||||
}
|
||||
|
||||
bool MachineBase::add_component(std::string name, HWCompType type, MMIODevice *dev_obj)
|
||||
bool MachineBase::add_component(std::string name, HWCompType type, HWComponent *dev_obj)
|
||||
{
|
||||
if (this->comp_map.count(name)) {
|
||||
LOG_F(ERROR, "Component %s already exists!", name.c_str());
|
||||
@ -32,7 +32,6 @@ bool MachineBase::add_component(std::string name, HWCompType type, MMIODevice *d
|
||||
}
|
||||
|
||||
this->comp_map[name] = dev_obj;
|
||||
this->name_to_type[name] = type;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -40,10 +39,9 @@ bool MachineBase::add_component(std::string name, HWCompType type, MMIODevice *d
|
||||
void MachineBase::add_alias(std::string name, std::string alias, HWCompType type)
|
||||
{
|
||||
this->aliases[alias] = name;
|
||||
this->name_to_type[alias] = type;
|
||||
}
|
||||
|
||||
MMIODevice *MachineBase::get_comp_by_name(std::string name)
|
||||
HWComponent *MachineBase::get_comp_by_name(std::string name)
|
||||
{
|
||||
if (this->aliases.count(name)) {
|
||||
name = this->aliases[name];
|
||||
@ -56,13 +54,13 @@ MMIODevice *MachineBase::get_comp_by_name(std::string name)
|
||||
}
|
||||
}
|
||||
|
||||
MMIODevice *MachineBase::get_comp_by_type(HWCompType type)
|
||||
HWComponent *MachineBase::get_comp_by_type(HWCompType type)
|
||||
{
|
||||
std::string comp_name;
|
||||
bool found = false;
|
||||
|
||||
for(auto it = this->name_to_type.begin(); it != this->name_to_type.end(); it++) {
|
||||
if (it->second == type) {
|
||||
for(auto it = this->comp_map.begin(); it != this->comp_map.end(); it++) {
|
||||
if (it->second->supports_type(type)) {
|
||||
comp_name = it->first;
|
||||
found = true;
|
||||
break;
|
||||
|
@ -30,20 +30,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "devices/mmiodevice.h"
|
||||
|
||||
/** types of different HW components */
|
||||
enum HWCompType : int {
|
||||
UNKNOWN = 0, /* unknown component type */
|
||||
MEM_CTRL = 1, /* memory controller */
|
||||
ROM = 2, /* read-only memory */
|
||||
RAM = 3, /* random access memory */
|
||||
MMIO_DEV = 4, /* memory mapped I/O device */
|
||||
PCI_HOST = 5, /* PCI host */
|
||||
PCI_DEV = 6, /* PCI device */
|
||||
I2C_DEV = 7, /* I2C device */
|
||||
ADB_DEV = 8 /* ADB device */
|
||||
};
|
||||
#include "devices/hwcomponent.h"
|
||||
|
||||
class MachineBase
|
||||
{
|
||||
@ -51,15 +38,14 @@ public:
|
||||
MachineBase(std::string name);
|
||||
~MachineBase();
|
||||
|
||||
bool add_component(std::string name, HWCompType type, MMIODevice *dev_obj);
|
||||
bool add_component(std::string name, HWCompType type, HWComponent *dev_obj);
|
||||
void add_alias(std::string name, std::string alias, HWCompType type);
|
||||
MMIODevice *get_comp_by_name(std::string name);
|
||||
MMIODevice *get_comp_by_type(HWCompType type);
|
||||
HWComponent *get_comp_by_name(std::string name);
|
||||
HWComponent *get_comp_by_type(HWCompType type);
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
std::map<std::string, MMIODevice *>comp_map;
|
||||
std::map<std::string, int> name_to_type;
|
||||
std::map<std::string, HWComponent *>comp_map;
|
||||
std::map<std::string, std::string> aliases;
|
||||
};
|
||||
|
||||
|
@ -26,11 +26,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include <thirdparty/loguru.hpp>
|
||||
#include "machinebase.h"
|
||||
#include "cpu/ppc/ppcemu.h"
|
||||
#include "devices/mpc106.h"
|
||||
#include "devices/machineid.h"
|
||||
#include "devices/macio.h"
|
||||
#include "cpu/ppc/ppcemu.h"
|
||||
#include "machinebase.h"
|
||||
#include "devices/viacuda.h"
|
||||
|
||||
int create_gossamer()
|
||||
{
|
||||
@ -55,7 +55,7 @@ int create_gossamer()
|
||||
gMachineObj->add_component("MachineID", HWCompType::MMIO_DEV,
|
||||
new GossamerID(0x3d8c));
|
||||
grackle_obj->add_mmio_region(0xFF000004, 4096,
|
||||
gMachineObj->get_comp_by_name("MachineID"));
|
||||
dynamic_cast<MMIODevice *>(gMachineObj->get_comp_by_name("MachineID")));
|
||||
|
||||
/* add the Heathrow I/O controller */
|
||||
gMachineObj->add_component("Heathrow", HWCompType::MMIO_DEV, new HeathrowIC);
|
||||
|
Loading…
x
Reference in New Issue
Block a user