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

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

?? sbus.c

?? microwindows移植到S3C44B0的源碼
?? C
?? 第 1 頁 / 共 3 頁
字號:
/* $Id: sbus.c,v 1.17.2.1 2002/03/03 10:31:56 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一区二区三区免费野_久草精品视频
麻豆极品一区二区三区| 国产一区91精品张津瑜| 欧美精品在欧美一区二区少妇| 亚洲第一综合色| 7777精品伊人久久久大香线蕉 | 一本一本久久a久久精品综合麻豆| 亚洲欧美日韩国产综合在线| 欧美日韩电影一区| 免费高清视频精品| 久久久精品免费网站| aaa亚洲精品| 亚洲一区二区在线观看视频| 日韩免费高清电影| 成人精品国产免费网站| 亚洲二区在线观看| 精品成人一区二区三区四区| 成人99免费视频| 色综合天天综合网国产成人综合天 | 黑人巨大精品欧美一区| 国产日韩欧美制服另类| 日本韩国欧美一区| 蜜桃91丨九色丨蝌蚪91桃色| 国产日韩精品一区| 欧美性色aⅴ视频一区日韩精品| 日韩精品欧美精品| 国产亚洲成年网址在线观看| 在线观看免费亚洲| 国产在线观看一区二区| 亚洲欧美激情小说另类| 日韩欧美二区三区| 91蜜桃视频在线| 日本亚洲最大的色成网站www| 国产亚洲欧美中文| 欧美午夜精品一区二区三区| 激情文学综合插| 一区二区三区产品免费精品久久75| 欧美一区二区三区不卡| 成人av中文字幕| 三级久久三级久久| 国产精品高潮呻吟久久| 日韩欧美aaaaaa| 91国产精品成人| 国产精品一区免费视频| 亚洲国产成人高清精品| 欧美韩国日本不卡| 欧美一卡2卡3卡4卡| va亚洲va日韩不卡在线观看| 免费成人在线网站| 亚洲免费观看高清| 久久久久久99久久久精品网站| 欧美性猛交xxxx黑人交| 成人一级黄色片| 日本成人在线看| 一区二区三区在线看| 久久久久久久一区| 制服.丝袜.亚洲.中文.综合| 91老司机福利 在线| 国产精品一区二区在线观看不卡 | 亚洲国产精品一区二区www在线| 国产亚洲美州欧州综合国| 91精品久久久久久久久99蜜臂| 播五月开心婷婷综合| 国内一区二区在线| 视频一区二区中文字幕| 亚洲人精品午夜| 中文字幕av一区二区三区| 精品免费视频.| 这里只有精品免费| 久久久久99精品国产片| 青青草97国产精品免费观看| 亚洲精品亚洲人成人网| 久久精品视频免费观看| 欧美精品电影在线播放| 日本精品一区二区三区四区的功能| 国产精品一区免费在线观看| 久久精品国产77777蜜臀| 性欧美疯狂xxxxbbbb| 亚洲激情中文1区| 亚洲欧美一区二区在线观看| 久久久精品国产免大香伊| 欧美成人福利视频| 欧美一级在线观看| 欧美一区中文字幕| 欧美日本一区二区| 欧美日韩小视频| 欧洲一区二区三区免费视频| av不卡免费在线观看| 成人激情免费网站| 国产成人日日夜夜| 国产91对白在线观看九色| 国产在线精品国自产拍免费| 激情五月播播久久久精品| 精品亚洲成av人在线观看| 日本中文一区二区三区| 日韩在线卡一卡二| 日本最新不卡在线| 日本va欧美va精品发布| 日韩电影在线一区| 日韩电影免费在线看| 免费在线成人网| 日韩精品久久理论片| 日韩精品电影一区亚洲| 婷婷久久综合九色综合伊人色| 性久久久久久久久久久久| 亚洲va欧美va人人爽| 亚洲va韩国va欧美va| 亚洲国产成人91porn| 三级成人在线视频| 蜜桃一区二区三区四区| 精品一区二区在线免费观看| 韩国视频一区二区| 国产一区二区三区最好精华液| 国产一区二区三区香蕉| 丁香天五香天堂综合| 成人丝袜18视频在线观看| 99综合电影在线视频| 在线看日本不卡| 欧美日韩国产成人在线免费| 欧美一区二区视频免费观看| 日韩欧美视频一区| 久久色成人在线| 国产精品午夜久久| 亚洲男人的天堂在线aⅴ视频| 一区二区三区不卡在线观看| 偷拍亚洲欧洲综合| 另类专区欧美蜜桃臀第一页| 国产美女在线精品| 成人激情免费网站| 在线观看国产日韩| 3d动漫精品啪啪一区二区竹菊| 精品国产一区a| 中文字幕国产一区| 亚洲男人电影天堂| 日本成人中文字幕在线视频| 国产麻豆精品视频| 91丝袜国产在线播放| 欧美日韩视频在线第一区 | 91视频91自| 欧美日韩国产一二三| 亚洲精品一区二区三区影院 | 欧美国产综合色视频| 亚洲美女电影在线| 日韩电影网1区2区| 国产91精品露脸国语对白| 色狠狠一区二区| 欧美一区二区三区视频免费| 日本一区免费视频| 亚洲一区二区三区不卡国产欧美| 蜜臀久久久久久久| 成人在线视频一区| 欧美揉bbbbb揉bbbbb| www国产成人免费观看视频 深夜成人网| 国产日韩欧美综合在线| 亚洲一区二区三区中文字幕在线| 麻豆一区二区三| 91丨porny丨最新| 日韩一级精品视频在线观看| 欧美激情综合五月色丁香小说| 亚洲午夜精品网| 国产一区二区在线看| 色猫猫国产区一区二在线视频| 欧美成人一区二区| 亚洲视频1区2区| 久久精品国产亚洲5555| 99久久精品免费看国产免费软件| 这里是久久伊人| 亚洲欧洲在线观看av| 日本欧美在线看| 99久久精品免费观看| 欧美videos大乳护士334| 亚洲欧美另类小说视频| 精品亚洲成a人| 欧美三级在线播放| 中文字幕第一页久久| 人人狠狠综合久久亚洲| 91在线云播放| 精品99999| 婷婷亚洲久悠悠色悠在线播放| 成人app下载| 精品国产三级电影在线观看| 亚洲在线视频免费观看| 风流少妇一区二区| 制服丝袜中文字幕一区| 亚洲欧美经典视频| 国产高清亚洲一区| 日韩一区二区免费高清| 亚洲精品乱码久久久久| 国产精品综合久久| 欧美精选午夜久久久乱码6080| 国产精品久久久久久久蜜臀| 极品瑜伽女神91| 欧美日产国产精品| 成人欧美一区二区三区| 国产精品夜夜爽| 日韩一二三区不卡| 亚洲成a人片在线不卡一二三区| 成人国产免费视频| 欧美精品一区在线观看| 琪琪一区二区三区| 欧美日韩国产大片|