⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcidpprivate.asm

📁 一个amccs5933芯片的驱动程序开发源程序和部分文档
💻 ASM
📖 第 1 页 / 共 3 页
字号:
	TITLE	C:\Kernel2000\pcidpprivate.c
	.386P
include listing.inc
if @Version gt 510
.model FLAT
else
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
_DATA	SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA	ENDS
CONST	SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST	ENDS
_BSS	SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS	ENDS
$$SYMBOLS	SEGMENT BYTE USE32 'DEBSYM'
$$SYMBOLS	ENDS
$$TYPES	SEGMENT BYTE USE32 'DEBTYP'
$$TYPES	ENDS
_TLS	SEGMENT DWORD USE32 PUBLIC 'TLS'
_TLS	ENDS
;	COMDAT _RtlConvertLongToLargeInteger@4
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
;	COMDAT _StartDevice@8
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
;	COMDAT _StopDevice@4
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
;	COMDAT _CancelStopDevice@8
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
;	COMDAT _RemoveDevice@4
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
;	COMDAT _DeviceCompletionRoutine@12
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
;	COMDAT _GetResources@16
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
;	COMDAT _GetNextEntry@16
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
;	COMDAT _PutBackEntry@8
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
;	COMDAT _FreeEntry@8
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
;	COMDAT _GetFreeEntry@4
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
;	COMDAT _InsertEntry@8
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
;	COMDAT _DeleteAllEntries@4
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
FLAT	GROUP _DATA, CONST, _BSS
	ASSUME	CS: FLAT, DS: FLAT, SS: FLAT
endif
PUBLIC	_StartDevice@8
PUBLIC	_DeviceCompletionRoutine@12
PUBLIC	_GetResources@16
EXTRN	__imp__MmMapIoSpace@16:NEAR
EXTRN	__imp__IoSetDeviceInterfaceState@8:NEAR
EXTRN	__imp__KeInitializeDpc@12:NEAR
EXTRN	_DbgBreakPoint@0:NEAR
EXTRN	_DbgPrint:NEAR
EXTRN	__imp__KeWaitForSingleObject@20:NEAR
EXTRN	__imp__KeInitializeSpinLock@4:NEAR
EXTRN	__imp_@IofCallDriver@8:NEAR
EXTRN	__imp__IoConnectInterrupt@44:NEAR
EXTRN	_PCIDPForDpcIsr@16:NEAR
EXTRN	_PCIDPISR@8:NEAR
;	COMDAT _StartDevice@8
; File c:\kernel2000\pcidpprivate.c
_TEXT	SEGMENT
$SG8430	DB	'[PCIDP]->Entering StartDevice...', 0aH, 00H
	ORG $+2
$SG8468	DB	'[PCIDP]->Leaving StartDevice, status=%ld...', 0aH, 00H
_DeviceObject$ = 8
_Irp$ = 12
_NTStatus$ = -12
_LIdx$ = -8
_DIdx$ = -4
_StartDevice@8 PROC NEAR				; COMDAT

; 24   : ){

	push	ebp
	mov	ebp, esp
	sub	esp, 12					; 0000000cH

; 25   : 	NTSTATUS NTStatus;
; 26   : 	BOOLEAN Status;
; 27   : 	ULONG LIdx;
; 28   : 	ULONG DIdx;
; 29   : 	CM_RESOURCE_LIST* Resources;
; 30   : 	MEMORY_CACHING_TYPE CacheType;
; 31   : 	KINTERRUPT_MODE InterruptMode;
; 32   : 	PIO_STACK_LOCATION IrpStack;
; 33   : 	PPCIDP_EXTENSION ObjExt = (PPCIDP_EXTENSION)DeviceObject->DeviceExtension;

	mov	eax, DWORD PTR _DeviceObject$[ebp]
	push	ebx
	push	esi
	push	edi
	mov	ebx, DWORD PTR [eax+40]

; 34   : 
; 35   : 	// Debug entry point
; 36   : 	DbgPrint("[PCIDP]->Entering StartDevice...\n");	//debug

	push	OFFSET FLAT:$SG8430
	call	_DbgPrint
	pop	ecx

; 37   : 	DbgBreakPoint();	//debug

	call	_DbgBreakPoint@0

; 38   : 
; 39   : 	IoSetDeviceInterfaceState(&ObjExt->SymbolicLinkName, TRUE);

	lea	eax, DWORD PTR [ebx+132]
	push	1
	push	eax
	call	DWORD PTR __imp__IoSetDeviceInterfaceState@8

; 40   : 
; 41   : 	// Let the lower level drivers handle the IRP first.
; 42   : 	IoCopyCurrentIrpStackLocationToNext(IN Irp);

	mov	edx, DWORD PTR _Irp$[ebp]
	push	7
	pop	ecx
	mov	esi, DWORD PTR [edx+96]
	lea	eax, DWORD PTR [esi-36]
	mov	edi, eax
	rep movsd
	and	BYTE PTR [eax+3], 0

; 43   : 
; 44   : 	IoSetCompletionRoutine(
; 45   : 		IN Irp,
; 46   : 		IN DeviceCompletionRoutine,
; 47   : 		IN NULL,			//Context
; 48   : 		IN TRUE,			//InvokeOnSuccess
; 49   : 		IN TRUE,			//InvokeOnError
; 50   : 		IN TRUE				//InvokeOnCancel
; 51   : 	);

	mov	eax, DWORD PTR [edx+96]
	sub	eax, 36					; 00000024H
	xor	edi, edi
	mov	DWORD PTR [eax+28], OFFSET FLAT:_DeviceCompletionRoutine@12
	mov	DWORD PTR [eax+32], edi
	mov	BYTE PTR [eax+3], 224			; 000000e0H

; 52   : 
; 53   : 	NTStatus = IoCallDriver(ObjExt->NextLowerDeviceObject, Irp);

	mov	ecx, DWORD PTR [ebx+140]
	call	DWORD PTR __imp_@IofCallDriver@8

; 54   : 	if(NTStatus == STATUS_PENDING){

	cmp	eax, 259				; 00000103H
	mov	DWORD PTR _NTStatus$[ebp], eax
	jne	SHORT $L8442

; 55   : 		KeWaitForSingleObject(
; 56   : 			IN &ObjExt->WaitEvent,
; 57   : 			IN Executive,				//WaitReason
; 58   : 			IN KernelMode,			//WaitMode
; 59   : 			IN FALSE,						//Alertable
; 60   : 			IN NULL							//Timeout
; 61   : 		);

	push	edi
	push	edi
	push	edi
	lea	eax, DWORD PTR [ebx+144]
	push	edi
	push	eax
	call	DWORD PTR __imp__KeWaitForSingleObject@20

; 62   : 		NTStatus = Irp->IoStatus.Status;

	mov	eax, DWORD PTR _Irp$[ebp]
	mov	eax, DWORD PTR [eax+24]
	mov	DWORD PTR _NTStatus$[ebp], eax
$L8442:

; 63   : 	}
; 64   : 
; 65   : 	// Processed after the lower level drivers have successfully finished with the IRP.
; 66   : 	if(NT_SUCCESS(NTStatus)){

	cmp	DWORD PTR _NTStatus$[ebp], edi
	jl	$L8459

; 67   : 		IrpStack = IoGetCurrentIrpStackLocation(IN Irp);
; 68   : 		Resources = IrpStack->Parameters.StartDevice.AllocatedResourcesTranslated;

	mov	eax, DWORD PTR _Irp$[ebp]
	mov	eax, DWORD PTR [eax+96]
	mov	esi, DWORD PTR [eax+8]

; 69   : 
; 70   : 		// Get the I/O port attributes.
; 71   : 		Status = GetResources(Resources, CmResourceTypePort, &LIdx, &DIdx);

	lea	eax, DWORD PTR _DIdx$[ebp]
	push	eax
	lea	eax, DWORD PTR _LIdx$[ebp]
	push	eax
	push	1
	push	esi
	call	_GetResources@16

; 72   : 		if(Status == TRUE){

	cmp	al, 1
	jne	SHORT $L8446

; 73   : 			ObjExt->IOAccess = Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Port.Start;

	mov	eax, DWORD PTR _LIdx$[ebp]
	mov	ecx, DWORD PTR _DIdx$[ebp]
	lea	eax, DWORD PTR [ecx+eax*2]
	shl	eax, 4
	mov	ecx, DWORD PTR [eax+esi+24]
	mov	DWORD PTR [ebx+8], ecx
	mov	eax, DWORD PTR [eax+esi+28]
	mov	DWORD PTR [ebx+12], eax

; 74   : 			ObjExt->IOAccessLength = Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Port.Length;

	mov	eax, DWORD PTR _DIdx$[ebp]
	mov	ecx, DWORD PTR _LIdx$[ebp]
	lea	eax, DWORD PTR [eax+ecx*2+2]
	shl	eax, 4
	mov	eax, DWORD PTR [eax+esi]
	mov	DWORD PTR [ebx+20], eax

; 75   : 		}
; 76   : 		else{

	jmp	SHORT $L8447
$L8446:

; 77   : 			//ObjExt->IOAccess = 0;
; 78   : 			ObjExt->IOAccessLength = 0;

	mov	DWORD PTR [ebx+20], edi
$L8447:

; 79   : 			//NTStatus = STATUS_INSUFFICIENT_RESOURCES;
; 80   : 			//Irp->IoStatus.Status = NTStatus;
; 81   : 			//return NTStatus;
; 82   : 		}
; 83   : 
; 84   : 		// Map to the memory base space in order to support driver services.
; 85   : 		Status = GetResources(Resources, CmResourceTypeMemory, &LIdx, &DIdx);

	lea	eax, DWORD PTR _DIdx$[ebp]
	push	eax
	lea	eax, DWORD PTR _LIdx$[ebp]
	push	eax
	push	3
	push	esi
	call	_GetResources@16

; 86   : 		if(Status == TRUE){

	cmp	al, 1
	jne	$L8448

; 87   : 			if(
; 88   : 				Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].Flags &
; 89   : 				CM_RESOURCE_MEMORY_COMBINEDWRITE
; 90   : 			)

	mov	eax, DWORD PTR _DIdx$[ebp]
	mov	ecx, DWORD PTR _LIdx$[ebp]
	lea	eax, DWORD PTR [eax+ecx*2]
	shl	eax, 4
	add	eax, esi
	mov	cx, WORD PTR [eax+22]
	test	cl, 8
	je	SHORT $L8449

; 91   : 				CacheType = MmWriteCombined;

	push	2
	pop	ecx

; 92   : 			else if(

	jmp	SHORT $L8451
$L8449:

; 93   : 				Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].Flags &
; 94   : 				CM_RESOURCE_MEMORY_CACHEABLE
; 95   : 			)

	movzx	ecx, cl
	shr	ecx, 5
	and	ecx, 1
$L8451:

; 96   : 				CacheType = MmCached;
; 97   : 			else
; 98   : 				CacheType = MmNonCached;
; 99   : 
; 100  : 			ObjExt->MemoryAccess = Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Memory.Start;

	mov	edx, DWORD PTR [eax+24]

; 101  : 			ObjExt->MemoryAccessLength = Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Memory.Length;
; 102  : 
; 103  : 			ObjExt->MemoryBase = (ULONG*)MmMapIoSpace(
; 104  : 				IN ObjExt->MemoryAccess,
; 105  : 				IN ObjExt->MemoryAccessLength,
; 106  : 				IN CacheType
; 107  : 			);

	push	ecx
	mov	DWORD PTR [ebx], edx
	mov	eax, DWORD PTR [eax+28]
	mov	DWORD PTR [ebx+4], eax
	mov	eax, DWORD PTR _DIdx$[ebp]
	mov	edx, DWORD PTR _LIdx$[ebp]
	lea	eax, DWORD PTR [eax+edx*2+2]
	shl	eax, 4
	mov	eax, DWORD PTR [eax+esi]
	push	eax
	mov	DWORD PTR [ebx+16], eax
	push	DWORD PTR [ebx+4]
	push	DWORD PTR [ebx]
	call	DWORD PTR __imp__MmMapIoSpace@16

; 108  : 			if(ObjExt->MemoryBase == NULL){

	cmp	eax, edi
	mov	DWORD PTR [ebx+24], eax
	jne	SHORT $L8455

; 109  : 				NTStatus = STATUS_SOME_NOT_MAPPED;
; 110  : 				//Irp->IoStatus.Status = NTStatus;
; 111  : 				return NTStatus;

	mov	eax, 263				; 00000107H
	jmp	$L8419
$L8455:

; 118  : 		}
; 119  : 
; 120  : 		// Map the PCI board's IRQ to a system vector.
; 121  : 		// todo: resolve the interrupt pin source
; 122  : 		ObjExt->InterruptObject = 0;
; 123  : 		//if((ULONG)CardInfo.u.type0.InterruptPin != 0){	//use IRP_MN_READ_CONFIG
; 124  : 
; 125  : 			// Connect the driver to the IRQ.
; 126  : 			Status = GetResources(Resources, CmResourceTypeInterrupt, &LIdx, &DIdx);

	lea	eax, DWORD PTR _DIdx$[ebp]
	mov	DWORD PTR [ebx+32], edi
	push	eax
	lea	eax, DWORD PTR _LIdx$[ebp]
	push	eax
	push	2
	push	esi
	call	_GetResources@16

; 127  : 			if(Status == TRUE){

	cmp	al, 1
	jne	SHORT $L8459

; 128  : 				if(
; 129  : 					Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].Flags &
; 130  : 					CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
; 131  : 				)
; 132  : 					InterruptMode = LevelSensitive;
; 133  : 				else
; 134  : 					InterruptMode = Latched;
; 135  : 
; 136  : 				NTStatus = IoConnectInterrupt(
; 137  : 					OUT &ObjExt->InterruptObject,
; 138  : 					IN PCIDPISR,				//pointer to ISR
; 139  : 					IN DeviceObject,		//context to send to ISR
; 140  : 					IN NULL,						//optional spinlock
; 141  : 					IN Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Interrupt.Vector,		//mapped interrupt vector u.Interrupt.Vector
; 142  : 					IN (KIRQL)Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Interrupt.Level,					//DIRQL	u.Interrupt.Level
; 143  : 					IN (KIRQL)Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Interrupt.Level,					//DIRQL	u.Interrupt.Level
; 144  : 					IN InterruptMode,		//latched/level interrupt
; 145  : 					IN TRUE,						//shareable interrupt
; 146  : 					IN Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Interrupt.Affinity,			//processor enable mask u.Interrupt.Affinity
; 147  : 					IN FALSE						//floating save (false for X86)
; 148  : 				);

	mov	edi, DWORD PTR _DIdx$[ebp]
	mov	ecx, DWORD PTR _LIdx$[ebp]
	push	0
	lea	eax, DWORD PTR [edi+ecx*2]
	lea	ecx, DWORD PTR [edi+ecx*2+2]
	shl	ecx, 4
	shl	eax, 4
	push	DWORD PTR [ecx+esi]
	add	eax, esi
	mov	edi, DWORD PTR _DeviceObject$[ebp]
	lea	esi, DWORD PTR [ebx+32]
	mov	dl, BYTE PTR [eax+24]
	push	1
	push	1
	push	edx
	push	edx
	push	DWORD PTR [eax+28]
	push	0
	push	edi
	push	OFFSET FLAT:_PCIDPISR@8
	push	esi
	call	DWORD PTR __imp__IoConnectInterrupt@44

; 149  : 				if(NTStatus != STATUS_SUCCESS){

	test	eax, eax
	mov	DWORD PTR _NTStatus$[ebp], eax
	je	SHORT $L8466

; 150  : 					ObjExt->InterruptObject = 0;

	and	DWORD PTR [esi], 0

; 151  : 					//Irp->IoStatus.Status = NTStatus;
; 152  : 					return NTStatus;

	jmp	SHORT $L8419
$L8466:

; 153  : 				}
; 154  : 
; 155  : 				// Register the PCIDPForDpcIsr routine with this device
; 156  : 				// driver.
; 157  : 				IoInitializeDpcRequest(
; 158  : 					IN DeviceObject,
; 159  : 					IN PCIDPForDpcIsr
; 160  : 				);

	push	edi
	add	edi, 116				; 00000074H
	push	OFFSET FLAT:_PCIDPForDpcIsr@16
	push	edi
	call	DWORD PTR __imp__KeInitializeDpc@12

; 161  : 
; 162  : 				// Set up the spin lock for the linked list holding pending IRPs.
; 163  : 				KeInitializeSpinLock(&ObjExt->LListSpin);

	add	ebx, 116				; 00000074H
	push	ebx
	call	DWORD PTR __imp__KeInitializeSpinLock@4
$L8459:

; 164  : 			}
; 165  : 		//}
; 166  : 	}
; 167  : 
; 168  : 	// Debug exit point
; 169  : 	DbgPrint("[PCIDP]->Leaving StartDevice, status=%ld...\n", NTStatus);	//debug

	push	DWORD PTR _NTStatus$[ebp]
	push	OFFSET FLAT:$SG8468
	call	_DbgPrint
	pop	ecx
	pop	ecx

; 170  : 	DbgBreakPoint();	//debug

	call	_DbgBreakPoint@0

; 171  : 
; 172  : 	return NTStatus;

	mov	eax, DWORD PTR _NTStatus$[ebp]
$L8419:
	pop	edi
	pop	esi
	pop	ebx

; 173  : }

	leave
	ret	8
$L8448:

; 112  : 			}
; 113  : 		}
; 114  : 		else{
; 115  : 			NTStatus = STATUS_INSUFFICIENT_RESOURCES;
; 116  : 			//Irp->IoStatus.Status = NTStatus;
; 117  : 			return NTStatus;

	mov	eax, -1073741670			; c000009aH
	jmp	SHORT $L8419
_StartDevice@8 ENDP
_TEXT	ENDS
PUBLIC	_StopDevice@4
PUBLIC	_DeleteAllEntries@4
EXTRN	__imp__MmUnmapIoSpace@8:NEAR
EXTRN	__imp__IoDisconnectInterrupt@4:NEAR
;	COMDAT _StopDevice@4
; File c:\kernel2000\pcidpprivate.c
_TEXT	SEGMENT
$SG8474	DB	'[PCIDP]->Entering StopDevice...', 0aH, 00H
_DeviceObject$ = 8
_StopDevice@4 PROC NEAR					; COMDAT

; 177  : 
; 178  : 	PPCIDP_EXTENSION ObjExt = (PPCIDP_EXTENSION)DeviceObject->DeviceExtension;

	mov	eax, DWORD PTR _DeviceObject$[esp-4]
	push	esi

; 179  : 
; 180  : 	// Debug entry point
; 181  : 	DbgPrint("[PCIDP]->Entering StopDevice...\n");	//debug

	push	OFFSET FLAT:$SG8474
	mov	esi, DWORD PTR [eax+40]
	call	_DbgPrint
	pop	ecx

; 182  : 	DbgBreakPoint();	//debug

	call	_DbgBreakPoint@0

; 183  : 
; 184  : 	// Disconnect the driver from the interrupt if enabled.
; 185  : 	if(ObjExt->InterruptObject)

	mov	eax, DWORD PTR [esi+32]
	test	eax, eax
	je	SHORT $L8475

; 186  : 		IoDisconnectInterrupt(ObjExt->InterruptObject);

	push	eax
	call	DWORD PTR __imp__IoDisconnectInterrupt@4
$L8475:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -