Create base class for memory controller devices.

Create 'devices' directory for virtual device
sources and move MPC106 source to it.
This commit is contained in:
Maxim Poliakovski 2019-08-19 01:34:24 +02:00
parent 843f010ac6
commit ac1f770f92
8 changed files with 228 additions and 14 deletions

131
devices/memctrlbase.cpp Normal file
View File

@ -0,0 +1,131 @@
#include <string>
#include <vector>
#include "memctrlbase.h"
MemCtrlBase::MemCtrlBase(std::string name)
{
this->name = name;
}
MemCtrlBase::~MemCtrlBase()
{
for (auto &reg : mem_regions) {
if (reg)
delete(reg);
}
this->mem_regions.clear();
this->address_map.clear();
}
AddressMapEntry *MemCtrlBase::find_range(uint32_t addr)
{
for (auto &entry : address_map) {
if (addr >= entry.start && addr <= entry.end)
return &entry;
}
return 0;
}
bool MemCtrlBase::add_mem_region(uint32_t start_addr, uint32_t size,
uint32_t dest_addr, uint32_t type, uint8_t init_val = 0)
{
AddressMapEntry entry;
/* error if a memory region for the given range already exists */
if (find_range(start_addr) || find_range(start_addr + size))
return false;
uint8_t *reg_content = new uint8_t[size];
if (!reg_content)
return false;
this->mem_regions.push_back(reg_content);
entry.start = start_addr;
entry.end = start_addr + size - 1;
entry.mirror = dest_addr;
entry.type = type;
entry.devobj = 0;
entry.mem_ptr = reg_content;
this->address_map.push_back(entry);
return true;
}
bool MemCtrlBase::add_rom_region(uint32_t start_addr, uint32_t size)
{
return add_mem_region(start_addr, size, 0, RT_ROM);
}
bool MemCtrlBase::add_ram_region(uint32_t start_addr, uint32_t size)
{
return add_mem_region(start_addr, size, 0, RT_RAM);
}
bool MemCtrlBase::add_mem_mirror(uint32_t start_addr, uint32_t dest_addr)
{
AddressMapEntry entry, *ref_entry;
ref_entry = find_range(dest_addr);
if (!ref_entry)
return false;
entry.start = start_addr;
entry.end = start_addr + (ref_entry->end - ref_entry->start) + 1;
entry.mirror = dest_addr;
entry.type = ref_entry->type | RT_MIRROR;
entry.devobj = 0;
entry.mem_ptr = ref_entry->mem_ptr;
this->address_map.push_back(entry);
return true;
}
bool MemCtrlBase::set_data(uint32_t reg_addr, const uint8_t *data, uint32_t size)
{
AddressMapEntry *ref_entry;
uint32_t cpy_size;
ref_entry = find_range(reg_addr);
if (!ref_entry)
return false;
cpy_size = std::min(ref_entry->end - ref_entry->start + 1, size);
memcpy(ref_entry->mem_ptr, data, cpy_size);
return true;
}
bool MemCtrlBase::add_mmio_region(uint32_t start_addr, uint32_t size,
MMIODevice *dev_instance)
{
AddressMapEntry entry;
/* error if another region for the given range already exists */
if (find_range(start_addr) || find_range(start_addr + size))
return false;
entry.start = start_addr;
entry.end = start_addr + size - 1;
entry.mirror = 0;
entry.type = RT_MMIO;
entry.devobj = dev_instance;
entry.mem_ptr = 0;
this->address_map.push_back(entry);
return true;
}

53
devices/memctrlbase.h Normal file
View File

@ -0,0 +1,53 @@
#ifndef MEMORY_CONTROLLER_BASE_H
#define MEMORY_CONTROLLER_BASE_H
#include <cinttypes>
#include <string>
#include <vector>
#include "mmiodevice.h"
enum RangeType {
RT_ROM = 1, /* read-only memory */
RT_RAM = 2, /* random access memory */
RT_MMIO = 4, /* memory mapped I/O */
RT_MIRROR = 8 /* region mirror (content of another region is acessible
at some other address) */
};
typedef struct AddressMapEntry {
uint32_t start; /* first address of the corresponding range */
uint32_t end; /* last address of the corresponding range */
uint32_t mirror; /* mirror address for RT_MIRROR */
uint32_t type; /* range type */
MMIODevice *devobj; /* pointer to device object */
unsigned char *mem_ptr; /* direct pointer to data for memory objects */
} AddressMapEntry;
/** Base class for memory controllers. */
class MemCtrlBase {
public:
MemCtrlBase(std::string name);
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);
virtual bool add_mem_mirror(uint32_t start_addr, uint32_t dest_addr);
virtual bool add_mmio_region(uint32_t start_addr, uint32_t size, MMIODevice *dev_instance);
virtual bool set_data(uint32_t reg_addr, const uint8_t *data, uint32_t size);
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;
private:
std::vector<uint8_t *> mem_regions;
std::vector<AddressMapEntry> address_map;
};
#endif /* MEMORY_CONTROLLER_BASE_H */

21
devices/mmiodevice.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef MMIO_DEVICE_H
#define MMIO_DEVICE_H
#include <cinttypes>
#include <string>
#define READ_WORD_BE(addr) ((addr)[0] << 16) | (addr)[1]
#define READ_DWORD_BE(addr) ((addr)[0] << 24) | ((addr)[1] << 16) | ((addr)[2] << 8) | (addr)[3]
/** Abstract class representing a simple, memory-mapped I/O device */
class MMIODevice {
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 */

View File

@ -10,10 +10,10 @@
#include <iostream>
#include <cstring>
#include <cinttypes>
#include "viacuda.h"
#include "../viacuda.h"
#include "mpc106.h"
#include "ppcemumain.h"
#include "ppcmemory.h"
#include "../ppcemumain.h"
#include "../ppcmemory.h"
bool mpc106_membound_change;
bool mpc106_mem_approve; //Confirm memory transaction

View File

@ -23,7 +23,7 @@
#include "macswim3.h"
#include "ppcmemory.h"
#include "viacuda.h"
#include "mpc106.h"
#include "devices/mpc106.h"
#include "openpic.h"
#include "debugger.h"
//#include <vector>

View File

@ -1,17 +1,26 @@
OBJS = main.o macioserial.o macscsi.o macswim3.o mpc106.o openpic.o poweropcodes.o \
ppcfpopcodes.o ppcgekkoopcodes.o ppcmemory.o ppcopcodes.o viacuda.o davbus.o \
debugger.o
EXE := dingusppc
MODULES := . devices
SRCS := $(foreach sdir,$(MODULES),$(wildcard $(sdir)/*.cpp))
#SRCS = $(wildcard *.cpp)
OBJS := $(patsubst %.cpp, %.o, $(SRCS))
OUT = dingusppc
CXX = g++
CXXFLAGS = -g -c -Wall -std=c++11
LFLAGS =
all: $(OBJS)
$(CXX) -g $(OBJS) -o $(OUT) $(LFLAGS)
VPATH := devices
*.o : *.cpp
$(CXX) $(CXXFLAGS) -c $(input) -o $(output)
DEPS = $(OBJS:.o=.d)
all: $(EXE)
$(EXE) : $(OBJS)
$(CXX) -o $@ $^
%.o : %.cpp
$(CXX) $(CXXFLAGS) -MMD -o $@ $<
clean:
rm -f *.o $(OUT)
rm -rf *.o *.d devices/*.o devices/*.d $(EXE)
-include $(DEPS)

View File

@ -20,7 +20,7 @@
#include "ppcemumain.h"
#include "ppcmemory.h"
#include "openpic.h"
#include "mpc106.h"
#include "devices/mpc106.h"
#include "davbus.h"
std::vector<uint32_t> pte_storage;