diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2013-03-17 19:09:04 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2013-03-17 19:09:04 +0000 |
commit | 76d9e2eb7899db30dda140e7120e1a807a653409 (patch) | |
tree | 8553e2d920ef0e1de4ce30206adfee2b800eef11 /sys | |
parent | 8d803cdddba74f2d52a45774bb6dac5956f18934 (diff) |
Set the `Power Immediate' bit upon attaching, to enable automatic restart
upon power failures. While most, if not all, x86-based Geode designs force this
bit to be set, loongson designs don't.
This makes Fuloong restart automatically upon power failure (they used to
require manual intervention before).
misfeature (and hints where to search for a fix) reported by Joel K. Bertrand;
ok pirofti@ deraadt@ mpi@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/glxpcib.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/sys/dev/pci/glxpcib.c b/sys/dev/pci/glxpcib.c index d55d0cadd87..5b93c115c99 100644 --- a/sys/dev/pci/glxpcib.c +++ b/sys/dev/pci/glxpcib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: glxpcib.c,v 1.9 2013/01/16 07:17:59 pirofti Exp $ */ +/* $OpenBSD: glxpcib.c,v 1.10 2013/03/17 19:09:03 miod Exp $ */ /* * Copyright (c) 2007 Marc Balmer <mbalmer@openbsd.org> @@ -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, struct device *self, void *aux) 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; @@ -384,6 +394,18 @@ glxpcib_attach(struct device *parent, struct device *self, void *aux) 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); |