]>
Commit | Line | Data |
---|---|---|
aeaef83d CLG |
1 | /* |
2 | * QEMU PowerNV, BMC related functions | |
3 | * | |
4 | * Copyright (c) 2016-2017, IBM Corporation. | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License, version 2, as | |
8 | * published by the Free Software Foundation. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License | |
16 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | |
17 | */ | |
18 | ||
19 | #include "qemu/osdep.h" | |
20 | #include "hw/hw.h" | |
21 | #include "sysemu/sysemu.h" | |
22 | #include "target/ppc/cpu.h" | |
23 | #include "qapi/error.h" | |
24 | #include "qemu/log.h" | |
25 | #include "hw/ipmi/ipmi.h" | |
26 | #include "hw/ppc/fdt.h" | |
27 | ||
28 | #include "hw/ppc/pnv.h" | |
29 | ||
30 | #include <libfdt.h> | |
31 | ||
32 | /* TODO: include definition in ipmi.h */ | |
33 | #define IPMI_SDR_FULL_TYPE 1 | |
34 | ||
bce0b691 CLG |
35 | /* |
36 | * OEM SEL Event data packet sent by BMC in response of a Read Event | |
37 | * Message Buffer command | |
38 | */ | |
39 | typedef struct OemSel { | |
40 | /* SEL header */ | |
41 | uint8_t id[2]; | |
42 | uint8_t type; | |
43 | uint8_t timestamp[4]; | |
44 | uint8_t manuf_id[3]; | |
45 | ||
46 | /* OEM SEL data (6 bytes) follows */ | |
47 | uint8_t netfun; | |
48 | uint8_t cmd; | |
49 | uint8_t data[4]; | |
50 | } OemSel; | |
51 | ||
52 | #define SOFT_OFF 0x00 | |
53 | #define SOFT_REBOOT 0x01 | |
54 | ||
55 | static void pnv_gen_oem_sel(IPMIBmc *bmc, uint8_t reboot) | |
56 | { | |
57 | /* IPMI SEL Event are 16 bytes long */ | |
58 | OemSel sel = { | |
59 | .id = { 0x55 , 0x55 }, | |
60 | .type = 0xC0, /* OEM */ | |
61 | .manuf_id = { 0x0, 0x0, 0x0 }, | |
62 | .timestamp = { 0x0, 0x0, 0x0, 0x0 }, | |
63 | .netfun = 0x3A, /* IBM */ | |
64 | .cmd = 0x04, /* AMI OEM SEL Power Notification */ | |
65 | .data = { reboot, 0xFF, 0xFF, 0xFF }, | |
66 | }; | |
67 | ||
68 | ipmi_bmc_gen_event(bmc, (uint8_t *) &sel, 0 /* do not log the event */); | |
69 | } | |
70 | ||
71 | void pnv_bmc_powerdown(IPMIBmc *bmc) | |
72 | { | |
73 | pnv_gen_oem_sel(bmc, SOFT_OFF); | |
74 | } | |
75 | ||
aeaef83d CLG |
76 | void pnv_bmc_populate_sensors(IPMIBmc *bmc, void *fdt) |
77 | { | |
78 | int offset; | |
79 | int i; | |
80 | const struct ipmi_sdr_compact *sdr; | |
81 | uint16_t nextrec; | |
82 | ||
83 | offset = fdt_add_subnode(fdt, 0, "/bmc"); | |
84 | _FDT(offset); | |
85 | ||
86 | _FDT((fdt_setprop_string(fdt, offset, "name", "bmc"))); | |
87 | _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 0x1))); | |
88 | _FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 0x0))); | |
89 | ||
90 | offset = fdt_add_subnode(fdt, offset, "sensors"); | |
91 | _FDT(offset); | |
92 | ||
93 | _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 0x1))); | |
94 | _FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 0x0))); | |
95 | ||
96 | for (i = 0; !ipmi_bmc_sdr_find(bmc, i, &sdr, &nextrec); i++) { | |
97 | int off; | |
98 | char *name; | |
99 | ||
100 | if (sdr->header.rec_type != IPMI_SDR_COMPACT_TYPE && | |
101 | sdr->header.rec_type != IPMI_SDR_FULL_TYPE) { | |
102 | continue; | |
103 | } | |
104 | ||
105 | name = g_strdup_printf("sensor@%x", sdr->sensor_owner_number); | |
106 | off = fdt_add_subnode(fdt, offset, name); | |
107 | _FDT(off); | |
108 | g_free(name); | |
109 | ||
110 | _FDT((fdt_setprop_cell(fdt, off, "reg", sdr->sensor_owner_number))); | |
111 | _FDT((fdt_setprop_string(fdt, off, "name", "sensor"))); | |
112 | _FDT((fdt_setprop_string(fdt, off, "compatible", "ibm,ipmi-sensor"))); | |
113 | _FDT((fdt_setprop_cell(fdt, off, "ipmi-sensor-reading-type", | |
114 | sdr->reading_type))); | |
115 | _FDT((fdt_setprop_cell(fdt, off, "ipmi-entity-id", | |
116 | sdr->entity_id))); | |
117 | _FDT((fdt_setprop_cell(fdt, off, "ipmi-entity-instance", | |
118 | sdr->entity_instance))); | |
119 | _FDT((fdt_setprop_cell(fdt, off, "ipmi-sensor-type", | |
120 | sdr->sensor_type))); | |
121 | } | |
122 | } |