]>
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" | |
aeaef83d CLG |
23 | #include "qemu/log.h" |
24 | #include "hw/ipmi/ipmi.h" | |
25 | #include "hw/ppc/fdt.h" | |
26 | ||
27 | #include "hw/ppc/pnv.h" | |
28 | ||
29 | #include <libfdt.h> | |
30 | ||
31 | /* TODO: include definition in ipmi.h */ | |
32 | #define IPMI_SDR_FULL_TYPE 1 | |
33 | ||
bce0b691 CLG |
34 | /* |
35 | * OEM SEL Event data packet sent by BMC in response of a Read Event | |
36 | * Message Buffer command | |
37 | */ | |
38 | typedef struct OemSel { | |
39 | /* SEL header */ | |
40 | uint8_t id[2]; | |
41 | uint8_t type; | |
42 | uint8_t timestamp[4]; | |
43 | uint8_t manuf_id[3]; | |
44 | ||
45 | /* OEM SEL data (6 bytes) follows */ | |
46 | uint8_t netfun; | |
47 | uint8_t cmd; | |
48 | uint8_t data[4]; | |
49 | } OemSel; | |
50 | ||
51 | #define SOFT_OFF 0x00 | |
52 | #define SOFT_REBOOT 0x01 | |
53 | ||
54 | static void pnv_gen_oem_sel(IPMIBmc *bmc, uint8_t reboot) | |
55 | { | |
56 | /* IPMI SEL Event are 16 bytes long */ | |
57 | OemSel sel = { | |
58 | .id = { 0x55 , 0x55 }, | |
59 | .type = 0xC0, /* OEM */ | |
60 | .manuf_id = { 0x0, 0x0, 0x0 }, | |
61 | .timestamp = { 0x0, 0x0, 0x0, 0x0 }, | |
62 | .netfun = 0x3A, /* IBM */ | |
63 | .cmd = 0x04, /* AMI OEM SEL Power Notification */ | |
64 | .data = { reboot, 0xFF, 0xFF, 0xFF }, | |
65 | }; | |
66 | ||
67 | ipmi_bmc_gen_event(bmc, (uint8_t *) &sel, 0 /* do not log the event */); | |
68 | } | |
69 | ||
70 | void pnv_bmc_powerdown(IPMIBmc *bmc) | |
71 | { | |
72 | pnv_gen_oem_sel(bmc, SOFT_OFF); | |
73 | } | |
74 | ||
b168a138 | 75 | void pnv_dt_bmc_sensors(IPMIBmc *bmc, void *fdt) |
aeaef83d CLG |
76 | { |
77 | int offset; | |
78 | int i; | |
79 | const struct ipmi_sdr_compact *sdr; | |
80 | uint16_t nextrec; | |
81 | ||
82 | offset = fdt_add_subnode(fdt, 0, "/bmc"); | |
83 | _FDT(offset); | |
84 | ||
85 | _FDT((fdt_setprop_string(fdt, offset, "name", "bmc"))); | |
86 | _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 0x1))); | |
87 | _FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 0x0))); | |
88 | ||
89 | offset = fdt_add_subnode(fdt, offset, "sensors"); | |
90 | _FDT(offset); | |
91 | ||
92 | _FDT((fdt_setprop_cell(fdt, offset, "#address-cells", 0x1))); | |
93 | _FDT((fdt_setprop_cell(fdt, offset, "#size-cells", 0x0))); | |
94 | ||
95 | for (i = 0; !ipmi_bmc_sdr_find(bmc, i, &sdr, &nextrec); i++) { | |
96 | int off; | |
97 | char *name; | |
98 | ||
99 | if (sdr->header.rec_type != IPMI_SDR_COMPACT_TYPE && | |
100 | sdr->header.rec_type != IPMI_SDR_FULL_TYPE) { | |
101 | continue; | |
102 | } | |
103 | ||
104 | name = g_strdup_printf("sensor@%x", sdr->sensor_owner_number); | |
105 | off = fdt_add_subnode(fdt, offset, name); | |
106 | _FDT(off); | |
107 | g_free(name); | |
108 | ||
109 | _FDT((fdt_setprop_cell(fdt, off, "reg", sdr->sensor_owner_number))); | |
110 | _FDT((fdt_setprop_string(fdt, off, "name", "sensor"))); | |
111 | _FDT((fdt_setprop_string(fdt, off, "compatible", "ibm,ipmi-sensor"))); | |
112 | _FDT((fdt_setprop_cell(fdt, off, "ipmi-sensor-reading-type", | |
113 | sdr->reading_type))); | |
114 | _FDT((fdt_setprop_cell(fdt, off, "ipmi-entity-id", | |
115 | sdr->entity_id))); | |
116 | _FDT((fdt_setprop_cell(fdt, off, "ipmi-entity-instance", | |
117 | sdr->entity_instance))); | |
118 | _FDT((fdt_setprop_cell(fdt, off, "ipmi-sensor-type", | |
119 | sdr->sensor_type))); | |
120 | } | |
121 | } |