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

📄 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_vr4131.c (libtk/VR4131) * *	PCI device access sequence */#include <basic.h>#include <libstr.h>#include <tk/syslib.h>#include <tm/tmonitor.h>#include "pci.h"/* PCI configuration information */LOCAL	PciInfo	*pciInfo = NULL;/* PCI configuration address definition */#define	CADDR(bus, dev, func)	(((bus) << 8) | ((dev) << 3) | (func))#define	BUSNO(caddr)		(((caddr) >> 8) & 0xff)#define	DEVNO(caddr)		(((caddr) >> 3) & 0x1f)#define	FUNCNO(caddr)		((caddr) & 0x07)/* PCI bus number definition *//* *  The PCI bus number/Bus#0 device number is defined as follows. * *  Host *  | *  | Bus #0(used by virtual objects and PCI bridge) *  | *  +----Device #2(PCI bridge) *  | *  | Bus #2 (for PCI devices) *  | *  +---- Device #a *  +---- Device #b *  +---- Device #c */#define	PCI_BRIDGE	0#define	PCI_IOPCI	1#define	PCI_EXTPCI	2/* VR4131 definitions */#define	IO_START	0xaf000000#define	PCIMMAW1REG	0x0C00	/* Master PCI memory space address				   conversion 1 */#define	PCIMMAW2REG	0x0C04	/* Master PCI memory space address				   conversion 2 */#define	PCITAW1REG	0x0C08	/* Target internal memory space				   conversion 1 */#define	PCITAW2REG	0x0C0C	/* Target internal memory space				   conversion 2 */#define	PCIMIOAWREG	0x0C10	/* Master PCI I/O space address				   conversion */#define	PCICONFDREG	0x0C14	/* Configuration address */#define	PCICONFAREG	0x0C18	/* Configuration data */#define	PCIMAILREG	0x0C1C	/* For mailbox use */#define	BUSERRADREG	0x0C24	/* Store bus/error generation address */#define	INTCNTSTAREG	0x0C28	/* Display interrupt status and control */#define	PCIEXACCREG	0x0C2C	/* Display exclusive access and control */#define	PCIRECONTREG	0x0C30	/* Retry/count */#define	PCIENREG	0x0C34	/* Finish configuration setting */#define	PCICLKSELREG	0x0C38	/* Select PCI bus action clock */#define	PCITRDYVREG	0x0C3C	/* Set TRDY signal */#define	PCICLKRUNREG	0x0C60	/* Set CLKRUN signal */#define	VENDORIDREG	0x0D00	/* Vendor ID */#define	DEVICEIDREG	0x0D00	/* Device ID */#define	COMMANDREG	0x0D04	/* PCI interface set command */#define	STATUSREG	0x0D04	/* PCI interface status */#define	REVIDREG	0x0D08	/* Device revision */#define	CLASSREG	0x0D08	/* Device class */#define	CACHELSREG	0x0D0C	/* System cache line size */#define	LATTIMEREG	0x0D0C	/* Set timer count value */#define	MAILBAREG	0x0D10	/* PCIMAILREG base address */#define	PCIMBA1REG	0x0D14	/* PCI memory space base address 1 */#define	PCIMBA2REG	0x0D18	/* PCI memory space base address 2 */#define	INTLINEREG	0x0D3C	/* PCI interrupt  line */#define	INTPINREG	0x0D3C	/* PCI interrupt terminal */#define	RETVALREG	0x0D40	/* Set retry/limit value */#define	PCIAPCNTREG	0x0D40	/* Select PCI arbitration protocol *//* PDAR input/output */#define	in_pdar_b(idx)		in_b(IO_START + (idx))#define	in_pdar_h(idx)		in_h(IO_START + (idx))#define	in_pdar_w(idx)		in_w(IO_START + (idx))#define	out_pdar_b(idx, dat)	out_b(IO_START + (idx), (dat))#define	out_pdar_h(idx, dat)	out_h(IO_START + (idx), (dat))#define	out_pdar_w(idx, dat)	out_w(IO_START + (idx), (dat))/* PCI configuration register input/output */LOCAL	UW	ioPciConf(W caddr, W reg, W mode, UW dat){  UW	ofs, cfg, msk, sh, idsl, imask;  UW	dt = ~0;  ofs = reg & 0xff;  switch (BUSNO(caddr)) {  case	PCI_BRIDGE:	/* Host-PCI bridge */    DI(imask);    switch (DEVNO(caddr)) {    case	PCI_EXTPCI:      ofs |= VENDORIDREG;      switch (mode) {      case	0x01:	dt = in_pdar_b(ofs);		break;      case	0x02:	dt = in_pdar_h(ofs & ~1);	break;      case	0x03:	dt = in_pdar_w(ofs & ~3);	break;      case	0x11:	out_pdar_b(ofs, dat);		break;      case	0x12:	out_pdar_h(ofs & ~1, dat);	break;      case	0x14:	out_pdar_w(ofs & ~3, dat);	break;      }    }    EI(imask);    return dt;  case	PCI_IOPCI:	/* Internal PCI device (does not exist) */    cfg = 0;    break;  case	PCI_EXTPCI:	/* External PCI device */    idsl = (((UW)0x00000800) << DEVNO(caddr)) & 0xfffff800;    cfg = idsl ? (idsl | ((FUNCNO(caddr)) << 8) | (ofs & ~3)) : 0;    break;  default:		/* External PCI device */    cfg = (caddr << 8) | (ofs & ~3) | 1;    break;  }  if (!cfg) return dt;  DI(imask);  out_pdar_w(PCICONFAREG, cfg);  switch (mode) {  default:  case	0x04:	dt = in_pdar_w(PCICONFDREG);    goto fin;  case	0x02:	dt = in_pdar_w(PCICONFDREG);    if (reg & 2) dt >>= 16;    dt &= 0x0000ffff;    goto fin;  case	0x01:	dt = in_pdar_w(PCICONFDREG);    if (reg & 1) dt >>= 8;    if (reg & 2) dt >>= 16;    dt &= 0x000000ff;    goto fin;  case	0x14:	out_pdar_w(PCICONFDREG, 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_pdar_w(PCICONFDREG);  out_pdar_w(PCICONFDREG, ((dat << sh) & msk) | (dt & ~msk)); fin:  EI(imask);  return dt;}/* Input from PCI configuration register (UB: 1 byte) */EXPORT	UB	inPciConfB(W caddr, W reg){  return (UB)ioPciConf(caddr, reg, 0x01, 0);}/* Input from PCI configuration register (UH: 2 byte) */EXPORT	UH	inPciConfH(W caddr, W reg){  return (UH)ioPciConf(caddr, reg, 0x02, 0);}/* Input from PCI configuration register (UW: 4 byte) */EXPORT	UW	inPciConfW(W caddr, W reg){  return (UW)ioPciConf(caddr, reg, 0x04, 0);}/* Output to PCI configuration register (UB: 1 byte) */EXPORT	void	outPciConfB(W caddr, W reg, UW dat){  ioPciConf(caddr, reg, 0x11, dat);}/* Output to PCI configuration register (UH: 2 byte) */EXPORT	void	outPciConfH(W caddr, W reg, UW dat){  ioPciConf(caddr, reg, 0x12, dat);}/* Output to PCI configuration register (UW: 4 byte) */EXPORT	void	outPciConfW(W caddr, W reg, UW dat){  ioPciConf(caddr, reg, 0x14, dat);}/* *	Get PCI configuration space base address/size  *	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 value >= 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;	/* Termination */    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 memory 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 + -