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

📄 pci.c

📁 日本著名的的嵌入式实时操作系统T-Kernel的源码及用户手册。
💻 C
字号:
/* *---------------------------------------------------------------------- *    T-Kernel * *    Copyright (C) 2004 by Ken Sakamura. All rights reserved. *    T-Kernel is distributed under the T-License. *---------------------------------------------------------------------- * *    Version:   1.01.00 *    Released by T-Engine Forum(http://www.t-engine.org) at 2004/6/28. * *---------------------------------------------------------------------- *//* *	@(#)pci.c (libtk/SH7751R) * *	PCI device access sequence  */#include <basic.h>#include <stdio.h>#include <stdlib.h>#include <tk/syslib.h>#include <util/tmonitor.h>#include "pci.h"/* PCI configuration information */LOCAL	PciInfo	*pciInfo = NULL;/* SH7751 definition */#define	PCIPAR	0xfe2001c0#define	PCIPDR	0xfe200220/* PCI configuration register input/output */LOCAL	UW	ioPciConf(W caddr, W reg, W mode, UW dat){	UW	cfg, msk, sh, imask;	UW	dt = ~0;	cfg = (caddr << 8) | (reg & 0xfc) | 0x80000000;	DI(imask);	out_w(PCIPAR, cfg);	switch (mode) {	default:	case	0x04:	dt = in_w(PCIPDR);			goto fin;	case	0x02:	dt = in_w(PCIPDR);			if (reg & 2) dt >>= 16;			dt &= 0x0000ffff;			goto fin;	case	0x01:	dt = in_w(PCIPDR);			if (reg & 1) dt >>= 8;			if (reg & 2) dt >>= 16;			dt &= 0x000000ff;			goto fin;	case	0x14:	out_w(PCIPDR, dat);			goto fin;	case	0x12:	sh = (reg & 2) ? 16 : 0;			msk = 0x0000ffff << sh;			break;	case	0x11:	sh = ((reg & 1) ? 8 : 0) + ((reg & 2) ? 16 : 0);			msk = 0x000000ff << sh;			break;	}	dt = in_w(PCIPDR);	out_w(PCIPAR, cfg);	out_w(PCIPDR, ((dat << sh) & msk) | (dt & ~msk)); fin:	EI(imask);	return dt;}/* Input from PCI configuration register (UB: 1byte) */EXPORT	UB	inPciConfB(W caddr, W reg){	return (UB)ioPciConf(caddr, reg, 0x01, 0);}/* Input from PCI configuration register (UH: 2byte) */EXPORT	UH	inPciConfH(W caddr, W reg){	return (UH)ioPciConf(caddr, reg, 0x02, 0);}/* Input from PCI configuration register (UW: 4byte) */EXPORT	UW	inPciConfW(W caddr, W reg){	return (UW)ioPciConf(caddr, reg, 0x04, 0);}/* Output to PCI configuration register (UB: 1byte) */EXPORT	void	outPciConfB(W caddr, W reg, UW dat){	ioPciConf(caddr, reg, 0x11, dat);}/* Output to PCI configuration register (UH: 2byte) */EXPORT	void	outPciConfH(W caddr, W reg, UW dat){	ioPciConf(caddr, reg, 0x12, dat);}/* Output to PCI configuration register (UW: 4byte) */EXPORT	void	outPciConfW(W caddr, W reg, UW dat){	ioPciConf(caddr, reg, 0x14, dat);}/* *	Get base address/size for PCI configuration space   *	Return value	PTTI	I = 1:I/O address, 0:memory address *			T = 0:32bit, 1:20bit, 2:64bit *			P = 1:prefetch enable */EXPORT	W	getPciBaseAddr(W caddr, W reg, VP *addr, W *size){	UW	imask;	UW	adr, tmp;	W	sz, kind;	/* Write 0xffffffff, then determine size from how far it was	   possible to write  from the top order */	DI(imask);	adr = inPciConfW(caddr, reg);	outPciConfW(caddr, reg, ~0);	tmp = inPciConfW(caddr, reg);	outPciConfW(caddr, reg, adr);	EI(imask);	if (adr & 1) {	/* I/O space */		kind = 1;		tmp &= ~0x03;		adr &= ~0x03;	} else {	/* Memory space */		kind = adr & 0x0f;		tmp &= ~0x0f;		adr &= ~0x0f;	}	if (!tmp) sz = 0;	else for (sz = 1; !(tmp & 1); tmp >>= 1) sz <<= 1;	*addr = (VP)adr;	*size = sz;	return kind;}/* *	PCI device search  * *	vendor	<  0x10000 : vendor, devid device  *		== 0x1ffff : devid number device  *		== 0x1#### : devid number class == #### device  *	Function number	>= 0 : PCI address  *		<  0 : not found  */EXPORT	INT	searchPciDev(W vendor, W devid){	W	i, caddr, class;	class = vendor & 0xffff;	if (!pciInfo) tm_extsvc(0x02, (INT)&pciInfo, 0, 0); 	for (i = 0; ; i++) {		caddr = pciInfo[i].caddr;		if (caddr == 0xffff) break;	/* Terminal */		if (vendor >= 0x10000) {			/* devid in order of appearance (0 - ) */			if (class == 0xffff || pciInfo[i].devclass == class) {				if (devid-- == 0) return caddr;			}		} else {			if (pciInfo[i].vendor == vendor &&			    pciInfo[i].devid  == devid) return caddr;		}	}	return -1;	/* Not found */}/* *	PCI - CPU memory / I/O space address conversion  * *	pciMemToCpuAddr:	Gets CPU memory address  *				corresponding to PCI memory address  *	pciIoToCpuAddr:	Gets CPU I/O address corresponding to PCI I/O space *				(for memory mapped I/O, the CPU memory address *				corresponding to the PCI I/O space) *	cpuAddrToPciMem:	Gets PCI memory address corresponding *				to CPU address */EXPORT	UW	pciMemToCpuAddr(UW pcimem){	UW	cnvaddr;	tm_extsvc(0x03, 0x00, pcimem, (INT)&cnvaddr);	return cnvaddr;}EXPORT	UW	pciIoToCpuAddr(UW pciio){	UW	cnvaddr;	tm_extsvc(0x03, 0x01, pciio, (INT)&cnvaddr);	return cnvaddr;}EXPORT	UW	cpuAddrToPciMem(UW cpuaddr){	UW	cnvaddr;	tm_extsvc(0x03, 0x02, cpuaddr, (INT)&cnvaddr);	return cnvaddr;}

⌨️ 快捷键说明

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