summaryrefslogtreecommitdiff
path: root/sys/arch/i386/pci/geodesc.c
diff options
context:
space:
mode:
authorTom Cosgrove <tom@cvs.openbsd.org>2006-10-17 21:28:24 +0000
committerTom Cosgrove <tom@cvs.openbsd.org>2006-10-17 21:28:24 +0000
commit08a118ed5154997667e4fc398bde4a9e15b137a3 (patch)
treee1f1a87d76ee4d763ea354f5334197f0f313dd27 /sys/arch/i386/pci/geodesc.c
parent2fbc82ef1ddf080644e5f703dcfd599573f22132 (diff)
Set the Geode SC1100-specific reset function in the geodesc driver,
rather than when CPUID says we're on any Geode. Should avoid reset failure on Nokia IP110s and other non-SC1100 Geode-based systems. Reset should hopefully still work on Soekris Net4801s and PC Engines WRAP systems, but no-one bothered to test and report back in two days. "commit" deraadt@
Diffstat (limited to 'sys/arch/i386/pci/geodesc.c')
-rw-r--r--sys/arch/i386/pci/geodesc.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/sys/arch/i386/pci/geodesc.c b/sys/arch/i386/pci/geodesc.c
index a38dc38624d..bede835d89b 100644
--- a/sys/arch/i386/pci/geodesc.c
+++ b/sys/arch/i386/pci/geodesc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: geodesc.c,v 1.6 2006/09/29 19:31:23 mpf Exp $ */
+/* $OpenBSD: geodesc.c,v 1.7 2006/10/17 21:28:23 tom Exp $ */
/*
* Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
@@ -45,6 +45,7 @@ struct geodesc_softc {
int geodesc_match(struct device *, void *, void *);
void geodesc_attach(struct device *, struct device *, void *);
int geodesc_wdogctl_cb(void *, int);
+void sc1100_sysreset(void);
struct cfattach geodesc_ca = {
sizeof(struct geodesc_softc), geodesc_match, geodesc_attach
@@ -89,6 +90,7 @@ geodesc_attach(struct device *parent, struct device *self, void *aux)
uint16_t cnfg, cba;
uint8_t sts, rev, iid;
pcireg_t reg;
+ extern void (*cpuresetfn)(void);
reg = pci_conf_read(pa->pa_pc, pa->pa_tag, SC1100_F5_SCRATCHPAD);
sc->sc_iot = pa->pa_iot;
@@ -124,6 +126,9 @@ geodesc_attach(struct device *parent, struct device *self, void *aux)
geodesc_timecounter.tc_priv = sc;
tc_init(&geodesc_timecounter);
#endif /* __HAVE_TIMECOUNTER */
+
+ /* We have a special way to reset the CPU on the SC1100 */
+ cpuresetfn = sc1100_sysreset;
}
int
@@ -146,3 +151,25 @@ geodesc_get_timecount(struct timecounter *tc)
return (bus_space_read_4(sc->sc_iot, sc->sc_ioh, GCB_TSC));
}
#endif /* __HAVE_TIMECOUNTER */
+
+void
+sc1100_sysreset(void)
+{
+ /*
+ * Reset AMD Geode SC1100.
+ *
+ * 1) Write PCI Configuration Address Register (0xcf8) to
+ * select Function 0, Register 0x44: Bridge Configuration,
+ * GPIO and LPC Configuration Register Space, Reset
+ * Control Register.
+ *
+ * 2) Write 0xf to PCI Configuration Data Register (0xcfc)
+ * to reset IDE controller, IDE bus, and PCI bus, and
+ * to trigger a system-wide reset.
+ *
+ * See AMD Geode SC1100 Processor Data Book, Revision 2.0,
+ * sections 6.3.1, 6.3.2, and 6.4.1.
+ */
+ outl(0xCF8, 0x80009044UL);
+ outb(0xCFC, 0x0F);
+}