cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

ipmi.c (3693B)


      1/*
      2 * IPMI ACPI firmware handling
      3 *
      4 * Copyright (c) 2015,2016 Corey Minyard, MontaVista Software, LLC
      5 *
      6 * This work is licensed under the terms of the GNU GPL, version 2 or later.
      7 * See the COPYING file in the top-level directory.
      8 */
      9
     10#include "qemu/osdep.h"
     11#include "hw/ipmi/ipmi.h"
     12#include "hw/acpi/aml-build.h"
     13#include "hw/acpi/acpi.h"
     14#include "hw/acpi/ipmi.h"
     15
     16static Aml *aml_ipmi_crs(IPMIFwInfo *info, const char *resource)
     17{
     18    Aml *crs = aml_resource_template();
     19
     20    /*
     21     * The base address is fixed and cannot change.  That may be different
     22     * if someone does PCI, but we aren't there yet.
     23     */
     24    switch (info->memspace) {
     25    case IPMI_MEMSPACE_IO:
     26        aml_append(crs, aml_io(AML_DECODE16, info->base_address,
     27                               info->base_address + info->register_length - 1,
     28                               info->register_spacing, info->register_length));
     29        break;
     30    case IPMI_MEMSPACE_MEM32:
     31        aml_append(crs,
     32                   aml_dword_memory(AML_POS_DECODE,
     33                            AML_MIN_FIXED, AML_MAX_FIXED,
     34                            AML_NON_CACHEABLE, AML_READ_WRITE,
     35                            0xffffffff,
     36                            info->base_address,
     37                            info->base_address + info->register_length - 1,
     38                            info->register_spacing, info->register_length));
     39        break;
     40    case IPMI_MEMSPACE_MEM64:
     41        aml_append(crs,
     42                   aml_qword_memory(AML_POS_DECODE,
     43                            AML_MIN_FIXED, AML_MAX_FIXED,
     44                            AML_NON_CACHEABLE, AML_READ_WRITE,
     45                            0xffffffffffffffffULL,
     46                            info->base_address,
     47                            info->base_address + info->register_length - 1,
     48                            info->register_spacing, info->register_length));
     49        break;
     50    case IPMI_MEMSPACE_SMBUS:
     51        aml_append(crs, aml_i2c_serial_bus_device(info->base_address,
     52                                                  resource));
     53        break;
     54    default:
     55        abort();
     56    }
     57
     58    if (info->interrupt_number) {
     59        aml_append(crs, aml_irq_no_flags(info->interrupt_number));
     60    }
     61
     62    return crs;
     63}
     64
     65static Aml *aml_ipmi_device(IPMIFwInfo *info, const char *resource)
     66{
     67    Aml *dev;
     68    uint16_t version = ((info->ipmi_spec_major_revision << 8)
     69                        | (info->ipmi_spec_minor_revision << 4));
     70
     71    assert(info->ipmi_spec_minor_revision <= 15);
     72
     73    dev = aml_device("MI%d", info->uuid);
     74    aml_append(dev, aml_name_decl("_HID", aml_eisaid("IPI0001")));
     75    aml_append(dev, aml_name_decl("_STR", aml_string("ipmi_%s",
     76                                                     info->interface_name)));
     77    aml_append(dev, aml_name_decl("_UID", aml_int(info->uuid)));
     78    aml_append(dev, aml_name_decl("_CRS", aml_ipmi_crs(info, resource)));
     79    aml_append(dev, aml_name_decl("_IFT", aml_int(info->interface_type)));
     80    aml_append(dev, aml_name_decl("_SRV", aml_int(version)));
     81
     82    return dev;
     83}
     84
     85void build_acpi_ipmi_devices(Aml *scope, BusState *bus, const char *resource)
     86{
     87
     88    BusChild *kid;
     89
     90    QTAILQ_FOREACH(kid, &bus->children,  sibling) {
     91        IPMIInterface *ii;
     92        IPMIInterfaceClass *iic;
     93        IPMIFwInfo info;
     94        Object *obj = object_dynamic_cast(OBJECT(kid->child),
     95                                          TYPE_IPMI_INTERFACE);
     96
     97        if (!obj) {
     98            continue;
     99        }
    100
    101        ii = IPMI_INTERFACE(obj);
    102        iic = IPMI_INTERFACE_GET_CLASS(obj);
    103        memset(&info, 0, sizeof(info));
    104        iic->get_fwinfo(ii, &info);
    105        aml_append(scope, aml_ipmi_device(&info, resource));
    106    }
    107}