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

📄 fb_sub.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Copyright (c) 1992, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: $Hdr: fb_sub.c,v 4.300 91/06/27 20:43:09 root Rel41 $ SONY * *	@(#)fb_sub.c	8.2 (Berkeley) 9/23/93 */#include "fb.h"#if NFB > 0/* * Frame buffer driver */#include <sys/types.h>#include <machine/pte.h>#include <machine/cpu.h>#include <machine/param.h>#include <sys/param.h>#include <sys/proc.h>#include <sys/user.h>#include <sys/buf.h>#include <vm/vm.h>#include <sys/systm.h>#include <sys/map.h>#include <sys/uio.h>#include <sys/kernel.h>#include <news3400/iop/framebuf.h>#include <news3400/iop/fbreg.h>#ifdef CPU_DOUBLE#ifdef IPC_MRX#include "../ipc/newsipc.h"#ifdef mips#define ipc_phys(x)	K0_TT0(x)#define ipc_log(x)	TT0_K0(x)#else /* mips */#define	ipc_phys(x)	(caddr_t)((int)(x) & ~0x80000000)#define	ipc_log(x)	(caddr_t)((int)(x) | 0x80000000)#endif /* mips */#endif /* IPC_MRX */#else /* CPU_DOUBLE */#define ipc_phys(x)	(caddr_t)((int)(x))#define ipc_log(x)	(caddr_t)((int)(x) | 0x80000000)#endif /* CPU_DOUBLE */#define MAX_FBMAP	3static struct fb_map	fbmap[MAX_FBMAP];/* bitblt type */#define BLTTYPE(ts, td)	((ts) << 2 | (td))static lSrcDest	srcdestlist[MAX_BATCHBITBLT];#define MAX_SIZE	(MAX_BATCHBITBLT * sizeof(lSrcDest))#define ODD_ADDR(x)	(((unsigned)(x))&1)#define MAXMSEG	4static int	segind;static struct memseg {	caddr_t		adrs;	int		len;	int		rw;	caddr_t		oadrs;	int		olen;	struct fb_map	*map;} mseg[MAXMSEG];#define BASE(a)	((int)(a) & ~(NBPG - 1))#ifdef CPU_DOUBLECOPYIN(src, dst, len, seg)	caddr_t src;	caddr_t dst;	int len;	int seg;{	switch (seg) {	case UIO_SYSSPACE:		bcopy(src, dst, len);		return (0);	case UIO_USERSPACE:		return (copyin(src, dst, len));	default:		panic("COPYIN: seg");		/* NOTREACHED */	}}#endif /* CPU_DOUBLE */fbgetmap(addr, len, map)	caddr_t addr;	int len;	struct fb_map *map;{	register struct pte *pte;	register caddr_t *p;	unsigned v;	register int npf;	int o;	v = pmax_btop(addr);	o = (int)addr & PGOFSET;	npf = btoc(len + o);	if (npf > NFBMAP)		return (EINVAL);	map->fm_vaddr = addr;	map->fm_offset = o;	map->fm_count = len;#ifdef CPU_DOUBLE	if (addr >= (caddr_t)KERNBASE) {#ifdef mips		p = map->fm_addr;		if (MACH_IS_CACHED(addr)) {			addr = ptob(v);			while (--npf >= 0) {				*p++ = (caddr_t)K0_TT0(addr);				addr += NBPG;			}			return (0);		}		if (MACH_IS_MAPPED(addr))			pte = kvtopte(addr);		else if (addr >= (caddr_t)&u)			pte = curproc->p_addr + btop(addr - (caddr_t)&u);		else			panic("fbgetmap: bad kernel addr");		while (--npf >= 0)			*p++ = (caddr_t)PHYS_TT0(ptob(pte++->pg_pfnum));#else /* mips */		pte = kvtopte(addr);		p = map->fm_addr;		while (--npf >= 0)			*p++ = (caddr_t)ptob(pte++->pg_pfnum);#endif /* mips */		return (0);	}	pte = vtopte(curproc, v);		/*KU:XXXXXXXXXXXXXXXXXX*/	p = map->fm_addr;	while (--npf >= 0) {		if (pte->pg_pfnum == 0)			panic("iop zero uentry");#ifdef mips		*p++ = (caddr_t)PHYS_TT0(ptob(pte++->pg_pfnum));#else		*p++ = (caddr_t)ptob(pte++->pg_pfnum);#endif	}#endif /* CPU_DOUBLE */	return (0);}fblockmem(ad, len, rw, map, seg)	register caddr_t ad;	register int len;	int rw;	struct fb_map *map;	int seg;{	register struct memseg *msp;	/* validity check */	if (len < 0)		return EFAULT;	else if (len == 0)		return 0;	else if (ad == 0)		return EFAULT;	else if (seg == UIO_USERSPACE &&		 !useracc(ad, len, rw == B_READ ? B_WRITE : B_READ))		return EFAULT;	else if (segind >= MAXMSEG)		return EFAULT;	/* insertion sort */	for (msp = mseg + segind - 1; msp >= mseg; msp--) {		if (msp->adrs > ad)			*(msp + 1) = *msp;		else			break;	}	msp++;#ifdef CPU_SINGLE	switch (seg) {	case UIO_SYSSPACE:		map->fm_vaddr = ad;		map->fm_offset = 0;		break;	case UIO_USERSPACE:		msp->adrs = (caddr_t)BASE(ad);		msp->len = (caddr_t)BASE(ad + len + NBPG - 1) - msp->adrs;		break;	default:		panic("fblockmem: seg");		/* NOTREACHED */	}#else /* CPU_SINGLE */	msp->adrs = (caddr_t)BASE(ad);	msp->len = (caddr_t)BASE(ad + len + NBPG - 1) - msp->adrs;#endif /* CPU_SINGLE */	msp->rw = rw;	msp->oadrs = ad;	msp->olen = len;	msp->map = map;	segind++;	return (0);}fblocksbitmap(bm, rw, map)	register lBitmap *bm;	int rw;	struct fb_map *map;{	register int len;	register int error = 0;	if (bm->depth > 32)		return EINVAL;	if (bm->type == BM_FB || bm->type == BM_0 || bm->type == BM_1)		return 0;	if (bm->type == BM_MEM)		len = bm->width * bm->rect.extent.y * bm->depth * sizeof(Word);	if (len < 0 || len > FB_MAX_IO)		return(EINVAL);	error = fblockmem((caddr_t)(bm->base), len, rw, map, UIO_USERSPACE);	if (error)		return error;	bm->base = (Word *)ipc_phys(map);	return 0;}voidfbinitlock(){	segind = 0;}voidfbdolock(){	register struct memseg *msp0, *msp1, *mspl;	register int i, tlen;	mspl = mseg + segind;	for (msp0 = mseg, msp1 = mseg + 1; msp1 < mspl; msp0++, msp1++) {		if (msp0->adrs + msp0->len > msp1->adrs) {			tlen = msp1->adrs - msp0->adrs + msp1->len;			msp1->adrs = msp0->adrs;			msp1->len = msp0->len > tlen ? msp0->len : tlen;			msp0->len = 0;			msp1->rw = (msp0->rw == B_READ || msp1->rw == B_READ) ?					B_READ : B_WRITE;		}	}	/* lock */	curproc->p_flag |= P_PHYSIO;	for (i = 0; i < segind; i++)		if (mseg[i].len && mseg[i].adrs && mseg[i].adrs		    < (caddr_t)KERNBASE)			vslock(mseg[i].adrs, mseg[i].len);	/* make map */	for (i = 0; i < segind; i++)		fbgetmap(mseg[i].oadrs, mseg[i].olen, mseg[i].map);}voidfbunlock(){	register int i;	int s = splfb();	for (i = 0; i < segind; i++) {		if (mseg[i].len && mseg[i].adrs && mseg[i].adrs		    < (caddr_t)KERNBASE) {			vsunlock(mseg[i].adrs, mseg[i].len, mseg[i].rw);#if defined(mips) && defined(CPU_DOUBLE)			if (mseg[i].rw == B_READ)				clean_kudcache(curproc,					       mseg[i].adrs, mseg[i].len);#endif		}	}	curproc->p_flag &= ~P_PHYSIO;	splx(s);	/* for 'fbinitlock() o wasureru ukkariyasan'... */	segind = 0;}checkbitmap(bm)	register lBitmap *bm;{	if (bm->depth > 32)		return EINVAL;	switch(bm->type) {	case BM_FB:	case BM_0:	case BM_1:		break;	case BM_MEM:		if (ODD_ADDR(bm->base))			return EINVAL;		if (bm->width == 0)			return EINVAL;		if ((bm->width * bm->rect.extent.y) << 1 > FB_MAX_IO)			return EINVAL;		break;	default:		return EINVAL;	}	if (bm->rect.extent.x < 0 || bm->rect.extent.y < 0)		return EINVAL;	else		return 0;}checkdepth(sbm, dbm)	lBitmap	*sbm, *dbm;{	register int ds = sbm->depth;	register int dd = dbm->depth;	if (ds > 1 && dd > 1 && ds != dd)		return -1;	else		return((ds > 1) << 1 | (dd > 1));}dobitblt(fbp, sbm, dbm)	struct fbreg *fbp;	lBitmap	*sbm, *dbm;{	register int error;	if (error = fblocksbitmap(sbm, B_WRITE, fbmap))		return error;	if (error = fblocksbitmap(dbm, B_READ, fbmap + 1))		return error;	fbdolock();	fbstart(fbp, 1);	fbunlock();	/* reset address */	if (sbm->type == BM_MEM)		sbm->base =		    (Word *)((struct fb_map *)ipc_log(sbm->base))->fm_vaddr;	if (dbm->type == BM_MEM)		dbm->base =		    (Word *)((struct fb_map *)ipc_log(dbm->base))->fm_vaddr;	return 0;}fbnbitblt(fbp, cmd)	register struct fbreg *fbp;	register lBitblt *cmd;{	register lBitblt *regcmd;	register int len, lens, lend;	register int i;	int pmask, mode;	int error = 0;	int blttype = BLTTYPE(cmd->srcBitmap.type, cmd->destBitmap.type);#ifdef CPU_DOUBLE	if ((blttype == BLTTYPE(BM_MEM, BM_MEM)) ||	    (blttype == BLTTYPE(BM_0, BM_MEM)) ||	    (blttype == BLTTYPE(BM_1, BM_MEM))) {		return(mfbnbitblt(fbp, cmd));		/* NOTREACHED */	}#endif	fbinitlock();	if (error = checkbitmap(&cmd->srcBitmap))		return error;	if (error = checkbitmap(&cmd->destBitmap))		return error;	if ((mode = checkdepth(&cmd->srcBitmap, &cmd->destBitmap)) < 0)		return EINVAL;	fbp->fb_command = FB_CBITBLT;	fbp->fb_bitblt = *cmd;	regcmd = &fbp->fb_bitblt;	/* process bitblt command */	switch (blttype) {	case BLTTYPE(BM_FB, BM_FB):	case BLTTYPE(BM_0, BM_FB):	case BLTTYPE(BM_1, BM_FB):		fbstart(fbp, 0);		break;	case BLTTYPE(BM_FB, BM_MEM):	case BLTTYPE(BM_0, BM_MEM):	case BLTTYPE(BM_1, BM_MEM):		len = cmd->destBitmap.width * cmd->destBitmap.rect.extent.y << 1;		if (len * cmd->destBitmap.depth <= FB_MAX_IO) {			error = dobitblt(fbp, &regcmd->srcBitmap,					      &regcmd->destBitmap);			return error;		}		/* bitblt each plane */		regcmd->destBitmap.depth = 1;		pmask = regcmd->planemask;		for (i = 0; i < cmd->destBitmap.depth; i++) {			if (mode == 3)	/* N to N */				regcmd->planemask = pmask & (1 << i);			if (error = dobitblt(fbp, &regcmd->srcBitmap,						  &regcmd->destBitmap))				return error;			regcmd->destBitmap.base += len >> 1;			if (mode == 1) {	/* N to N */				regcmd->planemask >>= 1;				regcmd->fore_color >>= 1;				regcmd->aux_color >>= 1;			}		}		break;	case BLTTYPE(BM_MEM, BM_FB):		len = cmd->srcBitmap.width * cmd->srcBitmap.rect.extent.y << 1;		if (len * cmd->srcBitmap.depth <= FB_MAX_IO) {			error = dobitblt(fbp, &regcmd->srcBitmap,					      &regcmd->destBitmap);			return error;		}		/* bitblt each plane */		regcmd->srcBitmap.depth = 1;		pmask = regcmd->planemask;		regcmd->fore_color = 0xff;		regcmd->aux_color = 0;		if (mode == 2) {	/* N to 1 */			for (i = 0; i < cmd->srcBitmap.depth; i++)				if (pmask & (1 << i))					break;			if (i >= cmd->srcBitmap.depth)				return 0;			regcmd->srcBitmap.base += (len >> 1) * i;			error = dobitblt(fbp, &regcmd->srcBitmap,					      &regcmd->destBitmap);			return error;		}		/* else (N to N) */		for (i = 0; i < cmd->srcBitmap.depth; i++) {			regcmd->planemask = pmask & (1 << i);			if (error = dobitblt(fbp, &regcmd->srcBitmap,						  &regcmd->destBitmap))				return error;			regcmd->srcBitmap.base += len >> 1;			regcmd->planemask >>= 1;		}		return 0;	case BLTTYPE(BM_MEM, BM_MEM):		lens = cmd->srcBitmap.width * cmd->srcBitmap.rect.extent.y << 1;		lend = cmd->destBitmap.width * cmd->destBitmap.rect.extent.y << 1;		if (lens * cmd->srcBitmap.depth <= FB_MAX_IO &&		    lend * cmd->destBitmap.depth <= FB_MAX_IO) {			error = dobitblt(fbp, &regcmd->srcBitmap,					      &regcmd->destBitmap);			return error;		}

⌨️ 快捷键说明

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