From cd1d0031e6cbae4fd61064e517118787dfb196ac Mon Sep 17 00:00:00 2001 From: Maxim Poliakovski Date: Sun, 7 Aug 2022 15:19:27 +0200 Subject: [PATCH] GC: implement attachable IOBus devices. --- devices/ioctrl/grandcentral.cpp | 34 ++++++++++++++++++++++++++++++--- devices/ioctrl/macio.h | 11 +++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/devices/ioctrl/grandcentral.cpp b/devices/ioctrl/grandcentral.cpp index 05e3e1d..203db32 100644 --- a/devices/ioctrl/grandcentral.cpp +++ b/devices/ioctrl/grandcentral.cpp @@ -120,11 +120,20 @@ uint32_t GrandCentral::read(uint32_t reg_start, uint32_t offset, int size) return this->viacuda->read((offset >> 9) & 0xF); case 0xA: // Board register 1 (IOBus dev #1) return BYTESWAP_32(this->emmo_pin << 8); + case 0xB: // IOBus dev #2 + case 0xC: // IOBus dev #3 + case 0xE: // IOBus dev #5 + if (this->iobus_devs[subdev_num - 10] != nullptr) { + return BYTESWAP_16(this->iobus_devs[subdev_num - 10]->iodev_read( + (offset >> 4) & 0x1F)); + } else { + LOG_F(ERROR, "GC: IOBus device #%d doesn't exist", subdev_num - 9); + return 0; + } + break; case 0xF: // NVRAM Data (IOBus dev #6) return this->nvram->read_byte( (this->nvram_addr_hi << 5) + ((offset >> 4) & 0x1F)); - default: - LOG_F(WARNING, "GC: unimplemented GBUS device #%d", subdev_num - 9); } } else if (offset & 0x8000) { // DMA register space unsigned subdev_num = (offset >> 12) & 0xF; @@ -182,6 +191,17 @@ void GrandCentral::write(uint32_t reg_start, uint32_t offset, uint32_t value, in case 7: // VIA-CUDA this->viacuda->write((offset >> 9) & 0xF, value); break; + case 0xA: // IOBus dev #1 + case 0xB: // IOBus dev #2 + case 0xC: // IOBus dev #3 + case 0xE: // IOBus dev #5 + if (this->iobus_devs[subdev_num - 10] != nullptr) { + this->iobus_devs[subdev_num - 10]->iodev_write( + (offset >> 4) & 0x1F, value); + } else { + LOG_F(ERROR, "GC: IOBus device #%d doesn't exist", subdev_num - 9); + } + break; case 0xD: // NVRAM High Address (IOBus dev #4) switch (size) { case 4: @@ -199,7 +219,8 @@ void GrandCentral::write(uint32_t reg_start, uint32_t offset, uint32_t value, in (this->nvram_addr_hi << 5) + ((offset >> 4) & 0x1F), value); break; default: - LOG_F(WARNING, "GC: unimplemented GBUS device #%d", subdev_num - 9); + LOG_F(WARNING, "GC: writing to unmapped I/O memory 0x%X", + this->base_addr + offset); } } else if (offset & 0x8000) { // DMA register space unsigned subdev_num = (offset >> 12) & 0xF; @@ -231,6 +252,13 @@ void GrandCentral::write(uint32_t reg_start, uint32_t offset, uint32_t value, in } } +void GrandCentral::attach_iodevice(int dev_num, IobusDevice* dev_obj) +{ + if (dev_num >= 0 && dev_num < 6) { + this->iobus_devs[dev_num] = dev_obj; + } +} + uint32_t GrandCentral::register_dev_int(IntSrc src_id) { switch (src_id) { diff --git a/devices/ioctrl/macio.h b/devices/ioctrl/macio.h index 2011b76..3f7f79b 100644 --- a/devices/ioctrl/macio.h +++ b/devices/ioctrl/macio.h @@ -84,6 +84,12 @@ enum { MIO_INT_LEVELS1 = 0x2C }; +class IobusDevice { +public: + virtual uint16_t iodev_read(uint32_t address) = 0; + virtual void iodev_write(uint32_t address, uint16_t value) = 0; +}; + class GrandCentral : public PCIDevice, public InterruptCtrl { public: GrandCentral(); @@ -103,6 +109,8 @@ public: void ack_int(uint32_t irq_id, uint8_t irq_line_state); void ack_dma_int(uint32_t irq_id, uint8_t irq_line_state); + void attach_iodevice(int dev_num, IobusDevice* dev_obj); + protected: void notify_bar_change(int bar_num); @@ -118,6 +126,9 @@ private: uint32_t nvram_addr_hi; + // IOBus devices + IobusDevice* iobus_devs[6] = { nullptr }; + // subdevice objects std::unique_ptr awacs; // AWACS audio codec instance