diff options
Diffstat (limited to 'pci.c')
-rw-r--r-- | pci.c | 58 |
1 files changed, 34 insertions, 24 deletions
@@ -3,7 +3,7 @@ * Released under version 2 of the Gnu Public License. * By Chris Brady * ---------------------------------------------------- - * MemTest86+ V4.00 Specific code (GPL V2.0) + * MemTest86+ V5.00 Specific code (GPL V2.0) * By Samuel DEMEULEMEESTER, sdemeule@memtest.org * http://www.x86-secret.com - http://www.memtest.org */ @@ -11,6 +11,8 @@ #include "io.h" #include "pci.h" #include "test.h" +#include "stdint.h" +#include "cpuid.h" #define PCI_CONF_TYPE_NONE 0 #define PCI_CONF_TYPE_1 1 @@ -68,30 +70,36 @@ int pci_conf_write(unsigned bus, unsigned dev, unsigned fn, unsigned reg, unsign { int result; - if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) + if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255 && pci_conf_type != PCI_CONF_TYPE_1)) return -1; result = -1; - switch(pci_conf_type) { - case PCI_CONF_TYPE_1: - outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8); - switch(len) { - case 1: outb(value, 0xCFC + (reg & 3)); result = 0; break; - case 2: outw(value, 0xCFC + (reg & 2)); result = 0; break; - case 4: outl(value, 0xCFC); result = 0; break; - } - break; - case PCI_CONF_TYPE_2: - outb(0xF0 | (fn << 1), 0xCF8); - outb(bus, 0xCFA); - - switch(len) { - case 1: outb(value, PCI_CONF2_ADDRESS(dev, reg)); result = 0; break; - case 2: outw(value, PCI_CONF2_ADDRESS(dev, reg)); result = 0; break; - case 4: outl(value, PCI_CONF2_ADDRESS(dev, reg)); result = 0; break; - } - outb(0, 0xCF8); - break; + + switch(pci_conf_type) + { + case PCI_CONF_TYPE_1: + if(reg < 256){ + outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8); + }else{ + outl(PCI_CONF3_ADDRESS(bus, dev, fn, reg), 0xCF8); + } + switch(len) { + case 1: outb(value, 0xCFC + (reg & 3)); result = 0; break; + case 2: outw(value, 0xCFC + (reg & 2)); result = 0; break; + case 4: outl(value, 0xCFC); result = 0; break; + } + break; + case PCI_CONF_TYPE_2: + outb(0xF0 | (fn << 1), 0xCF8); + outb(bus, 0xCFA); + + switch(len) { + case 1: outb(value, PCI_CONF2_ADDRESS(dev, reg)); result = 0; break; + case 2: outw(value, PCI_CONF2_ADDRESS(dev, reg)); result = 0; break; + case 4: outl(value, PCI_CONF2_ADDRESS(dev, reg)); result = 0; break; + } + outb(0, 0xCF8); + break; } return result; } @@ -120,9 +128,9 @@ static int pci_check_direct(void) unsigned char tmpCFB; unsigned int tmpCF8; - if (cpu_id.vend_id[0] == 'A' && cpu_id.type == 15) { + if (cpu_id.vend_id.char_array[0] == 'A' && cpu_id.vers.bits.family == 0xF) { pci_conf_type = PCI_CONF_TYPE_1; - return 0; + return 0; } else { /* Check if configuration type 1 works. */ pci_conf_type = PCI_CONF_TYPE_1; @@ -138,6 +146,7 @@ static int pci_check_direct(void) outl(tmpCF8, 0xCF8); /* Check if configuration type 2 works. */ + pci_conf_type = PCI_CONF_TYPE_2; outb(0x00, 0xCFB); outb(0x00, 0xCF8); @@ -145,6 +154,7 @@ static int pci_check_direct(void) if (inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00 && (pci_sanity_check() == 0)) { outb(tmpCFB, 0xCFB); return 0; + } outb(tmpCFB, 0xCFB); |