| 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,3 – 1995/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,13 – 1995/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,37 – 1995/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 |
| |
| 1995/0725 | ulong addr, *p; | |
| 1995/0721 | int base, len; | |
| 1995/0517 | lock(&pcicfglock); | |
| 1995/0725 | if(pcicfgmode == -1) pcicfginit(busno); | |
| 1995/0517 |
| |
| 1995/0721 |
| |
| 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 | } | |
| 1995/0721/sys/src/9/pc/pci.c:38,59 – 1995/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) { | |
| 1995/0725 | ulong addr, *p; | |
| 1995/0721 | int base, len; lock(&pcicfglock); | |
| 1995/0725 | if(pcicfgmode == -1) pcicfginit(busno); | |
| 1995/0721 |
| |
| 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 | } | |