📄 ohcdpdd.c
字号:
//
// 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:
system.c
Abstract:
Device dependant part of the USB Universal Host Controller Driver (UHCD).
Notes:
--*/
#ifdef USBOHCI_DMA_IN_SRAM
#pragma message ("OHCI using Internal SRAM")
#else
#pragma message ("OHCI using SDRAM")
#endif
#include <windows.h>
#include <nkintr.h>
#include <ceddk.h>
#include <devload.h>
#ifndef OSV_LOCAL_MERLIN
// giisr is only supported in Jameson,
// since this is a Merlin build, don't include it.
#include <giisr.h>
#endif
#include <uhcdddsi.h>
#include "bvd1.h"
#include "sa11x1.h"
#include "macros.h"
#ifndef PLAT_LUBBOCK
// Bulverde will use XLLP library to
// access GPIOs and Clocks.
#include "xllp_gpio.h"
#include "xllp_clkmgr.h"
#include "xllp_usbohci.h"
#endif
#ifndef DEBUG
#define ZONE_INIT 1
#endif
// Registry key and value names
#define OHCI_DRIVER_KEY TEXT("Drivers\\BuiltIn\\OHCI")
#define IRQ_VALUE_NAME TEXT("Irq")
#define IOBASE_VALUE_NAME TEXT("MemBase")
extern void usWait(unsigned msVal);
extern PVOID VirtualAllocCopy(unsigned size,char *str,PVOID pVirtualAddress);
void TurnOnSRAMClocks();
// Amount of memory to use for HCD buffer
extern DWORD gcTotalAvailablePhysicalMemory;// = OHCI_DMA_BUFFER_SIZE; //28672; // 28K
extern DWORD gcHighPriorityPhysicalMemory;// = OHCI_DMA_BUFFER_HIGHPRI_SIZE; //0x5000; // 20K
extern DWORD dwSysIntrOhciMdd;//=SYSINTR_OHCI_MDD;
extern DWORD dwSysIntrOhciPdd;//=SYSINTR_OHCI_PDD
#ifdef PLAT_LUBBOCK
extern DWORD dwSKBase;//=SK_BA
#endif
//Dma Buffer
extern DWORD dwOhciDmaBufferPhysical;//=OHCI_DMA_BUFFER_PHYSICAL
extern PVOID pOhciDmaBufferVirtual;//=OHCI_DMA_BUFFER_U_VIRTUAL
extern DWORD dwOhciDmaBufferSize;//=OHCI_DMA_BUFFER_SIZE
// Daughter card register structures
#ifdef PLAT_LUBBOCK
volatile struct SK_IRQRegisterBlock *v_pDCIRQReg;
volatile struct SK_SC_PLLRegisterBlock *v_pDCPLLReg;
volatile struct SK_SMCRegisterBlock *v_pDCSMCReg;
#endif
#ifndef PLAT_LUBBOCK
volatile XLLP_CLKMGR_T *v_pDCCLKReg;
volatile XLLP_GPIO_T *v_pDCGPIOReg;
volatile XLLP_USBOHCI_T *v_pDCUSBOHCIReg;
#endif
volatile struct SK_USBRegisterBlock *v_pDCUSBReg;
PVOID v_pOHCIDMABuffer;
volatile MEMC_STRUCT *v_pDCMEMCReg; // on the cotulla, xsc1.h
// Interrupt Service Thread Globals
VOID *gOHCIPDDIntrEvent;
VOID *gOHCIPDDIntrThread;
static HANDLE g_IsrHandle = NULL;
typedef struct _SUhcdPdd
{
LPVOID lpvMemoryObject;
LPVOID lpvUhcdMddObject;
PVOID pvVirtualAddress; // DMA buffers as seen by the CPU
PHYSICAL_ADDRESS LogicalAddress; // DMA buffers as seen by the DMA controller and bus interfaces
#ifndef OSV_LOCAL_MERLIN
DMA_ADAPTER_OBJECT AdapterObject;
#endif
TCHAR szDriverRegKey[MAX_PATH];
PUCHAR ioPortBase;
DWORD dwSysIntr;
CRITICAL_SECTION csPdd; // serializes access to the PDD object
} SUhcdPdd;
#define UnusedParameter(x) x = x
// set up virtual addresses for registers on the sa11x1
BOOL
OhcdPddInitializeAddresses(void)
{
#ifdef PLAT_LUBBOCK
v_pDCPLLReg = (volatile struct SK_SC_PLLRegisterBlock *)
VirtualAllocCopy(SK_SC_PLL_SPACE,"OHCI v_pDCPLLReg: ",(PVOID)(dwSKBase + SK_PLL_BASE));
if (v_pDCPLLReg == NULL) {
goto error_return;
}
v_pDCIRQReg = (volatile struct SK_IRQRegisterBlock *)
VirtualAllocCopy(SK_IRQ_SPACE,"OHCI v_pDCIRQReg",(PVOID)(dwSKBase + SK_IRQ_BASE));
if (v_pDCIRQReg == NULL) {
goto error_return;
}
v_pDCSMCReg = (volatile struct SK_SMCRegisterBlock *)
VirtualAllocCopy(SK_SMC_SPACE,"OHCI v_pDCSMCReg",(PVOID)(dwSKBase + SMC_BASE));
if (v_pDCSMCReg == NULL) {
goto error_return;
}
v_pDCMEMCReg = (volatile MEMC_STRUCT *)
VirtualAllocCopy(sizeof(MEMC_STRUCT),"OHCI v_pDCMEMCReg",(PVOID)(MEMC_BASE_U_VIRTUAL));
if (v_pDCMEMCReg == NULL) {
goto error_return;
}
v_pDCUSBReg = (volatile struct SK_USBRegisterBlock *)
VirtualAllocCopy(SK_USB_HCI_SPACE,"OHCI v_pDCUSBReg: ",(PVOID)(dwSKBase +USB_BASE));
if (v_pDCUSBReg == NULL) {
goto error_return;
}
v_pOHCIDMABuffer =
// VirtualAllocCopy(OHCI_DMA_BUFFER_SIZE,"OHCI v_pOHCIDMABuffer", (PVOID) OHCI_DMA_BUFFER_U_VIRTUAL);
VirtualAllocCopy(dwOhciDmaBufferSize,"OHCI v_pOHCIDMABuffer", pOhciDmaBufferVirtual);
if (v_pOHCIDMABuffer == NULL) {
goto error_return;
}
#endif
#ifndef PLAT_LUBBOCK
// the bulverde needs access to the clkmgr to enable the USBHOST clock
v_pDCCLKReg = (volatile XLLP_CLKMGR_T*)
VirtualAllocCopy(sizeof(XLLP_CLKMGR_T), "OHCI v_pDCCLKReg", (PVOID)(CLK_BASE_U_VIRTUAL));
if( v_pDCCLKReg == NULL ) {
goto error_return;
}
// the bulverde needs access to the gpio regs to set up the gpios that
// are tied to the external MAX1693EUB USB Power Switch
v_pDCGPIOReg = (volatile XLLP_GPIO_T*)
VirtualAllocCopy(sizeof(XLLP_GPIO_T), "OHCI v_pDCGPIOReg", (PVOID)(GPIO_BASE_U_VIRTUAL));
if( v_pDCCLKReg == NULL ) {
goto error_return;
}
// map the usb ohci register block.
// use the old cotulla global pointer for now.
// later, during code clean up, consolidate the two pointers into one
// and reconcile their usage differences.
v_pDCUSBReg = (volatile struct SK_USBRegisterBlock *)
VirtualAllocCopy(SK_USB_HCI_SPACE,"OHCI v_pDCUSBReg: ",(PVOID)(USBH_BASE_U_VIRTUAL));
if (v_pDCUSBReg == NULL) {
goto error_return;
}
v_pDCUSBOHCIReg = (volatile XLLP_USBOHCI_T*)v_pDCUSBReg;
#ifdef USBOHCI_DMA_IN_SRAM
// initialize the sram here.
{
volatile unsigned long *v_pDCIMReg = NULL;
// map the memory
v_pDCIMReg = (volatile unsigned long*)VirtualAllocCopy(
sizeof( 64 * sizeof( volatile unsigned long ) ),
"OHCI v_pDCIMReg: ",
(PVOID)(IM_CONTROL_BASE_U_VIRTUAL)
);
if( v_pDCIMReg == NULL )
{
// error
RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses: failed mapping v_pDCIMReg to %08x.\r\n"), IM_CONTROL_BASE_U_VIRTUAL));
}
else
{
RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses: v_pDCIMReg: %08x = %08x.\r\n"), v_pDCIMReg,IM_CONTROL_BASE_U_VIRTUAL));
RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses: v_pDCIMReg: impmr %08x.\r\n"), v_pDCIMReg[0] ));
RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses: v_pDCIMReg: impsr %08x.\r\n"), v_pDCIMReg[2] ));
// I don't think the imrmr register really exists
//RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses: v_pDCIMReg: imrmr %08x.\r\n"), v_pDCIMReg[4] ));
// test access to this memory
v_pDCIMReg[0] = 188; // the control register, 0 enables all internal sram banks, disables auto-wake and disables entry to standby
RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses: v_pDCIMReg:Mimpmr %08x.\r\n"), v_pDCIMReg[0] ));
// set the bank power control, auto wake enable, and DST fields
v_pDCIMReg[0] = 0; // the control register, 0 enables all internal sram banks, disables auto-wake and disables entry to standby
RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses: v_pDCIMReg:Fimpmr %08x.\r\n"), v_pDCIMReg[0] ));
// free the mapped memory
VirtualFree((PVOID)v_pDCIMReg,0,MEM_RELEASE);
}
}
v_pOHCIDMABuffer =
// VirtualAllocCopy(OHCI_DMA_BUFFER_SIZE,"OHCI v_pOHCIDMABuffer", (PVOID) OHCI_DMA_BUFFER_U_VIRTUAL);
VirtualAllocCopy(dwOhciDmaBufferSize,"OHCI v_pOHCIDMABuffer", (PVOID)IM_STORAGE_BASE_U_VIRTUAL);
if (v_pOHCIDMABuffer == NULL) {
goto error_return;
}
{
// Test access to the OHCIDMABuffer:
volatile unsigned long *pulTemp = (volatile unsigned long*)v_pOHCIDMABuffer;
// the SRAM needs to be clocked, just like other memory and peripherals.
TurnOnSRAMClocks();
RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses: testing access to OHCIDMABuffer %08x mapped to %08x.\r\n"), IM_STORAGE_BASE_U_VIRTUAL, pulTemp ));
RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses: 00-0f: %08x %08x %08x %08x\r\n"), pulTemp[0], pulTemp[1], pulTemp[2], pulTemp[3] ));
RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses: 10-1f: %08x %08x %08x %08x\r\n"), pulTemp[4], pulTemp[5], pulTemp[6], pulTemp[7] ));
pulTemp[0] = 188;
pulTemp[1] = 189;
pulTemp[2] = 190;
pulTemp[3] = 191;
pulTemp[4] = 192;
pulTemp[5] = 193;
pulTemp[6] = 194;
pulTemp[7] = 195;
RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses:M00-0f: %08x %08x %08x %08x\r\n"), pulTemp[0], pulTemp[1], pulTemp[2], pulTemp[3] ));
RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses:M10-1f: %08x %08x %08x %08x\r\n"), pulTemp[4], pulTemp[5], pulTemp[6], pulTemp[7] ));
}
// change the value of a global pointer that contains the uncached virtual address
// of the memory buffer used to hold the usb structures. usb structures are built
// in this area, and the USB OHCI reads and writes to this area, also.
RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses: dwohciBPhy: old %08x.\r\n"), dwOhciDmaBufferPhysical));
dwOhciDmaBufferPhysical = IM_STORAGE_BASE_PHYSICAL;
RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses: dwohciBPhy: new %08x.\r\n"), dwOhciDmaBufferPhysical));
#else
v_pOHCIDMABuffer =
// VirtualAllocCopy(OHCI_DMA_BUFFER_SIZE,"OHCI v_pOHCIDMABuffer", (PVOID) OHCI_DMA_BUFFER_U_VIRTUAL);
VirtualAllocCopy(dwOhciDmaBufferSize,"OHCI v_pOHCIDMABuffer", pOhciDmaBufferVirtual);
if (v_pOHCIDMABuffer == NULL) {
goto error_return;
}
#endif
#endif
#ifdef PLAT_LUBBOCK
RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses: v_pDCPLLReg: %08x = %08x.\r\n"), v_pDCPLLReg,(dwSKBase + SK_PLL_BASE)));
RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses: v_pDCIRQReg: %08x = %08x.\r\n"), v_pDCIRQReg,(dwSKBase + SK_IRQ_BASE)));
RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses: v_pDCSMCReg: %08x = %08x.\r\n"), v_pDCSMCReg,(dwSKBase + SMC_BASE)));
RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses: v_pDCMEMCReg: %08x = %08x.\r\n"), v_pDCMEMCReg,MEMC_BASE_U_VIRTUAL));
#endif
#ifndef PLAT_LUBBOCK
RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses: v_pDCCLKReg: %08x = %08x.\r\n"), v_pDCCLKReg,CLK_BASE_U_VIRTUAL));
RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses: v_pDCGPIOReg: %08x = %08x.\r\n"), v_pDCGPIOReg,GPIO_BASE_U_VIRTUAL));
#endif
#ifdef USBOHCI_DMA_IN_SRAM
RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses: v_pOHCIDMABuffer: %08x = %08x.\r\n"), v_pOHCIDMABuffer,IM_STORAGE_BASE_U_VIRTUAL));
#else
RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses: v_pOHCIDMABuffer: %08x = %08x.\r\n"), v_pOHCIDMABuffer,pOhciDmaBufferVirtual));
#endif
RETAILMSG(ZONE_INIT,(TEXT("OhcdPddInitializeAddresses: v_pDCUSBReg: %08x = %08x.\r\n"), v_pDCUSBReg,USBH_BASE_U_VIRTUAL));
return TRUE;
error_return:
ERRORMSG(1,(TEXT("OHCI Driver InitializeAddresses: Failed!.\r\n")));
#ifdef PLAT_LUBBOCK
if (v_pDCPLLReg) VirtualFree((PVOID)v_pDCPLLReg,0,MEM_RELEASE);
if (v_pDCIRQReg) VirtualFree((PVOID)v_pDCIRQReg,0,MEM_RELEASE);
if (v_pDCSMCReg) VirtualFree((PVOID)v_pDCSMCReg,0,MEM_RELEASE);
if (v_pDCMEMCReg) VirtualFree((PVOID)v_pDCMEMCReg,0,MEM_RELEASE);
#endif
#ifndef PLAT_LUBBOCK
if (v_pDCCLKReg) VirtualFree((PVOID)v_pDCCLKReg,0,MEM_RELEASE);
if (v_pDCGPIOReg) VirtualFree((PVOID)v_pDCGPIOReg,0,MEM_RELEASE);
#endif
if (v_pDCUSBReg) VirtualFree((PVOID)v_pDCUSBReg,0,MEM_RELEASE);
if (v_pOHCIDMABuffer) VirtualFree((PVOID)v_pOHCIDMABuffer,0,MEM_RELEASE);
#ifdef PLAT_LUBBOCK
v_pDCMEMCReg = 0;
v_pDCSMCReg = 0;
v_pDCIRQReg = 0;
v_pDCPLLReg = 0;
#endif
#ifndef PLAT_LUBBOCK
v_pDCCLKReg = 0;
v_pDCGPIOReg = 0;
#endif
v_pDCUSBReg = 0;
v_pOHCIDMABuffer = 0;
return 0;
}
VOID OHCI_Reset()
{
#ifdef PLAT_LUBBOCK
// go through USB initialization sequence SA-1111 TRM p. 6-1
//WRITE_BITFIELD(struct skpcrBITS,&v_pDCPLLReg->skpcr,DCLKEn,1); //Enable DMA Clocks
WRITE_BITFIELD(struct skpcrBITS,&v_pDCPLLReg->skpcr,UCLKEn,1); //Enable USB Clocks
usWait(10);
// Force reset
WRITE_BITFIELD(struct resetBITS,&v_pDCUSBReg->Reset,forceIfReset,1);
WRITE_BITFIELD(struct resetBITS,&v_pDCUSBReg->Reset,forceHcReset,1);
usWait(100);
WRITE_BITFIELD(struct resetBITS,&v_pDCUSBReg->Reset,forceIfReset,0);
WRITE_BITFIELD(struct resetBITS,&v_pDCUSBReg->Reset,forceHcReset,0);
WRITE_BITFIELD(struct resetBITS,&v_pDCUSBReg->Reset,clkGenReset,0);
WRITE_BITFIELD(struct resetBITS,&v_pDCUSBReg->Reset,uSleepStandbyEn,0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -