예제 #1
0
파일: pl310.c 프로젝트: ChristosKa/freebsd
static void
pl310_inv_range(vm_paddr_t start, vm_size_t size)
{

	if ((pl310_softc == NULL) || !pl310_softc->sc_enabled)
		return;

	PL310_LOCK(pl310_softc);
	if (start & g_l2cache_align_mask) {
		size += start & g_l2cache_align_mask;
		start &= ~g_l2cache_align_mask;
	}
	if (size & g_l2cache_align_mask) {
		size &= ~g_l2cache_align_mask;
		size += g_l2cache_line_size;
	}
	while (size > 0) {
		pl310_write4(pl310_softc, PL310_INV_LINE_PA, start);
		start += g_l2cache_line_size;
		size -= g_l2cache_line_size;
	}

	pl310_cache_sync();
	PL310_UNLOCK(pl310_softc);
}
예제 #2
0
static void
pl310_drain_writebuf(void)
{

	if ((pl310_softc == NULL) || !pl310_softc->sc_enabled)
		return;

	PL310_LOCK(pl310_softc);
	pl310_cache_sync();
	PL310_UNLOCK(pl310_softc);
}
예제 #3
0
static void
pl310_wbinv_range(vm_paddr_t start, vm_size_t size)
{

	if ((pl310_softc == NULL) || !pl310_softc->sc_enabled)
		return;

	PL310_LOCK(pl310_softc);
	if (start & g_l2cache_align_mask) {
		size += start & g_l2cache_align_mask;
		start &= ~g_l2cache_align_mask;
	}
	if (size & g_l2cache_align_mask) {
		size &= ~g_l2cache_align_mask;
	   	size += g_l2cache_line_size;
	}


#ifdef PL310_ERRATA_727915
	if (pl310_softc->sc_rtl_revision >= CACHE_ID_RELEASE_r2p0 &&
	    pl310_softc->sc_rtl_revision < CACHE_ID_RELEASE_r3p1)
		platform_pl310_write_debug(pl310_softc, 3);
#endif
	while (size > 0) {
#ifdef PL310_ERRATA_588369
		if (pl310_softc->sc_rtl_revision <= CACHE_ID_RELEASE_r1p0) {
			/*
			 * Errata 588369 says that clean + inv may keep the
			 * cache line if it was clean, the recommanded
			 * workaround is to clean then invalidate the cache
			 * line, with write-back and cache linefill disabled.
			 */
			pl310_write4(pl310_softc, PL310_CLEAN_LINE_PA, start);
			pl310_write4(pl310_softc, PL310_INV_LINE_PA, start);
		} else
#endif
			pl310_write4(pl310_softc, PL310_CLEAN_INV_LINE_PA,
			    start);
		start += g_l2cache_line_size;
		size -= g_l2cache_line_size;
	}
#ifdef PL310_ERRATA_727915
	if (pl310_softc->sc_rtl_revision >= CACHE_ID_RELEASE_r2p0 &&
	    pl310_softc->sc_rtl_revision < CACHE_ID_RELEASE_r3p1)
		platform_pl310_write_debug(pl310_softc, 0);
#endif

	pl310_cache_sync();
	PL310_UNLOCK(pl310_softc);
}
예제 #4
0
static void
pl310_wbinv_all(void)
{

	if ((pl310_softc == NULL) || !pl310_softc->sc_enabled)
		return;

	PL310_LOCK(pl310_softc);
#ifdef PL310_ERRATA_727915
	if (pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r2p0 ||
	    pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r3p0)
		platform_pl310_write_debug(pl310_softc, 3);
#endif
	pl310_write4(pl310_softc, PL310_CLEAN_INV_WAY, g_l2cache_way_mask);
	pl310_wait_background_op(PL310_CLEAN_INV_WAY, g_l2cache_way_mask);
	pl310_cache_sync();
#ifdef PL310_ERRATA_727915
	if (pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r2p0 ||
	    pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r3p0)
		platform_pl310_write_debug(pl310_softc, 0);
#endif
	PL310_UNLOCK(pl310_softc);
}
예제 #5
0
파일: pl310.c 프로젝트: ChristosKa/freebsd
static void
pl310_wbinv_all(void)
{

	if ((pl310_softc == NULL) || !pl310_softc->sc_enabled)
		return;

	PL310_LOCK(pl310_softc);
#ifdef PL310_ERRATA_727915
	if (pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r2p0) {
		int i, j;

		for (i = 0; i < g_ways_assoc; i++) {
			for (j = 0; j < g_way_size / g_l2cache_line_size; j++) {
				pl310_write4(pl310_softc, 
				    PL310_CLEAN_INV_LINE_IDX,
				    (i << 28 | j << 5));
			}
		}
		pl310_cache_sync();
		PL310_UNLOCK(pl310_softc);
		return;

	}
	if (pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r3p0)
		platform_pl310_write_debug(pl310_softc, 3);
#endif
	pl310_write4(pl310_softc, PL310_CLEAN_INV_WAY, g_l2cache_way_mask);
	pl310_wait_background_op(PL310_CLEAN_INV_WAY, g_l2cache_way_mask);
	pl310_cache_sync();
#ifdef PL310_ERRATA_727915
	if (pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r3p0)
		platform_pl310_write_debug(pl310_softc, 0);
#endif
	PL310_UNLOCK(pl310_softc);
}