summaryrefslogtreecommitdiffstats
path: root/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'pci.c')
-rw-r--r--pci.c58
1 files changed, 34 insertions, 24 deletions
diff --git a/pci.c b/pci.c
index e6c2cf6..075a07f 100644
--- a/pci.c
+++ b/pci.c
@@ -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);