Commit 8c8639df authored by Mike Day's avatar Mike Day Committed by Alexander Graf
Browse files

spapr_rtas: add set-indicator RTAS interface



This interface allows a guest to control various platform/device
sensors. Initially, we only implement support necessary to control
sensors that are required for hotplug: DR connector indicators/LEDs,
resource allocation state, and resource isolation state.

See docs/specs/ppc-spapr-hotplug.txt for a complete description of
this interface.

Signed-off-by: default avatarMike Day <ncmike@ncultra.org>
Signed-off-by: default avatarMichael Roth <mdroth@linux.vnet.ibm.com>
Reviewed-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
Signed-off-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
parent 094d2058
Loading
Loading
Loading
Loading
+84 −0
Original line number Diff line number Diff line
@@ -35,6 +35,18 @@
#include "qapi-event.h"

#include <libfdt.h>
#include "hw/ppc/spapr_drc.h"

/* #define DEBUG_SPAPR */

#ifdef DEBUG_SPAPR
#define DPRINTF(fmt, ...) \
    do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
#else
#define DPRINTF(fmt, ...) \
    do { } while (0)
#endif


static void rtas_display_character(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                                   uint32_t token, uint32_t nargs,
@@ -295,6 +307,76 @@ static void rtas_get_power_level(PowerPCCPU *cpu, sPAPREnvironment *spapr,
    rtas_st(rets, 1, 100);
}

static bool sensor_type_is_dr(uint32_t sensor_type)
{
    switch (sensor_type) {
    case RTAS_SENSOR_TYPE_ISOLATION_STATE:
    case RTAS_SENSOR_TYPE_DR:
    case RTAS_SENSOR_TYPE_ALLOCATION_STATE:
        return true;
    }

    return false;
}

static void rtas_set_indicator(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                               uint32_t token, uint32_t nargs,
                               target_ulong args, uint32_t nret,
                               target_ulong rets)
{
    uint32_t sensor_type;
    uint32_t sensor_index;
    uint32_t sensor_state;
    sPAPRDRConnector *drc;
    sPAPRDRConnectorClass *drck;

    if (nargs != 3 || nret != 1) {
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
        return;
    }

    sensor_type = rtas_ld(args, 0);
    sensor_index = rtas_ld(args, 1);
    sensor_state = rtas_ld(args, 2);

    if (!sensor_type_is_dr(sensor_type)) {
        goto out_unimplemented;
    }

    /* if this is a DR sensor we can assume sensor_index == drc_index */
    drc = spapr_dr_connector_by_index(sensor_index);
    if (!drc) {
        DPRINTF("rtas_set_indicator: invalid sensor/DRC index: %xh\n",
                sensor_index);
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
        return;
    }
    drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);

    switch (sensor_type) {
    case RTAS_SENSOR_TYPE_ISOLATION_STATE:
        drck->set_isolation_state(drc, sensor_state);
        break;
    case RTAS_SENSOR_TYPE_DR:
        drck->set_indicator_state(drc, sensor_state);
        break;
    case RTAS_SENSOR_TYPE_ALLOCATION_STATE:
        drck->set_allocation_state(drc, sensor_state);
        break;
    default:
        goto out_unimplemented;
    }

    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
    return;

out_unimplemented:
    /* currently only DR-related sensors are implemented */
    DPRINTF("rtas_set_indicator: sensor/indicator not implemented: %d\n",
            sensor_type);
    rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
}

static struct rtas_call {
    const char *name;
    spapr_rtas_fn fn;
@@ -424,6 +506,8 @@ static void core_rtas_register_types(void)
                        rtas_set_power_level);
    spapr_rtas_register(RTAS_GET_POWER_LEVEL, "get-power-level",
                        rtas_get_power_level);
    spapr_rtas_register(RTAS_SET_INDICATOR, "set-indicator",
                        rtas_set_indicator);
}

type_init(core_rtas_register_types)
+11 −0
Original line number Diff line number Diff line
@@ -430,6 +430,17 @@ int spapr_allocate_irq_block(int num, bool lsi, bool msi);
#define RTAS_SYSPARM_DIAGNOSTICS_RUN_MODE        42
#define RTAS_SYSPARM_UUID                        48

/* RTAS indicator/sensor types
 *
 * as defined by PAPR+ 2.7 7.3.5.4, Table 41
 *
 * NOTE: currently only DR-related sensors are implemented here
 */
#define RTAS_SENSOR_TYPE_ISOLATION_STATE        9001
#define RTAS_SENSOR_TYPE_DR                     9002
#define RTAS_SENSOR_TYPE_ALLOCATION_STATE       9003
#define RTAS_SENSOR_TYPE_ENTITY_SENSE RTAS_SENSOR_TYPE_ALLOCATION_STATE

/* Possible values for the platform-processor-diagnostics-run-mode parameter
 * of the RTAS ibm,get-system-parameter call.
 */