From fb56a6b5368d20b56eeb92bc836c1248781e36e8 Mon Sep 17 00:00:00 2001 From: joevt Date: Fri, 23 Dec 2022 19:40:39 -0800 Subject: [PATCH 01/17] Fix gazelle sys-id. It should match AAPL,cpu-id property from real Power Mac 6500. --- devices/memctrl/psx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; } From 37c352955c79bc29f74cd08301b3af8701849599 Mon Sep 17 00:00:00 2001 From: joevt Date: Fri, 2 Sep 2022 00:59:35 -0700 Subject: [PATCH 02/17] Allow bit 1 of I/O BARs to be set. Usually bit 1 of I/O BARs is 0 since it is reserved, but control has an I/O BAR where this bit is set. bar_cfg is used to determine the default values of the least significant bits (2 bits for I/O BARs and 4 bits for Memory BARs). The upper bits of bar_cfg determine which bits can be set and also determines the size of the BAR. --- devices/common/pci/pcidevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devices/common/pci/pcidevice.cpp b/devices/common/pci/pcidevice.cpp index 0570dbe..a4ba484 100644 --- a/devices/common/pci/pcidevice.cpp +++ b/devices/common/pci/pcidevice.cpp @@ -246,7 +246,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); From 190718fbeede0940f61fa7e0037ac14b72c571d1 Mon Sep 17 00:00:00 2001 From: joevt Date: Fri, 2 Sep 2022 00:18:00 -0700 Subject: [PATCH 03/17] Add BAR 0 to control. BAR 0 exists on a real Power Mac 8600 and the dingusppc 7500. On a Power Mac 8600, the initial value is 0x84000003. In Open Firmware, you can write to all bits of the BAR and read the value back except the 2 least significant bits are always %11. Bit 0 indicates I/O space. Bit 1 is reserved and should be zero so maybe this is not a real I/O space BAR. 0x8400000 is written to the BAR by Open Firmware. It doesn't look like a normal I/O address which are usually 16 bits. On the emulated 7500, 0x02000000 is written to the BAR by Open Firmware sometime during probe-all. The BAR did not behave as it does in the Power Mac 8600. This commit fixes that. Two questions remain: 1) Which fcode writes to the BAR? Is it the probe fcode or is it the control fcode? There's no config-_! in the control fcode. 2) What is the purpose of the BAR? Writing to it can cause a hang. The testbits code below seems to succeed - it restores the original value after reading the result of testing each bit and before displaying the result. The values shown for the MSB (0x84 on the 8600 and 0x02 on the 7500) could be three flag bits. ``` dev vci0 : testbits { adr ; org } cr adr config-l@ dup -> org ." original : " 8 u.r cr 20 0 do 1 1f i - << dup 8 u.r ." : " adr config-l! adr config-l@ org adr config-l! 8 u.r cr loop ; 15810 testbits \ 15810 is the address of the BAR on the emulated 7500. ``` --- devices/video/control.cpp | 157 ++++++++++++++++++++------------------ devices/video/control.h | 1 + 2 files changed, 85 insertions(+), 73 deletions(-) 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; From 5aaae40d94368e62ba4c30dbef25869e4e89ba36 Mon Sep 17 00:00:00 2001 From: joevt Date: Tue, 25 Oct 2022 23:06:59 -0700 Subject: [PATCH 04/17] Add Nvidia vendor ID. In case you want to emulate an Nvidia GPU in the future (for Core Image, etc.) --- devices/common/pci/pcidevice.h | 1 + 1 file changed, 1 insertion(+) 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, }; From 0bd9d0e973fbe5498d7b6e5ada9872b63a40e3ae Mon Sep 17 00:00:00 2001 From: joevt Date: Sun, 11 Dec 2022 11:09:02 -0800 Subject: [PATCH 05/17] Fix HWComponent name initialization. First, remove name override for subclasses of HWComponent (Chaos and ScsiBus) because HWComponent has its own name field. HWComponent name should be set as early as possible in the constructor so it can be used in log messages. PCIDevice should set name of HWComponent (through MMIODevice) in its constructor, using the name that is given to its constructor. For Bandit and Grackle, they don't need to set the HWComponent name since its PCIDevice constructor will now do it. Chaos is not a PCIDevice so it should set the MMIODevice name itself. Why does PCIDevice have a name that is separate from the HWComponent name? --- devices/common/pci/bandit.cpp | 4 ++-- devices/common/pci/bandit.h | 1 - devices/common/pci/pcidevice.cpp | 1 + devices/common/scsi/scsi.h | 2 -- devices/memctrl/mpc106.cpp | 2 -- 5 files changed, 3 insertions(+), 7 deletions(-) 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 a4ba484..6ad4e25 100644 --- a/devices/common/pci/pcidevice.cpp +++ b/devices/common/pci/pcidevice.cpp @@ -31,6 +31,7 @@ along with this program. If not, see . PCIDevice::PCIDevice(std::string name) { + this->name = name; this->pci_name = name; this->pci_rd_stat = [this]() { return this->status; }; 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/memctrl/mpc106.cpp b/devices/memctrl/mpc106.cpp index dc9eb89..9c23611 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); From 911acb4bc214598a5f2511277a97511236eeb76d Mon Sep 17 00:00:00 2001 From: joevt Date: Mon, 12 Dec 2022 00:13:49 -0800 Subject: [PATCH 06/17] Remove MPC106 RAM allocation failed error. It might not be an error - usually it just means that it was already allocated so demote this message to a warning. Related memory allocation changes: - Added find_range_exact which searches for an allocation that exactly matches a range. - Added find_range_contains which searches for an allocation that is completely contained within a range. - Added find_range_overlaps which searches for an allocation that overlaps any part of a range. - Added is_range_free which is similar to the above three. It returns false if any allocated range overlaps a range. It reports the regions that it overlaps. - Fix add_mem_region and add_memio_region so that they don't just check the first byte and last byte. - Memory allocation logging should include the range (first byte..last byte) and device if possible. - Log memory allocations. --- devices/memctrl/memctrlbase.cpp | 98 +++++++++++++++++++++++++++++++-- devices/memctrl/memctrlbase.h | 5 ++ devices/memctrl/mpc106.cpp | 2 +- 3 files changed, 98 insertions(+), 7 deletions(-) diff --git a/devices/memctrl/memctrlbase.cpp b/devices/memctrl/memctrlbase.cpp index f9805f8..8632263 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,6 +228,8 @@ 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; } diff --git a/devices/memctrl/memctrlbase.h b/devices/memctrl/memctrlbase.h index 2769f16..484f79c 100644 --- a/devices/memctrl/memctrlbase.h +++ b/devices/memctrl/memctrlbase.h @@ -72,6 +72,11 @@ public: 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 9c23611..cf00d14 100644 --- a/devices/memctrl/mpc106.cpp +++ b/devices/memctrl/mpc106.cpp @@ -253,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); } } From 52fa30b71d9f6a5ca904c8eee4513ac909ddfd6c Mon Sep 17 00:00:00 2001 From: joevt Date: Mon, 12 Dec 2022 00:16:59 -0800 Subject: [PATCH 07/17] Add ability to unregister mmio region. mmio regions are registered when a PCI BAR is set. Add the ability to reverse that - for when a PCI BAR is changed. --- devices/common/pci/pcihost.cpp | 8 ++++++++ devices/common/pci/pcihost.h | 1 + devices/memctrl/memctrlbase.cpp | 22 ++++++++++++++++++++++ devices/memctrl/memctrlbase.h | 1 + 4 files changed, 32 insertions(+) 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/memctrl/memctrlbase.cpp b/devices/memctrl/memctrlbase.cpp index 8632263..6e0c6d2 100644 --- a/devices/memctrl/memctrlbase.cpp +++ b/devices/memctrl/memctrlbase.cpp @@ -233,6 +233,28 @@ bool MemCtrlBase::add_mmio_region(uint32_t start_addr, uint32_t size, MMIODevice 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 484f79c..209bff1 100644 --- a/devices/memctrl/memctrlbase.h +++ b/devices/memctrl/memctrlbase.h @@ -68,6 +68,7 @@ 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); From 2f08a0b3276584edfe2f579b5fb95f105bf73285 Mon Sep 17 00:00:00 2001 From: joevt Date: Mon, 12 Dec 2022 00:26:43 -0800 Subject: [PATCH 08/17] Fix Gossamer machineID allocation size. When the allocation is logged, it will look appear like this: Added mmio region 0xFF000004..0xFF000FFF (Machine-id) instead of like this: Added mmio region 0xFF000004..0xFF001003 (Machine-id) --- machines/machinegossamer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/machines/machinegossamer.cpp b/machines/machinegossamer.cpp index 1e8e0db..5dab78d 100644 --- a/machines/machinegossamer.cpp +++ b/machines/machinegossamer.cpp @@ -107,7 +107,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)) { From b61a7c4aea120959e9aeeb9b50c25f2b6369d30b Mon Sep 17 00:00:00 2001 From: joevt Date: Wed, 21 Dec 2022 02:24:22 -0800 Subject: [PATCH 09/17] Log something from machine initialization. The machine type and its corresponding source file name should appear once in the log output. --- machines/machinecatalyst.cpp | 2 ++ machines/machinegazelle.cpp | 2 ++ machines/machinegossamer.cpp | 2 ++ machines/machinepdm.cpp | 2 ++ machines/machinetnt.cpp | 2 ++ 5 files changed, 10 insertions(+) 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/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 5dab78d..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")); 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/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")); From bd5a88f02f54bea18ff7d1b63f6b3351fe2f7880 Mon Sep 17 00:00:00 2001 From: joevt Date: Wed, 21 Dec 2022 07:02:54 -0800 Subject: [PATCH 10/17] Ignore Xcode project files. --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) 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 From 64fec88436c4349f276e5dbbfa31ea0593556302 Mon Sep 17 00:00:00 2001 From: joevt Date: Wed, 21 Dec 2022 03:20:39 -0800 Subject: [PATCH 11/17] Fix compiler warnings: cast loses precision. Use explicit cast when converting large integer types to smaller integer types when it is known that the most significant bytes are not required. For pcidevice, check the ROM file size before casting to int. We'll allow expansion ROM sizes up to 4MB but usually they are 64K, sometimes 128K, rarely 256K. for machinefactory, change the type to size_t so that it can correctly get the size of files that are larger than 4GB; it already checks the file size is 4MB before we need to cast to uint32_t. For floppyimg, check the image size before casting to int. For raw images, only allow files up to 2MB. For DiskCopy42 images, it already checks the file size, so do the cast after that. --- core/mathutils.h | 4 ++-- cpu/ppc/poweropcodes.cpp | 2 +- cpu/ppc/ppcexec.cpp | 24 ++++++++++++------------ cpu/ppc/ppcmmu.cpp | 2 +- cpu/ppc/ppcopcodes.cpp | 6 +++--- debugger/debugger.cpp | 8 ++++---- devices/common/ofnvram.cpp | 2 +- devices/common/pci/pcidevice.cpp | 7 +++++-- devices/floppy/floppyimg.cpp | 12 +++++++++--- devices/floppy/superdrive.cpp | 2 +- devices/serial/chario.cpp | 6 +++--- devices/sound/soundserver.cpp | 4 ++-- machines/machinefactory.cpp | 5 +++-- machines/machineproperties.cpp | 2 +- 14 files changed, 48 insertions(+), 38 deletions(-) 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/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/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..006acc4 100644 --- a/cpu/ppc/ppcmmu.cpp +++ b/cpu/ppc/ppcmmu.cpp @@ -1007,7 +1007,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 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/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/pcidevice.cpp b/devices/common/pci/pcidevice.cpp index 6ad4e25..39b3e23 100644 --- a/devices/common/pci/pcidevice.cpp +++ b/devices/common/pci/pcidevice.cpp @@ -189,7 +189,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; @@ -223,7 +226,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); 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/serial/chario.cpp b/devices/serial/chario.cpp index 1ed1907..c9892b9 100644 --- a/devices/serial/chario.cpp +++ b/devices/serial/chario.cpp @@ -377,7 +377,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 +443,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 +463,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/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/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/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)) { From 46bc8567e975302a16306eca67632ba9883db60f Mon Sep 17 00:00:00 2001 From: joevt Date: Wed, 21 Dec 2022 03:36:48 -0800 Subject: [PATCH 12/17] Fix compiler warnings: uninitialized variables. - mpc601_block_address_translation will now return 0 for prot and pa when bat_hit is false (when the if statement is not positive during the for loop). The calling function doesn't care what prot and pa are when bat_hit is false, but we do this to remove the compiler warining. - For tlb_flush_entry, the compiler thinks m might not always be in the range 0 to 5 so tlb1 and tlb2 might not get initialized by the switch statement. Add default to get around this warning. --- cpu/ppc/ppcmmu.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cpu/ppc/ppcmmu.cpp b/cpu/ppc/ppcmmu.cpp index 006acc4..cfc3a06 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]; From 5294a8b71cee166d0dc710f23da8455fc616c063 Mon Sep 17 00:00:00 2001 From: joevt Date: Wed, 21 Dec 2022 03:39:13 -0800 Subject: [PATCH 13/17] Fix compiler warnings: unused variables. --- cpu/ppc/ppcmmu.cpp | 8 ++++---- devices/floppy/swim3.cpp | 2 +- devices/serial/chario.cpp | 1 - devices/video/atirage.cpp | 2 +- devices/video/displayid.cpp | 1 - 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/cpu/ppc/ppcmmu.cpp b/cpu/ppc/ppcmmu.cpp index cfc3a06..1c9a9a7 100644 --- a/cpu/ppc/ppcmmu.cpp +++ b/cpu/ppc/ppcmmu.cpp @@ -1082,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 @@ -1121,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/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/serial/chario.cpp b/devices/serial/chario.cpp index c9892b9..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++; 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/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: From 85d0900d7da6d4fc4324e342b828adf61f4d42d2 Mon Sep 17 00:00:00 2001 From: joevt Date: Wed, 21 Dec 2022 03:41:17 -0800 Subject: [PATCH 14/17] Fix compiler warnings: possible misuse of comma. --- devices/common/machineid.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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; From 1b221bc0bd50d675077695160c156c7a79c95c81 Mon Sep 17 00:00:00 2001 From: joevt Date: Wed, 21 Dec 2022 04:15:55 -0800 Subject: [PATCH 15/17] Fix compiler warnings: never executed. --- devices/serial/escc.cpp | 1 - 1 file changed, 1 deletion(-) 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(); From f2db6bd0669b06c2ad2480ff339403571e193f1a Mon Sep 17 00:00:00 2001 From: joevt Date: Sat, 24 Dec 2022 20:36:22 -0800 Subject: [PATCH 16/17] Add missing header. --- devices/common/pci/pcidevice.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/devices/common/pci/pcidevice.cpp b/devices/common/pci/pcidevice.cpp index 39b3e23..bb03f66 100644 --- a/devices/common/pci/pcidevice.cpp +++ b/devices/common/pci/pcidevice.cpp @@ -27,6 +27,7 @@ along with this program. If not, see . #include #include +#include #include PCIDevice::PCIDevice(std::string name) From 19adb54cd8eea2f401720157fdedd866e3a90489 Mon Sep 17 00:00:00 2001 From: joevt Date: Sat, 24 Dec 2022 21:07:58 -0800 Subject: [PATCH 17/17] Fix compiler warnings. These were detected by github Actions but not by Xcode. --- core/timermanager.cpp | 4 ++-- cpu/ppc/ppcexceptions.cpp | 2 +- cpu/ppc/ppcmmu.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) 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/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/ppcmmu.cpp b/cpu/ppc/ppcmmu.cpp index 1c9a9a7..9e08900 100644 --- a/cpu/ppc/ppcmmu.cpp +++ b/cpu/ppc/ppcmmu.cpp @@ -968,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:");