From 34c0afbf8dc16a92d6b6d74704bde7f1359ea85c Mon Sep 17 00:00:00 2001 From: drochner Date: Thu, 30 May 2002 12:06:43 +0000 Subject: [PATCH] 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) --- sys/dev/pci/pci_map.c | 38 +++++++++++++++++++++++++++++--------- sys/dev/pci/pcivar.h | 3 ++- sys/dev/pci/vga_pci.c | 19 ++++++++++++------- 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/sys/dev/pci/pci_map.c b/sys/dev/pci/pci_map.c index d5bc3a61e45f..2c58c5a47942 100644 --- a/sys/dev/pci/pci_map.c +++ b/sys/dev/pci/pci_map.c @@ -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. @@ -41,7 +41,7 @@ */ #include -__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 #include @@ -214,17 +214,37 @@ pci_mem_find(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t type, 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 pci_mapreg_type(pci_chipset_tag_t pc, pcitag_t tag, int reg) { - pcireg_t rv; - rv = pci_conf_read(pc, tag, reg); - if (PCI_MAPREG_TYPE(rv) == PCI_MAPREG_TYPE_IO) - rv &= PCI_MAPREG_TYPE_MASK; - else - rv &= PCI_MAPREG_TYPE_MASK|PCI_MAPREG_MEM_TYPE_MASK; - return (rv); + return (_PCI_MAPREG_TYPEBITS(pci_conf_read(pc, tag, reg))); +} + +int +pci_mapreg_probe(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t *typep) +{ + 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 diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h index e2e9e3f466ce..4d3fcb419085 100644 --- a/sys/dev/pci/pcivar.h +++ b/sys/dev/pci/pcivar.h @@ -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. @@ -178,6 +178,7 @@ extern struct cfdriver pci_cd; * Configuration space access and utility functions. (Note that most, * 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)); int pci_mapreg_info __P((pci_chipset_tag_t, pcitag_t, int, pcireg_t, bus_addr_t *, bus_size_t *, int *)); diff --git a/sys/dev/pci/vga_pci.c b/sys/dev/pci/vga_pci.c index 5fd1aa971afb..b75ca495ab83 100644 --- a/sys/dev/pci/vga_pci.c +++ b/sys/dev/pci/vga_pci.c @@ -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. @@ -28,7 +28,7 @@ */ #include -__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 #include @@ -151,8 +151,11 @@ vga_pci_attach(struct device *parent, struct device *self, void *aux) */ for (bar = 0; bar < NBARS; bar++) { reg = PCI_MAPREG_START + (bar * 4); - psc->sc_bars[bar].vb_type = pci_mapreg_type(psc->sc_pc, - psc->sc_pcitag, reg); + if (!pci_mapreg_probe(psc->sc_pc, 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) == PCI_MAPREG_TYPE_IO) { /* Don't bother fetching I/O BARs. */ @@ -163,14 +166,16 @@ vga_pci_attach(struct device *parent, struct device *self, void *aux) /* XXX */ printf("%s: WARNING: ignoring 64-bit BAR @ 0x%02x\n", sc->sc_dev.dv_xname, reg); + bar++; continue; } - /* Ignore errors (unimplemented BARs). */ - (void) pci_mapreg_info(psc->sc_pc, psc->sc_pcitag, reg, + if (pci_mapreg_info(psc->sc_pc, psc->sc_pcitag, reg, psc->sc_bars[bar].vb_type, &psc->sc_bars[bar].vb_base, &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? */