implement a check whether a BAR is present at all at a given configuration

space address and use it where the mappings of the VGA card are registered
before descenting too deep into "memory" type specific code
(pci_mem_find() gets noisy if it doesn't like the register)
This commit is contained in:
drochner 2002-05-30 12:06:43 +00:00
parent 0bb4958e16
commit 34c0afbf8d
3 changed files with 43 additions and 17 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: pci_map.c,v 1.11 2002/05/29 14:57:36 bouyer Exp $ */ /* $NetBSD: pci_map.c,v 1.12 2002/05/30 12:06:43 drochner Exp $ */
/*- /*-
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@ -41,7 +41,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pci_map.c,v 1.11 2002/05/29 14:57:36 bouyer Exp $"); __KERNEL_RCSID(0, "$NetBSD: pci_map.c,v 1.12 2002/05/30 12:06:43 drochner Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -214,17 +214,37 @@ pci_mem_find(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t type,
return (0); return (0);
} }
#define _PCI_MAPREG_TYPEBITS(reg) \
(PCI_MAPREG_TYPE(reg) == PCI_MAPREG_TYPE_IO ? \
reg & PCI_MAPREG_TYPE_MASK : \
reg & (PCI_MAPREG_TYPE_MASK|PCI_MAPREG_MEM_TYPE_MASK))
pcireg_t pcireg_t
pci_mapreg_type(pci_chipset_tag_t pc, pcitag_t tag, int reg) pci_mapreg_type(pci_chipset_tag_t pc, pcitag_t tag, int reg)
{ {
pcireg_t rv;
rv = pci_conf_read(pc, tag, reg); return (_PCI_MAPREG_TYPEBITS(pci_conf_read(pc, tag, reg)));
if (PCI_MAPREG_TYPE(rv) == PCI_MAPREG_TYPE_IO) }
rv &= PCI_MAPREG_TYPE_MASK;
else int
rv &= PCI_MAPREG_TYPE_MASK|PCI_MAPREG_MEM_TYPE_MASK; pci_mapreg_probe(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t *typep)
return (rv); {
pcireg_t address, mask;
int s;
s = splhigh();
address = pci_conf_read(pc, tag, reg);
pci_conf_write(pc, tag, reg, 0xffffffff);
mask = pci_conf_read(pc, tag, reg);
pci_conf_write(pc, tag, reg, address);
splx(s);
if (mask == 0) /* unimplemented mapping register */
return (0);
if (typep)
*typep = _PCI_MAPREG_TYPEBITS(address);
return (1);
} }
int int

View File

@ -1,4 +1,4 @@
/* $NetBSD: pcivar.h,v 1.51 2002/05/18 21:40:41 sommerfeld Exp $ */ /* $NetBSD: pcivar.h,v 1.52 2002/05/30 12:06:43 drochner Exp $ */
/* /*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved. * Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@ -178,6 +178,7 @@ extern struct cfdriver pci_cd;
* Configuration space access and utility functions. (Note that most, * Configuration space access and utility functions. (Note that most,
* e.g. make_tag, conf_read, conf_write are declared by pci_machdep.h.) * e.g. make_tag, conf_read, conf_write are declared by pci_machdep.h.)
*/ */
int pci_mapreg_probe __P((pci_chipset_tag_t, pcitag_t, int, pcireg_t *));
pcireg_t pci_mapreg_type __P((pci_chipset_tag_t, pcitag_t, int)); pcireg_t pci_mapreg_type __P((pci_chipset_tag_t, pcitag_t, int));
int pci_mapreg_info __P((pci_chipset_tag_t, pcitag_t, int, pcireg_t, int pci_mapreg_info __P((pci_chipset_tag_t, pcitag_t, int, pcireg_t,
bus_addr_t *, bus_size_t *, int *)); bus_addr_t *, bus_size_t *, int *));

View File

@ -1,4 +1,4 @@
/* $NetBSD: vga_pci.c,v 1.10 2002/03/17 19:41:00 atatat Exp $ */ /* $NetBSD: vga_pci.c,v 1.11 2002/05/30 12:06:43 drochner Exp $ */
/* /*
* Copyright (c) 1995, 1996 Carnegie-Mellon University. * Copyright (c) 1995, 1996 Carnegie-Mellon University.
@ -28,7 +28,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vga_pci.c,v 1.10 2002/03/17 19:41:00 atatat Exp $"); __KERNEL_RCSID(0, "$NetBSD: vga_pci.c,v 1.11 2002/05/30 12:06:43 drochner Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -151,8 +151,11 @@ vga_pci_attach(struct device *parent, struct device *self, void *aux)
*/ */
for (bar = 0; bar < NBARS; bar++) { for (bar = 0; bar < NBARS; bar++) {
reg = PCI_MAPREG_START + (bar * 4); reg = PCI_MAPREG_START + (bar * 4);
psc->sc_bars[bar].vb_type = pci_mapreg_type(psc->sc_pc, if (!pci_mapreg_probe(psc->sc_pc, psc->sc_pcitag, reg,
psc->sc_pcitag, reg); &psc->sc_bars[bar].vb_type)) {
/* there is no valid mapping register */
continue;
}
if (PCI_MAPREG_TYPE(psc->sc_bars[bar].vb_type) == if (PCI_MAPREG_TYPE(psc->sc_bars[bar].vb_type) ==
PCI_MAPREG_TYPE_IO) { PCI_MAPREG_TYPE_IO) {
/* Don't bother fetching I/O BARs. */ /* Don't bother fetching I/O BARs. */
@ -163,14 +166,16 @@ vga_pci_attach(struct device *parent, struct device *self, void *aux)
/* XXX */ /* XXX */
printf("%s: WARNING: ignoring 64-bit BAR @ 0x%02x\n", printf("%s: WARNING: ignoring 64-bit BAR @ 0x%02x\n",
sc->sc_dev.dv_xname, reg); sc->sc_dev.dv_xname, reg);
bar++;
continue; continue;
} }
/* Ignore errors (unimplemented BARs). */ if (pci_mapreg_info(psc->sc_pc, psc->sc_pcitag, reg,
(void) pci_mapreg_info(psc->sc_pc, psc->sc_pcitag, reg,
psc->sc_bars[bar].vb_type, psc->sc_bars[bar].vb_type,
&psc->sc_bars[bar].vb_base, &psc->sc_bars[bar].vb_base,
&psc->sc_bars[bar].vb_size, &psc->sc_bars[bar].vb_size,
&psc->sc_bars[bar].vb_flags); &psc->sc_bars[bar].vb_flags))
printf("%s: WARNING: strange BAR @ 0x%02x\n",
sc->sc_dev.dv_xname, reg);
} }
/* XXX Expansion ROM? */ /* XXX Expansion ROM? */