Port-i386 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