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 "..\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();
}

View File

@ -37,7 +37,6 @@
#ifndef OHCI_H_
#define OHCI_H_
#include <stdint.h>
#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;

View File

@ -35,6 +35,7 @@
// ******************************************************************
#include "USBDevice.h"
#include "OHCI.h"
#include <assert.h>
@ -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)

View File

@ -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()