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.
This commit is contained in:
Mike Smith 2000-04-16 20:48:33 +00:00
parent 27322174cd
commit 300451c472
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=59294
15 changed files with 736 additions and 89 deletions

View File

@ -31,8 +31,6 @@
* Code for dealing with the BIOS in x86 PC systems.
*/
#include "opt_pnp.h"
#include "isa.h"
#include <sys/param.h>
@ -79,9 +77,10 @@ bios32_init(void *junk)
struct PnPBIOS_table *pt;
u_int8_t ck, *cv;
int i;
char *p;
/*
* BIOS32 Service Directory
* BIOS32 Service Directory, PCI BIOS
*/
/* look for the signature */
@ -100,10 +99,15 @@ bios32_init(void *junk)
printf("bios32: Entry = 0x%x (%x) Rev = %d Len = %d\n",
sdh->entry, bios32_SDCI, sdh->revision, sdh->len);
}
/* See if there's a PCI BIOS entrypoint here */
PCIbios.ident.id = 0x49435024; /* PCI systems should have this */
if (!bios32_SDlookup(&PCIbios) && bootverbose)
printf("pcibios: PCI BIOS entry at 0x%x\n", PCIbios.entry);
/* Allow user override of PCI BIOS search */
if (((p = getenv("machdep.bios.pci")) == NULL) || strcmp(p, "disable")) {
/* See if there's a PCI BIOS entrypoint here */
PCIbios.ident.id = 0x49435024; /* PCI systems should have this */
if (!bios32_SDlookup(&PCIbios) && bootverbose)
printf("pcibios: PCI BIOS entry at 0x%x+0x%x\n", PCIbios.base, PCIbios.entry);
}
} else {
printf("bios32: Bad BIOS32 Service Directory\n");
}
@ -111,8 +115,11 @@ bios32_init(void *junk)
/*
* PnP BIOS
*
* Allow user override of PnP BIOS search
*/
if ((sigaddr = bios_sigsearch(0, "$PnP", 4, 16, 0)) != 0) {
if ((((p = getenv("machdep.bios.pnp")) == NULL) || strcmp(p, "disable")) &&
((sigaddr = bios_sigsearch(0, "$PnP", 4, 16, 0)) != 0)) {
/* get a virtual pointer to the structure */
pt = (struct PnPBIOS_table *)(uintptr_t)BIOS_PADDRTOVADDR(sigaddr);
@ -166,6 +173,7 @@ bios32_SDlookup(struct bios32_SDentry *ent)
ent->base = args.ebx;
ent->len = args.ecx;
ent->entry = args.edx;
ent->ventry = BIOS_PADDRTOVADDR(ent->base + ent->entry);
return (0); /* all OK */
}
return (1); /* failed */
@ -454,8 +462,6 @@ bios16(struct bios_args *args, char *fmt, ...)
return (i);
}
#ifdef PNPBIOS /* remove conditional later */
/*
* PnP BIOS interface; enumerate devices only known to the system
* BIOS and save information about them for later use.
@ -518,7 +524,7 @@ pnpbios_identify(driver_t *driver, device_t parent)
/* no PnP BIOS information */
if (pt == NULL)
return;
bzero(&args, sizeof(args));
args.seg.code16.base = BIOS_PADDRTOVADDR(pt->pmentrybase);
args.seg.code16.limit = 0xffff; /* XXX ? */
@ -623,5 +629,3 @@ static driver_t pnpbios_driver = {
static devclass_t pnpbios_devclass;
DRIVER_MODULE(pnpbios, isa, pnpbios_driver, pnpbios_devclass, 0, 0);
#endif /* PNPBIOS */

View File

@ -54,6 +54,7 @@ struct bios32_SDentry
u_int32_t base; /* base of service */
u_int32_t len; /* service length */
u_int32_t entry; /* entrypoint offset from base */
vm_offset_t ventry; /* entrypoint in kernel virtual segment */
};
extern int bios32_SDlookup(struct bios32_SDentry *ent);
@ -203,6 +204,16 @@ struct bios_args {
#define PNP_GET_BOOTFIRST "sp", 0x65
#define PNP_SET_BOOTFIRST "sp", 0x66
/*
* PCI BIOS functions
*/
#define PCIBIOS_READ_CONFIG_BYTE 0xb108
#define PCIBIOS_READ_CONFIG_WORD 0xb109
#define PCIBIOS_READ_CONFIG_DWORD 0xb10a
#define PCIBIOS_WRITE_CONFIG_BYTE 0xb10b
#define PCIBIOS_WRITE_CONFIG_WORD 0xb10c
#define PCIBIOS_WRITE_CONFIG_DWORD 0xb10d
extern int bios16(struct bios_args *, char *, ...);
extern int bios16_call(struct bios_regs *, char *);
extern int bios32(struct bios_regs *, u_int, u_short);

View File

@ -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;

View File

@ -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;

View File

@ -246,6 +246,14 @@
set to 0, an interrupt will not be assigned and the
controller will operate in polled mode only.
set machdep.bios.pnp=disable
Disable the use of the PnP BIOS (i386 only)
set machdep.bios.pci=disable
Disable the use of the PCI BIOS (i386 only)
set net.inet.tcp.tcbhashsize=<value> TCBHASHSIZE
Overrides the compile-time set value of TCBHASHSIZE or

View File

@ -1349,7 +1349,6 @@ options NATM #native ATM
#device uart0 at isa? port 0x330 irq 5
# The newpcm driver (use INSTEAD of snd0 and all VOXWARE drivers!).
# Note that motherboard sound devices may require options PNPBIOS.
#
# Supported cards include:
# Creative SoundBlaster ISA PnP/non-PnP
@ -2336,7 +2335,6 @@ options NMBCLUSTERS=1024
#options OLTR_NO_HAWKEYE_MAC
#options OLTR_NO_TMS_MAC
options PANIC_REBOOT_WAIT_TIME=16
options PNPBIOS
options PSM_DEBUG=1
options SCSI_NCR_DEBUG
options SCSI_NCR_MAX_SYNC=10000

View File

@ -193,9 +193,6 @@ OLTR_NO_BULLSEYE_MAC opt_oltr.h
# Defaults to NDGB*16.
NDGBPORTS opt_dgb.h
# Temporary options for moving to pnpbios
PNPBIOS opt_pnp.h
# -------------------------------
# EOF
# -------------------------------

View File

@ -1349,7 +1349,6 @@ options NATM #native ATM
#device uart0 at isa? port 0x330 irq 5
# The newpcm driver (use INSTEAD of snd0 and all VOXWARE drivers!).
# Note that motherboard sound devices may require options PNPBIOS.
#
# Supported cards include:
# Creative SoundBlaster ISA PnP/non-PnP
@ -2336,7 +2335,6 @@ options NMBCLUSTERS=1024
#options OLTR_NO_HAWKEYE_MAC
#options OLTR_NO_TMS_MAC
options PANIC_REBOOT_WAIT_TIME=16
options PNPBIOS
options PSM_DEBUG=1
options SCSI_NCR_DEBUG
options SCSI_NCR_MAX_SYNC=10000

View File

@ -1349,7 +1349,6 @@ options NATM #native ATM
#device uart0 at isa? port 0x330 irq 5
# The newpcm driver (use INSTEAD of snd0 and all VOXWARE drivers!).
# Note that motherboard sound devices may require options PNPBIOS.
#
# Supported cards include:
# Creative SoundBlaster ISA PnP/non-PnP
@ -2336,7 +2335,6 @@ options NMBCLUSTERS=1024
#options OLTR_NO_HAWKEYE_MAC
#options OLTR_NO_TMS_MAC
options PANIC_REBOOT_WAIT_TIME=16
options PNPBIOS
options PSM_DEBUG=1
options SCSI_NCR_DEBUG
options SCSI_NCR_MAX_SYNC=10000

View File

@ -31,8 +31,6 @@
* Code for dealing with the BIOS in x86 PC systems.
*/
#include "opt_pnp.h"
#include "isa.h"
#include <sys/param.h>
@ -79,9 +77,10 @@ bios32_init(void *junk)
struct PnPBIOS_table *pt;
u_int8_t ck, *cv;
int i;
char *p;
/*
* BIOS32 Service Directory
* BIOS32 Service Directory, PCI BIOS
*/
/* look for the signature */
@ -100,10 +99,15 @@ bios32_init(void *junk)
printf("bios32: Entry = 0x%x (%x) Rev = %d Len = %d\n",
sdh->entry, bios32_SDCI, sdh->revision, sdh->len);
}
/* See if there's a PCI BIOS entrypoint here */
PCIbios.ident.id = 0x49435024; /* PCI systems should have this */
if (!bios32_SDlookup(&PCIbios) && bootverbose)
printf("pcibios: PCI BIOS entry at 0x%x\n", PCIbios.entry);
/* Allow user override of PCI BIOS search */
if (((p = getenv("machdep.bios.pci")) == NULL) || strcmp(p, "disable")) {
/* See if there's a PCI BIOS entrypoint here */
PCIbios.ident.id = 0x49435024; /* PCI systems should have this */
if (!bios32_SDlookup(&PCIbios) && bootverbose)
printf("pcibios: PCI BIOS entry at 0x%x+0x%x\n", PCIbios.base, PCIbios.entry);
}
} else {
printf("bios32: Bad BIOS32 Service Directory\n");
}
@ -111,8 +115,11 @@ bios32_init(void *junk)
/*
* PnP BIOS
*
* Allow user override of PnP BIOS search
*/
if ((sigaddr = bios_sigsearch(0, "$PnP", 4, 16, 0)) != 0) {
if ((((p = getenv("machdep.bios.pnp")) == NULL) || strcmp(p, "disable")) &&
((sigaddr = bios_sigsearch(0, "$PnP", 4, 16, 0)) != 0)) {
/* get a virtual pointer to the structure */
pt = (struct PnPBIOS_table *)(uintptr_t)BIOS_PADDRTOVADDR(sigaddr);
@ -166,6 +173,7 @@ bios32_SDlookup(struct bios32_SDentry *ent)
ent->base = args.ebx;
ent->len = args.ecx;
ent->entry = args.edx;
ent->ventry = BIOS_PADDRTOVADDR(ent->base + ent->entry);
return (0); /* all OK */
}
return (1); /* failed */
@ -454,8 +462,6 @@ bios16(struct bios_args *args, char *fmt, ...)
return (i);
}
#ifdef PNPBIOS /* remove conditional later */
/*
* PnP BIOS interface; enumerate devices only known to the system
* BIOS and save information about them for later use.
@ -518,7 +524,7 @@ pnpbios_identify(driver_t *driver, device_t parent)
/* no PnP BIOS information */
if (pt == NULL)
return;
bzero(&args, sizeof(args));
args.seg.code16.base = BIOS_PADDRTOVADDR(pt->pmentrybase);
args.seg.code16.limit = 0xffff; /* XXX ? */
@ -623,5 +629,3 @@ static driver_t pnpbios_driver = {
static devclass_t pnpbios_devclass;
DRIVER_MODULE(pnpbios, isa, pnpbios_driver, pnpbios_devclass, 0, 0);
#endif /* PNPBIOS */

View File

@ -54,6 +54,7 @@ struct bios32_SDentry
u_int32_t base; /* base of service */
u_int32_t len; /* service length */
u_int32_t entry; /* entrypoint offset from base */
vm_offset_t ventry; /* entrypoint in kernel virtual segment */
};
extern int bios32_SDlookup(struct bios32_SDentry *ent);
@ -203,6 +204,16 @@ struct bios_args {
#define PNP_GET_BOOTFIRST "sp", 0x65
#define PNP_SET_BOOTFIRST "sp", 0x66
/*
* PCI BIOS functions
*/
#define PCIBIOS_READ_CONFIG_BYTE 0xb108
#define PCIBIOS_READ_CONFIG_WORD 0xb109
#define PCIBIOS_READ_CONFIG_DWORD 0xb10a
#define PCIBIOS_WRITE_CONFIG_BYTE 0xb10b
#define PCIBIOS_WRITE_CONFIG_WORD 0xb10c
#define PCIBIOS_WRITE_CONFIG_DWORD 0xb10d
extern int bios16(struct bios_args *, char *, ...);
extern int bios16_call(struct bios_regs *, char *);
extern int bios32(struct bios_regs *, u_int, u_short);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;