186e91dd7SCorey Minyard /* 286e91dd7SCorey Minyard * IPMI ACPI firmware handling 386e91dd7SCorey Minyard * 486e91dd7SCorey Minyard * Copyright (c) 2015,2016 Corey Minyard, MontaVista Software, LLC 586e91dd7SCorey Minyard * 686e91dd7SCorey Minyard * This work is licensed under the terms of the GNU GPL, version 2 or later. 786e91dd7SCorey Minyard * See the COPYING file in the top-level directory. 886e91dd7SCorey Minyard */ 986e91dd7SCorey Minyard 1086e91dd7SCorey Minyard #include "qemu/osdep.h" 1186e91dd7SCorey Minyard #include "hw/ipmi/ipmi.h" 1286e91dd7SCorey Minyard #include "hw/acpi/aml-build.h" 1386e91dd7SCorey Minyard #include "hw/acpi/acpi.h" 1486e91dd7SCorey Minyard #include "hw/acpi/ipmi.h" 1586e91dd7SCorey Minyard 16ea01c522SIgor Mammedov static Aml *aml_ipmi_crs(IPMIFwInfo *info) 1786e91dd7SCorey Minyard { 1886e91dd7SCorey Minyard Aml *crs = aml_resource_template(); 1986e91dd7SCorey Minyard 2086e91dd7SCorey Minyard /* 2186e91dd7SCorey Minyard * The base address is fixed and cannot change. That may be different 2286e91dd7SCorey Minyard * if someone does PCI, but we aren't there yet. 2386e91dd7SCorey Minyard */ 2486e91dd7SCorey Minyard switch (info->memspace) { 2586e91dd7SCorey Minyard case IPMI_MEMSPACE_IO: 2686e91dd7SCorey Minyard aml_append(crs, aml_io(AML_DECODE16, info->base_address, 2786e91dd7SCorey Minyard info->base_address + info->register_length - 1, 2886e91dd7SCorey Minyard info->register_spacing, info->register_length)); 2986e91dd7SCorey Minyard break; 3086e91dd7SCorey Minyard case IPMI_MEMSPACE_MEM32: 3186e91dd7SCorey Minyard aml_append(crs, 3286e91dd7SCorey Minyard aml_dword_memory(AML_POS_DECODE, 3386e91dd7SCorey Minyard AML_MIN_FIXED, AML_MAX_FIXED, 3486e91dd7SCorey Minyard AML_NON_CACHEABLE, AML_READ_WRITE, 3586e91dd7SCorey Minyard 0xffffffff, 3686e91dd7SCorey Minyard info->base_address, 3786e91dd7SCorey Minyard info->base_address + info->register_length - 1, 3886e91dd7SCorey Minyard info->register_spacing, info->register_length)); 3986e91dd7SCorey Minyard break; 4086e91dd7SCorey Minyard case IPMI_MEMSPACE_MEM64: 4186e91dd7SCorey Minyard aml_append(crs, 4286e91dd7SCorey Minyard aml_qword_memory(AML_POS_DECODE, 4386e91dd7SCorey Minyard AML_MIN_FIXED, AML_MAX_FIXED, 4486e91dd7SCorey Minyard AML_NON_CACHEABLE, AML_READ_WRITE, 4586e91dd7SCorey Minyard 0xffffffffffffffffULL, 4686e91dd7SCorey Minyard info->base_address, 4786e91dd7SCorey Minyard info->base_address + info->register_length - 1, 4886e91dd7SCorey Minyard info->register_spacing, info->register_length)); 4986e91dd7SCorey Minyard break; 5086e91dd7SCorey Minyard case IPMI_MEMSPACE_SMBUS: 51576d05b6SCorey Minyard aml_append(crs, aml_i2c_serial_bus_device(info->base_address, 52ea01c522SIgor Mammedov "^")); 5386e91dd7SCorey Minyard break; 5486e91dd7SCorey Minyard default: 5586e91dd7SCorey Minyard abort(); 5686e91dd7SCorey Minyard } 5786e91dd7SCorey Minyard 58*7376d10bSNicholas Piggin /* Should PCI interrupts also be appended? */ 59*7376d10bSNicholas Piggin if (info->irq_source == IPMI_ISA_IRQ && info->interrupt_number) { 6086e91dd7SCorey Minyard aml_append(crs, aml_irq_no_flags(info->interrupt_number)); 6186e91dd7SCorey Minyard } 6286e91dd7SCorey Minyard 6386e91dd7SCorey Minyard return crs; 6486e91dd7SCorey Minyard } 6586e91dd7SCorey Minyard 665876d9b5SIgor Mammedov void build_ipmi_dev_aml(AcpiDevAmlIf *adev, Aml *scope) 6786e91dd7SCorey Minyard { 6886e91dd7SCorey Minyard Aml *dev; 695876d9b5SIgor Mammedov IPMIFwInfo info = {}; 705876d9b5SIgor Mammedov IPMIInterface *ii = IPMI_INTERFACE(adev); 715876d9b5SIgor Mammedov IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); 725876d9b5SIgor Mammedov uint16_t version; 7386e91dd7SCorey Minyard 745876d9b5SIgor Mammedov iic->get_fwinfo(ii, &info); 755876d9b5SIgor Mammedov assert(info.ipmi_spec_minor_revision <= 15); 765876d9b5SIgor Mammedov version = ((info.ipmi_spec_major_revision << 8) 775876d9b5SIgor Mammedov | (info.ipmi_spec_minor_revision << 4)); 7886e91dd7SCorey Minyard 795876d9b5SIgor Mammedov dev = aml_device("MI%d", info.uuid); 8086e91dd7SCorey Minyard aml_append(dev, aml_name_decl("_HID", aml_eisaid("IPI0001"))); 8186e91dd7SCorey Minyard aml_append(dev, aml_name_decl("_STR", aml_string("ipmi_%s", 825876d9b5SIgor Mammedov info.interface_name))); 835876d9b5SIgor Mammedov aml_append(dev, aml_name_decl("_UID", aml_int(info.uuid))); 845876d9b5SIgor Mammedov aml_append(dev, aml_name_decl("_CRS", aml_ipmi_crs(&info))); 855876d9b5SIgor Mammedov aml_append(dev, aml_name_decl("_IFT", aml_int(info.interface_type))); 8686e91dd7SCorey Minyard aml_append(dev, aml_name_decl("_SRV", aml_int(version))); 8786e91dd7SCorey Minyard 885876d9b5SIgor Mammedov aml_append(scope, dev); 8986e91dd7SCorey Minyard } 90