diff --git a/.gitignore b/.gitignore index 16ce0a9..3584dc1 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,6 @@ build build-* *.dir *.user +DerivedData +*.xcodeproj/project.xcworkspace +*.xcodeproj/xcuserdata diff --git a/core/mathutils.h b/core/mathutils.h index fa552be..2807d54 100644 --- a/core/mathutils.h +++ b/core/mathutils.h @@ -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); diff --git a/core/timermanager.cpp b/core/timermanager.cpp index 1ae438e..7ea2dc7 100644 --- a/core/timermanager.cpp +++ b/core/timermanager.cpp @@ -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; diff --git a/cpu/ppc/poweropcodes.cpp b/cpu/ppc/poweropcodes.cpp index c3d47ba..1dd5b29 100644 --- a/cpu/ppc/poweropcodes.cpp +++ b/cpu/ppc/poweropcodes.cpp @@ -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); } diff --git a/cpu/ppc/ppcexceptions.cpp b/cpu/ppc/ppcexceptions.cpp index 17825e3..0356c49 100644 --- a/cpu/ppc/ppcexceptions.cpp +++ b/cpu/ppc/ppcexceptions.cpp @@ -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; } diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index 9236450..08ebb45 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -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 (...) { diff --git a/cpu/ppc/ppcmmu.cpp b/cpu/ppc/ppcmmu.cpp index af87cdb..9e08900 100644 --- a/cpu/ppc/ppcmmu.cpp +++ b/cpu/ppc/ppcmmu.cpp @@ -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; } diff --git a/cpu/ppc/ppcopcodes.cpp b/cpu/ppc/ppcopcodes.cpp index e899a75..895bc23 100644 --- a/cpu/ppc/ppcopcodes.cpp +++ b/cpu/ppc/ppcopcodes.cpp @@ -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; } diff --git a/debugger/debugger.cpp b/debugger/debugger.cpp index acdb9f8..9e0ef9a 100644 --- a/debugger/debugger.cpp +++ b/debugger/debugger.cpp @@ -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) { diff --git a/devices/common/machineid.h b/devices/common/machineid.h index d483418..7d81c50 100644 --- a/devices/common/machineid.h +++ b/devices/common/machineid.h @@ -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; diff --git a/devices/common/ofnvram.cpp b/devices/common/ofnvram.cpp index 9d9aacb..8b65ce8 100644 --- a/devices/common/ofnvram.cpp +++ b/devices/common/ofnvram.cpp @@ -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; diff --git a/devices/common/pci/bandit.cpp b/devices/common/pci/bandit.cpp index 9056e81..4358c5e 100644 --- a/devices/common/pci/bandit.cpp +++ b/devices/common/pci/bandit.cpp @@ -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 @@ -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) diff --git a/devices/common/pci/bandit.h b/devices/common/pci/bandit.h index cbd4ebf..edb991c7 100644 --- a/devices/common/pci/bandit.h +++ b/devices/common/pci/bandit.h @@ -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; }; diff --git a/devices/common/pci/pcidevice.cpp b/devices/common/pci/pcidevice.cpp index 0570dbe..bb03f66 100644 --- a/devices/common/pci/pcidevice.cpp +++ b/devices/common/pci/pcidevice.cpp @@ -27,10 +27,12 @@ along with this program. If not, see . #include #include +#include #include 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); diff --git a/devices/common/pci/pcidevice.h b/devices/common/pci/pcidevice.h index c0184cc..b1503a8 100644 --- a/devices/common/pci/pcidevice.h +++ b/devices/common/pci/pcidevice.h @@ -55,6 +55,7 @@ enum { PCI_VENDOR_ATI = 0x1002, PCI_VENDOR_MOTOROLA = 0x1057, PCI_VENDOR_APPLE = 0x106B, + PCI_VENDOR_NVIDIA = 0x10DE, }; diff --git a/devices/common/pci/pcihost.cpp b/devices/common/pci/pcihost.cpp index 51dacf1..761a57a 100644 --- a/devices/common/pci/pcihost.cpp +++ b/devices/common/pci/pcihost.cpp @@ -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 + (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)) { diff --git a/devices/common/pci/pcihost.h b/devices/common/pci/pcihost.h index d21c27e..5a0499a 100644 --- a/devices/common/pci/pcihost.h +++ b/devices/common/pci/pcihost.h @@ -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); diff --git a/devices/common/scsi/scsi.h b/devices/common/scsi/scsi.h index 56f6af0..b87b4f3 100644 --- a/devices/common/scsi/scsi.h +++ b/devices/common/scsi/scsi.h @@ -104,8 +104,6 @@ protected: void change_bus_phase(int initiator_id); private: - std::string name; - // SCSI devices registered with this bus std::array devices; diff --git a/devices/floppy/floppyimg.cpp b/devices/floppy/floppyimg.cpp index 619ccd0..69c0343 100644 --- a/devices/floppy/floppyimg.cpp +++ b/devices/floppy/floppyimg.cpp @@ -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; diff --git a/devices/floppy/superdrive.cpp b/devices/floppy/superdrive.cpp index 0205c96..b57b40b 100644 --- a/devices/floppy/superdrive.cpp +++ b/devices/floppy/superdrive.cpp @@ -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; diff --git a/devices/floppy/swim3.cpp b/devices/floppy/swim3.cpp index edf50d9..3b8c886 100644 --- a/devices/floppy/swim3.cpp +++ b/devices/floppy/swim3.cpp @@ -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: diff --git a/devices/memctrl/memctrlbase.cpp b/devices/memctrl/memctrlbase.cpp index f9805f8..6e0c6d2 100644 --- a/devices/memctrl/memctrlbase.cpp +++ b/devices/memctrl/memctrlbase.cpp @@ -25,6 +25,7 @@ along with this program. If not, see . #include #include #include +#include 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) { diff --git a/devices/memctrl/memctrlbase.h b/devices/memctrl/memctrlbase.h index 2769f16..209bff1 100644 --- a/devices/memctrl/memctrlbase.h +++ b/devices/memctrl/memctrlbase.h @@ -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: diff --git a/devices/memctrl/mpc106.cpp b/devices/memctrl/mpc106.cpp index dc9eb89..cf00d14 100644 --- a/devices/memctrl/mpc106.cpp +++ b/devices/memctrl/mpc106.cpp @@ -37,8 +37,6 @@ along with this program. If not, see . 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); } } diff --git a/devices/memctrl/psx.cpp b/devices/memctrl/psx.cpp index 1b8d40d..2c7a438 100644 --- a/devices/memctrl/psx.cpp +++ b/devices/memctrl/psx.cpp @@ -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; } diff --git a/devices/serial/chario.cpp b/devices/serial/chario.cpp index 1ed1907..a2e409e 100644 --- a/devices/serial/chario.cpp +++ b/devices/serial/chario.cpp @@ -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)); } diff --git a/devices/serial/escc.cpp b/devices/serial/escc.cpp index 22f1098..9e13a1f 100644 --- a/devices/serial/escc.cpp +++ b/devices/serial/escc.cpp @@ -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(); diff --git a/devices/sound/soundserver.cpp b/devices/sound/soundserver.cpp index 66091be..327a663 100644 --- a/devices/sound/soundserver.cpp +++ b/devices/sound/soundserver.cpp @@ -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; diff --git a/devices/video/atirage.cpp b/devices/video/atirage.cpp index 5efb89b..7b8d640 100644 --- a/devices/video/atirage.cpp +++ b/devices/video/atirage.cpp @@ -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)]; diff --git a/devices/video/control.cpp b/devices/video/control.cpp index b15b4c2..cfbcedc 100644 --- a/devices/video/control.cpp +++ b/devices/video/control.cpp @@ -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); } } diff --git a/devices/video/control.h b/devices/video/control.h index 323d695..89aa376 100644 --- a/devices/video/control.h +++ b/devices/video/control.h @@ -117,6 +117,7 @@ private: std::unique_ptr 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; diff --git a/devices/video/displayid.cpp b/devices/video/displayid.cpp index 4271757..58c9acb 100644 --- a/devices/video/displayid.cpp +++ b/devices/video/displayid.cpp @@ -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: diff --git a/machines/machinecatalyst.cpp b/machines/machinecatalyst.cpp index ae0ddf7..3cf0c09 100644 --- a/machines/machinecatalyst.cpp +++ b/machines/machinecatalyst.cpp @@ -36,6 +36,8 @@ along with this program. If not, see . int initialize_catalyst(std::string& id) { + LOG_F(INFO, "Building machine catalyst"); + PlatinumCtrl* platinum_obj; PCIHost *pci_host = dynamic_cast(gMachineObj->get_comp_by_name("Bandit1")); diff --git a/machines/machinefactory.cpp b/machines/machinefactory.cpp index e9971cd..468bd32 100644 --- a/machines/machinefactory.cpp +++ b/machines/machinefactory.cpp @@ -269,7 +269,8 @@ void MachineFactory::set_machine_settings(map &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!"); } diff --git a/machines/machinegazelle.cpp b/machines/machinegazelle.cpp index a109004..26a6dcb 100644 --- a/machines/machinegazelle.cpp +++ b/machines/machinegazelle.cpp @@ -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(gMachineObj->get_comp_by_name("PsxPci1")); // register O'Hare I/O controller with the main PCI bus diff --git a/machines/machinegossamer.cpp b/machines/machinegossamer.cpp index 1e8e0db..01f854b 100644 --- a/machines/machinegossamer.cpp +++ b/machines/machinegossamer.cpp @@ -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(gMachineObj->get_comp_by_name("Grackle")); @@ -107,7 +109,7 @@ int initialize_gossamer(std::string& id) gMachineObj->add_device("MachineID", std::unique_ptr(new GossamerID(sys_reg))); grackle_obj->add_mmio_region( - 0xFF000004, 4096, dynamic_cast(gMachineObj->get_comp_by_name("MachineID"))); + 0xFF000000 + 4, 4096 - 4, dynamic_cast(gMachineObj->get_comp_by_name("MachineID"))); // allocate ROM region if (!grackle_obj->add_rom_region(0xFFC00000, 0x400000)) { diff --git a/machines/machinepdm.cpp b/machines/machinepdm.cpp index 3681e57..ea2d9e6 100644 --- a/machines/machinepdm.cpp +++ b/machines/machinepdm.cpp @@ -38,6 +38,8 @@ along with this program. If not, see . int initialize_pdm(std::string& id) { + LOG_F(INFO, "Building machine pdm"); + uint16_t machine_id; // get raw pointer to HMC object diff --git a/machines/machineproperties.cpp b/machines/machineproperties.cpp index c82cf42..e4bfe6d 100644 --- a/machines/machineproperties.cpp +++ b/machines/machineproperties.cpp @@ -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)) { diff --git a/machines/machinetnt.cpp b/machines/machinetnt.cpp index 4e1df7e..2fda717 100644 --- a/machines/machinetnt.cpp +++ b/machines/machinetnt.cpp @@ -36,6 +36,8 @@ along with this program. If not, see . int initialize_tnt(std::string& id) { + LOG_F(INFO, "Building machine tnt"); + HammerheadCtrl* memctrl_obj; PCIHost *pci_host = dynamic_cast(gMachineObj->get_comp_by_name("Bandit1"));