1*23076bb3SCorey Minyard /* 2*23076bb3SCorey Minyard * QEMU IPMI emulation 3*23076bb3SCorey Minyard * 4*23076bb3SCorey Minyard * Copyright (c) 2015 Corey Minyard, MontaVista Software, LLC 5*23076bb3SCorey Minyard * 6*23076bb3SCorey Minyard * Permission is hereby granted, free of charge, to any person obtaining a copy 7*23076bb3SCorey Minyard * of this software and associated documentation files (the "Software"), to deal 8*23076bb3SCorey Minyard * in the Software without restriction, including without limitation the rights 9*23076bb3SCorey Minyard * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10*23076bb3SCorey Minyard * copies of the Software, and to permit persons to whom the Software is 11*23076bb3SCorey Minyard * furnished to do so, subject to the following conditions: 12*23076bb3SCorey Minyard * 13*23076bb3SCorey Minyard * The above copyright notice and this permission notice shall be included in 14*23076bb3SCorey Minyard * all copies or substantial portions of the Software. 15*23076bb3SCorey Minyard * 16*23076bb3SCorey Minyard * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17*23076bb3SCorey Minyard * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18*23076bb3SCorey Minyard * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19*23076bb3SCorey Minyard * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20*23076bb3SCorey Minyard * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21*23076bb3SCorey Minyard * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22*23076bb3SCorey Minyard * THE SOFTWARE. 23*23076bb3SCorey Minyard */ 24*23076bb3SCorey Minyard 25*23076bb3SCorey Minyard #include "hw/hw.h" 26*23076bb3SCorey Minyard #include "hw/ipmi/ipmi.h" 27*23076bb3SCorey Minyard #include "sysemu/sysemu.h" 28*23076bb3SCorey Minyard #include "qmp-commands.h" 29*23076bb3SCorey Minyard #include "qom/object_interfaces.h" 30*23076bb3SCorey Minyard #include "qapi/visitor.h" 31*23076bb3SCorey Minyard 32*23076bb3SCorey Minyard static int ipmi_do_hw_op(IPMIInterface *s, enum ipmi_op op, int checkonly) 33*23076bb3SCorey Minyard { 34*23076bb3SCorey Minyard switch (op) { 35*23076bb3SCorey Minyard case IPMI_RESET_CHASSIS: 36*23076bb3SCorey Minyard if (checkonly) { 37*23076bb3SCorey Minyard return 0; 38*23076bb3SCorey Minyard } 39*23076bb3SCorey Minyard qemu_system_reset_request(); 40*23076bb3SCorey Minyard return 0; 41*23076bb3SCorey Minyard 42*23076bb3SCorey Minyard case IPMI_POWEROFF_CHASSIS: 43*23076bb3SCorey Minyard if (checkonly) { 44*23076bb3SCorey Minyard return 0; 45*23076bb3SCorey Minyard } 46*23076bb3SCorey Minyard qemu_system_powerdown_request(); 47*23076bb3SCorey Minyard return 0; 48*23076bb3SCorey Minyard 49*23076bb3SCorey Minyard case IPMI_SEND_NMI: 50*23076bb3SCorey Minyard if (checkonly) { 51*23076bb3SCorey Minyard return 0; 52*23076bb3SCorey Minyard } 53*23076bb3SCorey Minyard qemu_mutex_lock_iothread(); 54*23076bb3SCorey Minyard qmp_inject_nmi(NULL); 55*23076bb3SCorey Minyard qemu_mutex_unlock_iothread(); 56*23076bb3SCorey Minyard return 0; 57*23076bb3SCorey Minyard 58*23076bb3SCorey Minyard case IPMI_POWERCYCLE_CHASSIS: 59*23076bb3SCorey Minyard case IPMI_PULSE_DIAG_IRQ: 60*23076bb3SCorey Minyard case IPMI_SHUTDOWN_VIA_ACPI_OVERTEMP: 61*23076bb3SCorey Minyard case IPMI_POWERON_CHASSIS: 62*23076bb3SCorey Minyard default: 63*23076bb3SCorey Minyard return IPMI_CC_COMMAND_NOT_SUPPORTED; 64*23076bb3SCorey Minyard } 65*23076bb3SCorey Minyard } 66*23076bb3SCorey Minyard 67*23076bb3SCorey Minyard static void ipmi_interface_class_init(ObjectClass *class, void *data) 68*23076bb3SCorey Minyard { 69*23076bb3SCorey Minyard IPMIInterfaceClass *ik = IPMI_INTERFACE_CLASS(class); 70*23076bb3SCorey Minyard 71*23076bb3SCorey Minyard ik->do_hw_op = ipmi_do_hw_op; 72*23076bb3SCorey Minyard } 73*23076bb3SCorey Minyard 74*23076bb3SCorey Minyard static TypeInfo ipmi_interface_type_info = { 75*23076bb3SCorey Minyard .name = TYPE_IPMI_INTERFACE, 76*23076bb3SCorey Minyard .parent = TYPE_INTERFACE, 77*23076bb3SCorey Minyard .class_size = sizeof(IPMIInterfaceClass), 78*23076bb3SCorey Minyard .class_init = ipmi_interface_class_init, 79*23076bb3SCorey Minyard }; 80*23076bb3SCorey Minyard 81*23076bb3SCorey Minyard static void isa_ipmi_bmc_check(Object *obj, const char *name, 82*23076bb3SCorey Minyard Object *val, Error **errp) 83*23076bb3SCorey Minyard { 84*23076bb3SCorey Minyard IPMIBmc *bmc = IPMI_BMC(val); 85*23076bb3SCorey Minyard 86*23076bb3SCorey Minyard if (bmc->intf) 87*23076bb3SCorey Minyard error_setg(errp, "BMC object is already in use"); 88*23076bb3SCorey Minyard } 89*23076bb3SCorey Minyard 90*23076bb3SCorey Minyard void ipmi_bmc_find_and_link(Object *obj, Object **bmc) 91*23076bb3SCorey Minyard { 92*23076bb3SCorey Minyard object_property_add_link(obj, "bmc", TYPE_IPMI_BMC, bmc, 93*23076bb3SCorey Minyard isa_ipmi_bmc_check, 94*23076bb3SCorey Minyard OBJ_PROP_LINK_UNREF_ON_RELEASE, 95*23076bb3SCorey Minyard &error_abort); 96*23076bb3SCorey Minyard } 97*23076bb3SCorey Minyard 98*23076bb3SCorey Minyard static Property ipmi_bmc_properties[] = { 99*23076bb3SCorey Minyard DEFINE_PROP_UINT8("slave_addr", IPMIBmc, slave_addr, 0x20), 100*23076bb3SCorey Minyard DEFINE_PROP_END_OF_LIST(), 101*23076bb3SCorey Minyard }; 102*23076bb3SCorey Minyard 103*23076bb3SCorey Minyard static void bmc_class_init(ObjectClass *oc, void *data) 104*23076bb3SCorey Minyard { 105*23076bb3SCorey Minyard DeviceClass *dc = DEVICE_CLASS(oc); 106*23076bb3SCorey Minyard 107*23076bb3SCorey Minyard dc->props = ipmi_bmc_properties; 108*23076bb3SCorey Minyard } 109*23076bb3SCorey Minyard 110*23076bb3SCorey Minyard static TypeInfo ipmi_bmc_type_info = { 111*23076bb3SCorey Minyard .name = TYPE_IPMI_BMC, 112*23076bb3SCorey Minyard .parent = TYPE_DEVICE, 113*23076bb3SCorey Minyard .instance_size = sizeof(IPMIBmc), 114*23076bb3SCorey Minyard .abstract = true, 115*23076bb3SCorey Minyard .class_size = sizeof(IPMIBmcClass), 116*23076bb3SCorey Minyard .class_init = bmc_class_init, 117*23076bb3SCorey Minyard }; 118*23076bb3SCorey Minyard 119*23076bb3SCorey Minyard static void ipmi_register_types(void) 120*23076bb3SCorey Minyard { 121*23076bb3SCorey Minyard type_register_static(&ipmi_interface_type_info); 122*23076bb3SCorey Minyard type_register_static(&ipmi_bmc_type_info); 123*23076bb3SCorey Minyard } 124*23076bb3SCorey Minyard 125*23076bb3SCorey Minyard type_init(ipmi_register_types) 126