📄 chw.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Module Name:
// CHW.cpp
// Abstract:
// This file implements the EHCI specific register routines
//
// Notes:
//
//
#include <windows.h>
#include <nkintr.h>
#define HCD_SUSPEND_RESUME 1 // For test only
#include <Uhcdddsi.h>
#include <globals.hpp>
#include <td.h>
#include <ctd.h>
#include <chw.h>
#ifndef _PREFAST_
#pragma warning(disable: 4068) // Disable pragma warnings
#endif
// ******************************** CDummyPipe **********************************
const USB_ENDPOINT_DESCRIPTOR dummpDesc = {
sizeof(USB_ENDPOINT_DESCRIPTOR),USB_ENDPOINT_DESCRIPTOR_TYPE, 0xff, USB_ENDPOINT_TYPE_INTERRUPT,8,1
};
CDummyPipe::CDummyPipe(IN CPhysMem * const pCPhysMem)
: CPipe( &dummpDesc,FALSE,TRUE,0xff,0xff,0xff,NULL)
, m_pCPhysMem(pCPhysMem)
{
ASSERT( m_pCPhysMem!=NULL);
m_bFrameSMask = 0xff;
m_bFrameCMask = 0;
};
// ************************************CPeriodicMgr******************************
CPeriodicMgr::CPeriodicMgr(IN CPhysMem * const pCPhysMem, DWORD dwFrameSize)
//
// Purpose: Contructor :Periodic Transfer or Queue Head Manage module
//
// Parameters: pCPhysMem - pointer to CPhysMem object
// dwFrameSize - Isoch Frame Size (Mached with hardware).
//
// Returns: Nothing
//
// Notes:
// ******************************************************************
: m_pCPhysMem(pCPhysMem)
, m_dwFrameSize(dwFrameSize)
, m_pCDumpPipe(new CDummyPipe(pCPhysMem))
{
ASSERT(pCPhysMem);
ASSERT(dwFrameSize == 0x400|| dwFrameSize== 0x200 || dwFrameSize== 0x100);
m_pFrameList = NULL;
m_pFramePhysAddr = 0;
m_dwFrameMask=0xff;
switch(dwFrameSize) {
case 0x400: default:
m_dwFrameMask=0x3ff;
break;
case 0x200:
m_dwFrameMask=0x1ff;
break;
case 0x100:
m_dwFrameMask=0xff;
break;
}
ASSERT(m_pCDumpPipe);
// Create Dummy Pipe for static
}
// ******************************************************************
CPeriodicMgr::~CPeriodicMgr()
//
// Purpose: Decontructor :Periodic Transfer or Queue Head Manage module
//
// Parameters:
//
// Returns: Nothing
//
// Notes:
// ******************************************************************
{
DeInit();
if (m_pCDumpPipe)
delete m_pCDumpPipe;
}
// ******************************************************************
BOOL CPeriodicMgr::Init()
//
// Purpose: Decontructor :Periodic Transfer or Queue Head Manage module Initilization
//
// Parameters:
//
// Returns: Nothing
//
// Notes:
// ******************************************************************
{
Lock();
if ( m_dwFrameSize == 0x400 || m_dwFrameSize== 0x200 || m_dwFrameSize== 0x100) {
if (m_pCPhysMem && m_pCPhysMem->AllocateSpecialMemory(m_dwFrameSize*sizeof(DWORD), ( UCHAR ** )&m_pFrameList))
m_pFramePhysAddr = m_pCPhysMem->VaToPa((UCHAR *)m_pFrameList);
else {
Unlock();
ASSERT(FALSE);
}
}
ASSERT(m_pFrameList!=NULL);
for(DWORD dwIndex=0;dwIndex< 2*PERIOD_TABLE_SIZE;dwIndex++) {
m_pStaticQHArray[dwIndex]= new(m_pCPhysMem) CQH(m_pCDumpPipe);
if (m_pStaticQHArray[dwIndex] == NULL) {
Unlock();
return FALSE;
}
}
// Actually the 0 never be used.
m_pStaticQHArray[0]->QueueQHead(NULL);
m_pStaticQHArray[1]->QueueQHead(NULL);
DWORD dwForwardBase=1;
DWORD dwForwardMask=0;
for(dwIndex=2;dwIndex< 2*PERIOD_TABLE_SIZE;dwIndex++) {
if ((dwIndex & (dwIndex-1))==0) { // power of 2.
dwForwardBase = dwIndex/2;
dwForwardMask = dwForwardBase -1 ;
}
if (m_pStaticQHArray[dwIndex]) {
m_pStaticQHArray[dwIndex]->QueueQHead(m_pStaticQHArray[dwForwardBase + (dwIndex & dwForwardMask)]);// binary queue head.
}
else {
Unlock();
return FALSE;
}
}
//Attahed QHead to FrameList;
if (m_dwFrameSize && m_pFrameList) {
for (dwIndex=0;dwIndex<m_dwFrameSize;dwIndex++) {
CQH * pQH = m_pStaticQHArray[PERIOD_TABLE_SIZE + dwIndex % PERIOD_TABLE_SIZE];
if (pQH) {
CNextLinkPointer staticQueueHead;
staticQueueHead.SetNextPointer(pQH->GetPhysAddr(),TYPE_SELECT_QH,TRUE);
*(m_pFrameList+dwIndex) = staticQueueHead.GetDWORD(); //Invalid Physical pointer.
}
else {
Unlock();
return FALSE;
}
}
}
else {
Unlock();
return FALSE;
}
Unlock();
return TRUE;
}
// ******************************************************************
void CPeriodicMgr::DeInit()
//
// Purpose: Decontructor :Periodic Transfer or Queue Head Manage module DeInitilization
//
// Parameters:
//
// Returns: Nothing
//
// Notes:
// ******************************************************************
{
Lock();
for(DWORD dwIndex=0;dwIndex< 2*PERIOD_TABLE_SIZE;dwIndex++) {
if (m_pStaticQHArray[dwIndex]) {
//delete( m_pCPhysMem, 0) m_pStaticQHArray[dwIndex];
m_pStaticQHArray[dwIndex]->~CQH();
m_pCPhysMem->FreeMemory((PBYTE)m_pStaticQHArray[dwIndex],m_pCPhysMem->VaToPa((PBYTE)m_pStaticQHArray[dwIndex]),CPHYSMEM_FLAG_HIGHPRIORITY | CPHYSMEM_FLAG_NOBLOCK);
m_pStaticQHArray[dwIndex] = NULL;
}
}
if (m_pFrameList) {
m_pCPhysMem->FreeSpecialMemory((PBYTE)m_pFrameList);
m_pFrameList = NULL;
}
Unlock();
}
// ******************************************************************
BOOL CPeriodicMgr::QueueITD(CITD * piTD,DWORD FrameIndex)
//
// Purpose: Decontructor :Queue High Speed Isoch Trasnfer.
//
// Parameters:
//
// Returns: Nothing
//
// Notes:
// ******************************************************************
{
FrameIndex &= m_dwFrameMask;
Lock();
if (piTD && m_pFrameList && FrameIndex< m_dwFrameSize) {
ASSERT(piTD->CNextLinkPointer::GetLinkValid()==FALSE);
CNextLinkPointer thisITD;
thisITD.SetNextPointer(piTD->GetPhysAddr(),TYPE_SELECT_ITD,TRUE);
piTD->CNextLinkPointer::SetDWORD(*(m_pFrameList + FrameIndex));
*(m_pFrameList+FrameIndex) = thisITD.GetDWORD();
Unlock();
return TRUE;
}
else {
ASSERT(FALSE);
}
Unlock();
return FALSE;
}
// ******************************************************************
BOOL CPeriodicMgr::QueueSITD(CSITD * psiTD,DWORD FrameIndex)
//
// Purpose: Decontructor :Queue High Speed Isoch Trasnfer.
//
// Parameters:
//
// Returns: Nothing
//
// Notes:
// ******************************************************************
{
FrameIndex &= m_dwFrameMask;
Lock();
if (psiTD && m_pFrameList && FrameIndex < m_dwFrameSize ) {
ASSERT(psiTD->CNextLinkPointer::GetLinkValid()==FALSE);
CNextLinkPointer thisITD;
thisITD.SetNextPointer( psiTD->GetPhysAddr(),TYPE_SELECT_SITD,TRUE);
psiTD->CNextLinkPointer::SetDWORD(*(m_pFrameList+ FrameIndex ));
*(m_pFrameList+ FrameIndex) = thisITD.GetDWORD();
Unlock();
return TRUE;
}
else {
ASSERT(FALSE);
}
Unlock();
return FALSE;
}
BOOL CPeriodicMgr::DeQueueTD(DWORD dwPhysAddr,DWORD FrameIndex)
{
FrameIndex &= m_dwFrameMask;
Lock();
if (m_pFrameList && FrameIndex< m_dwFrameSize) {
CNextLinkPointer * curPoint = (CNextLinkPointer *)(m_pFrameList+ FrameIndex);
if (curPoint!=NULL && curPoint->GetLinkValid() &&
curPoint->GetLinkType()!= TYPE_SELECT_QH &&
curPoint->GetPointer() != dwPhysAddr ) {
curPoint=curPoint->GetNextLinkPointer(m_pCPhysMem);
}
if (curPoint && curPoint->GetPointer() == dwPhysAddr) { // We find it
CNextLinkPointer * pNextPoint=curPoint->GetNextLinkPointer(m_pCPhysMem);
if (pNextPoint ) {
curPoint->SetDWORD(pNextPoint->GetDWORD());
Unlock();
return TRUE;
}
else
ASSERT(FALSE);
}
//else
// ASSERT(FALSE);
}
else
ASSERT(FALSE);
Unlock();
return FALSE;
}
PERIOD_TABLE CPeriodicMgr::periodTable[64] =
{ // period, qh-idx, s-mask
1, 0, 0xFF, // Dummy
1, 0, 0xFF, // 1111 1111 bits 0..7
2, 0, 0x55, // 0101 0101 bits 0,2,4,6
2, 0, 0xAA, // 1010 1010 bits 1,3,5,7
4, 0, 0x11, // 0001 0001 bits 0,4
4, 0, 0x44, // 0100 0100 bits 2,6
4, 0, 0x22, // 0010 0010 bits 1,5
4, 0, 0x88, // 1000 1000 bits 3,7
8, 0, 0x01, // 0000 0001 bits 0
8, 0, 0x10, // 0001 0000 bits 4
8, 0, 0x04, // 0000 0100 bits 2
8, 0, 0x40, // 0100 0000 bits 6
8, 0, 0x02, // 0000 0010 bits 1
8, 0, 0x20, // 0010 0000 bits 5
8, 0, 0x08, // 0000 1000 bits 3
8, 0, 0x80, // 1000 0000 bits 7
16, 1, 0x01, // 0000 0001 bits 0
16, 2, 0x01, // 0000 0001 bits 0
16, 1, 0x10, // 0001 0000 bits 4
16, 2, 0x10, // 0001 0000 bits 4
16, 1, 0x04, // 0000 0100 bits 2
16, 2, 0x04, // 0000 0100 bits 2
16, 1, 0x40, // 0100 0000 bits 6
16, 2, 0x40, // 0100 0000 bits 6
16, 1, 0x02, // 0000 0010 bits 1
16, 2, 0x02, // 0000 0010 bits 1
16, 1, 0x20, // 0010 0000 bits 5
16, 2, 0x20, // 0010 0000 bits 5
16, 1, 0x08, // 0000 1000 bits 3
16, 2, 0x08, // 0000 1000 bits 3
16, 1, 0x80, // 1000 0000 bits 7
16, 2, 0x80, // 1000 0000 bits 7
32, 3, 0x01, // 0000 0000 bits 0
32, 5, 0x01, // 0000 0000 bits 0
32, 4, 0x01, // 0000 0000 bits 0
32, 6, 0x01, // 0000 0000 bits 0
32, 3, 0x10, // 0000 0000 bits 4
32, 5, 0x10, // 0000 0000 bits 4
32, 4, 0x10, // 0000 0000 bits 4
32, 6, 0x10, // 0000 0000 bits 4
32, 3, 0x04, // 0000 0000 bits 2
32, 5, 0x04, // 0000 0000 bits 2
32, 4, 0x04, // 0000 0000 bits 2
32, 6, 0x04, // 0000 0000 bits 2
32, 3, 0x40, // 0000 0000 bits 6
32, 5, 0x40, // 0000 0000 bits 6
32, 4, 0x40, // 0000 0000 bits 6
32, 6, 0x40, // 0000 0000 bits 6
32, 3, 0x02, // 0000 0000 bits 1
32, 5, 0x02, // 0000 0000 bits 1
32, 4, 0x02, // 0000 0000 bits 1
32, 6, 0x02, // 0000 0000 bits 1
32, 3, 0x20, // 0000 0000 bits 5
32, 5, 0x20, // 0000 0000 bits 5
32, 4, 0x20, // 0000 0000 bits 5
32, 6, 0x20, // 0000 0000 bits 5
32, 3, 0x04, // 0000 0000 bits 3
32, 5, 0x04, // 0000 0000 bits 3
32, 4, 0x04, // 0000 0000 bits 3
32, 6, 0x04, // 0000 0000 bits 3
32, 3, 0x40, // 0000 0000 bits 7
32, 5, 0x40, // 0000 0000 bits 7
32, 4, 0x40, // 0000 0000 bits 7
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -