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

📄 com_sgd.c

📁 6440linuxDriver的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
void sgdt_append_sgd(	sgd_tbl_t*	sgdt,	sgd_t*		sgd	){	sgd_t*	pSGEntry = &sgdt->Entry_Ptr[sgdt->Valid_Entry_Count];	MV_U8	cnt = 1;	MV_U32	sgdsz;	sgd_getsz(sgd,sgdsz);	if( sgd->flags & SGD_WIDE )		cnt++;	MV_ASSERT( sgdt->Valid_Entry_Count+cnt<=sgdt->Max_Entry_Count );	sgdt_clear_eot(sgdt);	sgdt->Valid_Entry_Count += cnt;	sgdt->Byte_Count += sgdsz;	MV_CopyMemory( pSGEntry, sgd, sizeof(sgd_t) * cnt );	sgd_mark_eot(pSGEntry);}static int sgdt_append_virtual_wo_xctx(	sgd_tbl_t* sgdt,	MV_PVOID virtual_address,	MV_U32 size 	){	sgd_t* sg = &sgdt->Entry_Ptr[sgdt->Valid_Entry_Count];	sgd_v_t* vsg = (sgd_v_t*) sg;	MV_ASSERT( sgdt->Valid_Entry_Count+1<=sgdt->Max_Entry_Count );	if( sgdt->Valid_Entry_Count + 1 > sgdt->Max_Entry_Count )		return -1;	// not enough space	sgdt_clear_eot(sgdt);	vsg->flags = SGD_EOT | SGD_VWOXCTX;	vsg->size = size;	vsg->u.vaddr = virtual_address;	sgdt->Valid_Entry_Count++;	sgdt->Byte_Count += size;	return 0;}int sgdt_append_virtual(	sgd_tbl_t* sgdt,	MV_PVOID virtual_address,	MV_PVOID translation_ctx,	MV_U32 size 	){	sgd_t* sg;#ifdef USES_64B_POINTER	sgd_v64_t* vsg;#else	sgd_v32_t* vsg;#endif	if( translation_ctx == 0 )		return sgdt_append_virtual_wo_xctx(sgdt,virtual_address,size);	sg = &sgdt->Entry_Ptr[sgdt->Valid_Entry_Count];#ifdef USES_64B_POINTER	vsg = (sgd_v64_t*) sg;	MV_ASSERT( sgdt->Valid_Entry_Count+2<=sgdt->Max_Entry_Count );	if( sgdt->Valid_Entry_Count + 2 > sgdt->Max_Entry_Count )		return -1;	// not enough space	sgdt_clear_eot(sgdt);	vsg->u1.vaddr = virtual_address;	vsg->u2.xctx = translation_ctx;	vsg->flags = SGD_WIDE | SGD_VIRTUAL | SGD_EOT;	vsg->flagsEx = SGD_X64;	sgdt->Valid_Entry_Count++;#else	// USES_64B_POINTER	vsg = (sgd_v32_t*) sg;	MV_ASSERT( sgdt->Valid_Entry_Count+1<=sgdt->Max_Entry_Count );	if( sgdt->Valid_Entry_Count + 1 > sgdt->Max_Entry_Count )		return -1;	// not enough space	sgdt_clear_eot(sgdt);	vsg->vaddr = virtual_address;	vsg->xctx = translation_ctx;	vsg->flags = SGD_VIRTUAL | SGD_EOT;#endif	// !USES_64B_POINTER	vsg->size = size;	sgdt->Valid_Entry_Count++;	sgdt->Byte_Count += size;	return 0;}int sgdt_append_vp(	sgd_tbl_t*	sgdt,	MV_PVOID	virtual_address,	MV_U32		size,	MV_U32		address,	MV_U32		addressHigh	){	sgd_vp_t* sg = (sgd_vp_t*) &sgdt->Entry_Ptr[sgdt->Valid_Entry_Count];	MV_ASSERT( sgdt->Valid_Entry_Count+2<=sgdt->Max_Entry_Count );	if( sgdt->Valid_Entry_Count + 2 > sgdt->Max_Entry_Count )		return -1;	// not enough space	sgdt_clear_eot(sgdt);	sg->baseAddr.parts.low = address;	sg->baseAddr.parts.high = addressHigh;	sg->flags = SGD_VP | SGD_WIDE | SGD_EOT;	sg->size = size;	sg->u.vaddr = virtual_address;	sg->flagsEx = SGD_X64;	sgdt->Valid_Entry_Count += 2;	sgdt->Byte_Count += size;	return 0;}int sgdt_append_ref(	sgd_tbl_t*	sgdt,	MV_PVOID	ref,	MV_U32		offset,	MV_U32		size,	MV_BOOLEAN	refTbl	){	sgd_t* sg;	if( sgdt->Valid_Entry_Count )	{		sgdt_get_lastsgd(sgdt,sg);		if( sg->flags&(SGD_REFTBL|SGD_REFSGD) )		{			MV_PVOID lastRef;			MV_U32 lastOffset;						sgd_get_ref(sg, lastRef);			sgd_get_refoff(sg, lastOffset);			if( lastRef == ref				&& lastOffset + sg->size == offset )			{				// contiguous items!				sg->size += size;				sgdt->Byte_Count += size;				return 0;			}		}					}	sg = &sgdt->Entry_Ptr[sgdt->Valid_Entry_Count];	{#ifdef USES_64B_POINTER	sgd_ref64_t* rsg = (sgd_ref64_t*) sg;	MV_ASSERT( sgdt->Valid_Entry_Count+2<=sgdt->Max_Entry_Count );	if( sgdt->Valid_Entry_Count + 2 > sgdt->Max_Entry_Count )		return -1;	// not enough space	sgdt_clear_eot(sgdt);	rsg->u.ref = ref;	sgdt->Valid_Entry_Count++;	rsg->flags = SGD_WIDE | SGD_EOT | (refTbl ? SGD_REFTBL : SGD_REFSGD);	rsg->flagsEx = SGD_X64;#else	sgd_ref32_t* rsg = (sgd_ref32_t*) sg;	MV_ASSERT( sgdt->Valid_Entry_Count+1<=sgdt->Max_Entry_Count );	if( sgdt->Valid_Entry_Count + 1 > sgdt->Max_Entry_Count )		return -1;	// not enough space	sgdt_clear_eot(sgdt);	rsg->ref = ref;	rsg->flags = SGD_EOT | (refTbl ? SGD_REFTBL : SGD_REFSGD);#endif	rsg->offset = offset;	rsg->size = size;	sgdt->Valid_Entry_Count++;	sgdt->Byte_Count += size;	}	return 0;}voidsgdt_copy_partial(	sgd_tbl_t* sgdt,	sgd_t**	ppsgd,	MV_PU32	poff,	MV_U32	size	){	MV_U32	sgdsz;	MV_U32	tmpSize;	sgd_t	sgd[2];	while( size )	{		sgd_getsz( *ppsgd, sgdsz );		MV_ASSERT( sgdsz > *poff );		tmpSize = MV_MIN( size, sgdsz - *poff );		if( sgdt )		{			sgd_copy( sgd, *ppsgd );			sgd_setsz( sgd, tmpSize );			if( *poff )			{				if( sgd->flags & (SGD_REFTBL|SGD_REFSGD) )				{					MV_U32 refoff;					sgd_get_refoff( sgd, refoff );					sgd_set_refoff( sgd, refoff+(*poff) );				}				else				{					sgd->baseAddr = U64_ADD_U32( sgd->baseAddr, (*poff) );					if( sgd->flags & SGD_VP )					{						sgd_vp_t* vp = (sgd_vp_t*) sgd;						vp->u.vaddr = ((MV_U8*)vp->u.vaddr) + (*poff);					}				}			}			sgdt_append_sgd( sgdt, sgd );		}		if( size == sgdsz - *poff 			|| tmpSize == sgdsz - *poff )		{			sgd_inc( *ppsgd );			(*poff) = 0;		}		else			(*poff) += tmpSize;		size -= tmpSize;	}}#ifdef SIMULATORint SgVisitor(sgd_t* sg, MV_PVOID ctx){	MV_U32* p = (MV_U32*)ctx;	sgd_dump( sg, NULL );	(*p)++;	return 1;}void sgd_test(){	sgd_tbl_t SgTbl1 = {0,};	sgd_tbl_t SgTbl2 = {0,};	sgd_tbl_t SgTbl3 = {0,};	sgd_t Entries1[32];	sgd_t Entries2[32];	sgd_t Entries3[32];	SgTbl1.Max_Entry_Count = sizeof(Entries1)/sizeof(Entries1[0]);	SgTbl1.Entry_Ptr = Entries1;	SgTbl2.Max_Entry_Count = sizeof(Entries2)/sizeof(Entries2[0]);	SgTbl2.Entry_Ptr = Entries2;	SgTbl3.Max_Entry_Count = sizeof(Entries3)/sizeof(Entries3[0]);	SgTbl3.Entry_Ptr = Entries3;	int i;	for( i = 0; i < 32; i++ )	{		sgdt_append( &SgTbl2, 0x80000000+i*0x1000, 0x90000000, 0x1000 );	}	sgdt_dump( &SgTbl2, " " );	sgdt_append_reftbl( &SgTbl1, &SgTbl2, 0x3800, 0x1000*10 );	sgdt_append_virtual( &SgTbl1, (MV_PVOID)0x40000, (MV_PVOID)0x60000, 0x1000*10 );	sgdt_append_vp( &SgTbl1, (MV_PVOID)0x80000, 0x1000*10, 0x4000, 0 );	sgdt_dump( &SgTbl1, " " );	MV_PRINT( "Walking through the table:\n" );	MV_U32 index = 0;	sgd_table_walk( &SgTbl1, SgVisitor, &index );	sgd_iter_t iter;	sgd_t sg[2];	sgd_iter_init( &iter, SgTbl1.Entry_Ptr, 0, SgTbl1.Byte_Count );	MV_PRINT( "Walking through the table in another way:\n" );	i = 0;	while( sgd_iter_get_next( &iter, sg ) )	{		sgd_dump( sg, NULL );	}	sgdt_dump( &SgTbl1, " " );	sgd_t* sgd = SgTbl1.Entry_Ptr;	MV_U32 off = 0x1000;	sgdt_copy_partial( &SgTbl3, &sgd, &off, 0x1000 );	sgdt_copy_partial( &SgTbl3, &sgd, &off, 0x9000 );	sgdt_copy_partial( &SgTbl3, &sgd, &off, 0x9000 );	sgdt_copy_partial( &SgTbl3, &sgd, &off, 0x1000 );	sgdt_copy_partial( &SgTbl3, &sgd, &off, 0x1000 );	sgdt_dump( &SgTbl3, " " );}#endiftypedef struct _PRDTableWalkCtx{	MV_PVOID		pCore;	sgd_t*			pSg;	int				avail;	int				itemCnt;} PRDTableWalkCtx;static int PRDTablePrepareVisitor(sgd_t* sg, MV_PVOID _ctx){	PRDTableWalkCtx* ctx = (PRDTableWalkCtx*) _ctx;	if( !ctx->avail )		return 0;	if( sg->flags & (SGD_VIRTUAL|SGD_VWOXCTX) )	{		MV_U32 totalSize, thisSize;		MV_PVOID vaddr;		MV_PVOID xctx;		MV_U64 paddr;#ifdef _OS_LINUX		MV_ASSERT( 0 );#endif /* _OS_LINUX */		sgd_getsz( sg, totalSize );		if( sg->flags & SGD_VIRTUAL )		{			sgd_get_vaddr( sg, vaddr );			sgd_get_xctx( sg, xctx );		}		else		{			vaddr = ((sgd_v_t*)sg)->u.vaddr;			xctx = 0;		}		while( 1 )		{			thisSize = totalSize;			if( !HBA_ModuleGetPhysicalAddress(					ctx->pCore, 					vaddr,					xctx,					&paddr,					&thisSize) )				return 0;			ctx->avail--;			ctx->itemCnt++;			ctx->pSg->flags = 0;#ifdef ODIN_DRIVER			ctx->pSg->size = MV_CPU_TO_LE32(thisSize);#else			ctx->pSg->size = MV_CPU_TO_LE32(thisSize - 1);#endif			ctx->pSg->baseAddr.parts.low = MV_CPU_TO_LE32(paddr.parts.low);			ctx->pSg->baseAddr.parts.high = MV_CPU_TO_LE32(paddr.parts.high);			ctx->pSg++;			totalSize -= thisSize;			if( totalSize == 0 )				break;			if( !ctx->avail )				return 0;			vaddr = (MV_PVOID)((MV_PU8) vaddr + thisSize);		}	}	else	{		// including SGD_VP/SGD_PCTX		ctx->avail--;		ctx->itemCnt++;		ctx->pSg->flags = 0;#ifdef ODIN_DRIVER		ctx->pSg->size = MV_CPU_TO_LE32(sg->size);#else		ctx->pSg->size = MV_CPU_TO_LE32(sg->size - 1);#endif		ctx->pSg->baseAddr.parts.low = MV_CPU_TO_LE32(sg->baseAddr.parts.low);		ctx->pSg->baseAddr.parts.high = MV_CPU_TO_LE32(sg->baseAddr.parts.high);		ctx->pSg++;	}	return 1;}int sgdt_prepare_hwprd(	MV_PVOID		pCore,	sgd_tbl_t*		pSource,	sgd_t*			pSg,	int				availSgEntry	){	PRDTableWalkCtx ctx;	ctx.pCore = pCore;	ctx.pSg = pSg;	ctx.avail = availSgEntry;	ctx.itemCnt = 0;	if( !sgd_table_walk( pSource, PRDTablePrepareVisitor, &ctx) )		return 0;	return ctx.itemCnt;}#endif // USE_NEW_SGTABLE

⌨️ 快捷键说明

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