Interrupt stuff
This commit is contained in:
parent
48f861b6e8
commit
685227d874
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue