FreeBSD/sys/i386/i386/i686_mem.c
/*
 * Modify/add a variable MTRR to satisfy the request.
 *
 * XXX needs to be updated to properly support "busy" ranges.
 */
Modify/add a variable MTRR to satisfy the request.
XXX needs to be updated to properly support "busy" ranges.
Modify / add a variable MTRR to satisfy the request . XXX needs to be updated to properly support " busy " ranges .
static int
i686_mrsetvariable(struct mem_range_softc *sc, struct mem_range_desc *mrd,
    int *arg)
{
	struct mem_range_desc *curr_md, *free_md;
	int i;
	i = (sc->mr_cap & MR686_FIXMTRR) ? MTRR_N64K + MTRR_N16K + MTRR_N4K : 0;
	curr_md = sc->mr_desc + i;
	free_md = NULL;
	for (; i < sc->mr_ndesc; i++, curr_md++) {
		if (curr_md->mr_flags & MDF_ACTIVE) {
			if ((curr_md->mr_base == mrd->mr_base) &&
			    (curr_md->mr_len == mrd->mr_len)) {
				if (curr_md->mr_flags & MDF_BUSY)
					return (EBUSY);
				if (!(mrd->mr_flags & MDF_FORCE) &&
				    ((curr_md->mr_flags & MDF_ATTRMASK) ==
				    MDF_UNKNOWN))
					return (EACCES);
				free_md = curr_md;
				break;
			}
			if (mroverlap(curr_md, mrd)) {
				if (i686_mtrrconflict(curr_md->mr_flags,
				    mrd->mr_flags))
					return (EINVAL);
			}
		} else if (free_md == NULL) {
			free_md = curr_md;
		}
	}
	if (free_md == NULL)
		return (ENOSPC);
	free_md->mr_base = mrd->mr_base;
	free_md->mr_len = mrd->mr_len;
	free_md->mr_flags = mrcopyflags(MDF_ACTIVE, mrd->mr_flags);
	bcopy(mrd->mr_owner, free_md->mr_owner, sizeof(mrd->mr_owner));
	return (0);
}
static int i686_mrsetvariable ( struct mem_range_softc * sc , struct mem_range_desc * mrd , int * arg ) { struct mem_range_desc * curr_md , * free_md ; int i ; i = ( sc -> mr_cap & MR686_FIXMTRR ) ? MTRR_N64K + MTRR_N16K + MTRR_N4K : 0 ; curr_md = sc -> mr_desc + i ; free_md = NULL ; for ( ; i < sc -> mr_ndesc ; i ++ , curr_md ++ ) { if ( curr_md -> mr_flags & MDF_ACTIVE ) { if ( ( curr_md -> mr_base == mrd -> mr_base ) && ( curr_md -> mr_len == mrd -> mr_len ) ) { if ( curr_md -> mr_flags & MDF_BUSY ) return ( EBUSY ) ; if ( ! ( mrd -> mr_flags & MDF_FORCE ) && ( ( curr_md -> mr_flags & MDF_ATTRMASK ) == MDF_UNKNOWN ) ) return ( EACCES ) ; free_md = curr_md ; break ; } if ( mroverlap ( curr_md , mrd ) ) { if ( i686_mtrrconflict ( curr_md -> mr_flags , mrd -> mr_flags ) ) return ( EINVAL ) ; } } else if ( free_md == NULL ) { free_md = curr_md ; } } if ( free_md == NULL ) return ( ENOSPC ) ; free_md -> mr_base = mrd -> mr_base ; free_md -> mr_len = mrd -> mr_len ; free_md -> mr_flags = mrcopyflags ( MDF_ACTIVE , mrd -> mr_flags ) ; bcopy ( mrd -> mr_owner , free_md -> mr_owner , sizeof ( mrd -> mr_owner ) ) ; return ( 0 ) ; }
Modify/add a variable MTRR to satisfy the request.
Modify / add a variable MTRR to satisfy the request .
/*
	 * Scan the currently active variable descriptors, look for
	 * one we exactly match (straight takeover) and for possible
	 * accidental overlaps.
	 *
	 * Keep track of the first empty variable descriptor in case
	 * we can't perform a takeover.
	 */ /* Exact match? */ /* Whoops, owned by someone. */ /* Check that we aren't doing something risky */ /* Ok, just hijack this entry. */ /* Non-exact overlap? */ /* Between conflicting region types? */ /* Got somewhere to put it? */ /* Set up new descriptor. */