mirror of https://gitee.com/openkylin/qemu.git
ppc/pnv: generate an OEM SEL event on shutdown
OpenPOWER systems expect to be notified with such an event before a shutdown or a reboot. An OEM SEL message is sent with specific identifiers and a user data containing the request : OFF or REBOOT. Signed-off-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
aeaef83dab
commit
bce0b69159
14
hw/ppc/pnv.c
14
hw/ppc/pnv.c
|
@ -485,6 +485,15 @@ static void *powernv_create_fdt(MachineState *machine)
|
|||
return fdt;
|
||||
}
|
||||
|
||||
static void pnv_powerdown_notify(Notifier *n, void *opaque)
|
||||
{
|
||||
PnvMachineState *pnv = POWERNV_MACHINE(qdev_get_machine());
|
||||
|
||||
if (pnv->bmc) {
|
||||
pnv_bmc_powerdown(pnv->bmc);
|
||||
}
|
||||
}
|
||||
|
||||
static void ppc_powernv_reset(void)
|
||||
{
|
||||
MachineState *machine = MACHINE(qdev_get_machine());
|
||||
|
@ -638,6 +647,11 @@ static void ppc_powernv_init(MachineState *machine)
|
|||
|
||||
/* Create an RTC ISA device too */
|
||||
rtc_init(pnv->isa_bus, 2000, NULL);
|
||||
|
||||
/* OpenPOWER systems use a IPMI SEL Event message to notify the
|
||||
* host to powerdown */
|
||||
pnv->powerdown_notifier.notify = pnv_powerdown_notify;
|
||||
qemu_register_powerdown_notifier(&pnv->powerdown_notifier);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -32,6 +32,47 @@
|
|||
/* TODO: include definition in ipmi.h */
|
||||
#define IPMI_SDR_FULL_TYPE 1
|
||||
|
||||
/*
|
||||
* OEM SEL Event data packet sent by BMC in response of a Read Event
|
||||
* Message Buffer command
|
||||
*/
|
||||
typedef struct OemSel {
|
||||
/* SEL header */
|
||||
uint8_t id[2];
|
||||
uint8_t type;
|
||||
uint8_t timestamp[4];
|
||||
uint8_t manuf_id[3];
|
||||
|
||||
/* OEM SEL data (6 bytes) follows */
|
||||
uint8_t netfun;
|
||||
uint8_t cmd;
|
||||
uint8_t data[4];
|
||||
} OemSel;
|
||||
|
||||
#define SOFT_OFF 0x00
|
||||
#define SOFT_REBOOT 0x01
|
||||
|
||||
static void pnv_gen_oem_sel(IPMIBmc *bmc, uint8_t reboot)
|
||||
{
|
||||
/* IPMI SEL Event are 16 bytes long */
|
||||
OemSel sel = {
|
||||
.id = { 0x55 , 0x55 },
|
||||
.type = 0xC0, /* OEM */
|
||||
.manuf_id = { 0x0, 0x0, 0x0 },
|
||||
.timestamp = { 0x0, 0x0, 0x0, 0x0 },
|
||||
.netfun = 0x3A, /* IBM */
|
||||
.cmd = 0x04, /* AMI OEM SEL Power Notification */
|
||||
.data = { reboot, 0xFF, 0xFF, 0xFF },
|
||||
};
|
||||
|
||||
ipmi_bmc_gen_event(bmc, (uint8_t *) &sel, 0 /* do not log the event */);
|
||||
}
|
||||
|
||||
void pnv_bmc_powerdown(IPMIBmc *bmc)
|
||||
{
|
||||
pnv_gen_oem_sel(bmc, SOFT_OFF);
|
||||
}
|
||||
|
||||
void pnv_bmc_populate_sensors(IPMIBmc *bmc, void *fdt)
|
||||
{
|
||||
int offset;
|
||||
|
|
|
@ -134,6 +134,7 @@ typedef struct PnvMachineState {
|
|||
uint32_t cpld_irqstate;
|
||||
|
||||
IPMIBmc *bmc;
|
||||
Notifier powerdown_notifier;
|
||||
} PnvMachineState;
|
||||
|
||||
#define PNV_FDT_ADDR 0x01000000
|
||||
|
@ -143,6 +144,7 @@ typedef struct PnvMachineState {
|
|||
* BMC helpers
|
||||
*/
|
||||
void pnv_bmc_populate_sensors(IPMIBmc *bmc, void *fdt);
|
||||
void pnv_bmc_powerdown(IPMIBmc *bmc);
|
||||
|
||||
/*
|
||||
* POWER8 MMIO base addresses
|
||||
|
|
Loading…
Reference in New Issue