diff options
author | msmith <msmith@FreeBSD.org> | 2000-04-16 20:48:33 +0000 |
---|---|---|
committer | msmith <msmith@FreeBSD.org> | 2000-04-16 20:48:33 +0000 |
commit | 087c82acdb8383ded1820689980c59ee9fab52c6 (patch) | |
tree | 559bc6b745fdd12c5e689a44904bcf714abd567d /sys/i386/pci | |
parent | 9ae9f06eb1d211d712c6ce5cc3d26ac0336230a4 (diff) | |
download | FreeBSD-src-087c82acdb8383ded1820689980c59ee9fab52c6.zip FreeBSD-src-087c82acdb8383ded1820689980c59ee9fab52c6.tar.gz |
Some more i386-only BIOS-friendliness:
- Add support for using the PCI BIOS functions for configuration space
accesses, and make this the default.
- Make PNPBIOS the default (obsoletes the PNPBIOS config option).
- Add two new boot-time tunables to disable each of the above.
Diffstat (limited to 'sys/i386/pci')
-rw-r--r-- | sys/i386/pci/pci_bus.c | 121 | ||||
-rw-r--r-- | sys/i386/pci/pci_cfgreg.c | 121 | ||||
-rw-r--r-- | sys/i386/pci/pci_pir.c | 121 |
3 files changed, 336 insertions, 27 deletions
diff --git a/sys/i386/pci/pci_bus.c b/sys/i386/pci/pci_bus.c index f09c907..a1b399b 100644 --- a/sys/i386/pci/pci_bus.c +++ b/sys/i386/pci/pci_bus.c @@ -36,8 +36,115 @@ #include <pci/pcireg.h> #include <i386/isa/pcibus.h> +#include <machine/segments.h> +#include <machine/pc/bios.h> + static int cfgmech; static int devmax; +static int usebios; + +static int pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes); +static void pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes); +static int pcibios_cfgopen(void); +static int pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes); +static void pcireg_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes); +static int pcireg_cfgopen(void); + +/* read configuration space register */ + +int +pci_cfgread(pcicfgregs *cfg, int reg, int bytes) +{ + return(usebios ? + pcibios_cfgread(cfg, reg, bytes) : + pcireg_cfgread(cfg, reg, bytes)); +} + +/* write configuration space register */ + +void +pci_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +{ + return(usebios ? + pcibios_cfgwrite(cfg, reg, data, bytes) : + pcireg_cfgwrite(cfg, reg, data, bytes)); +} + +/* initialise access to PCI configuration space */ +static int +pci_cfgopen(void) +{ + if (pcibios_cfgopen() != 0) { + usebios = 1; + } else if (pcireg_cfgopen() != 0) { + usebios = 0; + } else { + return(0); + } + return(1); +} + +/* config space access using BIOS functions */ + +static int +pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes) +{ + struct bios_regs args; + + switch(bytes) { + case 1: + args.eax = PCIBIOS_READ_CONFIG_BYTE; + break; + case 2: + args.eax = PCIBIOS_READ_CONFIG_WORD; + break; + case 4: + args.eax = PCIBIOS_READ_CONFIG_DWORD; + break; + default: + return(-1); + } + args.ebx = (cfg->bus << 8) | (cfg->slot << 3) | (cfg->func); + args.edi = reg; + bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)); + /* check call results? */ + return(args.ecx); +} + +static void +pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +{ + struct bios_regs args; + + switch(bytes) { + case 1: + args.eax = PCIBIOS_WRITE_CONFIG_BYTE; + break; + case 2: + args.eax = PCIBIOS_WRITE_CONFIG_WORD; + break; + case 4: + args.eax = PCIBIOS_WRITE_CONFIG_DWORD; + break; + default: + return; + } + args.ebx = (cfg->bus << 8) | (cfg->slot << 3) | (cfg->func); + args.ecx = data; + args.edi = reg; + bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)); +} + +/* determine whether there is a PCI BIOS present */ + +static int +pcibios_cfgopen(void) +{ + /* check for a found entrypoint */ + return(PCIbios.entry != 0); +} + +/* configuration space access using direct register operations */ /* enable configuration space accesses and return data port address */ @@ -86,10 +193,8 @@ pci_cfgdisable(void) } } -/* read configuration space register */ - -int -pci_cfgread(pcicfgregs *cfg, int reg, int bytes) +static int +pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes) { int data = -1; int port; @@ -113,10 +218,8 @@ pci_cfgread(pcicfgregs *cfg, int reg, int bytes) return (data); } -/* write configuration space register */ - -void -pci_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +static void +pcireg_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) { int port; @@ -182,7 +285,7 @@ pci_cfgcheck(int maxdev) } static int -pci_cfgopen(void) +pcireg_cfgopen(void) { unsigned long mode1res,oldval1; unsigned char mode2res,oldval2; diff --git a/sys/i386/pci/pci_cfgreg.c b/sys/i386/pci/pci_cfgreg.c index f09c907..a1b399b 100644 --- a/sys/i386/pci/pci_cfgreg.c +++ b/sys/i386/pci/pci_cfgreg.c @@ -36,8 +36,115 @@ #include <pci/pcireg.h> #include <i386/isa/pcibus.h> +#include <machine/segments.h> +#include <machine/pc/bios.h> + static int cfgmech; static int devmax; +static int usebios; + +static int pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes); +static void pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes); +static int pcibios_cfgopen(void); +static int pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes); +static void pcireg_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes); +static int pcireg_cfgopen(void); + +/* read configuration space register */ + +int +pci_cfgread(pcicfgregs *cfg, int reg, int bytes) +{ + return(usebios ? + pcibios_cfgread(cfg, reg, bytes) : + pcireg_cfgread(cfg, reg, bytes)); +} + +/* write configuration space register */ + +void +pci_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +{ + return(usebios ? + pcibios_cfgwrite(cfg, reg, data, bytes) : + pcireg_cfgwrite(cfg, reg, data, bytes)); +} + +/* initialise access to PCI configuration space */ +static int +pci_cfgopen(void) +{ + if (pcibios_cfgopen() != 0) { + usebios = 1; + } else if (pcireg_cfgopen() != 0) { + usebios = 0; + } else { + return(0); + } + return(1); +} + +/* config space access using BIOS functions */ + +static int +pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes) +{ + struct bios_regs args; + + switch(bytes) { + case 1: + args.eax = PCIBIOS_READ_CONFIG_BYTE; + break; + case 2: + args.eax = PCIBIOS_READ_CONFIG_WORD; + break; + case 4: + args.eax = PCIBIOS_READ_CONFIG_DWORD; + break; + default: + return(-1); + } + args.ebx = (cfg->bus << 8) | (cfg->slot << 3) | (cfg->func); + args.edi = reg; + bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)); + /* check call results? */ + return(args.ecx); +} + +static void +pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +{ + struct bios_regs args; + + switch(bytes) { + case 1: + args.eax = PCIBIOS_WRITE_CONFIG_BYTE; + break; + case 2: + args.eax = PCIBIOS_WRITE_CONFIG_WORD; + break; + case 4: + args.eax = PCIBIOS_WRITE_CONFIG_DWORD; + break; + default: + return; + } + args.ebx = (cfg->bus << 8) | (cfg->slot << 3) | (cfg->func); + args.ecx = data; + args.edi = reg; + bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)); +} + +/* determine whether there is a PCI BIOS present */ + +static int +pcibios_cfgopen(void) +{ + /* check for a found entrypoint */ + return(PCIbios.entry != 0); +} + +/* configuration space access using direct register operations */ /* enable configuration space accesses and return data port address */ @@ -86,10 +193,8 @@ pci_cfgdisable(void) } } -/* read configuration space register */ - -int -pci_cfgread(pcicfgregs *cfg, int reg, int bytes) +static int +pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes) { int data = -1; int port; @@ -113,10 +218,8 @@ pci_cfgread(pcicfgregs *cfg, int reg, int bytes) return (data); } -/* write configuration space register */ - -void -pci_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +static void +pcireg_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) { int port; @@ -182,7 +285,7 @@ pci_cfgcheck(int maxdev) } static int -pci_cfgopen(void) +pcireg_cfgopen(void) { unsigned long mode1res,oldval1; unsigned char mode2res,oldval2; diff --git a/sys/i386/pci/pci_pir.c b/sys/i386/pci/pci_pir.c index f09c907..a1b399b 100644 --- a/sys/i386/pci/pci_pir.c +++ b/sys/i386/pci/pci_pir.c @@ -36,8 +36,115 @@ #include <pci/pcireg.h> #include <i386/isa/pcibus.h> +#include <machine/segments.h> +#include <machine/pc/bios.h> + static int cfgmech; static int devmax; +static int usebios; + +static int pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes); +static void pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes); +static int pcibios_cfgopen(void); +static int pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes); +static void pcireg_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes); +static int pcireg_cfgopen(void); + +/* read configuration space register */ + +int +pci_cfgread(pcicfgregs *cfg, int reg, int bytes) +{ + return(usebios ? + pcibios_cfgread(cfg, reg, bytes) : + pcireg_cfgread(cfg, reg, bytes)); +} + +/* write configuration space register */ + +void +pci_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +{ + return(usebios ? + pcibios_cfgwrite(cfg, reg, data, bytes) : + pcireg_cfgwrite(cfg, reg, data, bytes)); +} + +/* initialise access to PCI configuration space */ +static int +pci_cfgopen(void) +{ + if (pcibios_cfgopen() != 0) { + usebios = 1; + } else if (pcireg_cfgopen() != 0) { + usebios = 0; + } else { + return(0); + } + return(1); +} + +/* config space access using BIOS functions */ + +static int +pcibios_cfgread(pcicfgregs *cfg, int reg, int bytes) +{ + struct bios_regs args; + + switch(bytes) { + case 1: + args.eax = PCIBIOS_READ_CONFIG_BYTE; + break; + case 2: + args.eax = PCIBIOS_READ_CONFIG_WORD; + break; + case 4: + args.eax = PCIBIOS_READ_CONFIG_DWORD; + break; + default: + return(-1); + } + args.ebx = (cfg->bus << 8) | (cfg->slot << 3) | (cfg->func); + args.edi = reg; + bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)); + /* check call results? */ + return(args.ecx); +} + +static void +pcibios_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +{ + struct bios_regs args; + + switch(bytes) { + case 1: + args.eax = PCIBIOS_WRITE_CONFIG_BYTE; + break; + case 2: + args.eax = PCIBIOS_WRITE_CONFIG_WORD; + break; + case 4: + args.eax = PCIBIOS_WRITE_CONFIG_DWORD; + break; + default: + return; + } + args.ebx = (cfg->bus << 8) | (cfg->slot << 3) | (cfg->func); + args.ecx = data; + args.edi = reg; + bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)); +} + +/* determine whether there is a PCI BIOS present */ + +static int +pcibios_cfgopen(void) +{ + /* check for a found entrypoint */ + return(PCIbios.entry != 0); +} + +/* configuration space access using direct register operations */ /* enable configuration space accesses and return data port address */ @@ -86,10 +193,8 @@ pci_cfgdisable(void) } } -/* read configuration space register */ - -int -pci_cfgread(pcicfgregs *cfg, int reg, int bytes) +static int +pcireg_cfgread(pcicfgregs *cfg, int reg, int bytes) { int data = -1; int port; @@ -113,10 +218,8 @@ pci_cfgread(pcicfgregs *cfg, int reg, int bytes) return (data); } -/* write configuration space register */ - -void -pci_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) +static void +pcireg_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes) { int port; @@ -182,7 +285,7 @@ pci_cfgcheck(int maxdev) } static int -pci_cfgopen(void) +pcireg_cfgopen(void) { unsigned long mode1res,oldval1; unsigned char mode2res,oldval2; |