Port-amd64 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

support for HPET on Nvidia nForce PCI-ISA bridges



Hi,

I have a Dell Optiplex 740, which unfortunately does not provide an
HPET device in the ACPI device tree (and there is no BIOS flag to
enable it ...), even if an HPET table exists.

I luckily noticed that the HPET registers address could be found on
the NVIDIA nForce430 PCI-ISA Bridge, and then mapped to attach a
functional hpet device.

Attached a new nfpcib(4) drivers which enable all of this ... I
currently restricted it to the nForce430 bridge i can test, but other
variant should  be able to do the same.

Anyone interested ?

njoly@petaure [amd64/conf]> grep nfpcib PETAURE
nfpcib*         at pci? dev ? function ?        # Nvidia PCI-ISA w/ HPET
hpet*           at nfpcib?
isa0            at nfpcib?

njoly@petaure [~]> dmesg | grep -e nfpcib -e hpet
nfpcib0 at pci0 dev 10 function 0
nfpcib0: NVIDIA nForce430 PCI-ISA Bridge (rev. 0xa3)
hpet0 at nfpcib0: HPET timer
timecounter: Timecounter "hpet0" frequency 25000000 Hz quality 2000
isa0 at nfpcib0

njoly@petaure [~]> sysctl kern.timecounter
kern.timecounter.choice = TSC(q=-100, f=2505325650 Hz) clockinterrupt(q=0, 
f=100 Hz) hpet0(q=2000, f=25000000 Hz) ACPI-Fast(q=1000, f=3579545 Hz) 
lapic(q=-100, f=200505662 Hz) i8254(q=100, f=1193182 Hz) dummy(q=-1000000, 
f=1000000 Hz)
kern.timecounter.hardware = hpet0
kern.timecounter.timestepwarnings = 0

-- 
Nicolas Joly

Biological Software and Databanks.
Institut Pasteur, Paris.
Index: sys/arch/x86/pci/files.pci
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/pci/files.pci,v
retrieving revision 1.7
diff -u -p -r1.7 files.pci
--- sys/arch/x86/pci/files.pci  3 Aug 2008 19:32:03 -0000       1.7
+++ sys/arch/x86/pci/files.pci  19 Mar 2009 01:54:07 -0000
@@ -16,8 +16,14 @@ file arch/x86/pci/pchb_rnd.c         pchb & rnd
 # PCI-ISA bridges
 device pcib: isabus
 attach pcib at pci
-file   arch/x86/pci/pcib.c             pcib | ichlpcib | gscpcib | piixpcib | 
viapcib |
-                                       amdpcib
+file   arch/x86/pci/pcib.c             pcib | ichlpcib | gscpcib | piixpcib |
+                                       viapcib | amdpcib | nfpcib
+
+define nfpcib_hpet {}
+device nfpcib {} : isabus, nfpcib_hpet
+attach nfpcib at pci
+attach hpet at nfpcib_hpet with nfpcib_hpet
+file   arch/x86/pci/nfpcib.c                   nfpcib
 
 device amdpcib {} : isabus
 attach amdpcib at pci
Index: sys/arch/x86/pci/nfpcib.c
===================================================================
RCS file: sys/arch/x86/pci/nfpcib.c
diff -N sys/arch/x86/pci/nfpcib.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ sys/arch/x86/pci/nfpcib.c   19 Mar 2009 01:54:07 -0000
@@ -0,0 +1,145 @@
+/* $NetBSD$ */
+
+/*
+ * Copyright (c) 2009 Nicolas Joly
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD$");
+
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/param.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcidevs.h>
+
+#include <sys/time.h>
+#include <sys/timetc.h>
+
+#include <dev/ic/hpetreg.h>
+#include <dev/ic/hpetvar.h>
+
+#include "hpet.h"
+#include "pcibvar.h"
+
+struct nfpcib_softc {
+       struct pcib_softc       sc_pcib;
+
+       struct pci_attach_args  sc_pa;
+
+       bus_space_tag_t         sc_memt;
+       bus_space_handle_t      sc_memh;
+};
+
+static int     nfpcib_match(device_t, cfdata_t, void *);
+static void    nfpcib_attach(device_t, device_t, void *);
+
+CFATTACH_DECL_NEW(nfpcib, sizeof(struct nfpcib_softc), nfpcib_match,
+    nfpcib_attach, NULL, NULL);
+
+#if NHPET > 0
+static int     nfpcib_hpet_match(device_t, cfdata_t, void *);
+static void    nfpcib_hpet_attach(device_t, device_t, void *);
+static void    nfpcib_hpet_configure(device_t);
+
+CFATTACH_DECL_NEW(nfpcib_hpet, sizeof(struct hpet_softc), nfpcib_hpet_match,
+    nfpcib_hpet_attach, NULL, NULL);
+
+struct nfpcib_hpet_attach_arg {
+       bus_space_tag_t hpet_memt;
+       uint32_t        hpet_addr;
+};
+#endif
+
+static int
+nfpcib_match(device_t parent, cfdata_t match, void *aux)
+{
+       struct pci_attach_args *pa = aux;
+
+       if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NVIDIA) &&
+           (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NVIDIA_NFORCE430_PCIB))
+               return 2;
+
+       return 0;
+}
+
+static void
+nfpcib_attach(device_t parent, device_t self, void *aux)
+{
+       struct nfpcib_softc *sc = device_private(self);
+       struct pci_attach_args *pa = aux;
+
+       sc->sc_pa = *pa;
+
+       pcibattach(parent, self, aux);
+
+#if NHPET > 0
+       nfpcib_hpet_configure(self);
+#endif
+}
+
+#if NHPET > 0
+static void
+nfpcib_hpet_configure(device_t self)
+{
+       struct nfpcib_softc *sc = device_private(self);
+       struct nfpcib_hpet_attach_arg arg;
+       uint32_t addr;
+
+       addr = pci_conf_read(sc->sc_pa.pa_pc, sc->sc_pa.pa_tag, 0x44);
+
+       arg.hpet_memt = sc->sc_pa.pa_memt;
+       arg.hpet_addr = addr;
+       config_found_ia(self, "nfpcib_hpet", &arg, NULL);
+}
+
+static int
+nfpcib_hpet_match(device_t parent, cfdata_t match, void *aux)
+{
+       return 1;
+}
+
+static void
+nfpcib_hpet_attach(device_t parent, device_t self, void *aux)
+{
+       struct hpet_softc *sc = device_private(self);
+       struct nfpcib_hpet_attach_arg *arg = aux;
+
+       aprint_naive("\n");
+       aprint_normal(": HPET timer\n");
+
+       sc->sc_memt = arg->hpet_memt;
+       if (bus_space_map(sc->sc_memt, arg->hpet_addr, HPET_WINDOW_SIZE, 0,
+                         &sc->sc_memh)) {
+               aprint_error_dev(self, "HPET memory window could not be 
mapped\n");
+               return;
+       }
+
+       hpet_attach_subr(self);
+}
+#endif


Home | Main Index | Thread Index | Old Index