亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? sbus.c

?? ARM8008光盤linux-kernel
?? C
?? 第 1 頁 / 共 3 頁
字號:
/* $Id: sbus.c,v 1.17 2001/10/09 02:24:33 davem Exp $ * sbus.c: UltraSparc SBUS controller support. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) */#include <linux/kernel.h>#include <linux/types.h>#include <linux/mm.h>#include <linux/spinlock.h>#include <linux/slab.h>#include <linux/init.h>#include <asm/page.h>#include <asm/sbus.h>#include <asm/io.h>#include <asm/upa.h>#include <asm/cache.h>#include <asm/dma.h>#include <asm/irq.h>#include <asm/starfire.h>#include "iommu_common.h"/* These should be allocated on an SMP_CACHE_BYTES * aligned boundry for optimal performance. * * On SYSIO, using an 8K page size we have 1GB of SBUS * DMA space mapped.  We divide this space into equally * sized clusters.  Currently we allow clusters up to a * size of 1MB.  If anything begins to generate DMA * mapping requests larger than this we will need to * increase things a bit. */#define NCLUSTERS	8UL#define ONE_GIG		(1UL * 1024UL * 1024UL * 1024UL)#define CLUSTER_SIZE	(ONE_GIG / NCLUSTERS)#define CLUSTER_MASK	(CLUSTER_SIZE - 1)#define CLUSTER_NPAGES	(CLUSTER_SIZE >> IO_PAGE_SHIFT)#define MAP_BASE	((u32)0xc0000000)struct sbus_iommu {/*0x00*/spinlock_t		lock;/*0x08*/iopte_t			*page_table;/*0x10*/unsigned long		strbuf_regs;/*0x18*/unsigned long		iommu_regs;/*0x20*/unsigned long		sbus_control_reg;/*0x28*/volatile unsigned long	strbuf_flushflag;	/* If NCLUSTERS is ever decresed to 4 or lower,	 * you must increase the size of the type of	 * these counters.  You have been duly warned. -DaveM	 *//*0x30*/struct {		u16	next;		u16	flush;	} alloc_info[NCLUSTERS];	/* The lowest used consistent mapping entry.  Since	 * we allocate consistent maps out of cluster 0 this	 * is relative to the beginning of closter 0.	 *//*0x50*/u32		lowest_consistent_map;};/* Offsets from iommu_regs */#define SYSIO_IOMMUREG_BASE	0x2400UL#define IOMMU_CONTROL	(0x2400UL - 0x2400UL)	/* IOMMU control register */#define IOMMU_TSBBASE	(0x2408UL - 0x2400UL)	/* TSB base address register */#define IOMMU_FLUSH	(0x2410UL - 0x2400UL)	/* IOMMU flush register */#define IOMMU_VADIAG	(0x4400UL - 0x2400UL)	/* SBUS virtual address diagnostic */#define IOMMU_TAGCMP	(0x4408UL - 0x2400UL)	/* TLB tag compare diagnostics */#define IOMMU_LRUDIAG	(0x4500UL - 0x2400UL)	/* IOMMU LRU queue diagnostics */#define IOMMU_TAGDIAG	(0x4580UL - 0x2400UL)	/* TLB tag diagnostics */#define IOMMU_DRAMDIAG	(0x4600UL - 0x2400UL)	/* TLB data RAM diagnostics */#define IOMMU_DRAM_VALID	(1UL << 30UL)static void __iommu_flushall(struct sbus_iommu *iommu){	unsigned long tag = iommu->iommu_regs + IOMMU_TAGDIAG;	int entry;	for (entry = 0; entry < 16; entry++) {		upa_writeq(0, tag);		tag += 8UL;	}	upa_readq(iommu->sbus_control_reg);	for (entry = 0; entry < NCLUSTERS; entry++) {		iommu->alloc_info[entry].flush =			iommu->alloc_info[entry].next;	}}static void iommu_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages){	while (npages--)		upa_writeq(base + (npages << IO_PAGE_SHIFT),			   iommu->iommu_regs + IOMMU_FLUSH);	upa_readq(iommu->sbus_control_reg);}/* Offsets from strbuf_regs */#define SYSIO_STRBUFREG_BASE	0x2800UL#define STRBUF_CONTROL	(0x2800UL - 0x2800UL)	/* Control */#define STRBUF_PFLUSH	(0x2808UL - 0x2800UL)	/* Page flush/invalidate */#define STRBUF_FSYNC	(0x2810UL - 0x2800UL)	/* Flush synchronization */#define STRBUF_DRAMDIAG	(0x5000UL - 0x2800UL)	/* data RAM diagnostic */#define STRBUF_ERRDIAG	(0x5400UL - 0x2800UL)	/* error status diagnostics */#define STRBUF_PTAGDIAG	(0x5800UL - 0x2800UL)	/* Page tag diagnostics */#define STRBUF_LTAGDIAG	(0x5900UL - 0x2800UL)	/* Line tag diagnostics */#define STRBUF_TAG_VALID	0x02ULstatic void strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages){	iommu->strbuf_flushflag = 0UL;	while (npages--)		upa_writeq(base + (npages << IO_PAGE_SHIFT),			   iommu->strbuf_regs + STRBUF_PFLUSH);	/* Whoopee cushion! */	upa_writeq(__pa(&iommu->strbuf_flushflag),		   iommu->strbuf_regs + STRBUF_FSYNC);	upa_readq(iommu->sbus_control_reg);	while (iommu->strbuf_flushflag == 0UL)		membar("#LoadLoad");}static iopte_t *alloc_streaming_cluster(struct sbus_iommu *iommu, unsigned long npages){	iopte_t *iopte, *limit, *first;	unsigned long cnum, ent, flush_point;	cnum = 0;	while ((1UL << cnum) < npages)		cnum++;	iopte  = iommu->page_table + (cnum * CLUSTER_NPAGES);	if (cnum == 0)		limit = (iommu->page_table +			 iommu->lowest_consistent_map);	else		limit = (iopte + CLUSTER_NPAGES);	iopte += ((ent = iommu->alloc_info[cnum].next) << cnum);	flush_point = iommu->alloc_info[cnum].flush;	first = iopte;	for (;;) {		if (iopte_val(*iopte) == 0UL) {			if ((iopte + (1 << cnum)) >= limit)				ent = 0;			else				ent = ent + 1;			iommu->alloc_info[cnum].next = ent;			if (ent == flush_point)				__iommu_flushall(iommu);			break;		}		iopte += (1 << cnum);		ent++;		if (iopte >= limit) {			iopte = (iommu->page_table + (cnum * CLUSTER_NPAGES));			ent = 0;		}		if (ent == flush_point)			__iommu_flushall(iommu);		if (iopte == first)			goto bad;	}	/* I've got your streaming cluster right here buddy boy... */	return iopte;bad:	printk(KERN_EMERG "sbus: alloc_streaming_cluster of npages(%ld) failed!\n",	       npages);	return NULL;}static void free_streaming_cluster(struct sbus_iommu *iommu, u32 base, unsigned long npages){	unsigned long cnum, ent;	iopte_t *iopte;	cnum = 0;	while ((1UL << cnum) < npages)		cnum++;	ent = (base & CLUSTER_MASK) >> (IO_PAGE_SHIFT + cnum);	iopte = iommu->page_table + ((base - MAP_BASE) >> IO_PAGE_SHIFT);	iopte_val(*iopte) = 0UL;	/* If the global flush might not have caught this entry,	 * adjust the flush point such that we will flush before	 * ever trying to reuse it.	 */#define between(X,Y,Z)	(((Z) - (Y)) >= ((X) - (Y)))	if (between(ent, iommu->alloc_info[cnum].next, iommu->alloc_info[cnum].flush))		iommu->alloc_info[cnum].flush = ent;#undef between}/* We allocate consistent mappings from the end of cluster zero. */static iopte_t *alloc_consistent_cluster(struct sbus_iommu *iommu, unsigned long npages){	iopte_t *iopte;	iopte = iommu->page_table + (1 * CLUSTER_NPAGES);	while (iopte > iommu->page_table) {		iopte--;		if (!(iopte_val(*iopte) & IOPTE_VALID)) {			unsigned long tmp = npages;			while (--tmp) {				iopte--;				if (iopte_val(*iopte) & IOPTE_VALID)					break;			}			if (tmp == 0) {				u32 entry = (iopte - iommu->page_table);				if (entry < iommu->lowest_consistent_map)					iommu->lowest_consistent_map = entry;				return iopte;			}		}	}	return NULL;}static void free_consistent_cluster(struct sbus_iommu *iommu, u32 base, unsigned long npages){	iopte_t *iopte = iommu->page_table + ((base - MAP_BASE) >> IO_PAGE_SHIFT);	if ((iopte - iommu->page_table) == iommu->lowest_consistent_map) {		iopte_t *walk = iopte + npages;		iopte_t *limit;		limit = iommu->page_table + CLUSTER_NPAGES;		while (walk < limit) {			if (iopte_val(*walk) != 0UL)				break;			walk++;		}		iommu->lowest_consistent_map =			(walk - iommu->page_table);	}	while (npages--)		*iopte++ = __iopte(0UL);}void *sbus_alloc_consistent(struct sbus_dev *sdev, size_t size, dma_addr_t *dvma_addr){	unsigned long order, first_page, flags;	struct sbus_iommu *iommu;	iopte_t *iopte;	void *ret;	int npages;	if (size <= 0 || sdev == NULL || dvma_addr == NULL)		return NULL;	size = IO_PAGE_ALIGN(size);	order = get_order(size);	if (order >= 10)		return NULL;	first_page = __get_free_pages(GFP_KERNEL, order);	if (first_page == 0UL)		return NULL;	memset((char *)first_page, 0, PAGE_SIZE << order);	iommu = sdev->bus->iommu;	spin_lock_irqsave(&iommu->lock, flags);	iopte = alloc_consistent_cluster(iommu, size >> IO_PAGE_SHIFT);	if (iopte == NULL) {		spin_unlock_irqrestore(&iommu->lock, flags);		free_pages(first_page, order);		return NULL;	}	/* Ok, we're committed at this point. */	*dvma_addr = MAP_BASE +	((iopte - iommu->page_table) << IO_PAGE_SHIFT);	ret = (void *) first_page;	npages = size >> IO_PAGE_SHIFT;	while (npages--) {		*iopte++ = __iopte(IOPTE_VALID | IOPTE_CACHE | IOPTE_WRITE |				   (__pa(first_page) & IOPTE_PAGE));		first_page += IO_PAGE_SIZE;	}	iommu_flush(iommu, *dvma_addr, size >> IO_PAGE_SHIFT);	spin_unlock_irqrestore(&iommu->lock, flags);	return ret;}void sbus_free_consistent(struct sbus_dev *sdev, size_t size, void *cpu, dma_addr_t dvma){	unsigned long order, npages;	struct sbus_iommu *iommu;	if (size <= 0 || sdev == NULL || cpu == NULL)		return;	npages = IO_PAGE_ALIGN(size) >> IO_PAGE_SHIFT;	iommu = sdev->bus->iommu;	spin_lock_irq(&iommu->lock);	free_consistent_cluster(iommu, dvma, npages);	iommu_flush(iommu, dvma, npages);	spin_unlock_irq(&iommu->lock);	order = get_order(size);	if (order < 10)		free_pages((unsigned long)cpu, order);}dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr, size_t size, int dir){	struct sbus_iommu *iommu = sdev->bus->iommu;	unsigned long npages, pbase, flags;	iopte_t *iopte;	u32 dma_base, offset;	unsigned long iopte_bits;	if (dir == SBUS_DMA_NONE)		BUG();	pbase = (unsigned long) ptr;	offset = (u32) (pbase & ~IO_PAGE_MASK);	size = (IO_PAGE_ALIGN(pbase + size) - (pbase & IO_PAGE_MASK));	pbase = (unsigned long) __pa(pbase & IO_PAGE_MASK);	spin_lock_irqsave(&iommu->lock, flags);	npages = size >> IO_PAGE_SHIFT;	iopte = alloc_streaming_cluster(iommu, npages);	if (iopte == NULL)		goto bad;	dma_base = MAP_BASE + ((iopte - iommu->page_table) << IO_PAGE_SHIFT);	npages = size >> IO_PAGE_SHIFT;	iopte_bits = IOPTE_VALID | IOPTE_STBUF | IOPTE_CACHE;	if (dir != SBUS_DMA_TODEVICE)		iopte_bits |= IOPTE_WRITE;	while (npages--) {		*iopte++ = __iopte(iopte_bits | (pbase & IOPTE_PAGE));		pbase += IO_PAGE_SIZE;	}	npages = size >> IO_PAGE_SHIFT;	spin_unlock_irqrestore(&iommu->lock, flags);	return (dma_base | offset);bad:	spin_unlock_irqrestore(&iommu->lock, flags);	BUG();	return 0;}void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t dma_addr, size_t size, int direction){	struct sbus_iommu *iommu = sdev->bus->iommu;	u32 dma_base = dma_addr & IO_PAGE_MASK;	unsigned long flags;	size = (IO_PAGE_ALIGN(dma_addr + size) - dma_base);	spin_lock_irqsave(&iommu->lock, flags);	free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT);	strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT);	spin_unlock_irqrestore(&iommu->lock, flags);}#define SG_ENT_PHYS_ADDRESS(SG)	\	((SG)->address ? \	 __pa((SG)->address) : \	 (__pa(page_address((SG)->page)) + (SG)->offset))static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg, int nused, int nelems, unsigned long iopte_bits){	struct scatterlist *dma_sg = sg;	struct scatterlist *sg_end = sg + nelems;	int i;	for (i = 0; i < nused; i++) {		unsigned long pteval = ~0UL;		u32 dma_npages;		dma_npages = ((dma_sg->dma_address & (IO_PAGE_SIZE - 1UL)) +			      dma_sg->dma_length +			      ((IO_PAGE_SIZE - 1UL))) >> IO_PAGE_SHIFT;		do {			unsigned long offset;			signed int len;

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
一区二区三区在线观看视频 | 久久精品视频一区二区| 欧美激情在线一区二区三区| 日韩av二区在线播放| 欧美精品一二三| 一级中文字幕一区二区| 91久久久免费一区二区| 一区二区三区视频在线看| 在线播放一区二区三区| 国产河南妇女毛片精品久久久| 一区二区三区免费在线观看| 婷婷一区二区三区| 欧美高清在线精品一区| 国产在线看一区| 久久影院午夜片一区| 成人av资源下载| 99国产欧美久久久精品| 中文字幕一区二区三中文字幕| 99久久精品费精品国产一区二区| 久久综合狠狠综合| 色偷偷久久人人79超碰人人澡| 日韩中文字幕一区二区三区| 亚洲国产精品成人综合 | 精品女同一区二区| 午夜精品一区二区三区电影天堂 | 国产精品青草久久| 成人高清视频免费观看| 精品欧美久久久| 亚洲成av人影院| 国产欧美一区视频| 欧美久久高跟鞋激| 国产麻豆精品theporn| 亚洲午夜在线观看视频在线| 精品成人一区二区三区| 99精品视频在线免费观看| 午夜在线成人av| 国产午夜亚洲精品理论片色戒| 91精品一区二区三区在线观看| 国产精品亚洲а∨天堂免在线| 亚洲一区二区三区自拍| 久久久久久久久一| 欧美日韩国产天堂| 色综合天天性综合| 国产精品系列在线播放| 九色综合国产一区二区三区| 亚洲综合一区在线| 亚洲日本丝袜连裤袜办公室| 国产喷白浆一区二区三区| 精品少妇一区二区三区日产乱码 | 91浏览器入口在线观看| 国产综合久久久久影院| 日韩1区2区日韩1区2区| 亚洲va国产天堂va久久en| 亚洲免费av高清| 亚洲蜜臀av乱码久久精品蜜桃| 亚洲欧洲日韩女同| 国产精品卡一卡二| 国产精品美女久久久久久2018| 中文欧美字幕免费| 亚洲国产成人一区二区三区| 欧美激情一二三区| 日本一区二区不卡视频| 精品日韩在线观看| 91精品国产麻豆| 欧美一区二区三区在线视频| 欧美喷潮久久久xxxxx| 色综合婷婷久久| 色屁屁一区二区| 欧美色成人综合| 69av一区二区三区| 欧美变态凌虐bdsm| 国产亚洲精品中文字幕| 中国av一区二区三区| 亚洲手机成人高清视频| 一区二区三区四区五区视频在线观看| 亚洲美女精品一区| 五月天精品一区二区三区| 日韩av中文字幕一区二区| 麻豆精品精品国产自在97香蕉| 精品一区二区av| 国产馆精品极品| 色综合色综合色综合色综合色综合| 欧洲视频一区二区| 日韩一区和二区| 久久这里只有精品6| 国产精品久久免费看| 一区二区三区四区五区视频在线观看 | 欧洲一区二区av| 欧美日韩午夜影院| 欧美三级电影网站| 欧美最猛性xxxxx直播| 欧美亚洲一区三区| 欧美日韩精品电影| 欧美mv和日韩mv的网站| 国产欧美日韩久久| 国产精品二三区| 一二三区精品福利视频| 亚洲福利一二三区| 丝袜国产日韩另类美女| 国内外精品视频| 成人avav在线| 在线观看亚洲精品| 日本一区二区三区电影| **性色生活片久久毛片| 婷婷开心激情综合| 成人福利视频网站| 欧美精三区欧美精三区| 国产色一区二区| 视频一区二区三区中文字幕| 国产精品一二一区| 91豆麻精品91久久久久久| 久久只精品国产| 亚洲第一福利视频在线| 成人av在线网站| 日韩午夜激情电影| 亚洲手机成人高清视频| 精品一区二区在线视频| 色吧成人激情小说| 国产日韩成人精品| 日韩国产欧美在线观看| 韩国一区二区三区| 欧美日韩免费高清一区色橹橹 | 国产成人小视频| 色综合天天综合网国产成人综合天| 日韩久久精品一区| 一区二区高清在线| 成人午夜伦理影院| 欧美不卡视频一区| 亚洲444eee在线观看| 极品少妇xxxx偷拍精品少妇| 91毛片在线观看| 久久久久国产精品厨房| 性久久久久久久| 韩日av一区二区| 色菇凉天天综合网| 久久免费美女视频| 激情丁香综合五月| 日韩一级片在线观看| 亚洲国产色一区| 91麻豆精品视频| 国产精品成人一区二区艾草| 国产成人免费xxxxxxxx| 欧美精品一区在线观看| 青青草伊人久久| 色欧美片视频在线观看| 亚洲免费视频中文字幕| 成人黄色网址在线观看| 久久久久99精品国产片| 国产在线乱码一区二区三区| 国产网红主播福利一区二区| 精品一区二区影视| 精品国产免费人成在线观看| 男男gaygay亚洲| 日韩视频在线一区二区| 日本伊人精品一区二区三区观看方式 | 经典一区二区三区| 精品欧美一区二区在线观看 | 亚洲综合精品自拍| 在线观看日韩高清av| 亚洲电影视频在线| 欧美自拍偷拍一区| 亚洲国产中文字幕在线视频综合| 成人性生交大片免费看视频在线 | 亚洲自拍与偷拍| 成人丝袜18视频在线观看| 精品国产91亚洲一区二区三区婷婷| 久久精品国产亚洲一区二区三区| 精品国产乱码久久久久久老虎| 狠狠色综合色综合网络| www精品美女久久久tv| 国产精品一区2区| 中文字幕日本不卡| 欧洲激情一区二区| 五月婷婷激情综合| 91精品在线免费观看| 九九久久精品视频| 国产亚洲一区字幕| 99久久99久久精品免费看蜜桃| 一区二区国产视频| 91玉足脚交白嫩脚丫在线播放| 亚洲欧美区自拍先锋| 欧美男男青年gay1069videost| 日韩高清欧美激情| 久久久久国产免费免费| 一本色道久久加勒比精品| 日韩在线一区二区三区| 久久伊人中文字幕| 色婷婷综合中文久久一本| 一区二区视频免费在线观看| 在线播放91灌醉迷j高跟美女| 久久99精品一区二区三区三区| 国产日韩精品视频一区| 成人福利视频在线看| 天堂成人国产精品一区| 久久久精品一品道一区| 色偷偷成人一区二区三区91| 久久爱另类一区二区小说| 国产精品免费视频一区| 欧美日韩一区二区三区四区| 久久99精品一区二区三区三区|