Interrupt stuff

This commit is contained in:
ergo720 2018-05-28 00:49:19 +02:00
parent 48f861b6e8
commit 685227d874
4 changed files with 40 additions and 16 deletions

View File

@ -35,8 +35,7 @@
// ****************************************************************** // ******************************************************************
#include "OHCI.h" #include "OHCI.h"
#include "..\CxbxKrnl\CxbxKrnl.h" #include "CxbxKrnl\EmuKrnl.h" // For HalSystemInterrupt
#include "..\CxbxKrnl\Emu.h" // For EmuWarning
#define USB_HZ 12000000 #define USB_HZ 12000000
@ -53,9 +52,10 @@ OHCI* g_pHostController1 = nullptr;
OHCI* g_pHostController2 = nullptr; OHCI* g_pHostController2 = nullptr;
OHCI::OHCI(USBDevice* UsbObj) OHCI::OHCI(USBDevice* UsbObj, int Irq)
{ {
UsbInstance = UsbObj; UsbInstance = UsbObj;
Irq_n = Irq;
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
UsbInstance->USB_RegisterPort(&Registers.RhPort[i].Port, this, i, USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); 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.HcControl |= Reset;
Registers.HcCommandStatus = 0; Registers.HcCommandStatus = 0;
Registers.HcInterruptStatus = 0; Registers.HcInterruptStatus = 0;
Registers.HcInterrupt = OHCI_INTR_MASTER_INTERRUPT_ENABLED; // enable interrupts Registers.HcInterrupt = OHCI_INTR_MIE; // enable interrupts
Registers.HcHCCA = 0; Registers.HcHCCA = 0;
Registers.HcPeriodCurrentED = 0; Registers.HcPeriodCurrentED = 0;
@ -144,7 +144,7 @@ void OHCI::OHCI_SOF()
{ {
SOFtime = GetTime_NS(pEOFtimer); // set current SOF time SOFtime = GetTime_NS(pEOFtimer); // set current SOF time
Timer_Start(pEOFtimer, SOFtime + UsbFrameTime); // make timer expire at SOF + 1 virtual ms from now 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) void OHCI::OHCI_ChangeState(uint32_t Value)
@ -323,8 +323,8 @@ void OHCI::OHCI_WriteRegister(xbaddr Addr, uint32_t Value)
// SOC is read-only // SOC is read-only
Value &= ~OHCI_STATUS_SOC; Value &= ~OHCI_STATUS_SOC;
// From the standard: "The Host Controller must ensure that bits written as 1 become set // 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." // in the register while bits written as 0 remain unchanged in the register."
Registers.HcCommandStatus |= Value; Registers.HcCommandStatus |= Value;
if (Registers.HcCommandStatus & OHCI_STATUS_HCR) { if (Registers.HcCommandStatus & OHCI_STATUS_HCR) {
@ -335,15 +335,18 @@ void OHCI::OHCI_WriteRegister(xbaddr Addr, uint32_t Value)
break; break;
case 3: // HcInterruptStatus case 3: // HcInterruptStatus
// TODO Registers.HcInterruptStatus &= ~Value;
OHCI_UpdateInterrupt();
break; break;
case 4: // HcInterruptEnable case 4: // HcInterruptEnable
// TODO Registers.HcInterrupt |= Value;
OHCI_UpdateInterrupt();
break; break;
case 5: // HcInterruptDisable case 5: // HcInterruptDisable
// TODO Registers.HcInterrupt &= ~Value;
OHCI_UpdateInterrupt();
break; break;
case 6: // HcHCCA 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();
}

View File

@ -37,7 +37,6 @@
#ifndef OHCI_H_ #ifndef OHCI_H_
#define OHCI_H_ #define OHCI_H_
#include <stdint.h>
#include "Cxbx.h" #include "Cxbx.h"
#include "USBDevice.h" #include "USBDevice.h"
#include "..\CxbxKrnl\Timer.h" #include "..\CxbxKrnl\Timer.h"
@ -66,8 +65,10 @@
#define OHCI_STATUS_BLF (1<<2) // BulkListFilled #define OHCI_STATUS_BLF (1<<2) // BulkListFilled
#define OHCI_STATUS_OCR (1<<3) // OwnershipChangeRequest #define OHCI_STATUS_OCR (1<<3) // OwnershipChangeRequest
#define OHCI_STATUS_SOC ((1<<6)|(1<<7)) // SchedulingOverrunCount #define OHCI_STATUS_SOC ((1<<6)|(1<<7)) // SchedulingOverrunCount
// HcInterruptStatus
#define OHCI_INTR_SF (1<<2) // Start of frame
// HcInterruptEnable, HcInterruptDisable // HcInterruptEnable, HcInterruptDisable
#define OHCI_INTR_MASTER_INTERRUPT_ENABLED (1<<31) // MasterInterruptEnable #define OHCI_INTR_MIE (1<<31) // MasterInterruptEnable
// HcHCCA // HcHCCA
#define OHCI_HCCA_MASK 0xFFFFFF00 // HCCA mask #define OHCI_HCCA_MASK 0xFFFFFF00 // HCCA mask
// HcControlHeadED // HcControlHeadED
@ -144,7 +145,7 @@ class OHCI
{ {
public: public:
// constructor // constructor
OHCI(USBDevice* UsbObj); OHCI(USBDevice* UsbObj, int Irqn);
// destructor // destructor
~OHCI() {} ~OHCI() {}
// read a register // read a register
@ -168,6 +169,8 @@ class OHCI
USBDevice* UsbInstance; USBDevice* UsbInstance;
// usb packet // usb packet
USBPacket UsbPacket; USBPacket UsbPacket;
// irq number
int Irq_n;
// EOF callback wrapper // EOF callback wrapper
static void OHCI_FrameBoundaryWrapper(void* pVoid); static void OHCI_FrameBoundaryWrapper(void* pVoid);
@ -185,6 +188,10 @@ class OHCI
void OHCI_BusStop(); void OHCI_BusStop();
// generate a SOF event, and start a timer for EOF // generate a SOF event, and start a timer for EOF
void OHCI_SOF(); void OHCI_SOF();
// change interrupt status
void OHCI_UpdateInterrupt();
// fire an interrupt
void OHCI_SetInterrupt(uint32_t Value);
}; };
extern OHCI* g_pHostController1; extern OHCI* g_pHostController1;

View File

@ -35,6 +35,7 @@
// ****************************************************************** // ******************************************************************
#include "USBDevice.h" #include "USBDevice.h"
#include "OHCI.h"
#include <assert.h> #include <assert.h>
@ -52,11 +53,11 @@ void USBDevice::Init(unsigned int address)
m_VendorId = PCI_VENDOR_ID_NVIDIA; m_VendorId = PCI_VENDOR_ID_NVIDIA;
if (address == USB0_BASE) { if (address == USB0_BASE) {
g_pHostController1 = new OHCI(this); g_pHostController1 = new OHCI(this, 1);
return; return;
} }
g_pHostController2 = new OHCI(this); g_pHostController2 = new OHCI(this, 9);
} }
uint32_t USBDevice::MMIORead(int barIndex, uint32_t addr, unsigned size) uint32_t USBDevice::MMIORead(int barIndex, uint32_t addr, unsigned size)

View File

@ -37,7 +37,6 @@
#define USBDEVICE_H_ #define USBDEVICE_H_
#include "..\PCIDevice.h" #include "..\PCIDevice.h"
#include "OHCI.h"
// This is a linux struct for vectored I/O. See readv() and writev() // This is a linux struct for vectored I/O. See readv() and writev()