mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-01-10 13:29:38 +00:00
Merge pull request #40 from joevt/master
Gazelle fixes, PCI changes and additions, MMIO changes, etc.
This commit is contained in:
commit
e510c11be2
3
.gitignore
vendored
3
.gitignore
vendored
@ -29,3 +29,6 @@ build
|
||||
build-*
|
||||
*.dir
|
||||
*.user
|
||||
DerivedData
|
||||
*.xcodeproj/project.xcworkspace
|
||||
*.xcodeproj/xcuserdata
|
||||
|
@ -34,13 +34,13 @@ inline void _u32xu64(uint32_t a, uint64_t b, uint64_t &hi, uint32_t &lo)
|
||||
{
|
||||
uint64_t p0 = (b & 0xffffffff) * a;
|
||||
uint64_t p1 = (b >> 32) * a;
|
||||
lo = p0;
|
||||
lo = (uint32_t)p0;
|
||||
hi = (p0 >> 32) + p1;
|
||||
}
|
||||
|
||||
inline void _u64xu64(uint64_t a, uint64_t b, uint64_t &hi, uint64_t &lo)
|
||||
{
|
||||
uint32_t p0h; uint64_t p0l; _u32xu64(b, a, p0h, p0l);
|
||||
uint32_t p0h; uint64_t p0l; _u32xu64((uint32_t)b, a, p0h, p0l);
|
||||
uint64_t p1h; uint32_t p1l; _u32xu64(b >> 32, a, p1h, p1l);
|
||||
lo = p0l + ((uint64_t)p1l << 32);
|
||||
hi = p0h + p1h + (lo < p0l);
|
||||
|
@ -32,7 +32,7 @@ TimerManager* TimerManager::timer_manager;
|
||||
uint32_t TimerManager::add_oneshot_timer(uint64_t timeout, timer_cb cb)
|
||||
{
|
||||
if (!timeout || timeout <= MIN_TIMEOUT_NS) {
|
||||
LOG_F(WARNING, "One-shot timer too short, timeout=%llu ns", timeout);
|
||||
LOG_F(WARNING, "One-shot timer too short, timeout=%llu ns", (long long unsigned)timeout);
|
||||
}
|
||||
|
||||
TimerInfo* ti = new TimerInfo;
|
||||
@ -58,7 +58,7 @@ uint32_t TimerManager::add_oneshot_timer(uint64_t timeout, timer_cb cb)
|
||||
uint32_t TimerManager::add_cyclic_timer(uint64_t interval, timer_cb cb)
|
||||
{
|
||||
if (!interval || interval <= MIN_TIMEOUT_NS) {
|
||||
LOG_F(WARNING, "Cyclic timer interval too short, timeout=%llu ns", interval);
|
||||
LOG_F(WARNING, "Cyclic timer interval too short, timeout=%llu ns", (long long unsigned)interval);
|
||||
}
|
||||
|
||||
TimerInfo* ti = new TimerInfo;
|
||||
|
@ -45,7 +45,7 @@ inline void power_setsoov(uint32_t a, uint32_t b, uint32_t d) {
|
||||
/** mask generator for rotate and shift instructions (§ 4.2.1.4 PowerpC PEM) */
|
||||
static inline uint32_t power_rot_mask(unsigned rot_mb, unsigned rot_me) {
|
||||
uint32_t m1 = 0xFFFFFFFFUL >> rot_mb;
|
||||
uint32_t m2 = 0xFFFFFFFFUL << (31 - rot_me);
|
||||
uint32_t m2 = (uint32_t)(0xFFFFFFFFUL << (31 - rot_me));
|
||||
return ((rot_mb <= rot_me) ? m2 & m1 : m1 | m2);
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,7 @@ void ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits) {
|
||||
break;
|
||||
|
||||
default:
|
||||
ABORT_F("Unknown exception occured: %X\n", exception_type);
|
||||
ABORT_F("Unknown exception occured: %X\n", (unsigned)exception_type);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -849,38 +849,38 @@ uint64_t reg_op(string& reg_name, uint64_t val, bool is_write) {
|
||||
try {
|
||||
if (reg_name_u == "PC") {
|
||||
if (is_write)
|
||||
ppc_state.pc = val;
|
||||
ppc_state.pc = (uint32_t)val;
|
||||
return ppc_state.pc;
|
||||
}
|
||||
if (reg_name_u == "MSR") {
|
||||
if (is_write)
|
||||
ppc_state.msr = val;
|
||||
ppc_state.msr = (uint32_t)val;
|
||||
return ppc_state.msr;
|
||||
}
|
||||
if (reg_name_u == "CR") {
|
||||
if (is_write)
|
||||
ppc_state.cr = val;
|
||||
ppc_state.cr = (uint32_t)val;
|
||||
return ppc_state.cr;
|
||||
}
|
||||
if (reg_name_u == "FPSCR") {
|
||||
if (is_write)
|
||||
ppc_state.fpscr = val;
|
||||
ppc_state.fpscr = (uint32_t)val;
|
||||
return ppc_state.fpscr;
|
||||
}
|
||||
|
||||
if (reg_name_u.substr(0, 1) == "R") {
|
||||
reg_num_str = reg_name_u.substr(1);
|
||||
reg_num = stoul(reg_num_str, NULL, 0);
|
||||
reg_num = (unsigned)stoul(reg_num_str, NULL, 0);
|
||||
if (reg_num < 32) {
|
||||
if (is_write)
|
||||
ppc_state.gpr[reg_num] = val;
|
||||
ppc_state.gpr[reg_num] = (uint32_t)val;
|
||||
return ppc_state.gpr[reg_num];
|
||||
}
|
||||
}
|
||||
|
||||
if (reg_name_u.substr(0, 1) == "FR") {
|
||||
reg_num_str = reg_name_u.substr(2);
|
||||
reg_num = stoul(reg_num_str, NULL, 0);
|
||||
reg_num = (unsigned)stoul(reg_num_str, NULL, 0);
|
||||
if (reg_num < 32) {
|
||||
if (is_write)
|
||||
ppc_state.fpr[reg_num].int64_r = val;
|
||||
@ -890,20 +890,20 @@ uint64_t reg_op(string& reg_name, uint64_t val, bool is_write) {
|
||||
|
||||
if (reg_name_u.substr(0, 3) == "SPR") {
|
||||
reg_num_str = reg_name_u.substr(3);
|
||||
reg_num = stoul(reg_num_str, NULL, 0);
|
||||
reg_num = (unsigned)stoul(reg_num_str, NULL, 0);
|
||||
if (reg_num < 1024) {
|
||||
if (is_write)
|
||||
ppc_state.spr[reg_num] = val;
|
||||
ppc_state.spr[reg_num] = (uint32_t)val;
|
||||
return ppc_state.spr[reg_num];
|
||||
}
|
||||
}
|
||||
|
||||
if (reg_name_u.substr(0, 2) == "SR") {
|
||||
reg_num_str = reg_name_u.substr(2);
|
||||
reg_num = stoul(reg_num_str, NULL, 0);
|
||||
reg_num = (unsigned)stoul(reg_num_str, NULL, 0);
|
||||
if (reg_num < 16) {
|
||||
if (is_write)
|
||||
ppc_state.sr[reg_num] = val;
|
||||
ppc_state.sr[reg_num] = (uint32_t)val;
|
||||
return ppc_state.sr[reg_num];
|
||||
}
|
||||
}
|
||||
@ -911,7 +911,7 @@ uint64_t reg_op(string& reg_name, uint64_t val, bool is_write) {
|
||||
spr = SPRName2Num.find(reg_name_u);
|
||||
if (spr != SPRName2Num.end()) {
|
||||
if (is_write)
|
||||
ppc_state.spr[spr->second] = val;
|
||||
ppc_state.spr[spr->second] = (uint32_t)val;
|
||||
return ppc_state.spr[spr->second];
|
||||
}
|
||||
} catch (...) {
|
||||
|
@ -125,11 +125,11 @@ static BATResult mpc601_block_address_translation(uint32_t la)
|
||||
|
||||
// logical to physical translation
|
||||
pa = bat_entry->phys_hi | (la & ~bat_entry->hi_mask);
|
||||
break;
|
||||
return BATResult{bat_hit, prot, pa};
|
||||
}
|
||||
}
|
||||
|
||||
return BATResult{bat_hit, prot, pa};
|
||||
return BATResult{bat_hit, 0, 0};
|
||||
}
|
||||
|
||||
/** PowerPC-style block address translation. */
|
||||
@ -742,6 +742,7 @@ void tlb_flush_entry(uint32_t ea)
|
||||
tlb1 = &dtlb1_mode2[0];
|
||||
tlb2 = &dtlb2_mode2[0];
|
||||
break;
|
||||
default:
|
||||
case 5:
|
||||
tlb1 = &dtlb1_mode3[0];
|
||||
tlb2 = &dtlb2_mode3[0];
|
||||
@ -967,7 +968,7 @@ void mmu_print_regs()
|
||||
}
|
||||
}
|
||||
|
||||
LOG_F(INFO, "");
|
||||
LOG_F(INFO, "%s", "");
|
||||
LOG_F(INFO, "SDR1 = 0x%X", ppc_state.spr[SPR::SDR1]);
|
||||
LOG_F(INFO, "Segment registers:");
|
||||
|
||||
@ -1007,7 +1008,7 @@ inline T mmu_read_vmem(uint32_t guest_va)
|
||||
// perform full address translation and refill the secondary TLB
|
||||
tlb2_entry = dtlb2_refill(guest_va, 0);
|
||||
if (tlb2_entry->flags & PAGE_NOPHYS) {
|
||||
return UnmappedVal;
|
||||
return (T)UnmappedVal;
|
||||
}
|
||||
}
|
||||
#ifdef TLB_PROFILING
|
||||
@ -1081,8 +1082,8 @@ inline void mmu_write_vmem(uint32_t guest_va, T value)
|
||||
}
|
||||
if (!(tlb1_entry->flags & TLBFlags::PTE_SET_C)) {
|
||||
// perform full page address translation to update PTE.C bit
|
||||
PATResult pat_res = page_address_translation(guest_va, false,
|
||||
!!(ppc_state.msr & 0x4000), true);
|
||||
page_address_translation(guest_va, false,
|
||||
!!(ppc_state.msr & 0x4000), true);
|
||||
tlb1_entry->flags |= TLBFlags::PTE_SET_C;
|
||||
|
||||
// don't forget to update the secondary TLB as well
|
||||
@ -1120,8 +1121,8 @@ inline void mmu_write_vmem(uint32_t guest_va, T value)
|
||||
|
||||
if (!(tlb2_entry->flags & TLBFlags::PTE_SET_C)) {
|
||||
// perform full page address translation to update PTE.C bit
|
||||
PATResult pat_res = page_address_translation(guest_va, false,
|
||||
!!(ppc_state.msr & 0x4000), true);
|
||||
page_address_translation(guest_va, false,
|
||||
!!(ppc_state.msr & 0x4000), true);
|
||||
tlb2_entry->flags |= TLBFlags::PTE_SET_C;
|
||||
}
|
||||
|
||||
|
@ -729,7 +729,7 @@ void dppc_interpreter::ppc_srawi() {
|
||||
/** mask generator for rotate and shift instructions (§ 4.2.1.4 PowerpC PEM) */
|
||||
static inline uint32_t rot_mask(unsigned rot_mb, unsigned rot_me) {
|
||||
uint32_t m1 = 0xFFFFFFFFUL >> rot_mb;
|
||||
uint32_t m2 = 0xFFFFFFFFUL << (31 - rot_me);
|
||||
uint32_t m2 = (uint32_t)(0xFFFFFFFFUL << (31 - rot_me));
|
||||
return ((rot_mb <= rot_me) ? m2 & m1 : m1 | m2);
|
||||
}
|
||||
|
||||
@ -861,11 +861,11 @@ static inline void calc_rtcl_value()
|
||||
uint64_t new_ts = get_virt_time_ns();
|
||||
uint64_t rtc_l = new_ts - rtc_timestamp + rtc_lo;
|
||||
if (rtc_l >= ONE_BILLION_NS) { // check RTCL overflow
|
||||
rtc_hi += rtc_l / ONE_BILLION_NS;
|
||||
rtc_hi += (uint32_t)(rtc_l / ONE_BILLION_NS);
|
||||
rtc_lo = rtc_l % ONE_BILLION_NS;
|
||||
}
|
||||
else {
|
||||
rtc_lo = rtc_l;
|
||||
rtc_lo = (uint32_t)rtc_l;
|
||||
}
|
||||
rtc_timestamp = new_ts;
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ using namespace std;
|
||||
|
||||
static uint32_t str2addr(string& addr_str) {
|
||||
try {
|
||||
return stoul(addr_str, NULL, 0);
|
||||
return (uint32_t)stoul(addr_str, NULL, 0);
|
||||
} catch (invalid_argument& exc) {
|
||||
throw invalid_argument(string("Cannot convert ") + addr_str);
|
||||
}
|
||||
@ -60,7 +60,7 @@ static uint32_t str2addr(string& addr_str) {
|
||||
|
||||
static uint32_t str2num(string& num_str) {
|
||||
try {
|
||||
return stol(num_str, NULL, 0);
|
||||
return (uint32_t)stol(num_str, NULL, 0);
|
||||
} catch (invalid_argument& exc) {
|
||||
throw invalid_argument(string("Cannot convert ") + num_str);
|
||||
}
|
||||
@ -512,7 +512,7 @@ void enter_debugger() {
|
||||
}
|
||||
} else if (cmd == "next" || cmd == "ni") {
|
||||
addr_str = "PC";
|
||||
addr = get_reg(addr_str) + 4;
|
||||
addr = (uint32_t)get_reg(addr_str) + 4;
|
||||
ppc_exec_until(addr);
|
||||
} else if (cmd == "until") {
|
||||
ss >> addr_str;
|
||||
@ -588,7 +588,7 @@ void enter_debugger() {
|
||||
#endif
|
||||
} else {
|
||||
addr_str = "PC";
|
||||
addr = get_reg(addr_str);
|
||||
addr = (uint32_t)get_reg(addr_str);
|
||||
disasm(1, addr);
|
||||
}
|
||||
} catch (invalid_argument& exc) {
|
||||
|
@ -75,7 +75,8 @@ private:
|
||||
class GossamerID : public MMIODevice {
|
||||
public:
|
||||
GossamerID(const uint16_t id) {
|
||||
this->id = id, this->name = "Machine-id";
|
||||
this->id = id;
|
||||
this->name = "Machine-id";
|
||||
supports_types(HWCompType::MMIO_DEV);
|
||||
};
|
||||
~GossamerID() = default;
|
||||
|
@ -39,7 +39,7 @@ using namespace std;
|
||||
|
||||
static uint32_t str2env(string& num_str) {
|
||||
try {
|
||||
return stoul(num_str, NULL, 0);
|
||||
return (uint32_t)stoul(num_str, NULL, 0);
|
||||
} catch (invalid_argument& exc) {
|
||||
try {
|
||||
string num_str2 = string("0x") + num_str;
|
||||
|
@ -298,6 +298,8 @@ void Bandit::verbose_address_space()
|
||||
|
||||
Chaos::Chaos(std::string name) : PCIHost()
|
||||
{
|
||||
this->name = name;
|
||||
|
||||
supports_types(HWCompType::PCI_HOST);
|
||||
|
||||
MemCtrlBase *mem_ctrl = dynamic_cast<MemCtrlBase *>
|
||||
@ -308,8 +310,6 @@ Chaos::Chaos(std::string name) : PCIHost()
|
||||
// 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 rgn_start, uint32_t offset, int size)
|
||||
|
@ -102,7 +102,6 @@ public:
|
||||
void write(uint32_t rgn_start, uint32_t offset, uint32_t value, int size);
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
uint32_t config_addr;
|
||||
};
|
||||
|
||||
|
@ -27,10 +27,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include <cinttypes>
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
PCIDevice::PCIDevice(std::string name)
|
||||
{
|
||||
this->name = name;
|
||||
this->pci_name = name;
|
||||
|
||||
this->pci_rd_stat = [this]() { return this->status; };
|
||||
@ -188,7 +190,10 @@ int PCIDevice::attach_exp_rom_image(const std::string img_path)
|
||||
|
||||
// determine image size
|
||||
img_file.seekg(0, std::ios::end);
|
||||
uint32_t exp_rom_image_size = img_file.tellg();
|
||||
size_t exp_rom_image_size = img_file.tellg();
|
||||
if (exp_rom_image_size > 4*1024*1024) {
|
||||
throw std::runtime_error("expansion ROM file too large");
|
||||
}
|
||||
|
||||
// verify PCI struct offset
|
||||
uint16_t pci_struct_offset = 0;
|
||||
@ -222,7 +227,7 @@ int PCIDevice::attach_exp_rom_image(const std::string img_path)
|
||||
}
|
||||
else {
|
||||
LOG_F(WARNING, "%s: loaded expansion rom (%d bytes adjusted to %d bytes).",
|
||||
this->pci_name.c_str(), exp_rom_image_size, this->exp_rom_size);
|
||||
this->pci_name.c_str(), (int)exp_rom_image_size, this->exp_rom_size);
|
||||
}
|
||||
|
||||
this->exp_bar_cfg = ~(this->exp_rom_size - 1);
|
||||
@ -246,7 +251,7 @@ void PCIDevice::set_bar_value(int bar_num, uint32_t value)
|
||||
{
|
||||
uint32_t bar_cfg = this->bars_cfg[bar_num];
|
||||
if (bar_cfg & 1) {
|
||||
this->bars[bar_num] = (value & 0xFFFFFFFCUL) | 1;
|
||||
this->bars[bar_num] = (value & 0xFFFFFFFCUL) | (bar_cfg & 3);
|
||||
} else {
|
||||
if (bar_cfg & 6) {
|
||||
ABORT_F("Invalid or unsupported PCI space type: %d", (bar_cfg >> 1) & 3);
|
||||
|
@ -55,6 +55,7 @@ enum {
|
||||
PCI_VENDOR_ATI = 0x1002,
|
||||
PCI_VENDOR_MOTOROLA = 0x1057,
|
||||
PCI_VENDOR_APPLE = 0x106B,
|
||||
PCI_VENDOR_NVIDIA = 0x10DE,
|
||||
};
|
||||
|
||||
|
||||
|
@ -53,6 +53,14 @@ bool PCIHost::pci_register_mmio_region(uint32_t start_addr, uint32_t size, PCIDe
|
||||
return mem_ctrl->add_mmio_region(start_addr, size, obj);
|
||||
}
|
||||
|
||||
bool PCIHost::pci_unregister_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->remove_mmio_region(start_addr, size, obj);
|
||||
}
|
||||
|
||||
void PCIHost::attach_pci_device(std::string& dev_name, int slot_id)
|
||||
{
|
||||
if (!DeviceRegistry::device_registered(dev_name)) {
|
||||
|
@ -42,6 +42,7 @@ public:
|
||||
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);
|
||||
virtual bool pci_unregister_mmio_region(uint32_t start_addr, uint32_t size, PCIDevice* obj);
|
||||
|
||||
virtual void attach_pci_device(std::string& dev_name, int slot_id);
|
||||
|
||||
|
@ -104,8 +104,6 @@ protected:
|
||||
void change_bus_phase(int initiator_id);
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
|
||||
// SCSI devices registered with this bus
|
||||
std::array<ScsiDevice*, SCSI_MAX_DEVS> devices;
|
||||
|
||||
|
@ -90,7 +90,12 @@ int RawFloppyImg::calc_phys_params()
|
||||
|
||||
// determine image size
|
||||
img_file.seekg(0, img_file.end);
|
||||
this->img_size = img_file.tellg();
|
||||
size_t img_size = img_file.tellg();
|
||||
if (img_size > 2*1024*1024) {
|
||||
LOG_F(ERROR, "RawFloppyImg: image size is too large to determine disk format from image size!");
|
||||
return -1;
|
||||
}
|
||||
this->img_size = (int)img_size;
|
||||
img_file.seekg(0, img_file.beg);
|
||||
|
||||
img_file.close();
|
||||
@ -212,7 +217,7 @@ int DiskCopy42Img::calc_phys_params() {
|
||||
|
||||
// determine image size
|
||||
img_file.seekg(0, img_file.end);
|
||||
this->img_size = img_file.tellg();
|
||||
size_t img_size = img_file.tellg();
|
||||
img_file.seekg(0, img_file.beg);
|
||||
|
||||
// get data size from image
|
||||
@ -221,11 +226,12 @@ int DiskCopy42Img::calc_phys_params() {
|
||||
img_file.read((char *)&buf, 4);
|
||||
this->data_size = READ_DWORD_BE_U(buf);
|
||||
|
||||
if (this->data_size > this->img_size) {
|
||||
if (this->data_size > img_size) {
|
||||
img_file.close();
|
||||
LOG_F(ERROR, "DiskCopy42Img: invalid data size %d", this->data_size);
|
||||
return -1;
|
||||
}
|
||||
this->img_size = (int)img_size;
|
||||
|
||||
uint8_t disk_format = 0xFFU;
|
||||
|
||||
|
@ -295,7 +295,7 @@ uint64_t MacSuperDrive::sync_to_disk()
|
||||
track_time_ns -= this->index_delay;
|
||||
|
||||
// calculate current sector number from timestamp
|
||||
int cur_sect_num = this->cur_sector = track_time_ns / this->sector_delay;
|
||||
int cur_sect_num = this->cur_sector = (int)(track_time_ns / this->sector_delay);
|
||||
|
||||
this->sector_start_time = this->track_start_time + cur_sect_num * this->sector_delay +
|
||||
this->index_delay;
|
||||
|
@ -128,7 +128,7 @@ uint8_t Swim3Ctrl::read(uint8_t reg_offset)
|
||||
|
||||
void Swim3Ctrl::write(uint8_t reg_offset, uint8_t value)
|
||||
{
|
||||
uint8_t old_mode_reg, status_addr;
|
||||
uint8_t status_addr;
|
||||
|
||||
switch(reg_offset) {
|
||||
case Swim3Reg::Timer:
|
||||
|
@ -25,6 +25,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <loguru.hpp>
|
||||
|
||||
|
||||
MemCtrlBase::~MemCtrlBase() {
|
||||
@ -52,12 +53,74 @@ AddressMapEntry* MemCtrlBase::find_range(uint32_t addr) {
|
||||
}
|
||||
|
||||
|
||||
AddressMapEntry* MemCtrlBase::find_range_exact(uint32_t addr, uint32_t size, MMIODevice* dev_instance) {
|
||||
if (size) {
|
||||
uint32_t end = addr + size - 1;
|
||||
for (auto& entry : address_map) {
|
||||
if (addr == entry->start && end == entry->end && (!dev_instance || dev_instance == entry->devobj) )
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
AddressMapEntry* MemCtrlBase::find_range_contains(uint32_t addr, uint32_t size) {
|
||||
if (size) {
|
||||
uint32_t end = addr + size - 1;
|
||||
for (auto& entry : address_map) {
|
||||
if (addr >= entry->start && end <= entry->end)
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
AddressMapEntry* MemCtrlBase::find_range_overlaps(uint32_t addr, uint32_t size) {
|
||||
if (size) {
|
||||
uint32_t end = addr + size - 1;
|
||||
for (auto& entry : address_map) {
|
||||
if (end >= entry->start && addr <= entry->end)
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
bool MemCtrlBase::is_range_free(uint32_t addr, uint32_t size) {
|
||||
bool result = true;
|
||||
if (size) {
|
||||
uint32_t end = addr + size - 1;
|
||||
for (auto& entry : address_map) {
|
||||
if (addr == entry->start && end == entry->end) {
|
||||
LOG_F(WARNING, "memory region 0x%X..0x%X%s%s%s already exists", addr, end, entry->devobj ? " (" : "", entry->devobj ? entry->devobj->get_name().c_str() : "", entry->devobj ? ")" : "");
|
||||
result = false;
|
||||
}
|
||||
else if (addr >= entry->start && end <= entry->end) {
|
||||
LOG_F(WARNING, "0x%X..0x%X already exists in memory region 0x%X..0x%X%s%s%s", addr, end, entry->start, entry->end, entry->devobj ? " (" : "", entry->devobj ? entry->devobj->get_name().c_str() : "", entry->devobj ? ")" : "");
|
||||
result = false;
|
||||
}
|
||||
else if (end >= entry->start && addr <= entry->end) {
|
||||
LOG_F(ERROR, "0x%X..0x%X overlaps existing memory region 0x%X..0x%X%s%s%s", addr, end, entry->start, entry->end, entry->devobj ? " (" : "", entry->devobj ? entry->devobj->get_name().c_str() : "", entry->devobj ? ")" : "");
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
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))
|
||||
if (!is_range_free(start_addr, size))
|
||||
return false;
|
||||
|
||||
uint8_t* reg_content = new uint8_t[size];
|
||||
@ -66,8 +129,9 @@ bool MemCtrlBase::add_mem_region(
|
||||
|
||||
entry = new AddressMapEntry;
|
||||
|
||||
uint32_t end = start_addr + size - 1;
|
||||
entry->start = start_addr;
|
||||
entry->end = start_addr + size - 1;
|
||||
entry->end = end;
|
||||
entry->mirror = dest_addr;
|
||||
entry->type = type;
|
||||
entry->devobj = 0;
|
||||
@ -75,6 +139,14 @@ bool MemCtrlBase::add_mem_region(
|
||||
|
||||
this->address_map.push_back(entry);
|
||||
|
||||
LOG_F(INFO, "Added mem region 0x%X..0x%X (%s%s%s%s) -> 0x%X", start_addr, end,
|
||||
entry->type & RT_ROM ? "ROM," : "",
|
||||
entry->type & RT_RAM ? "RAM," : "",
|
||||
entry->type & RT_MMIO ? "MMIO," : "",
|
||||
entry->type & RT_MIRROR ? "MIRROR," : "",
|
||||
dest_addr
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -98,8 +170,9 @@ bool MemCtrlBase::add_mem_mirror(uint32_t start_addr, uint32_t dest_addr) {
|
||||
|
||||
entry = new AddressMapEntry;
|
||||
|
||||
uint32_t end = start_addr + (ref_entry->end - ref_entry->start);
|
||||
entry->start = start_addr;
|
||||
entry->end = start_addr + (ref_entry->end - ref_entry->start);
|
||||
entry->end = end;
|
||||
entry->mirror = dest_addr;
|
||||
entry->type = ref_entry->type | RT_MIRROR;
|
||||
entry->devobj = 0;
|
||||
@ -107,6 +180,16 @@ bool MemCtrlBase::add_mem_mirror(uint32_t start_addr, uint32_t dest_addr) {
|
||||
|
||||
this->address_map.push_back(entry);
|
||||
|
||||
LOG_F(INFO, "Added mem region mirror 0x%X..0x%X (%s%s%s%s) -> 0x%X : 0x%X..0x%X%s%s%s", start_addr, end,
|
||||
entry->type & RT_ROM ? "ROM," : "",
|
||||
entry->type & RT_RAM ? "RAM," : "",
|
||||
entry->type & RT_MMIO ? "MMIO," : "",
|
||||
entry->type & RT_MIRROR ? "MIRROR," : "",
|
||||
dest_addr,
|
||||
ref_entry->start, ref_entry->end,
|
||||
ref_entry->devobj ? " (" : "", ref_entry->devobj ? ref_entry->devobj->get_name().c_str() : "", ref_entry->devobj ? ")" : ""
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -129,14 +212,15 @@ bool MemCtrlBase::set_data(uint32_t reg_addr, const uint8_t* data, uint32_t size
|
||||
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 - 1))
|
||||
/* error if a memory region for the given range already exists */
|
||||
if (!is_range_free(start_addr, size))
|
||||
return false;
|
||||
|
||||
entry = new AddressMapEntry;
|
||||
|
||||
uint32_t end = start_addr + size - 1;
|
||||
entry->start = start_addr;
|
||||
entry->end = start_addr + size - 1;
|
||||
entry->end = end;
|
||||
entry->mirror = 0;
|
||||
entry->type = RT_MMIO;
|
||||
entry->devobj = dev_instance;
|
||||
@ -144,9 +228,33 @@ bool MemCtrlBase::add_mmio_region(uint32_t start_addr, uint32_t size, MMIODevice
|
||||
|
||||
this->address_map.push_back(entry);
|
||||
|
||||
LOG_F(INFO, "Added mmio region 0x%X..0x%X%s%s%s", start_addr, end, dev_instance ? " (" : "", dev_instance ? dev_instance->get_name().c_str() : "", dev_instance ? ")" : "");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemCtrlBase::remove_mmio_region(uint32_t start_addr, uint32_t size, MMIODevice* dev_instance) {
|
||||
int found = 0;
|
||||
|
||||
uint32_t end = start_addr + size - 1;
|
||||
address_map.erase(std::remove_if(address_map.begin(), address_map.end(),
|
||||
[start_addr, end, dev_instance, &found](const AddressMapEntry *entry) {
|
||||
bool result = (start_addr == entry->start && end == entry->end && (!dev_instance || dev_instance == entry->devobj));
|
||||
found += result;
|
||||
return result;
|
||||
}
|
||||
), address_map.end());
|
||||
|
||||
if (found == 0)
|
||||
LOG_F(ERROR, "Cannot find mmio region 0x%X..0x%X%s%s%s to remove", start_addr, end, dev_instance ? " (" : "", dev_instance ? dev_instance->get_name().c_str() : "", dev_instance ? ")" : "");
|
||||
else if (found > 1)
|
||||
LOG_F(ERROR, "Removed %d occurrences of mmio region 0x%X..0x%X%s%s%s", found, start_addr, end, dev_instance ? " (" : "", dev_instance ? dev_instance->get_name().c_str() : "", dev_instance ? ")" : "");
|
||||
else
|
||||
LOG_F(INFO, "Removed mmio region 0x%X..0x%X%s%s%s", start_addr, end, dev_instance ? " (" : "", dev_instance ? dev_instance->get_name().c_str() : "", dev_instance ? ")" : "");
|
||||
|
||||
return (found > 0);
|
||||
}
|
||||
|
||||
AddressMapEntry* MemCtrlBase::find_rom_region()
|
||||
{
|
||||
for (auto& entry : address_map) {
|
||||
|
@ -68,10 +68,16 @@ public:
|
||||
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 remove_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);
|
||||
AddressMapEntry* find_range_exact(uint32_t addr, uint32_t size, MMIODevice* dev_instance);
|
||||
AddressMapEntry* find_range_contains(uint32_t addr, uint32_t size);
|
||||
AddressMapEntry* find_range_overlaps(uint32_t addr, uint32_t size);
|
||||
bool is_range_free(uint32_t addr, uint32_t size);
|
||||
|
||||
AddressMapEntry* find_rom_region();
|
||||
|
||||
protected:
|
||||
|
@ -37,8 +37,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
MPC106::MPC106() : MemCtrlBase(), PCIDevice("Grackle"), PCIHost()
|
||||
{
|
||||
this->name = "Grackle";
|
||||
|
||||
supports_types(HWCompType::MEM_CTRL | HWCompType::MMIO_DEV |
|
||||
HWCompType::PCI_HOST | HWCompType::PCI_DEV);
|
||||
|
||||
@ -255,7 +253,7 @@ void MPC106::setup_ram() {
|
||||
}
|
||||
|
||||
if (!this->add_ram_region(0, ram_size)) {
|
||||
LOG_F(ERROR, "MPC106 RAM allocation failed!");
|
||||
LOG_F(WARNING, "MPC106 RAM allocation 0x%X..0x%X failed (maybe already exists?)", 0, ram_size - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ PsxCtrl::PsxCtrl(int bridge_num, std::string name)
|
||||
// add MMIO region for the PSX control registers
|
||||
add_mmio_region(0xF8000000, 0x70, this);
|
||||
|
||||
this->sys_id = 0x30040000; // TODO: use correct value here!
|
||||
this->sys_id = 0x10000000;
|
||||
this->chip_rev = 0; // old PSX, what's about PSX+?
|
||||
this->sys_config = PSX_BUS_SPEED_50;
|
||||
}
|
||||
|
@ -336,7 +336,6 @@ void CharIoSocket::rcv_disable()
|
||||
bool CharIoSocket::rcv_char_available()
|
||||
{
|
||||
static int consecutivechars = 0;
|
||||
static int count = 0;
|
||||
|
||||
if (consecutivechars >= 15) {
|
||||
consecutivechars++;
|
||||
@ -377,7 +376,7 @@ bool CharIoSocket::rcv_char_available()
|
||||
if (sockfd != -1) {
|
||||
if (FD_ISSET(sockfd, &readfds)) {
|
||||
uint8_t c;
|
||||
int received = recv(sockfd, &c, 1, 0);
|
||||
int received = (int)recv(sockfd, &c, 1, 0);
|
||||
if (received == -1) {
|
||||
if (acceptfd == -1) {
|
||||
//LOG_F(INFO, "socket sock read (not accepted yet) err: %s", strerror(errno)); // this happens once before accept
|
||||
@ -443,7 +442,7 @@ int CharIoSocket::xmit_char(uint8_t c)
|
||||
CharIoSocket::rcv_char_available();
|
||||
|
||||
if (acceptfd != -1) {
|
||||
int sent = send(acceptfd, &c, 1, 0);
|
||||
int sent = (int)send(acceptfd, &c, 1, 0);
|
||||
if (sent == -1) {
|
||||
LOG_F(INFO, "socket accept write err: %s", strerror(errno));
|
||||
}
|
||||
@ -463,7 +462,7 @@ int CharIoSocket::rcv_char(uint8_t *c)
|
||||
CharIoSocket::rcv_char_available();
|
||||
|
||||
if (acceptfd != -1) {
|
||||
int received = recv(acceptfd, c, 1, 0);
|
||||
int received = (int)recv(acceptfd, c, 1, 0);
|
||||
if (received == -1) {
|
||||
LOG_F(INFO, "socket accept read err: %s", strerror(errno));
|
||||
}
|
||||
|
@ -92,7 +92,6 @@ uint8_t EsccController::read(uint8_t reg_offset)
|
||||
} else {
|
||||
return this->ch_a->read_reg(this->reg_ptr);
|
||||
}
|
||||
this->reg_ptr = 0;
|
||||
break;
|
||||
case EsccReg::Port_B_Data:
|
||||
return this->ch_b->receive_byte();
|
||||
|
@ -147,12 +147,12 @@ long sound_out_callback(cubeb_stream *stream, void *user_data,
|
||||
out_frames = 0;
|
||||
|
||||
while (req_frames > 0) {
|
||||
if (!dma_ch->pull_data(req_frames << 2, &got_len, &p_in)) {
|
||||
if (!dma_ch->pull_data((uint32_t)req_frames << 2, &got_len, &p_in)) {
|
||||
frames = got_len >> 2;
|
||||
|
||||
in_buf = (int16_t*)p_in;
|
||||
|
||||
for (int i = frames; i > 0; i--) {
|
||||
for (int i = (int)frames; i > 0; i--) {
|
||||
out_buf[0] = BYTESWAP_16(in_buf[0]);
|
||||
out_buf[1] = BYTESWAP_16(in_buf[1]);
|
||||
in_buf += 2;
|
||||
|
@ -557,7 +557,7 @@ void ATIRage::crtc_enable() {
|
||||
void ATIRage::draw_hw_cursor(uint8_t *dst_buf, int dst_pitch) {
|
||||
uint8_t *src_buf, *src_row, *dst_row, px4;
|
||||
|
||||
int horz_offset = READ_DWORD_LE_A(&this->mm_regs[ATI_CUR_HORZ_VERT_OFF]) & 0x3F;
|
||||
// int horz_offset = READ_DWORD_LE_A(&this->mm_regs[ATI_CUR_HORZ_VERT_OFF]) & 0x3F;
|
||||
int vert_offset = (READ_DWORD_LE_A(&this->mm_regs[ATI_CUR_HORZ_VERT_OFF]) >> 16) & 0x3F;
|
||||
|
||||
src_buf = &this->vram_ptr[(READ_DWORD_LE_A(&this->mm_regs[ATI_CUR_OFFSET]) * 8)];
|
||||
|
@ -59,6 +59,7 @@ ControlVideo::ControlVideo()
|
||||
this->vendor_id = PCI_VENDOR_APPLE;
|
||||
this->device_id = 3;
|
||||
this->class_rev = 0;
|
||||
this->bars_cfg[0] = 0xFFFFFFFFUL; // I/O region (4 bytes but it's weird because bit 1 is set)
|
||||
this->bars_cfg[1] = 0xFFFFF000UL; // base address for the HW registers (4KB)
|
||||
this->bars_cfg[2] = 0xFC000000UL; // base address for the VRAM (64MB)
|
||||
|
||||
@ -84,6 +85,10 @@ ControlVideo::ControlVideo()
|
||||
void ControlVideo::notify_bar_change(int bar_num)
|
||||
{
|
||||
switch (bar_num) {
|
||||
case 0:
|
||||
this->io_base = this->bars[bar_num] & ~3;
|
||||
LOG_F(INFO, "Control: I/O space address set to 0x%08X", this->io_base);
|
||||
break;
|
||||
case 1:
|
||||
if (this->regs_base != (this->bars[bar_num] & 0xFFFFFFF0UL)) {
|
||||
this->regs_base = this->bars[bar_num] & 0xFFFFFFF0UL;
|
||||
@ -116,18 +121,22 @@ uint32_t ControlVideo::read(uint32_t rgn_start, uint32_t offset, int size)
|
||||
}
|
||||
}
|
||||
|
||||
switch (offset >> 4) {
|
||||
case ControlRegs::TEST:
|
||||
result = this->test;
|
||||
break;
|
||||
case ControlRegs::MON_SENSE:
|
||||
result = this->cur_mon_id << 6;
|
||||
break;
|
||||
default:
|
||||
LOG_F(INFO, "read from 0x%08X:0x%08X", rgn_start, offset);
|
||||
if (rgn_start == this->regs_base) {
|
||||
switch (offset >> 4) {
|
||||
case ControlRegs::TEST:
|
||||
result = this->test;
|
||||
break;
|
||||
case ControlRegs::MON_SENSE:
|
||||
result = this->cur_mon_id << 6;
|
||||
break;
|
||||
default:
|
||||
LOG_F(INFO, "read from 0x%08X:0x%08X", rgn_start, offset);
|
||||
}
|
||||
|
||||
return BYTESWAP_32(result);
|
||||
}
|
||||
|
||||
return BYTESWAP_32(result);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ControlVideo::write(uint32_t rgn_start, uint32_t offset, uint32_t value, int size)
|
||||
@ -141,75 +150,77 @@ void ControlVideo::write(uint32_t rgn_start, uint32_t offset, uint32_t value, in
|
||||
return;
|
||||
}
|
||||
|
||||
value = BYTESWAP_32(value);
|
||||
if (rgn_start == this->regs_base) {
|
||||
value = BYTESWAP_32(value);
|
||||
|
||||
switch (offset >> 4) {
|
||||
case ControlRegs::VFPEQ:
|
||||
case ControlRegs::VFP:
|
||||
case ControlRegs::VAL:
|
||||
case ControlRegs::VBP:
|
||||
case ControlRegs::VBPEQ:
|
||||
case ControlRegs::VSYNC:
|
||||
case ControlRegs::VHLINE:
|
||||
case ControlRegs::PIPED:
|
||||
case ControlRegs::HPIX:
|
||||
case ControlRegs::HFP:
|
||||
case ControlRegs::HAL:
|
||||
case ControlRegs::HBWAY:
|
||||
case ControlRegs::HSP:
|
||||
case ControlRegs::HEQ:
|
||||
case ControlRegs::HLFLN:
|
||||
case ControlRegs::HSERR:
|
||||
this->swatch_params[(offset >> 4) - 1] = value;
|
||||
break;
|
||||
case ControlRegs::TEST:
|
||||
if (this->test != value) {
|
||||
if ((this->test & ~TEST_STROBE) != (value & ~TEST_STROBE)) {
|
||||
this->test = value;
|
||||
this->test_shift = 0;
|
||||
LOG_F(9, "New TEST value: 0x%08X", this->test);
|
||||
} else {
|
||||
LOG_F(9, "TEST strobe bit flipped, new value: 0x%08X", value);
|
||||
this->test = value;
|
||||
if (++this->test_shift >= 3) {
|
||||
LOG_F(9, "Received TEST reg value: 0x%08X", this->test & ~TEST_STROBE);
|
||||
if ((this->test ^ this->prev_test) & 0x400) {
|
||||
if (this->test & 0x400) {
|
||||
this->disable_display();
|
||||
} else {
|
||||
this->enable_display();
|
||||
switch (offset >> 4) {
|
||||
case ControlRegs::VFPEQ:
|
||||
case ControlRegs::VFP:
|
||||
case ControlRegs::VAL:
|
||||
case ControlRegs::VBP:
|
||||
case ControlRegs::VBPEQ:
|
||||
case ControlRegs::VSYNC:
|
||||
case ControlRegs::VHLINE:
|
||||
case ControlRegs::PIPED:
|
||||
case ControlRegs::HPIX:
|
||||
case ControlRegs::HFP:
|
||||
case ControlRegs::HAL:
|
||||
case ControlRegs::HBWAY:
|
||||
case ControlRegs::HSP:
|
||||
case ControlRegs::HEQ:
|
||||
case ControlRegs::HLFLN:
|
||||
case ControlRegs::HSERR:
|
||||
this->swatch_params[(offset >> 4) - 1] = value;
|
||||
break;
|
||||
case ControlRegs::TEST:
|
||||
if (this->test != value) {
|
||||
if ((this->test & ~TEST_STROBE) != (value & ~TEST_STROBE)) {
|
||||
this->test = value;
|
||||
this->test_shift = 0;
|
||||
LOG_F(9, "New TEST value: 0x%08X", this->test);
|
||||
} else {
|
||||
LOG_F(9, "TEST strobe bit flipped, new value: 0x%08X", value);
|
||||
this->test = value;
|
||||
if (++this->test_shift >= 3) {
|
||||
LOG_F(9, "Received TEST reg value: 0x%08X", this->test & ~TEST_STROBE);
|
||||
if ((this->test ^ this->prev_test) & 0x400) {
|
||||
if (this->test & 0x400) {
|
||||
this->disable_display();
|
||||
} else {
|
||||
this->enable_display();
|
||||
}
|
||||
this->prev_test = this->test;
|
||||
}
|
||||
this->prev_test = this->test;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ControlRegs::GBASE:
|
||||
this->fb_base = value;
|
||||
break;
|
||||
case ControlRegs::ROW_WORDS:
|
||||
this->row_words = value;
|
||||
break;
|
||||
case ControlRegs::MON_SENSE:
|
||||
LOG_F(9, "Control: monitor sense written with 0x%X", value);
|
||||
value = (value >> 3) & 7;
|
||||
this->cur_mon_id = this->display_id->read_monitor_sense(value & 7, value ^ 7);
|
||||
break;
|
||||
case ControlRegs::ENABLE:
|
||||
this->flags = value;
|
||||
break;
|
||||
case ControlRegs::GSC_DIVIDE:
|
||||
this->clock_divider = value;
|
||||
break;
|
||||
case ControlRegs::REFRESH_COUNT:
|
||||
LOG_F(INFO, "Control: refresh count set to 0x%08X", value);
|
||||
break;
|
||||
case ControlRegs::INT_ENABLE:
|
||||
this->int_enable = value;
|
||||
break;
|
||||
default:
|
||||
LOG_F(INFO, "write 0x%08X to 0x%08X:0x%08X", value, rgn_start, offset);
|
||||
}
|
||||
break;
|
||||
case ControlRegs::GBASE:
|
||||
this->fb_base = value;
|
||||
break;
|
||||
case ControlRegs::ROW_WORDS:
|
||||
this->row_words = value;
|
||||
break;
|
||||
case ControlRegs::MON_SENSE:
|
||||
LOG_F(9, "Control: monitor sense written with 0x%X", value);
|
||||
value = (value >> 3) & 7;
|
||||
this->cur_mon_id = this->display_id->read_monitor_sense(value & 7, value ^ 7);
|
||||
break;
|
||||
case ControlRegs::ENABLE:
|
||||
this->flags = value;
|
||||
break;
|
||||
case ControlRegs::GSC_DIVIDE:
|
||||
this->clock_divider = value;
|
||||
break;
|
||||
case ControlRegs::REFRESH_COUNT:
|
||||
LOG_F(INFO, "Control: refresh count set to 0x%08X", value);
|
||||
break;
|
||||
case ControlRegs::INT_ENABLE:
|
||||
this->int_enable = value;
|
||||
break;
|
||||
default:
|
||||
LOG_F(INFO, "write 0x%08X to 0x%08X:0x%08X", value, rgn_start, offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,6 +117,7 @@ private:
|
||||
std::unique_ptr<uint8_t[]> vram_ptr;
|
||||
|
||||
uint32_t vram_size;
|
||||
uint32_t io_base = 0;
|
||||
uint32_t vram_base = 0;
|
||||
uint32_t regs_base = 0;
|
||||
uint32_t prev_test = 0x433;
|
||||
|
@ -88,7 +88,6 @@ DisplayID::DisplayID(uint8_t std_code, uint8_t ext_code)
|
||||
uint8_t DisplayID::read_monitor_sense(uint8_t levels, uint8_t dirs)
|
||||
{
|
||||
uint8_t scl, sda;
|
||||
uint16_t result;
|
||||
|
||||
switch(this->id_kind) {
|
||||
case Disp_Id_Kind::DDC2B:
|
||||
|
@ -36,6 +36,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
int initialize_catalyst(std::string& id)
|
||||
{
|
||||
LOG_F(INFO, "Building machine catalyst");
|
||||
|
||||
PlatinumCtrl* platinum_obj;
|
||||
|
||||
PCIHost *pci_host = dynamic_cast<PCIHost*>(gMachineObj->get_comp_by_name("Bandit1"));
|
||||
|
@ -269,7 +269,8 @@ void MachineFactory::set_machine_settings(map<string, string> &settings) {
|
||||
|
||||
string MachineFactory::machine_name_from_rom(string& rom_filepath) {
|
||||
ifstream rom_file;
|
||||
uint32_t file_size, config_info_offset, rom_id;
|
||||
size_t file_size;
|
||||
uint32_t config_info_offset, rom_id;
|
||||
char rom_id_str[17];
|
||||
|
||||
string machine_name = "";
|
||||
@ -354,7 +355,7 @@ int MachineFactory::load_boot_rom(string& rom_filepath) {
|
||||
gMachineObj->get_comp_by_type(HWCompType::MEM_CTRL));
|
||||
|
||||
if ((rom_reg = mem_ctrl->find_rom_region())) {
|
||||
mem_ctrl->set_data(rom_reg->start, sysrom_mem, file_size);
|
||||
mem_ctrl->set_data(rom_reg->start, sysrom_mem, (uint32_t)file_size);
|
||||
} else {
|
||||
ABORT_F("Could not locate physical ROM region!");
|
||||
}
|
||||
|
@ -47,6 +47,8 @@ int get_cpu_pll_value(const uint64_t cpu_freq_hz) {
|
||||
|
||||
int initialize_gazelle(std::string& id)
|
||||
{
|
||||
LOG_F(INFO, "Building machine gazelle");
|
||||
|
||||
PCIHost *pci_host = dynamic_cast<PCIHost*>(gMachineObj->get_comp_by_name("PsxPci1"));
|
||||
|
||||
// register O'Hare I/O controller with the main PCI bus
|
||||
|
@ -94,6 +94,8 @@ static void setup_ram_slot(std::string name, int i2c_addr, int capacity_megs) {
|
||||
|
||||
int initialize_gossamer(std::string& id)
|
||||
{
|
||||
LOG_F(INFO, "Building machine gossamer");
|
||||
|
||||
// get pointer to the memory controller/PCI host bridge object
|
||||
MPC106* grackle_obj = dynamic_cast<MPC106*>(gMachineObj->get_comp_by_name("Grackle"));
|
||||
|
||||
@ -107,7 +109,7 @@ int initialize_gossamer(std::string& id)
|
||||
|
||||
gMachineObj->add_device("MachineID", std::unique_ptr<GossamerID>(new GossamerID(sys_reg)));
|
||||
grackle_obj->add_mmio_region(
|
||||
0xFF000004, 4096, dynamic_cast<MMIODevice*>(gMachineObj->get_comp_by_name("MachineID")));
|
||||
0xFF000000 + 4, 4096 - 4, dynamic_cast<MMIODevice*>(gMachineObj->get_comp_by_name("MachineID")));
|
||||
|
||||
// allocate ROM region
|
||||
if (!grackle_obj->add_rom_region(0xFFC00000, 0x400000)) {
|
||||
|
@ -38,6 +38,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
int initialize_pdm(std::string& id)
|
||||
{
|
||||
LOG_F(INFO, "Building machine pdm");
|
||||
|
||||
uint16_t machine_id;
|
||||
|
||||
// get raw pointer to HMC object
|
||||
|
@ -73,7 +73,7 @@ bool StrProperty::check_val(std::string str)
|
||||
uint32_t IntProperty::get_int()
|
||||
{
|
||||
try {
|
||||
uint32_t result = strtoul(this->get_string().c_str(), 0, 0);
|
||||
uint32_t result = (uint32_t)strtoul(this->get_string().c_str(), 0, 0);
|
||||
|
||||
/* perform value check */
|
||||
if (!this->check_val(result)) {
|
||||
|
@ -36,6 +36,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
int initialize_tnt(std::string& id)
|
||||
{
|
||||
LOG_F(INFO, "Building machine tnt");
|
||||
|
||||
HammerheadCtrl* memctrl_obj;
|
||||
|
||||
PCIHost *pci_host = dynamic_cast<PCIHost*>(gMachineObj->get_comp_by_name("Bandit1"));
|
||||
|
Loading…
x
Reference in New Issue
Block a user