diff --git a/devices/common/ata/cmd646.cpp b/devices/common/ata/cmd646.cpp index 052b470..7e3f93c 100644 --- a/devices/common/ata/cmd646.cpp +++ b/devices/common/ata/cmd646.cpp @@ -228,7 +228,7 @@ void CmdIdeCtrl::update_irq(const int ch_num, const uint8_t irq_level) { this->mrdmode &= ~(ch_num ? BM_CH1_INT : BM_CH0_INT); if (!irq_level || forward_irq) - this->irq_info.int_ctrl_obj->ack_int(this->irq_info.irq_id, irq_level); + this->pci_interrupt(irq_level); } static const DeviceDescription CmdIde_Descriptor = { diff --git a/devices/common/ata/cmd646.h b/devices/common/ata/cmd646.h index 63a6a11..469134c 100644 --- a/devices/common/ata/cmd646.h +++ b/devices/common/ata/cmd646.h @@ -78,11 +78,6 @@ public: bool pci_io_read(uint32_t offset, uint32_t size, uint32_t* res) override; bool pci_io_write(uint32_t offset, uint32_t value, uint32_t size) override; - int device_postinit() override { - this->irq_info = this->host_instance->register_pci_int(this); - return 0; - }; - private: void notify_bar_change(int bar_num); uint8_t read_config_reg(uint32_t reg_offset); @@ -108,8 +103,6 @@ private: uint8_t mrdmode = 0; uint8_t udma_time_cr = 0; - - IntDetails irq_info = {}; }; #endif // CMD646_IDE_H diff --git a/devices/common/hwinterrupt.h b/devices/common/hwinterrupt.h index 5f5e8c5..e4d4410 100644 --- a/devices/common/hwinterrupt.h +++ b/devices/common/hwinterrupt.h @@ -71,6 +71,15 @@ enum IntSrc : uint32_t { DMA_DAVBUS_Rx, DMA_ETHERNET_Tx, DMA_ETHERNET_Rx, + FIREWIRE, + PCI_J12, + PCI_J11, + PCI_J10, + PCI_J9, + ATA, + USB, + PIPPIN_E, + PIPPIN_F, }; /** Base class for interrupt controllers. */ diff --git a/devices/common/pci/bandit.cpp b/devices/common/pci/bandit.cpp index 1b134c8..7e237c2 100644 --- a/devices/common/pci/bandit.cpp +++ b/devices/common/pci/bandit.cpp @@ -235,32 +235,7 @@ inline void BanditHost::cfg_setup(uint32_t offset, int size, int &bus_num, } int BanditHost::device_postinit() { - std::string pci_dev_name; - - static const std::map pci_slots1 = { - {"pci_A1", DEV_FUN(0xD,0)}, {"pci_B1", DEV_FUN(0xE,0)}, {"pci_C1", DEV_FUN(0xF,0)} - }; - - static const std::map pci_slots2 = { - {"pci_D2", DEV_FUN(0xD,0)}, {"pci_E2", DEV_FUN(0xE,0)}, {"pci_F2", DEV_FUN(0xF,0)} - }; - - static const std::map vci_slots = { - {"vci_D", DEV_FUN(0xD,0)}, {"vci_E", DEV_FUN(0xE,0)}, {"vci_F", DEV_FUN(0xF,0)} - }; - - for (auto& slot : - this->bridge_num == 0 ? vci_slots : - this->bridge_num == 1 ? pci_slots1 : - this->bridge_num == 2 ? pci_slots2 : - pci_slots1 - ) { - pci_dev_name = GET_STR_PROP(slot.first); - if (!pci_dev_name.empty()) { - this->attach_pci_device(pci_dev_name, slot.second); - } - } - return 0; + return this->pcihost_device_postinit(); } Bandit::Bandit(int bridge_num, std::string name, int dev_id, int rev) @@ -346,7 +321,18 @@ static const PropMap Chaos_Properties = { new StrProperty("")}, {"vci_E", new StrProperty("")}, - {"vci_F", +}; + +static const PropMap PsxPci1_Properties = { + {"pci_A1", + new StrProperty("")}, + {"pci_B1", + new StrProperty("")}, + {"pci_C1", + new StrProperty("")}, + {"pci_E1", + new StrProperty("")}, + {"pci_F1", new StrProperty("")}, }; @@ -359,7 +345,7 @@ static const DeviceDescription Bandit2_Descriptor = { }; static const DeviceDescription PsxPci1_Descriptor = { - Bandit::create_psx_first, {}, Bandit1_Properties + Bandit::create_psx_first, {}, PsxPci1_Properties }; static const DeviceDescription Chaos_Descriptor = { diff --git a/devices/common/pci/bandit.h b/devices/common/pci/bandit.h index 79af68d..08d23cd 100644 --- a/devices/common/pci/bandit.h +++ b/devices/common/pci/bandit.h @@ -73,9 +73,6 @@ class BanditHost : public PCIHost, public MMIODevice { public: BanditHost(int bridge_num) { this->bridge_num = bridge_num; }; - // PCIHost methods - virtual void pci_interrupt(uint8_t irq_line_state, PCIBase *dev) {} - // MMIODevice methods uint32_t read(uint32_t rgn_start, uint32_t offset, int size); void write(uint32_t rgn_start, uint32_t offset, uint32_t value, int size); diff --git a/devices/common/pci/dec21154.cpp b/devices/common/pci/dec21154.cpp index 46845ab..9116afc 100644 --- a/devices/common/pci/dec21154.cpp +++ b/devices/common/pci/dec21154.cpp @@ -86,8 +86,28 @@ void DecPciBridge::pci_cfg_write(uint32_t reg_offs, uint32_t value, AccessDetail } } +static const PropMap Dec21154Yosemite_Properties = { + {"pci_FireWire", + new StrProperty("")}, + {"pci_UltraATA", + new StrProperty("")}, + {"pci_J11", + new StrProperty("")}, + {"pci_J10", + new StrProperty("")}, + {"pci_J9", + new StrProperty("")}, + {"pci_USB", + new StrProperty("")}, +}; + static const DeviceDescription Dec21154_Descriptor = { DecPciBridge::create, {}, {} }; +static const DeviceDescription Dec21154Yosemite_Descriptor = { + DecPciBridge::create_yosemite, {}, Dec21154Yosemite_Properties +}; + REGISTER_DEVICE(Dec21154, Dec21154_Descriptor); +REGISTER_DEVICE(Dec21154Yosemite, Dec21154Yosemite_Descriptor); diff --git a/devices/common/pci/dec21154.h b/devices/common/pci/dec21154.h index 4ededb2..6ba7cc3 100644 --- a/devices/common/pci/dec21154.h +++ b/devices/common/pci/dec21154.h @@ -44,6 +44,10 @@ public: return std::unique_ptr(new DecPciBridge("DEC21154")); } + static std::unique_ptr create_yosemite() { + return std::unique_ptr(new DecPciBridge("DEC21154Yosemite")); + } + // PCIDevice methods uint32_t pci_cfg_read(uint32_t reg_offs, AccessDetails &details); void pci_cfg_write(uint32_t reg_offs, uint32_t value, AccessDetails &details); diff --git a/devices/common/pci/pcibase.cpp b/devices/common/pci/pcibase.cpp index c6f2239..74c4523 100644 --- a/devices/common/pci/pcibase.cpp +++ b/devices/common/pci/pcibase.cpp @@ -301,3 +301,21 @@ void PCIBase::pci_wr_exp_rom_bar(uint32_t data) } } } + +void PCIBase::pci_interrupt(uint8_t irq_line_state) { + if (!(this->command & 0x0400)) { + if (!this->int_details.int_ctrl_obj) + this->host_instance->register_pci_int(this); + if (this->int_details.int_ctrl_obj && this->int_details.irq_id) + this->int_details.int_ctrl_obj->ack_int(this->int_details.irq_id, irq_line_state); + else + LOG_F(ERROR, "Unhandled interrupt from device %s", this->get_name().c_str()); + /* A pci device should set the interrupt status bit when an interrupt occurs + * and it should clear the interrupt status bit when its interrupt bits are cleared. + * The interrupt status bit is new to PCI Local Bus Specification Revision 2.3 + * and Power Macs use PCI Local Bus Specification Revision 2.0. Some PCI cards + * might not implement this bit. + */ + //this->status |= 0x0008; + } +} diff --git a/devices/common/pci/pcibase.h b/devices/common/pci/pcibase.h index c3fbd55..16eea5c 100644 --- a/devices/common/pci/pcibase.h +++ b/devices/common/pci/pcibase.h @@ -77,6 +77,7 @@ typedef struct { } BarConfig; class PCIBase : public MMIODevice { +friend class PCIHost; public: PCIBase(std::string name, PCIHeaderType hdr_type, int num_bars); virtual ~PCIBase() = default; @@ -126,10 +127,12 @@ public: this->irq_pin = irq_pin; } - virtual void pci_interrupt(uint8_t irq_line_state) { - this->host_instance->pci_interrupt(irq_line_state, this); + virtual void set_int_details(IntDetails &int_details) { + this->int_details = int_details; } + virtual void pci_interrupt(uint8_t irq_line_state); + // MMIODevice methods virtual uint32_t read(uint32_t rgn_start, uint32_t offset, int size) { return 0; } virtual void write(uint32_t rgn_start, uint32_t offset, uint32_t value, int size) { } @@ -174,6 +177,8 @@ protected: // 0 = not writable; 1 = bit is enabled in command register uint16_t command_cfg = 0xffff - (1<<3) - (1<<7); // disable: special cycles and stepping + + IntDetails int_details = { 0 }; }; inline uint32_t pci_cfg_log(uint32_t value, AccessDetails &details) { diff --git a/devices/common/pci/pcibridgebase.cpp b/devices/common/pci/pcibridgebase.cpp index d40f5bd..722715c 100644 --- a/devices/common/pci/pcibridgebase.cpp +++ b/devices/common/pci/pcibridgebase.cpp @@ -85,3 +85,7 @@ void PCIBridgeBase::pci_cfg_write(uint32_t reg_offs, uint32_t value, AccessDetai return PCIBase::pci_cfg_write(reg_offs, value, details); } } + +int PCIBridgeBase::device_postinit() { + return this->pcihost_device_postinit(); +} diff --git a/devices/common/pci/pcibridgebase.h b/devices/common/pci/pcibridgebase.h index 0d99523..8c40380 100644 --- a/devices/common/pci/pcibridgebase.h +++ b/devices/common/pci/pcibridgebase.h @@ -68,6 +68,9 @@ public: std::function pci_rd_bridge_control; std::function pci_wr_bridge_control; + // HWComponent methods + virtual int device_postinit(); + protected: // PCI configuration space state uint8_t primary_bus = 0; diff --git a/devices/common/pci/pcihost.cpp b/devices/common/pci/pcihost.cpp index cabb446..5fbba96 100644 --- a/devices/common/pci/pcihost.cpp +++ b/devices/common/pci/pcihost.cpp @@ -145,7 +145,16 @@ PCIBase *PCIHost::attach_pci_device(const std::string& dev_name, int slot_id, co return dev; } -IntDetails PCIHost::register_pci_int(PCIBase* dev_instance) { +InterruptCtrl *PCIHost::get_interrupt_controller() { + if (!this->int_ctrl) { + InterruptCtrl *int_ctrl_obj = + dynamic_cast(gMachineObj->get_comp_by_type(HWCompType::INT_CTRL)); + this->int_ctrl = int_ctrl_obj; + } + return this->int_ctrl; +} + +bool PCIHost::register_pci_int(PCIBase* dev_instance) { bool dev_found = false; int dev_fun_num = 0; @@ -160,10 +169,24 @@ IntDetails PCIHost::register_pci_int(PCIBase* dev_instance) { ABORT_F("register_pci_int: requested device not found"); for (auto& irq : this->my_irq_map) { - if (irq.dev_fun_num == dev_fun_num) - return {this->int_ctrl, irq.irq_id}; + if (irq.dev_fun_num == dev_fun_num) { + IntDetails new_int_detail; + new_int_detail.int_ctrl_obj = this->get_interrupt_controller(); + if (new_int_detail.int_ctrl_obj && irq.int_src) + new_int_detail.irq_id = new_int_detail.int_ctrl_obj->register_dev_int(irq.int_src); + dev_instance->set_int_details(new_int_detail); + return true; + } } - ABORT_F("register_pci_int: no IRQ map for device 0x%X", dev_fun_num); + + PCIBridgeBase *self = dynamic_cast(this); + if (self) { + if (!self->int_details.int_ctrl_obj) + self->host_instance->register_pci_int(self); + dev_instance->set_int_details(self->int_details); + return true; + } + return false; } bool PCIHost::pci_io_read_loop(uint32_t offset, int size, uint32_t &res) @@ -245,3 +268,19 @@ PCIBase *PCIHost::pci_find_device(uint8_t dev_num, uint8_t fun_num) } return NULL; } + +int PCIHost::pcihost_device_postinit() +{ + std::string pci_dev_name; + + for (auto& slot : this->my_irq_map) { + if (slot.slot_name) { + pci_dev_name = GET_STR_PROP(slot.slot_name); + if (!pci_dev_name.empty()) { + this->attach_pci_device(pci_dev_name, slot.dev_fun_num, std::string("@") + slot.slot_name); + } + } + } + + return 0; +} diff --git a/devices/common/pci/pcihost.h b/devices/common/pci/pcihost.h index 7cf6c50..8a30746 100644 --- a/devices/common/pci/pcihost.h +++ b/devices/common/pci/pcihost.h @@ -53,7 +53,7 @@ typedef struct AccessDetails { typedef struct { const char * slot_name; int dev_fun_num; - uint32_t irq_id; + IntSrc int_src; } PciIrqMap; class PCIBase; @@ -86,16 +86,16 @@ public: virtual PCIBase *pci_find_device(uint8_t bus_num, uint8_t dev_num, uint8_t fun_num); virtual PCIBase *pci_find_device(uint8_t dev_num, uint8_t fun_num); - virtual void pci_interrupt(uint8_t irq_line_state, PCIBase *dev) {} - virtual void set_irq_map(const std::vector &irq_map) { this->my_irq_map = irq_map; }; + virtual int pcihost_device_postinit(); - virtual IntDetails register_pci_int(PCIBase* dev_instance); + virtual bool register_pci_int(PCIBase* dev_instance); virtual void set_interrupt_controller(InterruptCtrl * int_ctrl_obj) { this->int_ctrl = int_ctrl_obj; }; + virtual InterruptCtrl *get_interrupt_controller(); protected: std::unordered_map dev_map; diff --git a/devices/ioctrl/grandcentral.cpp b/devices/ioctrl/grandcentral.cpp index 1a5a056..b41aae0 100644 --- a/devices/ioctrl/grandcentral.cpp +++ b/devices/ioctrl/grandcentral.cpp @@ -450,6 +450,9 @@ uint32_t GrandCentral::register_dev_int(IntSrc src_id) { case IntSrc::PLATINUM : return INT_TO_IRQ_ID(0x1E); // EXT10 + case IntSrc::PIPPIN_F : return INT_TO_IRQ_ID(0x1D); // EXT9 + case IntSrc::PIPPIN_E : return INT_TO_IRQ_ID(0x1E); // EXT10 + default: ABORT_F("%s: unknown interrupt source %d", this->name.c_str(), src_id); } diff --git a/devices/ioctrl/heathrow.cpp b/devices/ioctrl/heathrow.cpp index b413773..8b7673c 100644 --- a/devices/ioctrl/heathrow.cpp +++ b/devices/ioctrl/heathrow.cpp @@ -383,14 +383,15 @@ uint32_t HeathrowIC::register_dev_int(IntSrc src_id) { switch (src_id) { case IntSrc::SCSI_MESH : return INT_TO_IRQ_ID(0x0C); - case IntSrc::IDE0 : return INT_TO_IRQ_ID(0x0D); + case IntSrc::IDE0 : return INT_TO_IRQ_ID(0x0D); // Beige G3 first IDE controller, or Yosemite ata-3 case IntSrc::IDE1 : return INT_TO_IRQ_ID(0x0E); case IntSrc::SCCA : return INT_TO_IRQ_ID(0x0F); case IntSrc::SCCB : return INT_TO_IRQ_ID(0x10); case IntSrc::DAVBUS : return INT_TO_IRQ_ID(0x11); case IntSrc::VIA_CUDA : return INT_TO_IRQ_ID(0x12); case IntSrc::SWIM3 : return INT_TO_IRQ_ID(0x13); - case IntSrc::NMI : return INT_TO_IRQ_ID(0x14); // nmiSource in AppleHeathrow/Heathrow.cpp + case IntSrc::NMI : return INT_TO_IRQ_ID(0x14); // nmiSource in AppleHeathrow/Heathrow.cpp; programmer-switch in B&W G3 + case IntSrc::PERCH2 : return INT_TO_IRQ_ID(0x15); case IntSrc::PCI_GPU : return INT_TO_IRQ_ID(0x16); case IntSrc::PCI_A : return INT_TO_IRQ_ID(0x17); @@ -398,7 +399,17 @@ uint32_t HeathrowIC::register_dev_int(IntSrc src_id) case IntSrc::PCI_C : return INT_TO_IRQ_ID(0x19); case IntSrc::PERCH1 : return INT_TO_IRQ_ID(0x1A); case IntSrc::PCI_PERCH : return INT_TO_IRQ_ID(0x1C); + + case IntSrc::FIREWIRE : return INT_TO_IRQ_ID(0x15); // Yosemite built-in PCI FireWire + case IntSrc::PCI_J12 : return INT_TO_IRQ_ID(0x16); // Yosemite 32-bit 66MHz slot for GPU + case IntSrc::PCI_J11 : return INT_TO_IRQ_ID(0x17); // Yosemite 64-bit 33MHz slot + case IntSrc::PCI_J10 : return INT_TO_IRQ_ID(0x18); // Yosemite 64-bit 33MHz slot + case IntSrc::PCI_J9 : return INT_TO_IRQ_ID(0x19); // Yosemite 64-bit 33MHz slot + case IntSrc::ATA : return INT_TO_IRQ_ID(0x1A); // Yosemite PCI pci-ata + case IntSrc::USB : return INT_TO_IRQ_ID(0x1C); // Yosemite PCI usb + case IntSrc::ETHERNET : return INT_TO_IRQ_ID(0x2A); + default: ABORT_F("Heathrow: unknown interrupt source %d", src_id); } diff --git a/devices/memctrl/mpc106.cpp b/devices/memctrl/mpc106.cpp index 1873ce3..3760f99 100644 --- a/devices/memctrl/mpc106.cpp +++ b/devices/memctrl/mpc106.cpp @@ -45,9 +45,6 @@ MPC106::MPC106() : MemCtrlBase(), PCIDevice("Grackle"), PCIHost() this->command = 6; this->status = 0x80; - // assign PCI device number zero to myself - this->pci_register_device(DEV_FUN(0,0), this); - // add PCI/ISA I/O space, 64K for now add_mmio_region(0xFE000000, 0x10000, this); @@ -57,59 +54,9 @@ MPC106::MPC106() : MemCtrlBase(), PCIDevice("Grackle"), PCIHost() int MPC106::device_postinit() { - std::string pci_dev_name; - - static const std::map pci_slots = { - {"pci_PERCH", DEV_FUN(0xC,0)}, {"pci_A1", DEV_FUN(0xD,0)}, - {"pci_B1", DEV_FUN(0xE,0)}, {"pci_C1", DEV_FUN(0xF,0)}, - {"pci_GPU", DEV_FUN(0x12,0)} - }; - - for (auto& slot : pci_slots) { - pci_dev_name = GET_STR_PROP(slot.first); - if (!pci_dev_name.empty()) { - this->attach_pci_device(pci_dev_name, slot.second, std::string("@") + slot.first); - } - } - - this->int_ctrl = dynamic_cast( - gMachineObj->get_comp_by_type(HWCompType::INT_CTRL)); - - this->irq_id_PCI_A = this->int_ctrl->register_dev_int(IntSrc::PCI_A ); - this->irq_id_PCI_B = this->int_ctrl->register_dev_int(IntSrc::PCI_B ); - this->irq_id_PCI_C = this->int_ctrl->register_dev_int(IntSrc::PCI_C ); - this->irq_id_PCI_GPU = this->int_ctrl->register_dev_int(IntSrc::PCI_GPU ); - this->irq_id_PCI_PERCH = this->int_ctrl->register_dev_int(IntSrc::PCI_PERCH); - - return 0; -} - -void MPC106::pci_interrupt(uint8_t irq_line_state, PCIBase *dev) { - auto it = std::find_if(dev_map.begin(), dev_map.end(), - [&dev](const std::pair &p) { - return p.second == dev; - } - ); - - if (it == dev_map.end()) { - LOG_F(ERROR, "Interrupt from unknown device %s", dev->get_name().c_str()); - } - else { - uint32_t irq_id; - switch (it->first) { - case DEV_FUN(0x0C,0): irq_id = this->irq_id_PCI_PERCH; break; - case DEV_FUN(0x0D,0): irq_id = this->irq_id_PCI_A ; break; - case DEV_FUN(0x0E,0): irq_id = this->irq_id_PCI_B ; break; - case DEV_FUN(0x0F,0): irq_id = this->irq_id_PCI_C ; break; - case DEV_FUN(0x12,0): irq_id = this->irq_id_PCI_GPU ; break; - default: - LOG_F(ERROR, "Interrupt from device %s at unexpected device/function %02x.%x", - dev->get_name().c_str(), it->first >> 3, it->first & 7); - return; - } - if (this->int_ctrl) - this->int_ctrl->ack_int(irq_id, irq_line_state); - } + // assign PCI device number zero to myself + this->pci_register_device(DEV_FUN(0,0), this); + return this->pcihost_device_postinit(); } uint32_t MPC106::read(uint32_t rgn_start, uint32_t offset, int size) { @@ -357,6 +304,8 @@ static const PropMap Grackle_Properties = { new StrProperty("")}, {"pci_GPU", new StrProperty("")}, + {"pci_J12", + new StrProperty("")}, }; static const DeviceDescription Grackle_Descriptor = { diff --git a/devices/memctrl/mpc106.h b/devices/memctrl/mpc106.h index cec1030..e0dccd4 100644 --- a/devices/memctrl/mpc106.h +++ b/devices/memctrl/mpc106.h @@ -82,8 +82,6 @@ public: uint32_t read(uint32_t rgn_start, uint32_t offset, int size); void write(uint32_t rgn_start, uint32_t offset, uint32_t value, int size); - virtual void pci_interrupt(uint8_t irq_line_state, PCIBase *dev); - int device_postinit(); protected: @@ -115,14 +113,6 @@ private: uint32_t mem_end[2] = {}; uint32_t ext_mem_end[2] = {}; uint8_t mem_bank_en = 0; - - // interrupt related stuff - InterruptCtrl* int_ctrl = nullptr; - uint32_t irq_id_PCI_A = 0; - uint32_t irq_id_PCI_B = 0; - uint32_t irq_id_PCI_C = 0; - uint32_t irq_id_PCI_GPU = 0; - uint32_t irq_id_PCI_PERCH = 0; }; #endif // MPC106_H diff --git a/machines/machinecatalyst.cpp b/machines/machinecatalyst.cpp index b00a598..05dff8e 100644 --- a/machines/machinecatalyst.cpp +++ b/machines/machinecatalyst.cpp @@ -36,6 +36,14 @@ along with this program. If not, see . #include +static std::vector bandit1_irq_map = { + {nullptr , DEV_FUN(0x0B,0), IntSrc::BANDIT1}, + {"pci_A1", DEV_FUN(0x0D,0), IntSrc::PCI_A}, + {"pci_B1", DEV_FUN(0x0E,0), IntSrc::PCI_B}, + {"pci_C1", DEV_FUN(0x0F,0), IntSrc::PCI_C}, + {nullptr , DEV_FUN(0x10,0), }, // GrandCentral +}; + int initialize_catalyst(std::string& id) { LOG_F(INFO, "Building machine Catalyst..."); @@ -43,6 +51,7 @@ int initialize_catalyst(std::string& id) PlatinumCtrl* platinum_obj; PCIHost *pci_host = dynamic_cast(gMachineObj->get_comp_by_name("Bandit1")); + pci_host->set_irq_map(bandit1_irq_map); // get (raw) pointer to the I/O controller GrandCentral* gc_obj = dynamic_cast(gMachineObj->get_comp_by_name("GrandCentral")); diff --git a/machines/machinefactory.cpp b/machines/machinefactory.cpp index 1d15c3f..89a59eb 100644 --- a/machines/machinefactory.cpp +++ b/machines/machinefactory.cpp @@ -85,16 +85,25 @@ static const map PropHelp = { {"cdr_img", "specifies path(s) to CD-ROM image(s)"}, {"cdr_img2", "specifies path(s) to secondary CD-ROM image(s)"}, {"mon_id", "specifies which monitor to emulate"}, + {"pci_GPU", "specifies PCI device for Beige G3 grackle device @12"}, + {"pci_J12", "insert a PCI device into 32-bit 66MHz slot J12"}, + {"pci_J11", "insert a PCI device into 64-bit 33MHz slot J11"}, + {"pci_J10", "insert a PCI device into 64-bit 33MHz slot J10"}, + {"pci_J9", "insert a PCI device into 64-bit 33MHz slot J9"}, + {"pci_FireWire", "insert a PCI device into PCI slot reserved for Yosemite FireWire"}, + {"pci_UltraATA", "insert a PCI device into PCI slot reserved for Yosemite Ultra ATA"}, + {"pci_USB", "insert a PCI device into PCI slot reserved for Yosemite USB"}, {"pci_PERCH", "insert a PCI device into PERCH slot"}, {"pci_A1", "insert a PCI device into A1 slot"}, {"pci_B1", "insert a PCI device into B1 slot"}, {"pci_C1", "insert a PCI device into C1 slot"}, + {"pci_E1", "insert a PCI device into E1 slot"}, + {"pci_F1", "insert a PCI device into F1 slot"}, {"pci_D2", "insert a PCI device into D2 slot"}, {"pci_E2", "insert a PCI device into E2 slot"}, {"pci_F2", "insert a PCI device into F2 slot"}, {"vci_D", "insert a VCI device 0x0D"}, {"vci_E", "insert a VCI device 0x0E"}, - {"vci_F", "insert a VCI device 0x0F"}, {"serial_backend", "specifies the backend for the serial port"}, {"emmo", "enables/disables factory HW tests during startup"}, {"cpu", "specifies CPU"}, diff --git a/machines/machinegazelle.cpp b/machines/machinegazelle.cpp index eccf962..cbc23f3 100644 --- a/machines/machinegazelle.cpp +++ b/machines/machinegazelle.cpp @@ -34,6 +34,16 @@ along with this program. If not, see . #include #include +static std::vector psx_irq_map = { + {nullptr , DEV_FUN(0x0B,0), IntSrc::BANDIT1}, + {"pci_A1", DEV_FUN(0x0D,0), IntSrc::PCI_A}, + {"pci_B1", DEV_FUN(0x0E,0), IntSrc::PCI_B}, + {"pci_C1", DEV_FUN(0x0F,0), IntSrc::PCI_C}, + {nullptr , DEV_FUN(0x10,0), }, // OHare + {"pci_E1", DEV_FUN(0x11,0), IntSrc::PCI_E}, + {"pci_F1", DEV_FUN(0x12,0), IntSrc::PCI_F}, +}; + // TODO: move it to /cpu/ppc int get_cpu_pll_value(const uint64_t cpu_freq_hz) { switch (cpu_freq_hz / 1000000) { @@ -53,6 +63,7 @@ int initialize_gazelle(std::string& id) LOG_F(INFO, "Building machine Gazelle..."); PCIHost *pci_host = dynamic_cast(gMachineObj->get_comp_by_name("PsxPci1")); + pci_host->set_irq_map(psx_irq_map); // register O'Hare I/O controller with the main PCI bus pci_host->pci_register_device( diff --git a/machines/machinegossamer.cpp b/machines/machinegossamer.cpp index b659f7a..fe88f51 100644 --- a/machines/machinegossamer.cpp +++ b/machines/machinegossamer.cpp @@ -41,6 +41,16 @@ along with this program. If not, see . #include #include +static const std::vector grackle_irq_map = { + {nullptr , DEV_FUN(0x00,0), }, // Grackle + {"pci_PERCH", DEV_FUN(0x0C,0), IntSrc::PCI_PERCH }, + {"pci_A1" , DEV_FUN(0x0D,0), IntSrc::PCI_A }, + {"pci_B1" , DEV_FUN(0x0E,0), IntSrc::PCI_B }, + {"pci_C1" , DEV_FUN(0x0F,0), IntSrc::PCI_C }, + {nullptr , DEV_FUN(0x10,0), }, // Heathrow + {"pci_GPU" , DEV_FUN(0x12,0), IntSrc::PCI_GPU }, +}; + // Bit definitions for the Gossamer system register at 0xFF000004 enum : uint16_t { FDC_TYPE_SWIM3 = (1 << 15), // Macintosh style floppy disk controller @@ -96,6 +106,7 @@ int initialize_gossamer(std::string& id) // get pointer to the memory controller/PCI host bridge object MPC106* grackle_obj = dynamic_cast(gMachineObj->get_comp_by_name("Grackle")); + grackle_obj->set_irq_map(grackle_irq_map); // configure the Gossamer system register uint16_t sys_reg = FDC_TYPE_SWIM3 | BURST_ROM_TRUE diff --git a/machines/machinepippin.cpp b/machines/machinepippin.cpp index 7ed32e3..dd64091 100644 --- a/machines/machinepippin.cpp +++ b/machines/machinepippin.cpp @@ -33,10 +33,19 @@ along with this program. If not, see . #include #include +static std::vector aspen_irq_map = { +// {nullptr , DEV_FUN(0x0B,0), IntSrc::BANDIT1 }, +// {"pci_A1", DEV_FUN(0x0D,0), IntSrc::PCI_A }, + {"pci_B1", DEV_FUN(0x0E,0), IntSrc::PIPPIN_E}, + {"pci_C1", DEV_FUN(0x0F,0), IntSrc::PIPPIN_F}, + {nullptr , DEV_FUN(0x10,0), }, // GrandCentral +}; + int initialize_pippin(std::string& id) { LOG_F(INFO, "Building machine Pippin..."); PCIHost *pci_host = dynamic_cast(gMachineObj->get_comp_by_name("AspenPci1")); + pci_host->set_irq_map(aspen_irq_map); // connect GrandCentral I/O controller to the PCI1 bus pci_host->pci_register_device(DEV_FUN(0x10,0), diff --git a/machines/machinetnt.cpp b/machines/machinetnt.cpp index 3c140d5..14a9509 100644 --- a/machines/machinetnt.cpp +++ b/machines/machinetnt.cpp @@ -35,6 +35,27 @@ along with this program. If not, see . #include +static std::vector bandit1_irq_map = { + {nullptr , DEV_FUN(0x0B,0), IntSrc::BANDIT1}, + {"pci_A1", DEV_FUN(0x0D,0), IntSrc::PCI_A}, + {"pci_B1", DEV_FUN(0x0E,0), IntSrc::PCI_B}, + {"pci_C1", DEV_FUN(0x0F,0), IntSrc::PCI_C}, + {nullptr , DEV_FUN(0x10,0), }, // GrandCentral +}; + +static std::vector bandit2_irq_map = { + {nullptr , DEV_FUN(0x0B,0), IntSrc::BANDIT2}, + {"pci_D2", DEV_FUN(0x0D,0), IntSrc::PCI_D}, + {"pci_E2", DEV_FUN(0x0E,0), IntSrc::PCI_E}, + {"pci_F2", DEV_FUN(0x0F,0), IntSrc::PCI_F}, +}; + +static std::vector chaos_irq_map = { + {nullptr, DEV_FUN(0x0B,0), IntSrc::CONTROL}, + {"vci_D", DEV_FUN(0x0D,0), IntSrc::PLANB}, + {"vci_E", DEV_FUN(0x0E,0), IntSrc::VCI }, +}; + int initialize_tnt(std::string& id) { LOG_F(INFO, "Building machine TNT..."); @@ -42,6 +63,7 @@ int initialize_tnt(std::string& id) HammerheadCtrl* memctrl_obj; PCIHost *pci_host = dynamic_cast(gMachineObj->get_comp_by_name("Bandit1")); + pci_host->set_irq_map(bandit1_irq_map); // get (raw) pointer to the I/O controller GrandCentral* gc_obj = dynamic_cast(gMachineObj->get_comp_by_name("GrandCentral")); @@ -53,6 +75,7 @@ int initialize_tnt(std::string& id) // get video PCI controller object PCIHost *vci_host = dynamic_cast(gMachineObj->get_comp_by_name("Chaos")); if (vci_host) { + vci_host->set_irq_map(chaos_irq_map); // connect built-in video device to the VCI bus vci_host->pci_register_device( DEV_FUN(0x0B,0), dynamic_cast(gMachineObj->get_comp_by_name("ControlVideo"))); @@ -71,6 +94,7 @@ int initialize_tnt(std::string& id) PCIHost *pci2_host = dynamic_cast(gMachineObj->get_comp_by_name_optional("Bandit2")); if (pci2_host) { + pci2_host->set_irq_map(bandit2_irq_map); // attach IOBus Device #3 0xF301C000 gMachineObj->add_device("BoardReg2", std::unique_ptr( new BoardRegister("Board Register 2", diff --git a/machines/machineyosemite.cpp b/machines/machineyosemite.cpp index 8c0c596..a5f59b8 100644 --- a/machines/machineyosemite.cpp +++ b/machines/machineyosemite.cpp @@ -29,6 +29,23 @@ along with this program. If not, see . #include #include +static const std::vector grackle_irq_map = { + {nullptr , DEV_FUN(0x00,0) }, // Grackle + {nullptr , DEV_FUN(0x0D,0) }, // Dec21154Yosemite + {"pci_J12", DEV_FUN(0x10,0), IntSrc::PCI_J12}, // GPU PCI slot, 66 MHz +}; + +// 33 MHz PCI devices behind the DEC21154 PCI-to-PCI bridge +static const std::vector pci_bridge_irq_map = { + {"pci_FireWire", DEV_FUN(0x00,0), IntSrc::FIREWIRE}, + {"pci_UltraATA", DEV_FUN(0x01,0), IntSrc::ATA }, + {"pci_J11" , DEV_FUN(0x02,0), IntSrc::PCI_J11 }, + {"pci_J10" , DEV_FUN(0x03,0), IntSrc::PCI_J10 }, + {"pci_J9" , DEV_FUN(0x04,0), IntSrc::PCI_J9 }, + {nullptr , DEV_FUN(0x05,0) }, // Heathrow + {"pci_USB" , DEV_FUN(0x06,0), IntSrc::USB }, +}; + static void setup_ram_slot(std::string name, int i2c_addr, int capacity_megs) { if (!capacity_megs) return; @@ -48,16 +65,18 @@ int initialize_yosemite(std::string& id) // get pointer to the memory controller/primary PCI bridge object MPC106* grackle_obj = dynamic_cast(gMachineObj->get_comp_by_name("Grackle")); + grackle_obj->set_irq_map(grackle_irq_map); // get pointer to the bridge of the secondary PCI bus - DecPciBridge *sec_bridge = dynamic_cast(gMachineObj->get_comp_by_name("Dec21154")); + DecPciBridge *sec_bridge = dynamic_cast(gMachineObj->get_comp_by_name("Dec21154Yosemite")); + sec_bridge->set_irq_map(pci_bridge_irq_map); // attach PCI devices to the PCI bridges grackle_obj->pci_register_device(DEV_FUN(16,0), dynamic_cast(gMachineObj->get_comp_by_name("AtiRage128"))); - grackle_obj->pci_register_device(DEV_FUN(13,0), - dynamic_cast(gMachineObj->get_comp_by_name("Dec21154"))); + // 00:0D.0 PCI Bridge + grackle_obj->pci_register_device(DEV_FUN(0x0D,0), dynamic_cast(sec_bridge)); // register CMD646U2 PCI Ultra ATA Controller sec_bridge->pci_register_device(DEV_FUN(1,0), @@ -66,29 +85,6 @@ int initialize_yosemite(std::string& id) sec_bridge->pci_register_device(DEV_FUN(5,0), dynamic_cast(gMachineObj->get_comp_by_name("Heathrow"))); - InterruptCtrl *int_ctrl_obj = - dynamic_cast(gMachineObj->get_comp_by_type(HWCompType::INT_CTRL)); - - static const std::vector grackle_irq_map = { - {"pci_J12", DEV_FUN(0x10,0), 1 << 22} // GPU PCI slot, 66 MHz - }; - - grackle_obj->set_interrupt_controller(int_ctrl_obj); - grackle_obj->set_irq_map(grackle_irq_map); - - // 33 MHz PCI devices behind the DEC21154 PCI-to-PCI bridge - static const std::vector pci_bridge_irq_map = { - {"pci_FireWire", DEV_FUN(0x00,0), 1 << 21}, - {"pci_UltraATA", DEV_FUN(0x01,0), 1 << 26}, - {"pci_J11", DEV_FUN(0x02,0), 1 << 23}, - {"pci_J10", DEV_FUN(0x03,0), 1 << 24}, - {"pci_J9", DEV_FUN(0x04,0), 1 << 25}, - {"pci_USB", DEV_FUN(0x06,0), 1 << 28} - }; - - sec_bridge->set_interrupt_controller(int_ctrl_obj); - sec_bridge->set_irq_map(pci_bridge_irq_map); - // allocate ROM region if (!grackle_obj->add_rom_region(0xFFF00000, 0x100000)) { LOG_F(ERROR, "Could not allocate ROM region!"); @@ -132,8 +128,13 @@ static const PropMap yosemite_settings = { }; static vector yosemite_devices = { - "Grackle", "Dec21154", "CmdAta", "BurgundySnd", "Heathrow", "AtaHardDisk", - "AtapiCdrom" + "Grackle", + "Dec21154Yosemite", + "CmdAta", + "BurgundySnd", + "Heathrow", + "AtaHardDisk", + "AtapiCdrom", }; static const MachineDescription yosemite_descriptor = {