ich9: implement strap SPKR pin logic
If the signal is sampled high, this indicates that the system is strapped to the "No Reboot" mode (ICH9 will disable the TCO Timer system reboot feature). The status of this strap is readable via the NO_REBOOT bit (CC: offset 0x3410:bit 5). The NO_REBOOT bit is set when SPKR pin on ICH9 is sampled high. This bit may be set or cleared by software if the strap is sampled low but may not override the strap when it indicates "No Reboot". This patch implements the logic where hardware has ability to set SPKR pin through a property named "noreboot" and it's sampled high by default. Signed-off-by: Paulo Alcantara <pcacjr@zytor.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
45dcdb9da6
commit
5add35bec1
@ -64,7 +64,7 @@ static void tco_timer_expired(void *opaque)
|
|||||||
tr->tco.sts2 |= TCO_BOOT_STS;
|
tr->tco.sts2 |= TCO_BOOT_STS;
|
||||||
tr->timeouts_no = 0;
|
tr->timeouts_no = 0;
|
||||||
|
|
||||||
if (!(gcs & ICH9_CC_GCS_NO_REBOOT)) {
|
if (!lpc->pin_strap.spkr_hi && !(gcs & ICH9_CC_GCS_NO_REBOOT)) {
|
||||||
watchdog_perform_action();
|
watchdog_perform_action();
|
||||||
tco_timer_stop(tr);
|
tco_timer_stop(tr);
|
||||||
return;
|
return;
|
||||||
|
@ -692,6 +692,11 @@ static const VMStateDescription vmstate_ich9_lpc = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static Property ich9_lpc_properties[] = {
|
||||||
|
DEFINE_PROP_BOOL("noreboot", ICH9LPCState, pin_strap.spkr_hi, true),
|
||||||
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
|
};
|
||||||
|
|
||||||
static void ich9_lpc_class_init(ObjectClass *klass, void *data)
|
static void ich9_lpc_class_init(ObjectClass *klass, void *data)
|
||||||
{
|
{
|
||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
@ -703,6 +708,7 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data)
|
|||||||
dc->reset = ich9_lpc_reset;
|
dc->reset = ich9_lpc_reset;
|
||||||
k->init = ich9_lpc_init;
|
k->init = ich9_lpc_init;
|
||||||
dc->vmsd = &vmstate_ich9_lpc;
|
dc->vmsd = &vmstate_ich9_lpc;
|
||||||
|
dc->props = ich9_lpc_properties;
|
||||||
k->config_write = ich9_lpc_config_write;
|
k->config_write = ich9_lpc_config_write;
|
||||||
dc->desc = "ICH9 LPC bridge";
|
dc->desc = "ICH9 LPC bridge";
|
||||||
k->vendor_id = PCI_VENDOR_ID_INTEL;
|
k->vendor_id = PCI_VENDOR_ID_INTEL;
|
||||||
|
@ -46,6 +46,11 @@ typedef struct ICH9LPCState {
|
|||||||
ICH9LPCPMRegs pm;
|
ICH9LPCPMRegs pm;
|
||||||
uint32_t sci_level; /* track sci level */
|
uint32_t sci_level; /* track sci level */
|
||||||
|
|
||||||
|
/* 2.24 Pin Straps */
|
||||||
|
struct {
|
||||||
|
bool spkr_hi;
|
||||||
|
} pin_strap;
|
||||||
|
|
||||||
/* 10.1 Chipset Configuration registers(Memory Space)
|
/* 10.1 Chipset Configuration registers(Memory Space)
|
||||||
which is pointed by RCBA */
|
which is pointed by RCBA */
|
||||||
uint8_t chip_config[ICH9_CC_SIZE];
|
uint8_t chip_config[ICH9_CC_SIZE];
|
||||||
|
@ -42,6 +42,7 @@ enum {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *args;
|
const char *args;
|
||||||
|
bool noreboot;
|
||||||
QPCIDevice *dev;
|
QPCIDevice *dev;
|
||||||
void *lpc_base;
|
void *lpc_base;
|
||||||
void *tco_io_base;
|
void *tco_io_base;
|
||||||
@ -53,7 +54,9 @@ static void test_init(TestData *d)
|
|||||||
QTestState *qs;
|
QTestState *qs;
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
s = g_strdup_printf("-machine q35 %s", !d->args ? "" : d->args);
|
s = g_strdup_printf("-machine q35 %s %s",
|
||||||
|
d->noreboot ? "" : "-global ICH9-LPC.noreboot=false",
|
||||||
|
!d->args ? "" : d->args);
|
||||||
qs = qtest_start(s);
|
qs = qtest_start(s);
|
||||||
qtest_irq_intercept_in(qs, "ioapic");
|
qtest_irq_intercept_in(qs, "ioapic");
|
||||||
g_free(s);
|
g_free(s);
|
||||||
@ -135,6 +138,7 @@ static void test_tco_defaults(void)
|
|||||||
TestData d;
|
TestData d;
|
||||||
|
|
||||||
d.args = NULL;
|
d.args = NULL;
|
||||||
|
d.noreboot = true;
|
||||||
test_init(&d);
|
test_init(&d);
|
||||||
g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_base + TCO_RLD), ==,
|
g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_base + TCO_RLD), ==,
|
||||||
TCO_RLD_DEFAULT);
|
TCO_RLD_DEFAULT);
|
||||||
@ -167,6 +171,7 @@ static void test_tco_timeout(void)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
d.args = NULL;
|
d.args = NULL;
|
||||||
|
d.noreboot = true;
|
||||||
test_init(&d);
|
test_init(&d);
|
||||||
|
|
||||||
stop_tco(&d);
|
stop_tco(&d);
|
||||||
@ -210,6 +215,7 @@ static void test_tco_max_timeout(void)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
d.args = NULL;
|
d.args = NULL;
|
||||||
|
d.noreboot = true;
|
||||||
test_init(&d);
|
test_init(&d);
|
||||||
|
|
||||||
stop_tco(&d);
|
stop_tco(&d);
|
||||||
@ -253,6 +259,7 @@ static void test_tco_second_timeout_pause(void)
|
|||||||
QDict *ad;
|
QDict *ad;
|
||||||
|
|
||||||
td.args = "-watchdog-action pause";
|
td.args = "-watchdog-action pause";
|
||||||
|
td.noreboot = false;
|
||||||
test_init(&td);
|
test_init(&td);
|
||||||
|
|
||||||
stop_tco(&td);
|
stop_tco(&td);
|
||||||
@ -277,6 +284,7 @@ static void test_tco_second_timeout_reset(void)
|
|||||||
QDict *ad;
|
QDict *ad;
|
||||||
|
|
||||||
td.args = "-watchdog-action reset";
|
td.args = "-watchdog-action reset";
|
||||||
|
td.noreboot = false;
|
||||||
test_init(&td);
|
test_init(&td);
|
||||||
|
|
||||||
stop_tco(&td);
|
stop_tco(&td);
|
||||||
@ -301,6 +309,7 @@ static void test_tco_second_timeout_shutdown(void)
|
|||||||
QDict *ad;
|
QDict *ad;
|
||||||
|
|
||||||
td.args = "-watchdog-action shutdown";
|
td.args = "-watchdog-action shutdown";
|
||||||
|
td.noreboot = false;
|
||||||
test_init(&td);
|
test_init(&td);
|
||||||
|
|
||||||
stop_tco(&td);
|
stop_tco(&td);
|
||||||
@ -325,6 +334,7 @@ static void test_tco_second_timeout_none(void)
|
|||||||
QDict *ad;
|
QDict *ad;
|
||||||
|
|
||||||
td.args = "-watchdog-action none";
|
td.args = "-watchdog-action none";
|
||||||
|
td.noreboot = false;
|
||||||
test_init(&td);
|
test_init(&td);
|
||||||
|
|
||||||
stop_tco(&td);
|
stop_tco(&td);
|
||||||
@ -349,6 +359,7 @@ static void test_tco_ticks_counter(void)
|
|||||||
uint16_t rld;
|
uint16_t rld;
|
||||||
|
|
||||||
d.args = NULL;
|
d.args = NULL;
|
||||||
|
d.noreboot = true;
|
||||||
test_init(&d);
|
test_init(&d);
|
||||||
|
|
||||||
stop_tco(&d);
|
stop_tco(&d);
|
||||||
@ -375,6 +386,7 @@ static void test_tco1_control_bits(void)
|
|||||||
uint16_t val;
|
uint16_t val;
|
||||||
|
|
||||||
d.args = NULL;
|
d.args = NULL;
|
||||||
|
d.noreboot = true;
|
||||||
test_init(&d);
|
test_init(&d);
|
||||||
|
|
||||||
val = TCO_LOCK;
|
val = TCO_LOCK;
|
||||||
@ -394,6 +406,7 @@ static void test_tco1_status_bits(void)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
d.args = NULL;
|
d.args = NULL;
|
||||||
|
d.noreboot = true;
|
||||||
test_init(&d);
|
test_init(&d);
|
||||||
|
|
||||||
stop_tco(&d);
|
stop_tco(&d);
|
||||||
@ -421,7 +434,8 @@ static void test_tco2_status_bits(void)
|
|||||||
uint16_t val;
|
uint16_t val;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
d.args = "-watchdog-action none";
|
d.args = NULL;
|
||||||
|
d.noreboot = true;
|
||||||
test_init(&d);
|
test_init(&d);
|
||||||
|
|
||||||
stop_tco(&d);
|
stop_tco(&d);
|
||||||
|
Loading…
Reference in New Issue
Block a user