The Geode companion chip, part of which attaches as glxpcib(4), can be
configured to restart automatically after a power failure, when power is
restored.
The following diff enables this functionality. Tested on a Lemote
Fuloong (where it works) and on a Lemote Yeeloong (where this feature is
disabled in hardware) only. Tests on x86 systems based upon the Geode,
such as the Soekris 5501 or the ALIX boards, would be appreciated.
Running a kernel with this diff, if you `shutdown -h now', remove the
power plug, and plug it back, your system should restart immediately,
unless some other part of the hardware forces this feature to be
disabled (e.g. on laptops such as the Lemote Yeeloong).
Note that this feature might have already been enabled by the BIOS on
the Soekrisens or the ALIXes, but this was definitely not the case on
Fuloongs.
Regardless of your kind system, this diff should not break anything. If
it does, please let me know.
Miod
Index: glxpcib.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/glxpcib.c,v
retrieving revision 1.9
diff -u -p -r1.9 glxpcib.c
--- glxpcib.c 16 Jan 2013 07:17:59 -0000 1.9
+++ glxpcib.c 12 Mar 2013 21:30:28 -0000
@@ -166,6 +166,15 @@
#define AMD5536_SMB_CTL2_FREQ 0x78 /* 100 kHz */
#define AMD5536_SMB_CTL3 0x06 /* control 3 */
+/* PMS */
+#define MSR_LBAR_PMS DIVIL_LBAR_PMS
+#define MSR_PMS_SIZE 0x80
+#define MSR_PMS_ADDR_MASK 0xff80
+#define AMD5536_PMS_SSC 0x54
+#define AMD5536_PMS_SSC_PI 0x00040000
+#define AMD5536_PMS_SSC_CLR_PI 0x00020000
+#define AMD5536_PMS_SSC_SET_PI 0x00010000
+
/*
* MSR registers we want to preserve accross suspend/resume
*/
@@ -275,6 +284,7 @@ glxpcib_attach(struct device *parent, st
u_int64_t sa;
struct i2cbus_attach_args iba;
int i2c = 0;
+ bus_space_handle_t tmpioh;
#endif
tc->tc_get_timecount = glxpcib_get_timecount;
tc->tc_counter_mask = 0xffffffff;
@@ -383,6 +393,18 @@ glxpcib_attach(struct device *parent, st
iba.iba_name = "iic";
iba.iba_tag = &sc->sc_smb_ic;
i2c = 1;
+ }
+
+ /* Map PMS I/O space and enable the ``Power Immediate'' feature */
+ sa = rdmsr(MSR_LBAR_PMS);
+ if (sa & MSR_LBAR_ENABLE &&
+ !bus_space_map(pa->pa_iot, sa & MSR_PMS_ADDR_MASK,
+ MSR_PMS_SIZE, 0, &tmpioh)) {
+ bus_space_write_4(pa->pa_iot, tmpioh, AMD5536_PMS_SSC,
+ AMD5536_PMS_SSC_SET_PI);
+ bus_space_barrier(pa->pa_iot, tmpioh, AMD5536_PMS_SSC, 4,
+ BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
+ bus_space_unmap(pa->pa_iot, tmpioh, MSR_PMS_SIZE);
}
#endif /* SMALL_KERNEL */
pcibattach(parent, self, aux);