From 685227d874cb5b4cf4499dc13af4a32b6339beac Mon Sep 17 00:00:00 2001 From: ergo720 Date: Mon, 28 May 2018 00:49:19 +0200 Subject: [PATCH] Interrupt stuff --- src/devices/USBController/OHCI.cpp | 37 ++++++++++++++++++------- src/devices/USBController/OHCI.h | 13 +++++++-- src/devices/USBController/USBDevice.cpp | 5 ++-- src/devices/USBController/USBDevice.h | 1 - 4 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/devices/USBController/OHCI.cpp b/src/devices/USBController/OHCI.cpp index e1d1c8328..b76c1c398 100644 --- a/src/devices/USBController/OHCI.cpp +++ b/src/devices/USBController/OHCI.cpp @@ -35,8 +35,7 @@ // ****************************************************************** #include "OHCI.h" -#include "..\CxbxKrnl\CxbxKrnl.h" -#include "..\CxbxKrnl\Emu.h" // For EmuWarning +#include "CxbxKrnl\EmuKrnl.h" // For HalSystemInterrupt #define USB_HZ 12000000 @@ -53,9 +52,10 @@ OHCI* g_pHostController1 = nullptr; OHCI* g_pHostController2 = nullptr; -OHCI::OHCI(USBDevice* UsbObj) +OHCI::OHCI(USBDevice* UsbObj, int Irq) { UsbInstance = UsbObj; + Irq_n = Irq; for (int i = 0; i < 2; i++) { UsbInstance->USB_RegisterPort(&Registers.RhPort[i].Port, this, i, USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); @@ -91,7 +91,7 @@ void OHCI::OHCI_StateReset() Registers.HcControl |= Reset; Registers.HcCommandStatus = 0; Registers.HcInterruptStatus = 0; - Registers.HcInterrupt = OHCI_INTR_MASTER_INTERRUPT_ENABLED; // enable interrupts + Registers.HcInterrupt = OHCI_INTR_MIE; // enable interrupts Registers.HcHCCA = 0; Registers.HcPeriodCurrentED = 0; @@ -144,7 +144,7 @@ void OHCI::OHCI_SOF() { SOFtime = GetTime_NS(pEOFtimer); // set current SOF time Timer_Start(pEOFtimer, SOFtime + UsbFrameTime); // make timer expire at SOF + 1 virtual ms from now - // TODO: interrupt + OHCI_SetInterrupt(OHCI_INTR_SF); } void OHCI::OHCI_ChangeState(uint32_t Value) @@ -323,8 +323,8 @@ void OHCI::OHCI_WriteRegister(xbaddr Addr, uint32_t Value) // SOC is read-only Value &= ~OHCI_STATUS_SOC; - // From the standard: "The Host Controller must ensure that bits written as ‘1’ become set - // in the register while bits written as ‘0’ remain unchanged in the register." + // From the standard: "The Host Controller must ensure that bits written as 1 become set + // in the register while bits written as 0 remain unchanged in the register." Registers.HcCommandStatus |= Value; if (Registers.HcCommandStatus & OHCI_STATUS_HCR) { @@ -335,15 +335,18 @@ void OHCI::OHCI_WriteRegister(xbaddr Addr, uint32_t Value) break; case 3: // HcInterruptStatus - // TODO + Registers.HcInterruptStatus &= ~Value; + OHCI_UpdateInterrupt(); break; case 4: // HcInterruptEnable - // TODO + Registers.HcInterrupt |= Value; + OHCI_UpdateInterrupt(); break; case 5: // HcInterruptDisable - // TODO + Registers.HcInterrupt &= ~Value; + OHCI_UpdateInterrupt(); break; case 6: // HcHCCA @@ -426,3 +429,17 @@ void OHCI::OHCI_WriteRegister(xbaddr Addr, uint32_t Value) } } } + +void OHCI::OHCI_UpdateInterrupt() +{ + if ((Registers.HcInterrupt & OHCI_INTR_MIE) && (Registers.HcInterruptStatus & Registers.HcInterrupt)) { + HalSystemInterrupts[Irq_n].Assert(true); + } + else { HalSystemInterrupts[Irq_n].Assert(false); } +} + +void OHCI::OHCI_SetInterrupt(uint32_t Value) +{ + Registers.HcInterruptStatus |= Value; + OHCI_UpdateInterrupt(); +} diff --git a/src/devices/USBController/OHCI.h b/src/devices/USBController/OHCI.h index 9894bedbd..fe5d70c86 100644 --- a/src/devices/USBController/OHCI.h +++ b/src/devices/USBController/OHCI.h @@ -37,7 +37,6 @@ #ifndef OHCI_H_ #define OHCI_H_ -#include #include "Cxbx.h" #include "USBDevice.h" #include "..\CxbxKrnl\Timer.h" @@ -66,8 +65,10 @@ #define OHCI_STATUS_BLF (1<<2) // BulkListFilled #define OHCI_STATUS_OCR (1<<3) // OwnershipChangeRequest #define OHCI_STATUS_SOC ((1<<6)|(1<<7)) // SchedulingOverrunCount +// HcInterruptStatus +#define OHCI_INTR_SF (1<<2) // Start of frame // HcInterruptEnable, HcInterruptDisable -#define OHCI_INTR_MASTER_INTERRUPT_ENABLED (1<<31) // MasterInterruptEnable +#define OHCI_INTR_MIE (1<<31) // MasterInterruptEnable // HcHCCA #define OHCI_HCCA_MASK 0xFFFFFF00 // HCCA mask // HcControlHeadED @@ -144,7 +145,7 @@ class OHCI { public: // constructor - OHCI(USBDevice* UsbObj); + OHCI(USBDevice* UsbObj, int Irqn); // destructor ~OHCI() {} // read a register @@ -168,6 +169,8 @@ class OHCI USBDevice* UsbInstance; // usb packet USBPacket UsbPacket; + // irq number + int Irq_n; // EOF callback wrapper static void OHCI_FrameBoundaryWrapper(void* pVoid); @@ -185,6 +188,10 @@ class OHCI void OHCI_BusStop(); // generate a SOF event, and start a timer for EOF void OHCI_SOF(); + // change interrupt status + void OHCI_UpdateInterrupt(); + // fire an interrupt + void OHCI_SetInterrupt(uint32_t Value); }; extern OHCI* g_pHostController1; diff --git a/src/devices/USBController/USBDevice.cpp b/src/devices/USBController/USBDevice.cpp index 4a96286e9..4454d0f11 100644 --- a/src/devices/USBController/USBDevice.cpp +++ b/src/devices/USBController/USBDevice.cpp @@ -35,6 +35,7 @@ // ****************************************************************** #include "USBDevice.h" +#include "OHCI.h" #include @@ -52,11 +53,11 @@ void USBDevice::Init(unsigned int address) m_VendorId = PCI_VENDOR_ID_NVIDIA; if (address == USB0_BASE) { - g_pHostController1 = new OHCI(this); + g_pHostController1 = new OHCI(this, 1); return; } - g_pHostController2 = new OHCI(this); + g_pHostController2 = new OHCI(this, 9); } uint32_t USBDevice::MMIORead(int barIndex, uint32_t addr, unsigned size) diff --git a/src/devices/USBController/USBDevice.h b/src/devices/USBController/USBDevice.h index 80ab0907b..2839b0809 100644 --- a/src/devices/USBController/USBDevice.h +++ b/src/devices/USBController/USBDevice.h @@ -37,7 +37,6 @@ #define USBDEVICE_H_ #include "..\PCIDevice.h" -#include "OHCI.h" // This is a linux struct for vectored I/O. See readv() and writev()