Пример #1
0
Файл: xics.c Проект: 5kg/kvmtool
static void rtas_int_on(struct kvm_cpu *vcpu, uint32_t token,
			uint32_t nargs, target_ulong args,
			uint32_t nret, target_ulong rets)
{
	struct ics_state *ics = vcpu->kvm->arch.icp->ics;
	uint32_t nr;

	if ((nargs != 1) || (nret != 1)) {
		rtas_st(vcpu->kvm, rets, 0, -3);
		return;
	}

	nr = rtas_ld(vcpu->kvm, args, 0);

	if (!ics_valid_irq(ics, nr)) {
		rtas_st(vcpu->kvm, rets, 0, -3);
		return;
	}

	/* ME: QEMU wrote xive_msi here, in #if 0.  Deleted. */

	rtas_st(vcpu->kvm, rets, 0, 0); /* Success */
}
Пример #2
0
Файл: xics.c Проект: 5kg/kvmtool
static void rtas_get_xive(struct kvm_cpu *vcpu, uint32_t token,
			  uint32_t nargs, target_ulong args,
			  uint32_t nret, target_ulong rets)
{
	struct ics_state *ics = vcpu->kvm->arch.icp->ics;
	uint32_t nr;

	if ((nargs != 1) || (nret != 3)) {
		rtas_st(vcpu->kvm, rets, 0, -3);
		return;
	}

	nr = rtas_ld(vcpu->kvm, args, 0);

	if (!ics_valid_irq(ics, nr)) {
		rtas_st(vcpu->kvm, rets, 0, -3);
		return;
	}

	rtas_st(vcpu->kvm, rets, 0, 0); /* Success */
	rtas_st(vcpu->kvm, rets, 1, ics->irqs[nr - ics->offset].server);
	rtas_st(vcpu->kvm, rets, 2, ics->irqs[nr - ics->offset].priority);
}
Пример #3
0
static void rtas_get_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                          uint32_t token,
                          uint32_t nargs, target_ulong args,
                          uint32_t nret, target_ulong rets)
{
    ICSState *ics = spapr->icp->ics;
    uint32_t nr;

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

    nr = rtas_ld(args, 0);

    if (!ics_valid_irq(ics, nr)) {
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
        return;
    }

    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
    rtas_st(rets, 1, ics->irqs[nr - ics->offset].server);
    rtas_st(rets, 2, ics->irqs[nr - ics->offset].priority);
}
Пример #4
0
static void rtas_int_off(sPAPREnvironment *spapr, uint32_t token,
                         uint32_t nargs, target_ulong args,
                         uint32_t nret, target_ulong rets)
{
    struct ics_state *ics = spapr->icp->ics;
    uint32_t nr;

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

    nr = rtas_ld(args, 0);

    if (!ics_valid_irq(ics, nr)) {
        rtas_st(rets, 0, -3);
        return;
    }

    ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server, 0xff,
                   ics->irqs[nr - ics->offset].priority);

    rtas_st(rets, 0, 0); /* Success */
}
Пример #5
0
static void rtas_get_power_level(PowerPCCPU *cpu, sPAPRMachineState *spapr,
                                  uint32_t token, uint32_t nargs,
                                  target_ulong args, uint32_t nret,
                                  target_ulong rets)
{
    int32_t power_domain;

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

    /* we currently only use a single, "live insert" powerdomain for
     * hotplugged/dlpar'd resources, so the power is always live/full (100)
     */
    power_domain = rtas_ld(args, 0);
    if (power_domain != -1) {
        rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
        return;
    }

    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
    rtas_st(rets, 1, 100);
}
Пример #6
0
static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
                                          sPAPREnvironment *spapr,
                                          uint32_t token, uint32_t nargs,
                                          target_ulong args,
                                          uint32_t nret, target_ulong rets)
{
    target_ulong parameter = rtas_ld(args, 0);
    target_ulong ret = RTAS_OUT_NOT_SUPPORTED;

    switch (parameter) {
    case DIAGNOSTICS_RUN_MODE:
        ret = RTAS_OUT_NOT_AUTHORIZED;
        break;
    }

    rtas_st(rets, 0, ret);
}
Пример #7
0
static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                                 uint32_t token, uint32_t nargs,
                                 target_ulong args,
                                 uint32_t nret, target_ulong rets)
{
    struct tm tm;

    if (nret != 8) {
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
        return;
    }

    qemu_get_timedate(&tm, spapr->rtc_offset);

    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
    rtas_st(rets, 1, tm.tm_year + 1900);
    rtas_st(rets, 2, tm.tm_mon + 1);
    rtas_st(rets, 3, tm.tm_mday);
    rtas_st(rets, 4, tm.tm_hour);
    rtas_st(rets, 5, tm.tm_min);
    rtas_st(rets, 6, tm.tm_sec);
    rtas_st(rets, 7, 0); /* we don't do nanoseconds */
}
Пример #8
0
static void rtas_nvram_fetch(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                             uint32_t token, uint32_t nargs,
                             target_ulong args,
                             uint32_t nret, target_ulong rets)
{
    sPAPRNVRAM *nvram = spapr->nvram;
    hwaddr offset, buffer, len;
    int alen;
    void *membuf;

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

    if (!nvram) {
        rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
        rtas_st(rets, 1, 0);
        return;
    }

    offset = rtas_ld(args, 0);
    buffer = rtas_ld(args, 1);
    len = rtas_ld(args, 2);

    if (((offset + len) < offset)
        || ((offset + len) > nvram->size)) {
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
        rtas_st(rets, 1, 0);
        return;
    }

    membuf = cpu_physical_memory_map(buffer, &len, 1);
    if (nvram->drive) {
        alen = bdrv_pread(nvram->drive, offset, membuf, len);
    } else {
        assert(nvram->buf);

        memcpy(membuf, nvram->buf + offset, len);
        alen = len;
    }
    cpu_physical_memory_unmap(membuf, len, 1, len);

    rtas_st(rets, 0, (alen < len) ? RTAS_OUT_HW_ERROR : RTAS_OUT_SUCCESS);
    rtas_st(rets, 1, (alen < 0) ? 0 : alen);
}
Пример #9
0
static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
                                          sPAPRMachineState *spapr,
                                          uint32_t token, uint32_t nargs,
                                          target_ulong args,
                                          uint32_t nret, target_ulong rets)
{
    target_ulong parameter = rtas_ld(args, 0);
    target_ulong ret = RTAS_OUT_NOT_SUPPORTED;

    switch (parameter) {
    case RTAS_SYSPARM_SPLPAR_CHARACTERISTICS:
    case RTAS_SYSPARM_DIAGNOSTICS_RUN_MODE:
    case RTAS_SYSPARM_UUID:
        ret = RTAS_OUT_NOT_AUTHORIZED;
        break;
    }

    rtas_st(rets, 0, ret);
}
Пример #10
0
static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                                 uint32_t token, uint32_t nargs,
                                 target_ulong args,
                                 uint32_t nret, target_ulong rets)
{
    struct tm tm;

    tm.tm_year = rtas_ld(args, 0) - 1900;
    tm.tm_mon = rtas_ld(args, 1) - 1;
    tm.tm_mday = rtas_ld(args, 2);
    tm.tm_hour = rtas_ld(args, 3);
    tm.tm_min = rtas_ld(args, 4);
    tm.tm_sec = rtas_ld(args, 5);

    /* Just generate a monitor event for the change */
    rtc_change_mon_event(&tm);
    spapr->rtc_offset = qemu_timedate_diff(&tm);

    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
Пример #11
0
static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu,
                                          sPAPRMachineState *spapr,
                                          uint32_t token, uint32_t nargs,
                                          target_ulong args,
                                          uint32_t nret, target_ulong rets)
{
    target_ulong parameter = rtas_ld(args, 0);
    target_ulong buffer = rtas_ld(args, 1);
    target_ulong length = rtas_ld(args, 2);
    target_ulong ret;

    switch (parameter) {
    case RTAS_SYSPARM_SPLPAR_CHARACTERISTICS: {
        char *param_val = g_strdup_printf("MaxEntCap=%d,"
                                          "DesMem=%llu,"
                                          "DesProcs=%d,"
                                          "MaxPlatProcs=%d",
                                          max_cpus,
                                          current_machine->ram_size / M_BYTE,
                                          smp_cpus,
                                          max_cpus);
        ret = sysparm_st(buffer, length, param_val, strlen(param_val) + 1);
        g_free(param_val);
        break;
    }
    case RTAS_SYSPARM_DIAGNOSTICS_RUN_MODE: {
        uint8_t param_val = DIAGNOSTICS_RUN_MODE_DISABLED;

        ret = sysparm_st(buffer, length, &param_val, sizeof(param_val));
        break;
    }
    case RTAS_SYSPARM_UUID:
        ret = sysparm_st(buffer, length, (unsigned char *)&qemu_uuid,
                         (qemu_uuid_set ? 16 : 0));
        break;
    default:
        ret = RTAS_OUT_NOT_SUPPORTED;
    }

    rtas_st(rets, 0, ret);
}
Пример #12
0
static void rtas_ibm_create_pe_dma_window(PowerPCCPU *cpu,
                                          sPAPRMachineState *spapr,
                                          uint32_t token, uint32_t nargs,
                                          target_ulong args,
                                          uint32_t nret, target_ulong rets)
{
    sPAPRPHBState *sphb;
    sPAPRTCETable *tcet = NULL;
    uint32_t addr, page_shift, window_shift, liobn;
    uint64_t buid, win_addr;
    int windows;

    if ((nargs != 5) || (nret != 4)) {
        goto param_error_exit;
    }

    buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2);
    addr = rtas_ld(args, 0);
    sphb = spapr_pci_find_phb(spapr, buid);
    if (!sphb || !sphb->ddw_enabled) {
        goto param_error_exit;
    }

    page_shift = rtas_ld(args, 3);
    window_shift = rtas_ld(args, 4);
    liobn = spapr_phb_get_free_liobn(sphb);
    windows = spapr_phb_get_active_win_num(sphb);

    if (!(sphb->page_size_mask & (1ULL << page_shift)) ||
        (window_shift < page_shift)) {
        goto param_error_exit;
    }

    if (!liobn || !sphb->ddw_enabled || windows == SPAPR_PCI_DMA_MAX_WINDOWS) {
        goto hw_error_exit;
    }

    tcet = spapr_tce_find_by_liobn(liobn);
    if (!tcet) {
        goto hw_error_exit;
    }

    win_addr = (windows == 0) ? sphb->dma_win_addr : sphb->dma64_win_addr;
    spapr_tce_table_enable(tcet, page_shift, win_addr,
                           1ULL << (window_shift - page_shift));
    if (!tcet->nb_table) {
        goto hw_error_exit;
    }

    trace_spapr_iommu_ddw_create(buid, addr, 1ULL << page_shift,
                                 1ULL << window_shift, tcet->bus_offset, liobn);

    rtas_st(rets, 0, RTAS_OUT_SUCCESS);
    rtas_st(rets, 1, liobn);
    rtas_st(rets, 2, tcet->bus_offset >> 32);
    rtas_st(rets, 3, tcet->bus_offset & ((uint32_t) -1));

    return;

hw_error_exit:
    rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
    return;

param_error_exit:
    rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
}