plan 9 kernel history: overview | file list | diff list

1995/0725/pc/pci.c (diff list | history)

1995/0721/sys/src/9/pc/pci.c:1,31995/0725/sys/src/9/pc/pci.c:1,7 (short | long | prev | next)
1995/0725    
/* 
 * Trivial PCI configuration code. 
 * Only deals with bus 0, amongst other glaring omissions. 
 */ 
1995/0517    
#include "u.h" 
#include "../port/lib.h" 
#include "mem.h" 
1995/0721/sys/src/9/pc/pci.c:8,131995/0725/sys/src/9/pc/pci.c:12,45
1995/0517    
 
static Lock pcicfglock; 
 
1995/0725    
static int pcicfgmode = -1; 
 
static void 
pcicfginit(int) 
{ 
	/* 
	 * Try to determine which PCI configuration mode is implemented. 
	 * Mode2 uses a byte at 0xCF8 and another at 0xCFA; Mode1 uses 
	 * a DWORD at 0xCF8 and another at 0xCFC and will pass through 
	 * any non-DWORD accesses as normal I/O cycles. There shouldn't be 
	 * a device behind theses addresses so if Mode2 accesses fail try 
	 * for Mode1 (which is preferred, Mode2 is deprecated). 
	 */ 
	outb(PCIcse, 0); 
	if(inb(PCIcse) == 0){ 
		pcicfgmode = 2; 
		return; 
	} 
 
	outl(PCIaddr, 0); 
	if(inl(PCIaddr) == 0){ 
		pcicfgmode = 1; 
		return; 
	} 
 
	pcicfgmode = -1; 
} 
 
1995/0517    
/* 
 * Read a chunk of PCI configuration space. 
 * Assumes arguments are within limits and regno and 
1995/0721/sys/src/9/pc/pci.c:16,371995/0725/sys/src/9/pc/pci.c:48,91
1995/0517    
void 
1995/0721    
pcicfgr(int busno, int devno, int funcno, int regno, void* data, int nbytes) 
1995/0517    
{ 
1995/0721    
	ulong* p; 
1995/0725    
	ulong addr, *p; 
1995/0721    
	int base, len; 
1995/0517    
 
	lock(&pcicfglock); 
	outb(PCIcse, 0x80|((funcno & 0x07)<<1)); 
	outb(PCIforward, busno); 
1995/0725    
	if(pcicfgmode == -1) 
		pcicfginit(busno); 
1995/0517    
 
	base = (0xC000|(devno<<8)) + regno; 
	p = data; 
	for(len = nbytes/sizeof(ulong); len > 0; len--){ 
		*p = inl(base); 
		p++; 
1995/0721    
		base += sizeof(*p); 
1995/0725    
	switch(pcicfgmode){ 
 
	case 1: 
		addr = 0x80000000|((busno & 0xFF)<<16)|((devno & 0x1F)<<11)|((funcno & 0x03)<<8); 
		p = data; 
		for(len = nbytes/sizeof(ulong); len > 0; len--){ 
			outl(PCIaddr, addr|(regno & 0xFF)); 
			*p = inl(PCIdata); 
			p++; 
			regno += sizeof(ulong); 
		} 
	 
		outl(PCIaddr, 0); 
		break; 
 
	case 2: 
		outb(PCIcse, 0x80|((funcno & 0x07)<<1)); 
		outb(PCIforward, busno); 
	 
		base = (0xC000|(devno<<8)) + regno; 
		p = data; 
		for(len = nbytes/sizeof(ulong); len > 0; len--){ 
			*p = inl(base); 
			p++; 
			base += sizeof(*p); 
		} 
	 
		outb(PCIcse, 0); 
		break; 
1995/0517    
	} 
 
	outb(PCIcse, 0x00); 
	unlock(&pcicfglock); 
} 
 
1995/0721/sys/src/9/pc/pci.c:38,591995/0725/sys/src/9/pc/pci.c:92,134
1995/0721    
void 
pcicfgw(int busno, int devno, int funcno, int regno, void* data, int nbytes) 
{ 
	ulong* p; 
1995/0725    
	ulong addr, *p; 
1995/0721    
	int base, len; 
 
	lock(&pcicfglock); 
	outb(PCIcse, 0x80|((funcno & 0x07)<<1)); 
	outb(PCIforward, busno); 
1995/0725    
	if(pcicfgmode == -1) 
		pcicfginit(busno); 
1995/0721    
 
	base = (0xC000|(devno<<8)) + regno; 
	p = data; 
	for(len = nbytes/sizeof(ulong); len > 0; len--){ 
		outl(base, *p); 
		p++; 
		base += sizeof(*p); 
1995/0725    
	switch(pcicfgmode){ 
 
	case 1: 
		addr = 0x80000000|((busno & 0xFF)<<16)|((devno & 0x1F)<<11)|((funcno & 0x03)<<8); 
		p = data; 
		for(len = nbytes/sizeof(ulong); len > 0; len--){ 
			outl(PCIaddr, addr|(regno & 0xFF)); 
			outl(PCIdata, *p); 
			p++; 
			regno += sizeof(ulong); 
		} 
	 
		outl(PCIaddr, 0); 
		break; 
 
	case 2: 
		outb(PCIcse, 0x80|((funcno & 0x07)<<1)); 
		outb(PCIforward, busno); 
	 
		base = (0xC000|(devno<<8)) + regno; 
		p = data; 
		for(len = nbytes/sizeof(ulong); len > 0; len--){ 
			outl(base, *p); 
			p++; 
			base += sizeof(*p); 
		} 
	 
		outb(PCIcse, 0); 
1995/0721    
	} 
 
	outb(PCIcse, 0x00); 
	unlock(&pcicfglock); 
} 
 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)