예제 #1
0
void
viking_cache_enable(void)
{
	u_int pcr;

	pcr = lda(SRMMU_PCR, ASI_SRMMU);

	if ((pcr & VIKING_PCR_ICE) == 0) {
		/* I-cache not on; "flash-clear" it now. */
		sta(0x80000000, ASI_ICACHECLR, 0);	/* Unlock */
		sta(0, ASI_ICACHECLR, 0);		/* clear */
	}
	if ((pcr & VIKING_PCR_DCE) == 0) {
		/* D-cache not on: "flash-clear" it. */
		sta(0x80000000, ASI_DCACHECLR, 0);
		sta(0, ASI_DCACHECLR, 0);
	}

	/* Turn on caches via MMU */
	sta(SRMMU_PCR, ASI_SRMMU, pcr | VIKING_PCR_DCE | VIKING_PCR_ICE);

	CACHEINFO.c_enabled = CACHEINFO.dc_enabled = 1;

	/* Now turn on MultiCache if it exists */
	if (cpuinfo.mxcc && CACHEINFO.ec_totalsize > 0) {
		/* Set external cache enable bit in MXCC control register */
		stda(MXCC_CTRLREG, ASI_CONTROL,
		     ldda(MXCC_CTRLREG, ASI_CONTROL) | MXCC_CTRLREG_CE);
		cpuinfo.flags |= CPUFLG_CACHEPAGETABLES; /* Ok to cache PTEs */
		CACHEINFO.ec_enabled = 1;
	}
}
예제 #2
0
/*
 * Switch video mode and clear screen
 */
void
tcx_s24_reset(struct tcx_softc *sc, int depth)
{
	struct rasops_info *ri = &sc->sc_sunfb.sf_ro;
	uint32_t pixel;
	paddr_t dst;
	int n;

	if (depth == 8)
		pixel = TCX_CTL_8_MAPPED | (ri->ri_devcmap[WSCOL_WHITE] & 0xff);
	else
		pixel = TCX_CTL_24_LEVEL | 0xffffff;

	/*
	 * Set the first 32 pixels as white in the intended mode, using the
	 * control plane.
	 */
	dst = sc->sc_cplane;
	for (n = 32; n != 0; n--) {
		sta(dst, ASI_BYPASS, pixel);
		dst += 4;
	}

	/*
	 * Do the remaining pixels: either with the blitter if we can use it,
	 * or continuing manual writes if we can't.
	 */
	if (sc->sc_blit != 0) {
		dst = sc->sc_blit + (32 << 3);
		pixel = ((sc->sc_blit_width - 1) << 24) | 0;
		for (n = sc->sc_sunfb.sf_fbsize - 32; n != 0;
		    n -= sc->sc_blit_width) {
			stda(dst, ASI_BYPASS, pixel);
			dst += sc->sc_blit_width << 3;
		}
	} else {
		/* this relies on video memory being contiguous */
		for (n = sc->sc_sunfb.sf_fbsize - 32; n != 0; n--) {
			sta(dst, ASI_BYPASS, pixel);
			dst += 4;
		}
	}
}
예제 #3
0
/*
 * Perform a stipple operation rop from (x, y) to (x + cnt - 1, y).
 *
 * We probably should honour the stipple alignment property (stipple-align),
 * in case it is different than 32 (1 << 5). However, due to the way
 * the stipple space is accessed, it is not possible to have a stricter
 * alignment requirement, so let's settle for 32. There probably haven't
 * been TCX boards with relaxed alignment rules anyway.
 */
void
tcx_stipple(struct tcx_softc *sc, int x, int y, int cnt, int rop, int bg)
{
	int rx;		/* aligned x */
	int lbcnt;	/* count of untouched pixels on the left */
	int rbcnt;	/* count of untouched pixels on the right */
	uint32_t wmask;	/* write mask */
	uint32_t soffs;	/* stipple offset */
	uint64_t scmd;

	scmd = rop << STIPPLE_ROP_SHIFT;
	scmd |= TCX_CTL_8_MAPPED | bg;	/* pixel bits, here in 8-bit mode */
	scmd <<= 32;

	/*
	 * The first pass needs to align the position to a 32 pixel
	 * boundary, which explains why the loop is a bit unnatural
	 * at first glance.
	 */
	rx = x & ~(32 - 1);
	soffs = sc->sc_stipple + ((y * sc->sc_sunfb.sf_width + rx) << 3);
	lbcnt = x - rx;
	wmask = 0xffffffff >> lbcnt;

	while (cnt != 0) {
		rbcnt = (32 - lbcnt) - cnt;
		if (rbcnt < 0)
			rbcnt = 0;
		if (rbcnt != 0)
			wmask &= ~((1 << rbcnt) - 1);

		stda(soffs, ASI_BYPASS, scmd | wmask);

		cnt -= (32 - lbcnt) - rbcnt;
		soffs += 32 << 3;

		/* further loops are aligned */
		lbcnt = 0;
		wmask = 0xffffffff;
	}
}
예제 #4
0
/*
 * Perform a blit operation, copying the line starting at computed
 * position src to computed position dst, for a length of len pixels.
 */
void
tcx_blit(struct tcx_softc *sc, uint32_t dst, uint32_t src, int len)
{
	int cx;
	uint32_t addr;

	addr = sc->sc_blit + (dst << 3);

	/* do the incomplete chunk first if needed */
	cx = len & (sc->sc_blit_width - 1);
	if (cx == 0)
		cx = sc->sc_blit_width;

	while (len != 0) {
		stda(addr, ASI_BYPASS, ((cx - 1) << 24) | src);
		src += cx;
		addr += cx << 3;
		len -= cx;
		/* and then full steam ahead for the others */
		cx = sc->sc_blit_width;
	}	
}
예제 #5
0
파일: cache.c 프로젝트: MarginC/kame
void
viking_cache_enable()
{
	u_int pcr;

	cache_alias_dist = max(
		CACHEINFO.ic_totalsize / CACHEINFO.ic_associativity,
		CACHEINFO.dc_totalsize / CACHEINFO.dc_associativity);
	cache_alias_bits = (cache_alias_dist - 1) & ~PGOFSET;

	pcr = lda(SRMMU_PCR, ASI_SRMMU);

	if ((pcr & VIKING_PCR_ICE) == 0) {
		/* I-cache not on; "flash-clear" it now. */
		sta(0x80000000, ASI_ICACHECLR, 0);	/* Unlock */
		sta(0, ASI_ICACHECLR, 0);		/* clear */
	}
	if ((pcr & VIKING_PCR_DCE) == 0) {
		/* D-cache not on: "flash-clear" it. */
		sta(0x80000000, ASI_DCACHECLR, 0);
		sta(0, ASI_DCACHECLR, 0);
	}

	/* Turn on caches via MMU */
	sta(SRMMU_PCR, ASI_SRMMU, pcr | VIKING_PCR_DCE | VIKING_PCR_ICE);

	CACHEINFO.c_enabled = CACHEINFO.dc_enabled = 1;

	/* Now turn on MultiCache if it exists */
	if (cpuinfo.mxcc && CACHEINFO.ec_totalsize > 0) {
		/* Multicache controller */
		stda(MXCC_ENABLE_ADDR, ASI_CONTROL,
		     ldda(MXCC_ENABLE_ADDR, ASI_CONTROL) |
		     (u_int64_t)MXCC_ENABLE_BIT);
		cpuinfo.flags |= CPUFLG_CACHEPAGETABLES; /* Ok to cache PTEs */
		CACHEINFO.ec_enabled = 1;
	}
	printf("cache enabled\n");
}
예제 #6
0
int
tcx_putchar(void *cookie, int row, int col, u_int uc, long attr)
{
	struct rasops_info *ri = cookie;
	struct tcx_softc *sc = ri->ri_hw;
	struct wsdisplay_font *font = ri->ri_font;
	int fg, bg, ul;
	int h, x, y;
	uint8_t *fontbits;
	uint32_t fgpattern, bgpattern;

	ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, &ul);
	fg = ri->ri_devcmap[fg] & 0xff;	/* 8 bit palette index */
	bg = ri->ri_devcmap[bg] & 0xff;	/* 8 bit palette index */

	x = ri->ri_xorigin + col * font->fontwidth;
	y = ri->ri_yorigin + row * font->fontheight;

	if (uc == ' ') {
		/* inline tcx_erasecols(cookie, row, col, 1, attr) */
		for (h = font->fontheight; h != 0; y++, h--)
			tcx_stipple(sc, x, y, font->fontwidth, GXcopy,
			    h == 2 && ul != 0 ? fg : bg);
	} else {
		int rx;
		int lbcnt, rbcnt;
		uint32_t soffs;
		uint64_t stmpl, scmd;

		stmpl = (GXcopy << STIPPLE_ROP_SHIFT) | TCX_CTL_8_MAPPED;

		fontbits = (uint8_t *)font->data +
		    (uc - font->firstchar) * ri->ri_fontscale;

		rx = x & ~(32 - 1);
		lbcnt = x - rx;
		rbcnt = (32 - lbcnt) - font->fontwidth; /* may be negative */
		soffs = sc->sc_stipple +
		    ((y * sc->sc_sunfb.sf_width + rx) << 3);

		for (h = font->fontheight; h != 0; y++, h--) {
			if (font->fontwidth <= 8)
				fgpattern = *(uint8_t *)fontbits >>
				    (8 - font->fontwidth);
			else /* if (font->fontwidth <= 16) */
				fgpattern = *(uint16_t *)fontbits >>
				    (16 - font->fontwidth);
			/* see tcx_accel_plug() for the reason why
			   larger font sizes are not supported, yet */
			fontbits += font->stride;

			/* underline */
			if (ul && h == 2)
				fgpattern = 0xffffffff &
				    ((1 << font->fontwidth) - 1);

			bgpattern = ~fgpattern &
			    ((1 << font->fontwidth) - 1);

			/*
			 * We have a pattern of font->fontwidth bits in
			 * the low bits of `fgpattern' and its one-complement
			 * in `bgpattern'. The bgpattern bits need to be
			 * painted with the background colour, while the
			 * fgpattern bits need to be painted with the
			 * foreground colour.
			 *
			 * The particular character cell position might
			 * span two stipple cells, so we have to account
			 * for this.
			 */

			if (rbcnt >= 0) {
				/* everything fits in one stipple cell. */

				/* foreground */
				scmd = (stmpl | fg) << 32;
				stda(soffs, ASI_BYPASS,
				    scmd | (fgpattern << rbcnt));

				/* background */
				scmd = (stmpl | bg) << 32;
				stda(soffs, ASI_BYPASS,
				    scmd | (bgpattern << rbcnt));
			} else {
				/* needs two stipple cells. */

				/* foreground, first stipple cell */
				scmd = (stmpl | fg) << 32;
				stda(soffs, ASI_BYPASS,
				    scmd | (fgpattern >> -rbcnt));

				/* background, first stipple cell */
				scmd = (stmpl | bg) << 32;
				stda(soffs, ASI_BYPASS,
				    scmd | (bgpattern >> -rbcnt));

				/* rotate patterns, relying on 32 bit size */
				fgpattern <<= (32 + rbcnt);
				bgpattern <<= (32 + rbcnt);

				/* foreground, second stipple cell */
				scmd = (stmpl | fg) << 32;
				stda(soffs + (32 << 3), ASI_BYPASS,
				    scmd | fgpattern);

				/* background, second stipple cell */
				scmd = (stmpl | bg) << 32;
				stda(soffs + (32 << 3), ASI_BYPASS,
				    scmd | bgpattern);
			}

			soffs += sc->sc_sunfb.sf_width << 3;
		}
	}