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

📄 space.c

📁 T-kernel 的extension源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
			la = (VB*)laddr + plen;			if ( plen >= len ) {				break;			}		}	} while ( i == (W)N_PTE );	if ( plen > len ) {		plen = len;	}	return plen;}/* * Check access attribute of logical space *	In a logical space of the task, check if it is possible to make access to len bytes *	of area (starting from a logical address laddr) from env environment in mode. *	If it is possible, return E_OK; if not possible, return E_MACV. * *	(*) Do not execute LockSEG(). *	   It causes deadlock when called from the disk driver. */EXPORT ER _ChkSpace( VP laddr, W len, UW mode, UW env ){	VP	la;	PDE	*pde;	PTE	*pte;	UW	chk_u, chk_w;	UW	imask;	W	i;	W	plen = 0;	/* Attributes necessary for access */	chk_u = ( (env & (UW)TMF_PPL(TSD_LSC_PPL_3)) == (UW)TMF_PPL(TSD_LSC_PPL_3) )? 1U: 0U;	chk_w = ( (mode & MA_WRITE) != 0U )? 1U: 0U;	/* Check non-logical spaces using a section table. */	if ( !isLogicalSpace(laddr) ) {		for ( i = (W)SECTION_NO(laddr); i < MAX_SECTION; ++i ) {			if ( SATB->s[i].s == 0 ) {				break; /* There is no section table. */			}			/* Check access right. */			if ( SATB->s[i].u < chk_u ) {				break;			}			if ( SATB->s[i].w < chk_w ) {				break;			}			if ( plen == 0 ) {				/* First page */				plen = SECTION_SIZE - (W)SECTION_OFS(laddr);			} else {				plen += SECTION_SIZE;			}			if ( plen > len ) {				break;			}		}		goto ret;	}	do {		la = (VB*)laddr + plen;		/* Disable interruption to prevent deletion of the page table		   while it is checked. */		DI(imask);		/* Obtain page directory entry */		pde = SATB + PDIR_NUM(la);		if ( pde->c[0].p == 0U ) {			/* No page table */			EI(imask);			break;		}		/* Obtain page table address. */		pte = PFAtoLADR(pde->c[0].pfa);		for ( i = (W)PTBL_NUM(la); i < (W)N_PTE; ++i ) {			if ( pte[i].w == (UW)PTE_NONE ) {				break; /* Invalid PTE */			}			/* Check access right. */			if ( pte[i].c.u < chk_u ) {				break;			}			if ( pte[i].c.w < chk_w ) {				break;			}			if ( plen == 0 ) {				/* First page */				plen = PAGESIZE - (W)POFS_NUM(la);			} else {				plen += PAGESIZE;			}			if ( plen >= len ) {				break;			}		}		EI(imask);	} while ( i == (W)N_PTE );ret:#ifdef DEBUG	if ( plen < len ) {		DEBUG_PRINT(("_ChkSpace(%#x, %d, %d, %#x) = E_MACV\n",						laddr, len, mode, env));	}#endif	return ( plen >= len )? E_OK: E_MACV;}/* * Check access attribute of logical space(TC character string) *	In a logical space of the task, check if it is possible to make access to an area *	(starting from a logical address str to TNULL or to the max-th character) from *	env environment in mode. When set at "max = 0", ignore the number (max) of characters. *	If it is possible, return the number of characters or the value of max (when "max > 0" *	and TNULL is not found before the max-th character); if not possible, return E_MACV. * *	(*) It is assumed that str is an even-number address. *	(*) Do not execute LockSEG(). *	   It causes deadlock when called from the disk driver. */EXPORT W _ChkSpaceTstr( TC *str, W max, UW mode, UW env ){	TC	*tp = str;	PDE	*pde;	PTE	*pte;	UW	chk_u, chk_w;	UW	imask;	W	i, n;#ifdef DEBUG	W	_max = max;#endif	/* Attributes necessary for access */	chk_u = ( (env & (UW)TMF_PPL(TSD_LSC_PPL_3)) == (UW)TMF_PPL(TSD_LSC_PPL_3) )? 1U: 0U;	chk_w = ( (mode & MA_WRITE) != 0U )? 1U: 0U;	/* Check non-logical spaces using a section table. */	if ( !isLogicalSpace(tp) ) {		for ( i = (W)SECTION_NO(tp); i < MAX_SECTION; ++i ) {			if ( SATB->s[i].s == 0 ) {				break; /* There is no section table. */			}			/* Check access right. */			if ( SATB->s[i].u < chk_u ) {				break;			}			if ( SATB->s[i].w < chk_w ) {				break;			}			/* Number of characters within this section */			n = (SECTION_SIZE - (W)SECTION_OFS(tp)) / (W)sizeof(TC);			/* TNULL checking */			while ( --n >= 0 ) {				if ( *tp == TNULL ) {					return tp - str;				}				tp++;				if ( --max == 0 ) {					return tp - str;				}			}		}		goto err_ret;	}	for ( ;; ) {		/* Disable interruption to prevent deletion of the page table		   while it is checked. */		DI(imask);		/* Obtain page directory entry */		pde = SATB + PDIR_NUM(tp);		if ( pde->c[0].p == 0U ) {			break;  /* No page table */		}		/* Obtain page table address. */		pte = PFAtoLADR(pde->c[0].pfa);		/* Page table entry */		pte += PTBL_NUM(tp);		if ( pte->w == (UW)PTE_NONE ) {			break; /* Invalid PTE */		}		/* Check access right. */		if ( pte->c.u < chk_u ) {			break;		}		if ( pte->c.w < chk_w ) {			break;		}		EI(imask);		/* Number of characters within this page */		n = (PAGESIZE - (W)POFS_NUM(tp)) / (W)sizeof(TC);		/* TNULL checking (Page-in may occur.) */		while ( --n >= 0 ) {			if ( *tp == TNULL ) {				return tp - str;			}			tp++;			if ( --max == 0 ) {				return tp - str;			}		}	}	EI(imask);err_ret:	DEBUG_PRINT(("_ChkSpaceTstr(%#x, %d, %d, %#x) = E_MACV\n",						str, _max, mode, env));	return E_MACV;}/* * Check access attribute of logical space(B character string) *	In a logical space of the task, check if it is possible to make access to an area *	(starting from a logical address str to '\0' or to the max-th byte) from *	env environment in mode. When set at "max = 0", ignore the number (max) of bytes. *	If it is possible, return the number of bytes or the value of max (when "max > 0" *	and '\0' is not found before the max-th byte); if not possible, return E_MACV. * *	(*) Do not execute LockSEG(). *	   It causes deadlock when called from the disk driver. */EXPORT W _ChkSpaceBstr( UB *str, W max, UW mode, UW env ){	UB	*p = str;	PDE	*pde;	PTE	*pte;	UW	chk_u, chk_w;	UW	imask;	W	i, n;#ifdef DEBUG	W	_max = max;#endif	/* Attributes necessary for access */	chk_u = ( (env & (UW)TMF_PPL(TSD_LSC_PPL_3)) == (UW)TMF_PPL(TSD_LSC_PPL_3) )? 1U: 0U;	chk_w = ( (mode & MA_WRITE) != 0U )? 1U: 0U;	/* Check non-logical spaces using a section table. */	if ( !isLogicalSpace(p) ) {		for ( i = (W)SECTION_NO(p); i < MAX_SECTION; ++i ) {			if ( SATB->s[i].s == 0 ) {				break; /* There is no section table. */			}			/* Check access right. */			if ( SATB->s[i].u < chk_u ) {				break;			}			if ( SATB->s[i].w < chk_w ) {				break;			}			/* Number of characters within this section */			n = SECTION_SIZE - (W)SECTION_OFS(p);			/* '\0' checking */			while ( --n >= 0 ) {				if ( *p == '\0' ) {					return p - str;				}				p++;				if ( --max == 0 ) {					return p - str;				}			}		}		goto err_ret;	}	for ( ;; ) {		/* Disable interruption to prevent deletion of the page table		   while it is checked. */		DI(imask);		/* Obtain page directory entry */		pde = SATB + PDIR_NUM(p);		if ( pde->c[0].p == 0U ) {			break;  /* No page table */		}		/* Obtain page table address. */		pte = PFAtoLADR(pde->c[0].pfa);		/* Page table entry */		pte += PTBL_NUM(p);		if ( pte->w == (UW)PTE_NONE ) {			break; /* Invalid PTE */		}		/* Check access right. */		if ( pte->c.u < chk_u ) {			break;		}		if ( pte->c.w < chk_w ) {			break;		}		EI(imask);		/* Number of characters within this page */		n = PAGESIZE - (W)POFS_NUM(p);		/* '\0' checking (Page-in may occur.) */		while ( --n >= 0 ) {			if ( *p == '\0' ) {				return p - str;			}			p++;			if ( --max == 0 ) {				return p - str;			}		}	}	EI(imask);err_ret:	DEBUG_PRINT(("_ChkSpaceBstr(%#x, %d, %d, %#x) = E_MACV\n",						str, _max, mode, env));	return E_MACV;}/* * Check access attribute of logical space *	In lsid logical space, check if it is possible to make access to up to len bytes of *	area (starting from a logical address laddr) from env environment in mode. *	mode = [MA_READ] | [MA_WRITE] | [MA_EXECUTE] *	When set at "mode = 0", check the existence of memory. *	As a return value, return the size of accessible area. *	Return value	0 - len	Number of accessible bytes *			< 0	Error * *	(*) Do not execute LockSEG(). *	   It causes deadlock when called from the disk driver. */EXPORT W _ChkSpaceLen( VP laddr, W len, UW mode, UW env, UW lsid ){	VP	uatb;	VP	la;	PDE	*pde;	PTE	*pte;	UW	chk_u, chk_w;	UW	imask;	W	i;	W	plen = 0;	ER	err;	if ( len <= 0 ) {		err = E_PAR;		goto err_ret1;	}	/* Attributes necessary for access */	chk_u = ( (env & (UW)TMF_PPL(TSD_LSC_PPL_3)) == (UW)TMF_PPL(TSD_LSC_PPL_3) )? 1U: 0U;	chk_w = ( (mode & MA_WRITE) != 0U )? 1U: 0U;	/* Check non-logical spaces using a section table. */	if ( !isLogicalSpace(laddr) ) {		for ( i = (W)SECTION_NO(laddr); i < MAX_SECTION; ++i ) {			if ( SATB->s[i].s == 0 ) {				break; /* There is no section table. */			}			/* Check access right. */			if ( SATB->s[i].u < chk_u ) {				break;			}			if ( SATB->s[i].w < chk_w ) {				break;			}			if ( plen == 0 ) {				/* First page */				plen = SECTION_SIZE - (W)SECTION_OFS(laddr);			} else {				plen += SECTION_SIZE;			}			if ( plen > len ) {				break;			}		}		return ( len < plen )? len: plen;	}	uatb = GetUATB_lsid(lsid);	do {		la = (VB*)laddr + plen;		/* Disable interruption to prevent deletion of the page table		   while it is checked. */		DI(imask);		/* Obtain page directory entry */		pde = GetPDE(la, uatb, &err);		if ( pde == NULL ) {			goto err_ret2;		}		if ( pde->c[0].p == 0U ) {			/* No page table */			EI(imask);			break;		}		/* Obtain page table address. */		pte = PFAtoLADR(pde->c[0].pfa);		for ( i = (W)PTBL_NUM(la); i < (W)N_PTE; ++i ) {			if ( pte[i].w == (UW)PTE_NONE ) {				break; /* Invalid PTE */			}			/* Check access right. */			if ( pte[i].c.u < chk_u ) {				break;			}			if ( pte[i].c.w < chk_w ) {				break;			}			if ( plen == 0 ) {				/* First page */				plen = PAGESIZE - (W)POFS_NUM(la);			} else {				plen += PAGESIZE;			}			if ( plen >= len ) {				break;			}		}		EI(imask);	} while ( i == (W)N_PTE );	return ( len < plen )? len: plen;err_ret2:	EI(imask);err_ret1:	DEBUG_PRINT(("_ChkSpaceLen(%#x, %d, %d, %#x, %d) = %d\n",					laddr, len, mode, env, lsid, err));	return err;}/* * Read from memory *	Read up to len bytes (starting from a logical address laddr on lsid logical space) *	and store it in the logical address buf located in a logical space of the task. *	Read a range of memory (starting from laddr) regardless of access right and return *	the number of bytes as a return value. *	It is necessary to prepare writable memory space for len bytes *	in buf area. *	When called from user level, return error (E_CTX). *	Return value	0 - len	Number of read bytes *			< 0	Error */EXPORT W __ReadMemSpace( VP laddr, VP buf, W len, UW lsid ){	VP	uatb;	VB	*la, *pa;	PDE	*pde;	PTE	*pte;	BOOL	curspc;	W	i, n, alen;	ER	err;	if ( len <= 0 ) {		err = E_PAR;		goto err_ret1;	}	/* Disable calls from user level. */	if ( (SCInfo.taskmode & (UW)TMF_PPL(TSD_LSC_PPL_3)) == (UW)TMF_PPL(TSD_LSC_PPL_3) ) {		err = E_CTX;		goto err_ret1;	}	/* Check buf access. */	err = _ChkSpace(buf, len, MA_WRITE, SCInfo.taskmode);	if ( err < E_OK ) {		goto err_ret1;	}	/* Non-logical spaces are accessed directly. */	if ( !isLogicalSpace(laddr) ) {		n = _ChkSpaceLen(laddr, len, MA_READ, SCInfo.taskmode, lsid);		if ( n > 0 ) {			memmove(buf, laddr, (size_t)n);		}		return n;	}	/* Make buf resident. */	err = __LockSpace(buf, len);	if ( err < E_OK ) {		goto err_ret1;	}	/* To refer to physical memory directly, flush the cache. */	ExtFlushCacheWT();	/* Performed in the current space: TRUE */	curspc = ( !isLocalSpace(laddr) || isCurrentSpace(lsid) );	uatb = GetUATB_lsid(lsid);	alen = 0;	do {		la = (VB*)laddr + alen;		/* Obtain page directory entry */		pde = GetPDE(la, uatb, &err);		if ( pde == NULL ) {			goto err_ret2;		}		if ( pde->c[0].p == 0U ) {			break; /* No page table */		}		/* Obtain page table address. */		pte = PFAtoLADR(pde->c[0].pfa);		for ( i = (W)PTBL_NUM(la); i < (W)N_PTE; ++i ) {			if ( pte[i].w == (UW)PTE_NONE ) {

⌨️ 快捷键说明

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