Exemplo n.º 1
0
/*
 * Get memory 
 */
LOCAL void* imalloc( size_t size, IMACB *imacb )
{
	QUEUE	*q;
	VP	mem;
	UW	imask;

	/* If it is smaller than the minimum fragment size,
	   allocate the minimum size to it. */
	if ( size < MIN_FRAGMENT ) {
		size = MIN_FRAGMENT;
	}
	size = ROUND(size);

	DI(imask);  /* Exclusive control by interrupt disable */
	SpinLock(&MemLockObj);

	/* Search FreeQue */
	q = searchFreeArea(size, imacb);
	if ( q != &imacb->freeque ) {
		/* There is free area: Split from FreeQue once */
		removeFreeQue(q);

		q = q - 1;
	} else {
		/* Reserve new pages because there is no free space */
		QUEUE	*e;
		size_t	n;

		/* Reserve pages */
		SpinUnlock(&MemLockObj);
		EI(imask);
		n = PageCount(size + sizeof(QUEUE) * 2);
		q = GetSysMemBlk(n, imacb->mematr);
		if ( q == NULL ) {
			goto err_ret;  /* Insufficient memory */
		}
		DI(imask);
		SpinLock(&MemLockObj);

		/* Register on AreaQue */
		e = (QUEUE*)((VB*)q + n * pagesz) - 1;
		insertAreaQue(&imacb->areaque, e);
		insertAreaQue(&imacb->areaque, q);
		setAreaFlag(q, AREA_TOP);
		setAreaFlag(e, AREA_END);
	}

	/* Allocate memory */
	mem = mem_alloc(q, size, imacb);

	SpinUnlock(&MemLockObj);
	EI(imask);
	return mem;

err_ret:
	BMS_DEBUG_PRINT(("imalloc error\n"));
	return NULL;
}
Exemplo n.º 2
0
/*
 * Memory map
 *	When paddr is NULL, allocate len bytes of memory having contiguous physical address,
 *	and returns the logical address to *laddr.
 *	When paddr is not NULL, map len bytes of physical memory from paddr and returns 
 *	the logical address to *laddr.
 *
 *	N.B. Access to *laddr may cause page fault.
 */
LOCAL ER _MapMemory( CONST void *paddr, INT len, UINT attr, void **laddr )
{
	ER	ercd;
	UINT	a;

	if ( len <= 0 ) {
		ercd = E_PAR;
		goto err_ret;
	}

	a = ( (attr & MM_USER) != 0 )? TA_RNG3: TA_RNG0;
	if ( (attr & MM_CDIS) != 0 ) {
		a |= TA_NOCACHE;
	}

	if ( paddr == NULL ) {
		/* Allocate memory automatically */
		*laddr = GetSysMemBlk((INT)smPageCount((UW)len), a);
		if ( *laddr == NULL ) {
			ercd = E_NOMEM;
			goto err_ret;
		}

		/* Set memory access privilege */
		ercd = _SetMemoryAccess(*laddr, len, (attr & (MM_READ|MM_WRITE|MM_EXECUTE)));
		if ( ercd < E_OK ) {
			RelSysMemBlk(*laddr);
			*laddr = NULL;
			goto err_ret;
		}

	} else {
		/* Logical address conversion */
		*laddr = toLogicalAddress(paddr);

		/* Flush cache */
		FlushCache(*laddr, len);

		if ( (attr & MM_CDIS) != 0 ) {
			/* Allocate logical addresses for cache off area */
			*laddr = toNoCacheLogicalAddress(*laddr);
		}
	}

	return E_OK;

err_ret:
#ifdef DEBUG
	TM_DEBUG_PRINT(("_MapMemory ercd = %d\n", ercd));
#endif
	return ercd;
}
Exemplo n.º 3
0
/*
 * Memory map
 *	Cache control required, but cache control by page cannot be
 *	provided without MMU (except for certain machines), so not implemented.
 */
LOCAL ER _MapMemory( VP paddr, INT len, UINT attr, VP *laddr )
{
	ER	ercd;

	if ( len <= 0 ) {
		ercd = E_PAR;
		goto err_ret;
	}

	if ( paddr == NULL ) {
		UINT a = ( (attr & MM_USER) != 0 )? TA_RNG3: TA_RNGS;
		if ( (attr & MM_CDIS) != 0 ) {
			a |= TA_NOCACHE;
		}

		/* Allocate memory automatically */
		*laddr = GetSysMemBlk((INT)smPageCount((UW)len), a);
		if ( *laddr == NULL ) {
			ercd = E_NOMEM;
			goto err_ret;
		}

	} else {
		/* Logical address conversion */
		*laddr = toLogicalAddress(paddr);

		/* Flush cache */
		FlushCache(*laddr, len);

		if ( (attr & MM_CDIS) != 0 ) {
			/* Allocate logical addresses for cache off area */
			*laddr = toNoCacheLogicalAddress(*laddr);
		}
	}

	return E_OK;

err_ret:
	DEBUG_PRINT(("_MapMemory ercd = %d\n", ercd));
	return ercd;
}