ED processing stuff
This commit is contained in:
parent
ea164dd769
commit
c0bc5545bb
|
@ -37,6 +37,91 @@
|
|||
#include "OHCI.h"
|
||||
#include "CxbxKrnl\EmuKrnl.h" // For HalSystemInterrupt
|
||||
|
||||
/* These macros are used to access the bits of the various registers */
|
||||
// HcControl
|
||||
#define OHCI_CTL_CBSR ((1<<0)|(1<<1)) // ControlBulkServiceRatio
|
||||
#define OHCI_CTL_PLE (1<<2) // PeriodicListEnable
|
||||
#define OHCI_CTL_IE (1<<3) // IsochronousEnable
|
||||
#define OHCI_CTL_CLE (1<<4) // ControlListEnable
|
||||
#define OHCI_CTL_BLE (1<<5) // BulkListEnable
|
||||
#define OHCI_CTL_HCFS ((1<<6)|(1<<7)) // HostControllerFunctionalState
|
||||
#define OHCI_CTL_IR (1<<8) // InterruptRouting
|
||||
#define OHCI_CTL_RWC (1<<9) // RemoteWakeupConnected
|
||||
#define OHCI_CTL_RWE (1<<10) // RemoteWakeupEnable
|
||||
// HcCommandStatus
|
||||
#define OHCI_STATUS_HCR (1<<0) // HostControllerReset
|
||||
#define OHCI_STATUS_CLF (1<<1) // ControlListFilled
|
||||
#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_SO (1<<0) // SchedulingOverrun
|
||||
#define OHCI_INTR_WD (1<<1) // WritebackDoneHead
|
||||
#define OHCI_INTR_SF (1<<2) // StartofFrame
|
||||
#define OHCI_INTR_RD (1<<3) // ResumeDetected
|
||||
#define OHCI_INTR_UE (1<<4) // UnrecoverableError
|
||||
#define OHCI_INTR_FNO (1<<5) // FrameNumberOverflow
|
||||
#define OHCI_INTR_RHSC (1<<6) // RootHubStatusChange
|
||||
#define OHCI_INTR_OC (1<<30) // OwnershipChange
|
||||
// HcInterruptEnable, HcInterruptDisable
|
||||
#define OHCI_INTR_MIE (1<<31) // MasterInterruptEnable
|
||||
// HcHCCA
|
||||
#define OHCI_HCCA_MASK 0xFFFFFF00 // HCCA mask
|
||||
// HcFmInterval
|
||||
#define OHCI_FMI_FI 0x00003FFF // FrameInterval
|
||||
#define OHCI_FMI_FIT 0x80000000 // FrameIntervalToggle
|
||||
// HcFmRemaining
|
||||
#define OHCI_FMR_FR 0x00003FFF // FrameRemaining
|
||||
#define OHCI_FMR_FRT 0x80000000 // FrameRemainingToggle
|
||||
// HcRhDescriptorA
|
||||
#define OHCI_RHA_RW_MASK 0x00000000 // Mask of supported features
|
||||
#define OHCI_RHA_PSM (1<<8) // PowerSwitchingMode
|
||||
#define OHCI_RHA_NPS (1<<9) // NoPowerSwitching
|
||||
#define OHCI_RHA_DT (1<<10) // DeviceType
|
||||
#define OHCI_RHA_OCPM (1<<11) // OverCurrentProtectionMode
|
||||
#define OHCI_RHA_NOCP (1<<12) // NoOverCurrentProtection
|
||||
// HcRhStatus
|
||||
#define OHCI_RHS_LPS (1<<0) // LocalPowerStatus
|
||||
#define OHCI_RHS_OCI (1<<1) // OverCurrentIndicator
|
||||
#define OHCI_RHS_DRWE (1<<15) // DeviceRemoteWakeupEnable
|
||||
#define OHCI_RHS_LPSC (1<<16) // LocalPowerStatusChange
|
||||
#define OHCI_RHS_OCIC (1<<17) // OverCurrentIndicatorChange
|
||||
#define OHCI_RHS_CRWE (1<<31) // ClearRemoteWakeupEnable
|
||||
// HcRhPortStatus
|
||||
#define OHCI_PORT_CCS (1<<0) // CurrentConnectStatus
|
||||
#define OHCI_PORT_PES (1<<1) // PortEnableStatus
|
||||
#define OHCI_PORT_PSS (1<<2) // PortSuspendStatus
|
||||
#define OHCI_PORT_POCI (1<<3) // PortOverCurrentIndicator
|
||||
#define OHCI_PORT_PRS (1<<4) // PortResetStatus
|
||||
#define OHCI_PORT_PPS (1<<8) // PortPowerStatus
|
||||
#define OHCI_PORT_LSDA (1<<9) // LowSpeedDeviceAttached
|
||||
#define OHCI_PORT_CSC (1<<16) // ConnectStatusChange
|
||||
#define OHCI_PORT_PESC (1<<17) // PortEnableStatusChange
|
||||
#define OHCI_PORT_PSSC (1<<18) // PortSuspendStatusChange
|
||||
#define OHCI_PORT_OCIC (1<<19) // PortOverCurrentIndicatorChange
|
||||
#define OHCI_PORT_PRSC (1<<20) // PortResetStatusChange
|
||||
#define OHCI_PORT_WTC (OHCI_PORT_CSC|OHCI_PORT_PESC|OHCI_PORT_PSSC \
|
||||
|OHCI_PORT_OCIC|OHCI_PORT_PRSC)
|
||||
|
||||
/* Bitfields for the first word of an ED */
|
||||
#define OHCI_ED_FA_SHIFT 0
|
||||
#define OHCI_ED_FA_MASK (0x7F<<OHCI_ED_FA_SHIFT)
|
||||
#define OHCI_ED_EN_SHIFT 7
|
||||
#define OHCI_ED_EN_MASK (0xF<<OHCI_ED_EN_SHIFT)
|
||||
#define OHCI_ED_D_SHIFT 11
|
||||
#define OHCI_ED_D_MASK (3<<OHCI_ED_D_SHIFT)
|
||||
#define OHCI_ED_S (1<<13)
|
||||
#define OHCI_ED_K (1<<14) // sKip
|
||||
#define OHCI_ED_F (1<<15) // Format
|
||||
#define OHCI_ED_MPS_SHIFT 16
|
||||
#define OHCI_ED_MPS_MASK (0x7FF<<OHCI_ED_MPS_SHIFT)
|
||||
|
||||
/* Flags in the HeadP field of an ED */
|
||||
#define OHCI_ED_H 1 // Halted
|
||||
|
||||
/* Mask for the four least significant bits in an ED address */
|
||||
#define OHCI_DPTR_MASK 0xFFFFFFF0
|
||||
|
||||
#define USB_HZ 12000000
|
||||
|
||||
#define USB_SPEED_LOW 0
|
||||
|
@ -84,8 +169,10 @@ void OHCI::OHCI_FrameBoundaryWorker()
|
|||
|
||||
// Process all the lists at the end of the frame
|
||||
if (m_Registers.HcControl & OHCI_CTL_PLE) {
|
||||
int n = m_Registers.HcFmNumber & 0x1f;
|
||||
ohci_service_ed_list(ohci, le32_to_cpu(hcca.intr[n]), 0);
|
||||
// From the standard: "The head pointer used for a particular frame is determined by using the last 5 bits of the
|
||||
// Frame Counter as an offset into the interrupt array within the HCCA."
|
||||
int n = m_Registers.HcFmNumber & 0x1F;
|
||||
OHCI_ServiceEDlist(hcca.HccaInterrruptTable[n], 0); // dropped little -> big endian conversion from XQEMU
|
||||
}
|
||||
|
||||
// Cancel all pending packets if either of the lists has been disabled
|
||||
|
@ -160,9 +247,14 @@ void OHCI::OHCI_FatalError()
|
|||
|
||||
bool OHCI::OHCI_ReadHCCA(xbaddr Paddr, OHCI_HCCA* Hcca)
|
||||
{
|
||||
// ergo720: I disassembled various xbe's of my games and discovered that the shared memory between
|
||||
// HCD and HC is allocated with MmAllocateContiguousMemory which means we can access it from
|
||||
// the contiguous region. Hopefully XDK revisions didn't alter this...
|
||||
// ergo720: there could be a peculiar problem if the shared memory between HCD and HC is allocated by the
|
||||
// VMManager with VirtualAlloc: the physical allocation would not reside in memory.bin and if we tried to
|
||||
// access the physical address of it, we would access an empty page. In practice, I disassembled various
|
||||
// xbe's of my games and discovered that this shared memory is allocated with MmAllocateContiguousMemory
|
||||
// which means we can access it from the contiguous region just fine (lucky)
|
||||
// ... provided that XDK revisions didn't alter this
|
||||
|
||||
// NOTE: this shared memory contains the HCCA + EDs and TDs
|
||||
|
||||
if (Paddr != xbnull) {
|
||||
std::memcpy(Hcca, reinterpret_cast<void*>(Paddr + CONTIGUOUS_MEMORY_BASE), sizeof(OHCI_HCCA));
|
||||
|
@ -186,6 +278,114 @@ bool OHCI::OHCI_WriteHCCA(xbaddr Paddr, OHCI_HCCA* Hcca)
|
|||
return true; // error
|
||||
}
|
||||
|
||||
bool OHCI::OHCI_ReadED(xbaddr Paddr, OHCI_ED* Ed)
|
||||
{
|
||||
return OHCI_GetDwords(Paddr, reinterpret_cast<uint32_t*>(Ed), sizeof(*Ed) >> 2); // ED is 16 bytes large
|
||||
}
|
||||
|
||||
bool OHCI::OHCI_WriteED(xbaddr Paddr, OHCI_ED* Ed)
|
||||
{
|
||||
// According to the standard, only the HeadP field is writable by the HC, so we'll write just that
|
||||
size_t OffsetOfHeadP = offsetof(OHCI_ED, HeadP);
|
||||
|
||||
return OHCI_WriteDwords(Paddr + OffsetOfHeadP, reinterpret_cast<uint32_t*>(reinterpret_cast<uint8_t*>(Ed) + OffsetOfHeadP), 1);
|
||||
}
|
||||
|
||||
bool OHCI::OHCI_GetDwords(xbaddr Paddr, uint32_t* Buffer, int Number)
|
||||
{
|
||||
if (Paddr != xbnull) {
|
||||
for (int i = 0; i < Number; i++, Buffer++, Paddr += sizeof(*Buffer)) {
|
||||
std::memcpy(Buffer, reinterpret_cast<void*>(Paddr + CONTIGUOUS_MEMORY_BASE), 4); // dropped little -> big endian conversion from XQEMU
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true; // error
|
||||
}
|
||||
|
||||
bool OHCI::OHCI_WriteDwords(xbaddr Paddr, uint32_t* Buffer, int Number)
|
||||
{
|
||||
if (Paddr != xbnull) {
|
||||
for (int i = 0; i < Number; i++, Buffer++, Paddr += sizeof(*Buffer)) {
|
||||
std::memcpy(reinterpret_cast<void*>(Paddr + CONTIGUOUS_MEMORY_BASE), Buffer, 4); // dropped big -> little endian conversion from XQEMU
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true; // error
|
||||
}
|
||||
|
||||
int OHCI::OHCI_ServiceEDlist(xbaddr Head, int Completion)
|
||||
{
|
||||
OHCI_ED ed;
|
||||
xbaddr next_ed;
|
||||
xbaddr current;
|
||||
int active;
|
||||
|
||||
active = 0;
|
||||
|
||||
if (Head == xbnull) {
|
||||
// no ED here, nothing to do
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (current = Head; current; current = next_ed) {
|
||||
if (OHCI_ReadED(current, &ed)) {
|
||||
EmuWarning("Ohci: ED read error at physical address 0x%X", current);
|
||||
OHCI_FatalError();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// From the standard "An Endpoint Descriptor (ED) is a 16-byte, memory resident structure that must be aligned to a
|
||||
// 16-byte boundary."
|
||||
next_ed = ed.NextED & OHCI_DPTR_MASK;
|
||||
|
||||
if ((ed.HeadP & OHCI_ED_H) || (ed.Flags & OHCI_ED_K)) { // halted or skip
|
||||
// Cancel pending packets for ED that have been paused
|
||||
xbaddr addr = ed.HeadP & OHCI_DPTR_MASK;
|
||||
if (AsyncTD && addr == AsyncTD) {
|
||||
usb_cancel_packet(&ohci->usb_packet);
|
||||
AsyncTD = xbnull;
|
||||
USB_DeviceEPstopped(m_UsbPacket.Endpoint->Dev, m_UsbPacket.Endpoint);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
while ((ed.HeadP & OHCI_DPTR_MASK) != ed.TailP) { // a TD is available to be processed
|
||||
#ifdef DEBUG_PACKET
|
||||
DPRINTF("ED @ 0x%.8x fa=%u en=%u d=%u s=%u k=%u f=%u mps=%u "
|
||||
"h=%u c=%u\n head=0x%.8x tailp=0x%.8x next=0x%.8x\n", cur,
|
||||
OHCI_BM(ed.flags, ED_FA), OHCI_BM(ed.flags, ED_EN),
|
||||
OHCI_BM(ed.flags, ED_D), (ed.flags & OHCI_ED_S) != 0,
|
||||
(ed.flags & OHCI_ED_K) != 0, (ed.flags & OHCI_ED_F) != 0,
|
||||
OHCI_BM(ed.flags, ED_MPS), (ed.head & OHCI_ED_H) != 0,
|
||||
(ed.head & OHCI_ED_C) != 0, ed.head & OHCI_DPTR_MASK,
|
||||
ed.tail & OHCI_DPTR_MASK, ed.next & OHCI_DPTR_MASK);
|
||||
#endif
|
||||
active = 1;
|
||||
|
||||
if ((ed.Flags & OHCI_ED_F) == 0) {
|
||||
// Handle control, interrupt or bulk endpoints
|
||||
if (ohci_service_td(ohci, &ed))
|
||||
break;
|
||||
}
|
||||
else {
|
||||
// Handle isochronous endpoints
|
||||
if (ohci_service_iso_td(ohci, &ed, completion))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Writeback ED
|
||||
if (OHCI_WriteED(current, &ed)) {
|
||||
OHCI_FatalError();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return active;
|
||||
}
|
||||
|
||||
void OHCI::OHCI_StateReset()
|
||||
{
|
||||
// The usb state can be USB_Suspend if it is a software reset, and USB_Reset if it is a hardware
|
||||
|
@ -220,6 +420,9 @@ void OHCI::OHCI_StateReset()
|
|||
|
||||
m_Registers.HcRhDescriptorA = OHCI_RHA_NPS | 2; // The xbox lacks the hw to switch off the power on the ports and has 2 ports per HC
|
||||
m_Registers.HcRhDescriptorB = 0; // The attached devices are removable and use PowerSwitchingMode to control the power on the ports
|
||||
|
||||
m_DoneCount = 7;
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
OHCIPort* Port = &m_Registers.RhPort[i];
|
||||
|
@ -228,7 +431,10 @@ void OHCI::OHCI_StateReset()
|
|||
USB_PortReset(&Port->UsbPort);
|
||||
}
|
||||
}
|
||||
m_DoneCount = 7;
|
||||
if (AsyncTD) {
|
||||
usb_cancel_packet(&ohci->usb_packet);
|
||||
AsyncTD = xbnull;
|
||||
}
|
||||
|
||||
OHCI_StopEndpoints();
|
||||
|
||||
|
@ -480,19 +686,19 @@ void OHCI::OHCI_WriteRegister(xbaddr Addr, uint32_t Value)
|
|||
break;
|
||||
|
||||
case 8: // HcControlHeadED
|
||||
m_Registers.HcControlHeadED = Value & OHCI_EDPTR_MASK;
|
||||
m_Registers.HcControlHeadED = Value & OHCI_DPTR_MASK;
|
||||
break;
|
||||
|
||||
case 9: // HcControlCurrentED
|
||||
m_Registers.HcControlCurrentED = Value & OHCI_EDPTR_MASK;
|
||||
m_Registers.HcControlCurrentED = Value & OHCI_DPTR_MASK;
|
||||
break;
|
||||
|
||||
case 10: // HcBulkHeadED
|
||||
m_Registers.HcBulkHeadED = Value & OHCI_EDPTR_MASK;
|
||||
m_Registers.HcBulkHeadED = Value & OHCI_DPTR_MASK;
|
||||
break;
|
||||
|
||||
case 11: // HcBulkCurrentED
|
||||
m_Registers.HcBulkCurrentED = Value & OHCI_EDPTR_MASK;
|
||||
m_Registers.HcBulkCurrentED = Value & OHCI_DPTR_MASK;
|
||||
break;
|
||||
|
||||
case 12: // HcDoneHead
|
||||
|
|
|
@ -43,83 +43,25 @@
|
|||
|
||||
|
||||
// Abbreviations used:
|
||||
// OHCI: Open Host Controller Interface; the standard used on the xbox to comunicate with the usb devices
|
||||
// OHCI: Open Host Controller Interface; the standard used on the Xbox to comunicate with the usb devices
|
||||
// HC: Host Controller; the hardware which interfaces with the usb device and the usb driver
|
||||
// HCD: Host Controller Driver; software which talks to the HC, it's linked in the xbe
|
||||
// SOF: start of frame; the beginning of a USB-defined frame
|
||||
// EOF: end of frame; the end of a USB-defined frame
|
||||
// ED: endpoint descriptor; a memory structure used by the HC to communicate with an endpoint
|
||||
// TD: transfer descriptor; a memory structure used by the HC to transfer a block of data to/from a device endpoint
|
||||
|
||||
|
||||
// These macros are used to access the bits of the various registers
|
||||
// HcControl
|
||||
#define OHCI_CTL_CBSR ((1<<0)|(1<<1)) // ControlBulkServiceRatio
|
||||
#define OHCI_CTL_PLE (1<<2) // PeriodicListEnable
|
||||
#define OHCI_CTL_IE (1<<3) // IsochronousEnable
|
||||
#define OHCI_CTL_CLE (1<<4) // ControlListEnable
|
||||
#define OHCI_CTL_BLE (1<<5) // BulkListEnable
|
||||
#define OHCI_CTL_HCFS ((1<<6)|(1<<7)) // HostControllerFunctionalState
|
||||
#define OHCI_CTL_IR (1<<8) // InterruptRouting
|
||||
#define OHCI_CTL_RWC (1<<9) // RemoteWakeupConnected
|
||||
#define OHCI_CTL_RWE (1<<10) // RemoteWakeupEnable
|
||||
// HcCommandStatus
|
||||
#define OHCI_STATUS_HCR (1<<0) // HostControllerReset
|
||||
#define OHCI_STATUS_CLF (1<<1) // ControlListFilled
|
||||
#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_SO (1<<0) // SchedulingOverrun
|
||||
#define OHCI_INTR_WD (1<<1) // WritebackDoneHead
|
||||
#define OHCI_INTR_SF (1<<2) // StartofFrame
|
||||
#define OHCI_INTR_RD (1<<3) // ResumeDetected
|
||||
#define OHCI_INTR_UE (1<<4) // UnrecoverableError
|
||||
#define OHCI_INTR_FNO (1<<5) // FrameNumberOverflow
|
||||
#define OHCI_INTR_RHSC (1<<6) // RootHubStatusChange
|
||||
#define OHCI_INTR_OC (1<<30) // OwnershipChange
|
||||
// HcInterruptEnable, HcInterruptDisable
|
||||
#define OHCI_INTR_MIE (1<<31) // MasterInterruptEnable
|
||||
// HcHCCA
|
||||
#define OHCI_HCCA_MASK 0xFFFFFF00 // HCCA mask
|
||||
// HcControlHeadED
|
||||
#define OHCI_EDPTR_MASK 0xFFFFFFF0 // endpoint descriptor mask
|
||||
// HcFmInterval
|
||||
#define OHCI_FMI_FI 0x00003FFF // FrameInterval
|
||||
#define OHCI_FMI_FIT 0x80000000 // FrameIntervalToggle
|
||||
// HcFmRemaining
|
||||
#define OHCI_FMR_FR 0x00003FFF // FrameRemaining
|
||||
#define OHCI_FMR_FRT 0x80000000 // FrameRemainingToggle
|
||||
// HcRhDescriptorA
|
||||
#define OHCI_RHA_RW_MASK 0x00000000 // Mask of supported features
|
||||
#define OHCI_RHA_PSM (1<<8) // PowerSwitchingMode
|
||||
#define OHCI_RHA_NPS (1<<9) // NoPowerSwitching
|
||||
#define OHCI_RHA_DT (1<<10) // DeviceType
|
||||
#define OHCI_RHA_OCPM (1<<11) // OverCurrentProtectionMode
|
||||
#define OHCI_RHA_NOCP (1<<12) // NoOverCurrentProtection
|
||||
// HcRhStatus
|
||||
#define OHCI_RHS_LPS (1<<0) // LocalPowerStatus
|
||||
#define OHCI_RHS_OCI (1<<1) // OverCurrentIndicator
|
||||
#define OHCI_RHS_DRWE (1<<15) // DeviceRemoteWakeupEnable
|
||||
#define OHCI_RHS_LPSC (1<<16) // LocalPowerStatusChange
|
||||
#define OHCI_RHS_OCIC (1<<17) // OverCurrentIndicatorChange
|
||||
#define OHCI_RHS_CRWE (1<<31) // ClearRemoteWakeupEnable
|
||||
// HcRhPortStatus
|
||||
#define OHCI_PORT_CCS (1<<0) // CurrentConnectStatus
|
||||
#define OHCI_PORT_PES (1<<1) // PortEnableStatus
|
||||
#define OHCI_PORT_PSS (1<<2) // PortSuspendStatus
|
||||
#define OHCI_PORT_POCI (1<<3) // PortOverCurrentIndicator
|
||||
#define OHCI_PORT_PRS (1<<4) // PortResetStatus
|
||||
#define OHCI_PORT_PPS (1<<8) // PortPowerStatus
|
||||
#define OHCI_PORT_LSDA (1<<9) // LowSpeedDeviceAttached
|
||||
#define OHCI_PORT_CSC (1<<16) // ConnectStatusChange
|
||||
#define OHCI_PORT_PESC (1<<17) // PortEnableStatusChange
|
||||
#define OHCI_PORT_PSSC (1<<18) // PortSuspendStatusChange
|
||||
#define OHCI_PORT_OCIC (1<<19) // PortOverCurrentIndicatorChange
|
||||
#define OHCI_PORT_PRSC (1<<20) // PortResetStatusChange
|
||||
#define OHCI_PORT_WTC (OHCI_PORT_CSC|OHCI_PORT_PESC|OHCI_PORT_PSSC \
|
||||
|OHCI_PORT_OCIC|OHCI_PORT_PRSC)
|
||||
/* endpoint descriptor */
|
||||
typedef struct _OHCI_ED {
|
||||
uint32_t Flags;
|
||||
uint32_t TailP;
|
||||
uint32_t HeadP;
|
||||
uint32_t NextED;
|
||||
}
|
||||
OHCI_ED;
|
||||
|
||||
// enum indicating the current HC state
|
||||
/* enum indicating the current HC state */
|
||||
typedef enum _OHCI_State
|
||||
{
|
||||
Reset = 0x00,
|
||||
|
@ -129,7 +71,7 @@ typedef enum _OHCI_State
|
|||
}
|
||||
OHCI_State;
|
||||
|
||||
// Host Controller Communications Area
|
||||
/* Host Controller Communications Area */
|
||||
typedef struct _OHCI_HCCA
|
||||
{
|
||||
uint32_t HccaInterrruptTable[32];
|
||||
|
@ -138,7 +80,7 @@ typedef struct _OHCI_HCCA
|
|||
}
|
||||
OHCI_HCCA;
|
||||
|
||||
// Small struct used to hold the HcRhPortStatus register and the usb port status
|
||||
/* Small struct used to hold the HcRhPortStatus register and the usb port status */
|
||||
typedef struct _OHCIPort
|
||||
{
|
||||
USBPort UsbPort;
|
||||
|
@ -146,7 +88,7 @@ typedef struct _OHCIPort
|
|||
}
|
||||
OHCIPort;
|
||||
|
||||
// All these registers are well documented in the OHCI standard
|
||||
/* All these registers are well documented in the OHCI standard */
|
||||
typedef struct _OHCI_Registers
|
||||
{
|
||||
// Control and Status partition
|
||||
|
@ -184,7 +126,7 @@ typedef struct _OHCI_Registers
|
|||
OHCI_Registers;
|
||||
|
||||
|
||||
// OHCI class representing the state of the HC
|
||||
/* OHCI class representing the state of the HC */
|
||||
class OHCI
|
||||
{
|
||||
public:
|
||||
|
@ -209,7 +151,7 @@ class OHCI
|
|||
uint64_t m_UsbFrameTime;
|
||||
// ticks per usb tick
|
||||
uint64_t m_TicksPerUsbTick;
|
||||
// usb packet
|
||||
// pending usb packet to process
|
||||
USBPacket m_UsbPacket;
|
||||
// ergo720: I believe it's the value of HcControl in the last frame
|
||||
uint32_t old_ctl;
|
||||
|
@ -218,6 +160,8 @@ class OHCI
|
|||
// ergo720: I think it's the DelayInterrupt flag in a TD
|
||||
// -> num of frames to wait before generating an interrupt for this TD
|
||||
int m_DoneCount;
|
||||
// the address of the pending TD
|
||||
xbaddr AsyncTD;
|
||||
|
||||
// EOF callback wrapper
|
||||
static void OHCI_FrameBoundaryWrapper(void* pVoid);
|
||||
|
@ -262,25 +206,35 @@ class OHCI
|
|||
bool OHCI_ReadHCCA(xbaddr Paddr, OHCI_HCCA* Hcca);
|
||||
// write the HCCA structure in memory
|
||||
bool OHCI_WriteHCCA(xbaddr Paddr, OHCI_HCCA* Hcca);
|
||||
// read an ED in memory
|
||||
bool OHCI_ReadED(xbaddr Paddr, OHCI_ED* Ed);
|
||||
// write an ED in memory
|
||||
bool OHCI_WriteED(xbaddr Paddr, OHCI_ED* Ed);
|
||||
// read an array of DWORDs in memory
|
||||
bool OHCI_GetDwords(xbaddr Paddr, uint32_t* Buffer, int Number);
|
||||
// write an array of DWORDs in memory
|
||||
bool OHCI_WriteDwords(xbaddr Paddr, uint32_t* Buffer, int Number);
|
||||
//
|
||||
int OHCI_ServiceEDlist(xbaddr Head, int Completion);
|
||||
|
||||
// register a port with the HC
|
||||
void USB_RegisterPort(USBPort* Port, int Index, int SpeedMask);
|
||||
//
|
||||
void USB_DeviceEPstopped(USBDev* Dev, USBEndpoint* EP);
|
||||
void USB_DeviceEPstopped(USBDev* Dev, USBEndpoint* Ep);
|
||||
// reset a usb port
|
||||
void USB_PortReset(USBPort* Port);
|
||||
// a device is attched
|
||||
void USB_Attach(USBPort* port);
|
||||
void USB_Attach(USBPort* Port);
|
||||
// a device is detached
|
||||
void USB_Detach(USBPort* port);
|
||||
void USB_Detach(USBPort* Port);
|
||||
// a device downstream from the device attached to the port (attached through a hub) is detached
|
||||
void ChildDetach(USBPort* port, USBDev* child);
|
||||
void ChildDetach(USBPort* Port, USBDev* Child);
|
||||
// TODO
|
||||
void Wakeup(USBPort* port);
|
||||
void Wakeup(USBPort* Port);
|
||||
// TODO
|
||||
void Complete(USBPort* port, USBPacket *p);
|
||||
void Complete(USBPort* Port, USBPacket *P);
|
||||
// reset a device
|
||||
void USB_DeviceReset(USBDev* dev);
|
||||
void USB_DeviceReset(USBDev* Dev);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -56,7 +56,7 @@ typedef enum USBPacketState {
|
|||
}
|
||||
USBPacketState;
|
||||
|
||||
// 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() */
|
||||
typedef struct _IoVec
|
||||
{
|
||||
void* Iov_Base;
|
||||
|
@ -73,6 +73,7 @@ typedef struct _IOVector
|
|||
}
|
||||
IOVector;
|
||||
|
||||
/* USB endpoint */
|
||||
typedef struct _USBEndpoint
|
||||
{
|
||||
uint8_t nr;
|
||||
|
@ -82,12 +83,12 @@ typedef struct _USBEndpoint
|
|||
int max_packet_size;
|
||||
bool pipeline;
|
||||
bool halted;
|
||||
USBDev *dev;
|
||||
USBDev* Dev; // device this endpoint belongs to
|
||||
//QTAILQ_HEAD(, USBPacket) queue;
|
||||
}
|
||||
USBEndpoint;
|
||||
|
||||
// definition of a USB device
|
||||
/* definition of a USB device */
|
||||
typedef struct _USBDev
|
||||
{
|
||||
DeviceState qdev;
|
||||
|
@ -181,13 +182,13 @@ typedef struct USBDeviceClass
|
|||
}
|
||||
USBDeviceClass;
|
||||
|
||||
// Structure used to hold information about an active USB packet
|
||||
/* Structure used to hold information about an active USB packet */
|
||||
typedef struct _USBPacket
|
||||
{
|
||||
// Data fields for use by the driver
|
||||
int Pid;
|
||||
uint64_t Id;
|
||||
USBEndpoint* Endpoint;
|
||||
USBEndpoint* Endpoint; // endpoint of the packet
|
||||
unsigned int stream;
|
||||
IOVector IoVec; // used to perform vectored I/O
|
||||
uint64_t parameter; // control transfers
|
||||
|
@ -203,7 +204,7 @@ typedef struct _USBPacket
|
|||
}
|
||||
USBPacket;
|
||||
|
||||
// Struct describing the status of a usb port
|
||||
/* Struct describing the status of a usb port */
|
||||
typedef struct _USBPort {
|
||||
USBDev* Dev; // usb device (if present)
|
||||
int SpeedMask; // usb speeds supported
|
||||
|
|
Loading…
Reference in New Issue