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