2018-12-09 20:45:56 +01:00
|
|
|
/*
|
|
|
|
* QEMU PowerPC sPAPR XIVE interrupt controller model
|
|
|
|
*
|
|
|
|
* Copyright (c) 2017-2018, IBM Corporation.
|
|
|
|
*
|
|
|
|
* This code is licensed under the GPL version 2 or later. See the
|
|
|
|
* COPYING file in the top-level directory.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "qemu/osdep.h"
|
|
|
|
#include "qemu/log.h"
|
2019-05-23 16:35:07 +02:00
|
|
|
#include "qemu/module.h"
|
2018-12-09 20:45:56 +01:00
|
|
|
#include "qapi/error.h"
|
|
|
|
#include "qemu/error-report.h"
|
|
|
|
#include "target/ppc/cpu.h"
|
|
|
|
#include "sysemu/cpus.h"
|
2019-08-12 07:23:38 +02:00
|
|
|
#include "sysemu/reset.h"
|
2019-08-12 07:23:45 +02:00
|
|
|
#include "migration/vmstate.h"
|
2018-12-09 20:45:56 +01:00
|
|
|
#include "monitor/monitor.h"
|
2018-12-11 23:38:14 +01:00
|
|
|
#include "hw/ppc/fdt.h"
|
2018-12-09 20:45:56 +01:00
|
|
|
#include "hw/ppc/spapr.h"
|
2019-01-17 08:53:26 +01:00
|
|
|
#include "hw/ppc/spapr_cpu_core.h"
|
2018-12-09 20:45:56 +01:00
|
|
|
#include "hw/ppc/spapr_xive.h"
|
|
|
|
#include "hw/ppc/xive.h"
|
|
|
|
#include "hw/ppc/xive_regs.h"
|
2019-08-12 07:23:51 +02:00
|
|
|
#include "hw/qdev-properties.h"
|
2020-11-23 17:37:17 +01:00
|
|
|
#include "trace.h"
|
2018-12-09 20:45:56 +01:00
|
|
|
|
|
|
|
/*
|
2023-07-14 13:32:24 +02:00
|
|
|
* XIVE Virtualization Controller BAR and Thread Management BAR that we
|
2018-12-09 20:45:56 +01:00
|
|
|
* use for the ESB pages and the TIMA pages
|
|
|
|
*/
|
|
|
|
#define SPAPR_XIVE_VC_BASE 0x0006010000000000ull
|
|
|
|
#define SPAPR_XIVE_TM_BASE 0x0006030203180000ull
|
|
|
|
|
2018-12-09 20:45:57 +01:00
|
|
|
/*
|
|
|
|
* The allocation of VP blocks is a complex operation in OPAL and the
|
|
|
|
* VP identifiers have a relation with the number of HW chips, the
|
|
|
|
* size of the VP blocks, VP grouping, etc. The QEMU sPAPR XIVE
|
|
|
|
* controller model does not have the same constraints and can use a
|
|
|
|
* simple mapping scheme of the CPU vcpu_id
|
|
|
|
*
|
|
|
|
* These identifiers are never returned to the OS.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define SPAPR_XIVE_NVT_BASE 0x400
|
|
|
|
|
|
|
|
/*
|
|
|
|
* sPAPR NVT and END indexing helpers
|
|
|
|
*/
|
|
|
|
static uint32_t spapr_xive_nvt_to_target(uint8_t nvt_blk, uint32_t nvt_idx)
|
|
|
|
{
|
|
|
|
return nvt_idx - SPAPR_XIVE_NVT_BASE;
|
|
|
|
}
|
|
|
|
|
2018-12-11 23:38:13 +01:00
|
|
|
static void spapr_xive_cpu_to_nvt(PowerPCCPU *cpu,
|
|
|
|
uint8_t *out_nvt_blk, uint32_t *out_nvt_idx)
|
|
|
|
{
|
|
|
|
assert(cpu);
|
|
|
|
|
|
|
|
if (out_nvt_blk) {
|
|
|
|
*out_nvt_blk = SPAPR_XIVE_BLOCK_ID;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (out_nvt_blk) {
|
|
|
|
*out_nvt_idx = SPAPR_XIVE_NVT_BASE + cpu->vcpu_id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int spapr_xive_target_to_nvt(uint32_t target,
|
|
|
|
uint8_t *out_nvt_blk, uint32_t *out_nvt_idx)
|
|
|
|
{
|
|
|
|
PowerPCCPU *cpu = spapr_find_cpu(target);
|
|
|
|
|
|
|
|
if (!cpu) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
spapr_xive_cpu_to_nvt(cpu, out_nvt_blk, out_nvt_idx);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* sPAPR END indexing uses a simple mapping of the CPU vcpu_id, 8
|
|
|
|
* priorities per CPU
|
|
|
|
*/
|
2019-05-13 10:42:34 +02:00
|
|
|
int spapr_xive_end_to_target(uint8_t end_blk, uint32_t end_idx,
|
|
|
|
uint32_t *out_server, uint8_t *out_prio)
|
|
|
|
{
|
|
|
|
|
|
|
|
assert(end_blk == SPAPR_XIVE_BLOCK_ID);
|
|
|
|
|
|
|
|
if (out_server) {
|
|
|
|
*out_server = end_idx >> 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (out_prio) {
|
|
|
|
*out_prio = end_idx & 0x7;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-12-11 23:38:13 +01:00
|
|
|
static void spapr_xive_cpu_to_end(PowerPCCPU *cpu, uint8_t prio,
|
|
|
|
uint8_t *out_end_blk, uint32_t *out_end_idx)
|
|
|
|
{
|
|
|
|
assert(cpu);
|
|
|
|
|
|
|
|
if (out_end_blk) {
|
|
|
|
*out_end_blk = SPAPR_XIVE_BLOCK_ID;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (out_end_idx) {
|
|
|
|
*out_end_idx = (cpu->vcpu_id << 3) + prio;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int spapr_xive_target_to_end(uint32_t target, uint8_t prio,
|
|
|
|
uint8_t *out_end_blk, uint32_t *out_end_idx)
|
|
|
|
{
|
|
|
|
PowerPCCPU *cpu = spapr_find_cpu(target);
|
|
|
|
|
|
|
|
if (!cpu) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
spapr_xive_cpu_to_end(cpu, prio, out_end_blk, out_end_idx);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-12-09 20:45:56 +01:00
|
|
|
/*
|
|
|
|
* On sPAPR machines, use a simplified output for the XIVE END
|
|
|
|
* structure dumping only the information related to the OS EQ.
|
|
|
|
*/
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
static void spapr_xive_end_pic_print_info(SpaprXive *xive, XiveEND *end,
|
2018-12-09 20:45:56 +01:00
|
|
|
Monitor *mon)
|
|
|
|
{
|
2019-05-08 19:19:46 +02:00
|
|
|
uint64_t qaddr_base = xive_end_qaddr(end);
|
2018-12-09 20:45:56 +01:00
|
|
|
uint32_t qindex = xive_get_field32(END_W1_PAGE_OFF, end->w1);
|
|
|
|
uint32_t qgen = xive_get_field32(END_W1_GENERATION, end->w1);
|
|
|
|
uint32_t qsize = xive_get_field32(END_W0_QSIZE, end->w0);
|
|
|
|
uint32_t qentries = 1 << (qsize + 10);
|
|
|
|
uint32_t nvt = xive_get_field32(END_W6_NVT_INDEX, end->w6);
|
|
|
|
uint8_t priority = xive_get_field32(END_W7_F0_PRIORITY, end->w7);
|
|
|
|
|
2019-05-08 19:19:46 +02:00
|
|
|
monitor_printf(mon, "%3d/%d % 6d/%5d @%"PRIx64" ^%d",
|
2018-12-09 20:45:57 +01:00
|
|
|
spapr_xive_nvt_to_target(0, nvt),
|
2019-05-08 19:19:46 +02:00
|
|
|
priority, qindex, qentries, qaddr_base, qgen);
|
2018-12-09 20:45:56 +01:00
|
|
|
|
|
|
|
xive_end_queue_pic_print_info(end, 6, mon);
|
|
|
|
}
|
|
|
|
|
2020-08-07 13:32:14 +02:00
|
|
|
/*
|
|
|
|
* kvm_irqchip_in_kernel() will cause the compiler to turn this
|
|
|
|
* info a nop if CONFIG_KVM isn't defined.
|
|
|
|
*/
|
|
|
|
#define spapr_xive_in_kernel(xive) \
|
|
|
|
(kvm_irqchip_in_kernel() && (xive)->fd != -1)
|
|
|
|
|
2020-12-15 18:40:25 +01:00
|
|
|
static void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon)
|
2018-12-09 20:45:56 +01:00
|
|
|
{
|
|
|
|
XiveSource *xsrc = &xive->source;
|
|
|
|
int i;
|
|
|
|
|
2020-08-07 13:32:14 +02:00
|
|
|
if (spapr_xive_in_kernel(xive)) {
|
2019-05-13 10:42:35 +02:00
|
|
|
Error *local_err = NULL;
|
|
|
|
|
|
|
|
kvmppc_xive_synchronize_state(xive, &local_err);
|
|
|
|
if (local_err) {
|
|
|
|
error_report_err(local_err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-09 10:07:50 +02:00
|
|
|
monitor_printf(mon, " LISN PQ EISN CPU/PRIO EQ\n");
|
2018-12-09 20:45:56 +01:00
|
|
|
|
|
|
|
for (i = 0; i < xive->nr_irqs; i++) {
|
|
|
|
uint8_t pq = xive_source_esb_get(xsrc, i);
|
|
|
|
XiveEAS *eas = &xive->eat[i];
|
|
|
|
|
|
|
|
if (!xive_eas_is_valid(eas)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
monitor_printf(mon, " %08x %s %c%c%c %s %08x ", i,
|
|
|
|
xive_source_irq_is_lsi(xsrc, i) ? "LSI" : "MSI",
|
|
|
|
pq & XIVE_ESB_VAL_P ? 'P' : '-',
|
|
|
|
pq & XIVE_ESB_VAL_Q ? 'Q' : '-',
|
2021-10-04 23:21:41 +02:00
|
|
|
xive_source_is_asserted(xsrc, i) ? 'A' : ' ',
|
2018-12-09 20:45:56 +01:00
|
|
|
xive_eas_is_masked(eas) ? "M" : " ",
|
|
|
|
(int) xive_get_field64(EAS_END_DATA, eas->w));
|
|
|
|
|
|
|
|
if (!xive_eas_is_masked(eas)) {
|
|
|
|
uint32_t end_idx = xive_get_field64(EAS_END_INDEX, eas->w);
|
|
|
|
XiveEND *end;
|
|
|
|
|
|
|
|
assert(end_idx < xive->nr_ends);
|
|
|
|
end = &xive->endt[end_idx];
|
|
|
|
|
|
|
|
if (xive_end_is_valid(end)) {
|
|
|
|
spapr_xive_end_pic_print_info(xive, end, mon);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
monitor_printf(mon, "\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool enable)
|
2019-01-02 06:57:43 +01:00
|
|
|
{
|
|
|
|
memory_region_set_enabled(&xive->source.esb_mmio, enable);
|
|
|
|
memory_region_set_enabled(&xive->tm_mmio, enable);
|
|
|
|
|
|
|
|
/* Disable the END ESBs until a guest OS makes use of them */
|
|
|
|
memory_region_set_enabled(&xive->end_source.esb_mmio, false);
|
|
|
|
}
|
|
|
|
|
2019-11-25 07:58:14 +01:00
|
|
|
static void spapr_xive_tm_write(void *opaque, hwaddr offset,
|
|
|
|
uint64_t value, unsigned size)
|
|
|
|
{
|
|
|
|
XiveTCTX *tctx = spapr_cpu_state(POWERPC_CPU(current_cpu))->tctx;
|
|
|
|
|
|
|
|
xive_tctx_tm_write(XIVE_PRESENTER(opaque), tctx, offset, value, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint64_t spapr_xive_tm_read(void *opaque, hwaddr offset, unsigned size)
|
|
|
|
{
|
|
|
|
XiveTCTX *tctx = spapr_cpu_state(POWERPC_CPU(current_cpu))->tctx;
|
|
|
|
|
|
|
|
return xive_tctx_tm_read(XIVE_PRESENTER(opaque), tctx, offset, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
const MemoryRegionOps spapr_xive_tm_ops = {
|
|
|
|
.read = spapr_xive_tm_read,
|
|
|
|
.write = spapr_xive_tm_write,
|
|
|
|
.endianness = DEVICE_BIG_ENDIAN,
|
|
|
|
.valid = {
|
|
|
|
.min_access_size = 1,
|
|
|
|
.max_access_size = 8,
|
|
|
|
},
|
|
|
|
.impl = {
|
|
|
|
.min_access_size = 1,
|
|
|
|
.max_access_size = 8,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2018-12-09 20:45:56 +01:00
|
|
|
static void spapr_xive_end_reset(XiveEND *end)
|
|
|
|
{
|
|
|
|
memset(end, 0, sizeof(*end));
|
|
|
|
|
|
|
|
/* switch off the escalation and notification ESBs */
|
|
|
|
end->w1 = cpu_to_be32(END_W1_ESe_Q | END_W1_ESn_Q);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void spapr_xive_reset(void *dev)
|
|
|
|
{
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprXive *xive = SPAPR_XIVE(dev);
|
2018-12-09 20:45:56 +01:00
|
|
|
int i;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The XiveSource has its own reset handler, which mask off all
|
|
|
|
* IRQs (!P|Q)
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Mask all valid EASs in the IRQ number space. */
|
|
|
|
for (i = 0; i < xive->nr_irqs; i++) {
|
|
|
|
XiveEAS *eas = &xive->eat[i];
|
|
|
|
if (xive_eas_is_valid(eas)) {
|
|
|
|
eas->w = cpu_to_be64(EAS_VALID | EAS_MASKED);
|
|
|
|
} else {
|
|
|
|
eas->w = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Clear all ENDs */
|
|
|
|
for (i = 0; i < xive->nr_ends; i++) {
|
|
|
|
spapr_xive_end_reset(&xive->endt[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void spapr_xive_instance_init(Object *obj)
|
|
|
|
{
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprXive *xive = SPAPR_XIVE(obj);
|
2018-12-09 20:45:56 +01:00
|
|
|
|
qom: Less verbose object_initialize_child()
All users of object_initialize_child() pass the obvious child size
argument. Almost all pass &error_abort and no properties. Tiresome.
Rename object_initialize_child() to
object_initialize_child_with_props() to free the name. New
convenience wrapper object_initialize_child() automates the size
argument, and passes &error_abort and no properties.
Rename object_initialize_childv() to
object_initialize_child_with_propsv() for consistency.
Convert callers with this Coccinelle script:
@@
expression parent, propname, type;
expression child, size;
symbol error_abort;
@@
- object_initialize_child(parent, propname, OBJECT(child), size, type, &error_abort, NULL)
+ object_initialize_child(parent, propname, child, size, type, &error_abort, NULL)
@@
expression parent, propname, type;
expression child;
symbol error_abort;
@@
- object_initialize_child(parent, propname, child, sizeof(*child), type, &error_abort, NULL)
+ object_initialize_child(parent, propname, child, type)
@@
expression parent, propname, type;
expression child;
symbol error_abort;
@@
- object_initialize_child(parent, propname, &child, sizeof(child), type, &error_abort, NULL)
+ object_initialize_child(parent, propname, &child, type)
@@
expression parent, propname, type;
expression child, size, err;
expression list props;
@@
- object_initialize_child(parent, propname, child, size, type, err, props)
+ object_initialize_child_with_props(parent, propname, child, size, type, err, props)
Note that Coccinelle chokes on ARMSSE typedef vs. macro in
hw/arm/armsse.c. Worked around by temporarily renaming the macro for
the spatch run.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
[Rebased: machine opentitan is new (commit fe0fe4735e7)]
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-37-armbru@redhat.com>
2020-06-10 07:32:25 +02:00
|
|
|
object_initialize_child(obj, "source", &xive->source, TYPE_XIVE_SOURCE);
|
2018-12-09 20:45:56 +01:00
|
|
|
|
2019-02-21 12:24:48 +01:00
|
|
|
object_initialize_child(obj, "end_source", &xive->end_source,
|
qom: Less verbose object_initialize_child()
All users of object_initialize_child() pass the obvious child size
argument. Almost all pass &error_abort and no properties. Tiresome.
Rename object_initialize_child() to
object_initialize_child_with_props() to free the name. New
convenience wrapper object_initialize_child() automates the size
argument, and passes &error_abort and no properties.
Rename object_initialize_childv() to
object_initialize_child_with_propsv() for consistency.
Convert callers with this Coccinelle script:
@@
expression parent, propname, type;
expression child, size;
symbol error_abort;
@@
- object_initialize_child(parent, propname, OBJECT(child), size, type, &error_abort, NULL)
+ object_initialize_child(parent, propname, child, size, type, &error_abort, NULL)
@@
expression parent, propname, type;
expression child;
symbol error_abort;
@@
- object_initialize_child(parent, propname, child, sizeof(*child), type, &error_abort, NULL)
+ object_initialize_child(parent, propname, child, type)
@@
expression parent, propname, type;
expression child;
symbol error_abort;
@@
- object_initialize_child(parent, propname, &child, sizeof(child), type, &error_abort, NULL)
+ object_initialize_child(parent, propname, &child, type)
@@
expression parent, propname, type;
expression child, size, err;
expression list props;
@@
- object_initialize_child(parent, propname, child, size, type, err, props)
+ object_initialize_child_with_props(parent, propname, child, size, type, err, props)
Note that Coccinelle chokes on ARMSSE typedef vs. macro in
hw/arm/armsse.c. Worked around by temporarily renaming the macro for
the spatch run.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
[Rebased: machine opentitan is new (commit fe0fe4735e7)]
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-37-armbru@redhat.com>
2020-06-10 07:32:25 +02:00
|
|
|
TYPE_XIVE_END_SOURCE);
|
2019-05-13 10:42:33 +02:00
|
|
|
|
|
|
|
/* Not connected to the KVM XIVE device */
|
|
|
|
xive->fd = -1;
|
2018-12-09 20:45:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void spapr_xive_realize(DeviceState *dev, Error **errp)
|
|
|
|
{
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprXive *xive = SPAPR_XIVE(dev);
|
2019-12-19 19:11:47 +01:00
|
|
|
SpaprXiveClass *sxc = SPAPR_XIVE_GET_CLASS(xive);
|
2018-12-09 20:45:56 +01:00
|
|
|
XiveSource *xsrc = &xive->source;
|
|
|
|
XiveENDSource *end_xsrc = &xive->end_source;
|
|
|
|
Error *local_err = NULL;
|
|
|
|
|
2020-11-20 18:46:39 +01:00
|
|
|
/* Set by spapr_irq_init() */
|
|
|
|
g_assert(xive->nr_irqs);
|
|
|
|
g_assert(xive->nr_ends);
|
|
|
|
|
2019-12-19 19:11:47 +01:00
|
|
|
sxc->parent_realize(dev, &local_err);
|
|
|
|
if (local_err) {
|
|
|
|
error_propagate(errp, local_err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-12-09 20:45:56 +01:00
|
|
|
/*
|
|
|
|
* Initialize the internal sources, for IPIs and virtual devices.
|
|
|
|
*/
|
qom: Put name parameter before value / visitor parameter
The object_property_set_FOO() setters take property name and value in
an unusual order:
void object_property_set_FOO(Object *obj, FOO_TYPE value,
const char *name, Error **errp)
Having to pass value before name feels grating. Swap them.
Same for object_property_set(), object_property_get(), and
object_property_parse().
Convert callers with this Coccinelle script:
@@
identifier fun = {
object_property_get, object_property_parse, object_property_set_str,
object_property_set_link, object_property_set_bool,
object_property_set_int, object_property_set_uint, object_property_set,
object_property_set_qobject
};
expression obj, v, name, errp;
@@
- fun(obj, v, name, errp)
+ fun(obj, name, v, errp)
Chokes on hw/arm/musicpal.c's lcd_refresh() with the unhelpful error
message "no position information". Convert that one manually.
Fails to convert hw/arm/armsse.c, because Coccinelle gets confused by
ARMSSE being used both as typedef and function-like macro there.
Convert manually.
Fails to convert hw/rx/rx-gdbsim.c, because Coccinelle gets confused
by RXCPU being used both as typedef and function-like macro there.
Convert manually. The other files using RXCPU that way don't need
conversion.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <20200707160613.848843-27-armbru@redhat.com>
[Straightforwad conflict with commit 2336172d9b "audio: set default
value for pcspk.iobase property" resolved]
2020-07-07 18:05:54 +02:00
|
|
|
object_property_set_int(OBJECT(xsrc), "nr-irqs", xive->nr_irqs,
|
2018-12-09 20:45:56 +01:00
|
|
|
&error_fatal);
|
qom: Put name parameter before value / visitor parameter
The object_property_set_FOO() setters take property name and value in
an unusual order:
void object_property_set_FOO(Object *obj, FOO_TYPE value,
const char *name, Error **errp)
Having to pass value before name feels grating. Swap them.
Same for object_property_set(), object_property_get(), and
object_property_parse().
Convert callers with this Coccinelle script:
@@
identifier fun = {
object_property_get, object_property_parse, object_property_set_str,
object_property_set_link, object_property_set_bool,
object_property_set_int, object_property_set_uint, object_property_set,
object_property_set_qobject
};
expression obj, v, name, errp;
@@
- fun(obj, v, name, errp)
+ fun(obj, name, v, errp)
Chokes on hw/arm/musicpal.c's lcd_refresh() with the unhelpful error
message "no position information". Convert that one manually.
Fails to convert hw/arm/armsse.c, because Coccinelle gets confused by
ARMSSE being used both as typedef and function-like macro there.
Convert manually.
Fails to convert hw/rx/rx-gdbsim.c, because Coccinelle gets confused
by RXCPU being used both as typedef and function-like macro there.
Convert manually. The other files using RXCPU that way don't need
conversion.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <20200707160613.848843-27-armbru@redhat.com>
[Straightforwad conflict with commit 2336172d9b "audio: set default
value for pcspk.iobase property" resolved]
2020-07-07 18:05:54 +02:00
|
|
|
object_property_set_link(OBJECT(xsrc), "xive", OBJECT(xive), &error_abort);
|
error: Eliminate error_propagate() with Coccinelle, part 1
When all we do with an Error we receive into a local variable is
propagating to somewhere else, we can just as well receive it there
right away. Convert
if (!foo(..., &err)) {
...
error_propagate(errp, err);
...
return ...
}
to
if (!foo(..., errp)) {
...
...
return ...
}
where nothing else needs @err. Coccinelle script:
@rule1 forall@
identifier fun, err, errp, lbl;
expression list args, args2;
binary operator op;
constant c1, c2;
symbol false;
@@
if (
(
- fun(args, &err, args2)
+ fun(args, errp, args2)
|
- !fun(args, &err, args2)
+ !fun(args, errp, args2)
|
- fun(args, &err, args2) op c1
+ fun(args, errp, args2) op c1
)
)
{
... when != err
when != lbl:
when strict
- error_propagate(errp, err);
... when != err
(
return;
|
return c2;
|
return false;
)
}
@rule2 forall@
identifier fun, err, errp, lbl;
expression list args, args2;
expression var;
binary operator op;
constant c1, c2;
symbol false;
@@
- var = fun(args, &err, args2);
+ var = fun(args, errp, args2);
... when != err
if (
(
var
|
!var
|
var op c1
)
)
{
... when != err
when != lbl:
when strict
- error_propagate(errp, err);
... when != err
(
return;
|
return c2;
|
return false;
|
return var;
)
}
@depends on rule1 || rule2@
identifier err;
@@
- Error *err = NULL;
... when != err
Not exactly elegant, I'm afraid.
The "when != lbl:" is necessary to avoid transforming
if (fun(args, &err)) {
goto out
}
...
out:
error_propagate(errp, err);
even though other paths to label out still need the error_propagate().
For an actual example, see sclp_realize().
Without the "when strict", Coccinelle transforms vfio_msix_setup(),
incorrectly. I don't know what exactly "when strict" does, only that
it helps here.
The match of return is narrower than what I want, but I can't figure
out how to express "return where the operand doesn't use @err". For
an example where it's too narrow, see vfio_intx_enable().
Silently fails to convert hw/arm/armsse.c, because Coccinelle gets
confused by ARMSSE being used both as typedef and function-like macro
there. Converted manually.
Line breaks tidied up manually. One nested declaration of @local_err
deleted manually. Preexisting unwanted blank line dropped in
hw/riscv/sifive_e.c.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20200707160613.848843-35-armbru@redhat.com>
2020-07-07 18:06:02 +02:00
|
|
|
if (!qdev_realize(DEVICE(xsrc), NULL, errp)) {
|
2018-12-09 20:45:56 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialize the END ESB source
|
|
|
|
*/
|
qom: Put name parameter before value / visitor parameter
The object_property_set_FOO() setters take property name and value in
an unusual order:
void object_property_set_FOO(Object *obj, FOO_TYPE value,
const char *name, Error **errp)
Having to pass value before name feels grating. Swap them.
Same for object_property_set(), object_property_get(), and
object_property_parse().
Convert callers with this Coccinelle script:
@@
identifier fun = {
object_property_get, object_property_parse, object_property_set_str,
object_property_set_link, object_property_set_bool,
object_property_set_int, object_property_set_uint, object_property_set,
object_property_set_qobject
};
expression obj, v, name, errp;
@@
- fun(obj, v, name, errp)
+ fun(obj, name, v, errp)
Chokes on hw/arm/musicpal.c's lcd_refresh() with the unhelpful error
message "no position information". Convert that one manually.
Fails to convert hw/arm/armsse.c, because Coccinelle gets confused by
ARMSSE being used both as typedef and function-like macro there.
Convert manually.
Fails to convert hw/rx/rx-gdbsim.c, because Coccinelle gets confused
by RXCPU being used both as typedef and function-like macro there.
Convert manually. The other files using RXCPU that way don't need
conversion.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <20200707160613.848843-27-armbru@redhat.com>
[Straightforwad conflict with commit 2336172d9b "audio: set default
value for pcspk.iobase property" resolved]
2020-07-07 18:05:54 +02:00
|
|
|
object_property_set_int(OBJECT(end_xsrc), "nr-ends", xive->nr_irqs,
|
2018-12-09 20:45:56 +01:00
|
|
|
&error_fatal);
|
qom: Put name parameter before value / visitor parameter
The object_property_set_FOO() setters take property name and value in
an unusual order:
void object_property_set_FOO(Object *obj, FOO_TYPE value,
const char *name, Error **errp)
Having to pass value before name feels grating. Swap them.
Same for object_property_set(), object_property_get(), and
object_property_parse().
Convert callers with this Coccinelle script:
@@
identifier fun = {
object_property_get, object_property_parse, object_property_set_str,
object_property_set_link, object_property_set_bool,
object_property_set_int, object_property_set_uint, object_property_set,
object_property_set_qobject
};
expression obj, v, name, errp;
@@
- fun(obj, v, name, errp)
+ fun(obj, name, v, errp)
Chokes on hw/arm/musicpal.c's lcd_refresh() with the unhelpful error
message "no position information". Convert that one manually.
Fails to convert hw/arm/armsse.c, because Coccinelle gets confused by
ARMSSE being used both as typedef and function-like macro there.
Convert manually.
Fails to convert hw/rx/rx-gdbsim.c, because Coccinelle gets confused
by RXCPU being used both as typedef and function-like macro there.
Convert manually. The other files using RXCPU that way don't need
conversion.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <20200707160613.848843-27-armbru@redhat.com>
[Straightforwad conflict with commit 2336172d9b "audio: set default
value for pcspk.iobase property" resolved]
2020-07-07 18:05:54 +02:00
|
|
|
object_property_set_link(OBJECT(end_xsrc), "xive", OBJECT(xive),
|
2019-11-15 16:55:37 +01:00
|
|
|
&error_abort);
|
error: Eliminate error_propagate() with Coccinelle, part 1
When all we do with an Error we receive into a local variable is
propagating to somewhere else, we can just as well receive it there
right away. Convert
if (!foo(..., &err)) {
...
error_propagate(errp, err);
...
return ...
}
to
if (!foo(..., errp)) {
...
...
return ...
}
where nothing else needs @err. Coccinelle script:
@rule1 forall@
identifier fun, err, errp, lbl;
expression list args, args2;
binary operator op;
constant c1, c2;
symbol false;
@@
if (
(
- fun(args, &err, args2)
+ fun(args, errp, args2)
|
- !fun(args, &err, args2)
+ !fun(args, errp, args2)
|
- fun(args, &err, args2) op c1
+ fun(args, errp, args2) op c1
)
)
{
... when != err
when != lbl:
when strict
- error_propagate(errp, err);
... when != err
(
return;
|
return c2;
|
return false;
)
}
@rule2 forall@
identifier fun, err, errp, lbl;
expression list args, args2;
expression var;
binary operator op;
constant c1, c2;
symbol false;
@@
- var = fun(args, &err, args2);
+ var = fun(args, errp, args2);
... when != err
if (
(
var
|
!var
|
var op c1
)
)
{
... when != err
when != lbl:
when strict
- error_propagate(errp, err);
... when != err
(
return;
|
return c2;
|
return false;
|
return var;
)
}
@depends on rule1 || rule2@
identifier err;
@@
- Error *err = NULL;
... when != err
Not exactly elegant, I'm afraid.
The "when != lbl:" is necessary to avoid transforming
if (fun(args, &err)) {
goto out
}
...
out:
error_propagate(errp, err);
even though other paths to label out still need the error_propagate().
For an actual example, see sclp_realize().
Without the "when strict", Coccinelle transforms vfio_msix_setup(),
incorrectly. I don't know what exactly "when strict" does, only that
it helps here.
The match of return is narrower than what I want, but I can't figure
out how to express "return where the operand doesn't use @err". For
an example where it's too narrow, see vfio_intx_enable().
Silently fails to convert hw/arm/armsse.c, because Coccinelle gets
confused by ARMSSE being used both as typedef and function-like macro
there. Converted manually.
Line breaks tidied up manually. One nested declaration of @local_err
deleted manually. Preexisting unwanted blank line dropped in
hw/riscv/sifive_e.c.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20200707160613.848843-35-armbru@redhat.com>
2020-07-07 18:06:02 +02:00
|
|
|
if (!qdev_realize(DEVICE(end_xsrc), NULL, errp)) {
|
2018-12-09 20:45:56 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the mapping address of the END ESB pages after the source ESBs */
|
2020-08-13 19:28:10 +02:00
|
|
|
xive->end_base = xive->vc_base + xive_source_esb_len(xsrc);
|
2018-12-09 20:45:56 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Allocate the routing tables
|
|
|
|
*/
|
|
|
|
xive->eat = g_new0(XiveEAS, xive->nr_irqs);
|
|
|
|
xive->endt = g_new0(XiveEND, xive->nr_ends);
|
|
|
|
|
2019-05-13 10:42:33 +02:00
|
|
|
xive->nodename = g_strdup_printf("interrupt-controller@%" PRIx64,
|
|
|
|
xive->tm_base + XIVE_TM_USER_PAGE * (1 << TM_SHIFT));
|
|
|
|
|
|
|
|
qemu_register_reset(spapr_xive_reset, dev);
|
2019-05-22 09:40:15 +02:00
|
|
|
|
2018-12-09 20:45:56 +01:00
|
|
|
/* TIMA initialization */
|
2019-11-25 07:58:14 +01:00
|
|
|
memory_region_init_io(&xive->tm_mmio, OBJECT(xive), &spapr_xive_tm_ops,
|
|
|
|
xive, "xive.tima", 4ull << TM_SHIFT);
|
2018-12-09 20:45:56 +01:00
|
|
|
|
2019-06-14 18:59:19 +02:00
|
|
|
/*
|
|
|
|
* Map all regions. These will be enabled or disabled at reset and
|
|
|
|
* can also be overridden by KVM memory regions if active
|
|
|
|
*/
|
2023-10-18 07:53:54 +02:00
|
|
|
memory_region_add_subregion(get_system_memory(), xive->vc_base,
|
|
|
|
&xsrc->esb_mmio);
|
|
|
|
memory_region_add_subregion(get_system_memory(), xive->end_base,
|
|
|
|
&end_xsrc->esb_mmio);
|
|
|
|
memory_region_add_subregion(get_system_memory(), xive->tm_base,
|
|
|
|
&xive->tm_mmio);
|
2018-12-09 20:45:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static int spapr_xive_get_eas(XiveRouter *xrtr, uint8_t eas_blk,
|
|
|
|
uint32_t eas_idx, XiveEAS *eas)
|
|
|
|
{
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprXive *xive = SPAPR_XIVE(xrtr);
|
2018-12-09 20:45:56 +01:00
|
|
|
|
|
|
|
if (eas_idx >= xive->nr_irqs) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
*eas = xive->eat[eas_idx];
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int spapr_xive_get_end(XiveRouter *xrtr,
|
|
|
|
uint8_t end_blk, uint32_t end_idx, XiveEND *end)
|
|
|
|
{
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprXive *xive = SPAPR_XIVE(xrtr);
|
2018-12-09 20:45:56 +01:00
|
|
|
|
|
|
|
if (end_idx >= xive->nr_ends) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(end, &xive->endt[end_idx], sizeof(XiveEND));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int spapr_xive_write_end(XiveRouter *xrtr, uint8_t end_blk,
|
|
|
|
uint32_t end_idx, XiveEND *end,
|
|
|
|
uint8_t word_number)
|
|
|
|
{
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprXive *xive = SPAPR_XIVE(xrtr);
|
2018-12-09 20:45:56 +01:00
|
|
|
|
|
|
|
if (end_idx >= xive->nr_ends) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(&xive->endt[end_idx], end, sizeof(XiveEND));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-12-09 20:45:57 +01:00
|
|
|
static int spapr_xive_get_nvt(XiveRouter *xrtr,
|
|
|
|
uint8_t nvt_blk, uint32_t nvt_idx, XiveNVT *nvt)
|
|
|
|
{
|
|
|
|
uint32_t vcpu_id = spapr_xive_nvt_to_target(nvt_blk, nvt_idx);
|
|
|
|
PowerPCCPU *cpu = spapr_find_cpu(vcpu_id);
|
|
|
|
|
|
|
|
if (!cpu) {
|
|
|
|
/* TODO: should we assert() if we can find a NVT ? */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* sPAPR does not maintain a NVT table. Return that the NVT is
|
|
|
|
* valid if we have found a matching CPU
|
|
|
|
*/
|
|
|
|
nvt->w0 = cpu_to_be32(NVT_W0_VALID);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int spapr_xive_write_nvt(XiveRouter *xrtr, uint8_t nvt_blk,
|
|
|
|
uint32_t nvt_idx, XiveNVT *nvt,
|
|
|
|
uint8_t word_number)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* We don't need to write back to the NVTs because the sPAPR
|
|
|
|
* machine should never hit a non-scheduled NVT. It should never
|
|
|
|
* get called.
|
|
|
|
*/
|
|
|
|
g_assert_not_reached();
|
|
|
|
}
|
|
|
|
|
2019-11-25 07:58:02 +01:00
|
|
|
static int spapr_xive_match_nvt(XivePresenter *xptr, uint8_t format,
|
|
|
|
uint8_t nvt_blk, uint32_t nvt_idx,
|
|
|
|
bool cam_ignore, uint8_t priority,
|
|
|
|
uint32_t logic_serv, XiveTCTXMatch *match)
|
|
|
|
{
|
|
|
|
CPUState *cs;
|
|
|
|
int count = 0;
|
|
|
|
|
|
|
|
CPU_FOREACH(cs) {
|
|
|
|
PowerPCCPU *cpu = POWERPC_CPU(cs);
|
|
|
|
XiveTCTX *tctx = spapr_cpu_state(cpu)->tctx;
|
|
|
|
int ring;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Skip partially initialized vCPUs. This can happen when
|
|
|
|
* vCPUs are hotplugged.
|
|
|
|
*/
|
|
|
|
if (!tctx) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check the thread context CAM lines and record matches.
|
|
|
|
*/
|
|
|
|
ring = xive_presenter_tctx_match(xptr, tctx, format, nvt_blk, nvt_idx,
|
|
|
|
cam_ignore, logic_serv);
|
|
|
|
/*
|
|
|
|
* Save the matching thread interrupt context and follow on to
|
|
|
|
* check for duplicates which are invalid.
|
|
|
|
*/
|
|
|
|
if (ring != -1) {
|
|
|
|
if (match->tctx) {
|
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: already found a thread "
|
|
|
|
"context NVT %x/%x\n", nvt_blk, nvt_idx);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
match->ring = ring;
|
|
|
|
match->tctx = tctx;
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2023-06-22 18:25:26 +02:00
|
|
|
static uint32_t spapr_xive_presenter_get_config(XivePresenter *xptr)
|
|
|
|
{
|
|
|
|
uint32_t cfg = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Let's claim GEN1 TIMA format. If running with KVM on P10, the
|
|
|
|
* correct answer is deep in the hardware and not accessible to
|
|
|
|
* us. But it shouldn't matter as it only affects the presenter
|
|
|
|
* as seen by a guest OS.
|
|
|
|
*/
|
|
|
|
cfg |= XIVE_PRESENTER_GEN1_TIMA_OS;
|
|
|
|
|
|
|
|
return cfg;
|
|
|
|
}
|
|
|
|
|
2019-11-25 07:58:19 +01:00
|
|
|
static uint8_t spapr_xive_get_block_id(XiveRouter *xrtr)
|
|
|
|
{
|
|
|
|
return SPAPR_XIVE_BLOCK_ID;
|
|
|
|
}
|
|
|
|
|
2022-03-02 06:51:39 +01:00
|
|
|
static int spapr_xive_get_pq(XiveRouter *xrtr, uint8_t blk, uint32_t idx,
|
|
|
|
uint8_t *pq)
|
|
|
|
{
|
|
|
|
SpaprXive *xive = SPAPR_XIVE(xrtr);
|
|
|
|
|
|
|
|
assert(SPAPR_XIVE_BLOCK_ID == blk);
|
|
|
|
|
|
|
|
*pq = xive_source_esb_get(&xive->source, idx);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int spapr_xive_set_pq(XiveRouter *xrtr, uint8_t blk, uint32_t idx,
|
|
|
|
uint8_t *pq)
|
|
|
|
{
|
|
|
|
SpaprXive *xive = SPAPR_XIVE(xrtr);
|
|
|
|
|
|
|
|
assert(SPAPR_XIVE_BLOCK_ID == blk);
|
|
|
|
|
|
|
|
*pq = xive_source_esb_set(&xive->source, idx, *pq);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-12-09 20:45:56 +01:00
|
|
|
static const VMStateDescription vmstate_spapr_xive_end = {
|
|
|
|
.name = TYPE_SPAPR_XIVE "/end",
|
|
|
|
.version_id = 1,
|
|
|
|
.minimum_version_id = 1,
|
|
|
|
.fields = (VMStateField []) {
|
|
|
|
VMSTATE_UINT32(w0, XiveEND),
|
|
|
|
VMSTATE_UINT32(w1, XiveEND),
|
|
|
|
VMSTATE_UINT32(w2, XiveEND),
|
|
|
|
VMSTATE_UINT32(w3, XiveEND),
|
|
|
|
VMSTATE_UINT32(w4, XiveEND),
|
|
|
|
VMSTATE_UINT32(w5, XiveEND),
|
|
|
|
VMSTATE_UINT32(w6, XiveEND),
|
|
|
|
VMSTATE_UINT32(w7, XiveEND),
|
|
|
|
VMSTATE_END_OF_LIST()
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
static const VMStateDescription vmstate_spapr_xive_eas = {
|
|
|
|
.name = TYPE_SPAPR_XIVE "/eas",
|
|
|
|
.version_id = 1,
|
|
|
|
.minimum_version_id = 1,
|
|
|
|
.fields = (VMStateField []) {
|
|
|
|
VMSTATE_UINT64(w, XiveEAS),
|
|
|
|
VMSTATE_END_OF_LIST()
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2019-05-13 10:42:37 +02:00
|
|
|
static int vmstate_spapr_xive_pre_save(void *opaque)
|
|
|
|
{
|
2020-08-07 13:32:14 +02:00
|
|
|
SpaprXive *xive = SPAPR_XIVE(opaque);
|
|
|
|
|
|
|
|
if (spapr_xive_in_kernel(xive)) {
|
|
|
|
return kvmppc_xive_pre_save(xive);
|
2019-05-13 10:42:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Called by the sPAPR IRQ backend 'post_load' method at the machine
|
|
|
|
* level.
|
|
|
|
*/
|
2019-09-27 02:53:53 +02:00
|
|
|
static int spapr_xive_post_load(SpaprInterruptController *intc, int version_id)
|
2019-05-13 10:42:37 +02:00
|
|
|
{
|
2020-08-07 13:32:14 +02:00
|
|
|
SpaprXive *xive = SPAPR_XIVE(intc);
|
|
|
|
|
|
|
|
if (spapr_xive_in_kernel(xive)) {
|
|
|
|
return kvmppc_xive_post_load(xive, version_id);
|
2019-05-13 10:42:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-12-09 20:45:56 +01:00
|
|
|
static const VMStateDescription vmstate_spapr_xive = {
|
|
|
|
.name = TYPE_SPAPR_XIVE,
|
|
|
|
.version_id = 1,
|
|
|
|
.minimum_version_id = 1,
|
2019-05-13 10:42:37 +02:00
|
|
|
.pre_save = vmstate_spapr_xive_pre_save,
|
|
|
|
.post_load = NULL, /* handled at the machine level */
|
2018-12-09 20:45:56 +01:00
|
|
|
.fields = (VMStateField[]) {
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
VMSTATE_UINT32_EQUAL(nr_irqs, SpaprXive, NULL),
|
|
|
|
VMSTATE_STRUCT_VARRAY_POINTER_UINT32(eat, SpaprXive, nr_irqs,
|
2018-12-09 20:45:56 +01:00
|
|
|
vmstate_spapr_xive_eas, XiveEAS),
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
VMSTATE_STRUCT_VARRAY_POINTER_UINT32(endt, SpaprXive, nr_ends,
|
2018-12-09 20:45:56 +01:00
|
|
|
vmstate_spapr_xive_end, XiveEND),
|
|
|
|
VMSTATE_END_OF_LIST()
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2019-09-26 06:31:13 +02:00
|
|
|
static int spapr_xive_claim_irq(SpaprInterruptController *intc, int lisn,
|
|
|
|
bool lsi, Error **errp)
|
|
|
|
{
|
|
|
|
SpaprXive *xive = SPAPR_XIVE(intc);
|
|
|
|
XiveSource *xsrc = &xive->source;
|
|
|
|
|
|
|
|
assert(lisn < xive->nr_irqs);
|
|
|
|
|
2020-11-23 17:37:17 +01:00
|
|
|
trace_spapr_xive_claim_irq(lisn, lsi);
|
|
|
|
|
2019-09-26 06:31:13 +02:00
|
|
|
if (xive_eas_is_valid(&xive->eat[lisn])) {
|
|
|
|
error_setg(errp, "IRQ %d is not free", lisn);
|
|
|
|
return -EBUSY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set default values when allocating an IRQ number
|
|
|
|
*/
|
|
|
|
xive->eat[lisn].w |= cpu_to_be64(EAS_VALID | EAS_MASKED);
|
|
|
|
if (lsi) {
|
|
|
|
xive_source_irq_set_lsi(xsrc, lisn);
|
|
|
|
}
|
|
|
|
|
2020-08-07 13:32:14 +02:00
|
|
|
if (spapr_xive_in_kernel(xive)) {
|
2019-09-26 06:31:13 +02:00
|
|
|
return kvmppc_xive_source_reset_one(xsrc, lisn, errp);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void spapr_xive_free_irq(SpaprInterruptController *intc, int lisn)
|
|
|
|
{
|
|
|
|
SpaprXive *xive = SPAPR_XIVE(intc);
|
|
|
|
assert(lisn < xive->nr_irqs);
|
|
|
|
|
2020-11-23 17:37:17 +01:00
|
|
|
trace_spapr_xive_free_irq(lisn);
|
|
|
|
|
2019-09-26 06:31:13 +02:00
|
|
|
xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
|
|
|
|
}
|
|
|
|
|
2018-12-09 20:45:56 +01:00
|
|
|
static Property spapr_xive_properties[] = {
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
DEFINE_PROP_UINT32("nr-irqs", SpaprXive, nr_irqs, 0),
|
|
|
|
DEFINE_PROP_UINT32("nr-ends", SpaprXive, nr_ends, 0),
|
|
|
|
DEFINE_PROP_UINT64("vc-base", SpaprXive, vc_base, SPAPR_XIVE_VC_BASE),
|
|
|
|
DEFINE_PROP_UINT64("tm-base", SpaprXive, tm_base, SPAPR_XIVE_TM_BASE),
|
2020-08-19 15:08:36 +02:00
|
|
|
DEFINE_PROP_UINT8("hv-prio", SpaprXive, hv_prio, 7),
|
2018-12-09 20:45:56 +01:00
|
|
|
DEFINE_PROP_END_OF_LIST(),
|
|
|
|
};
|
|
|
|
|
2019-09-26 06:11:23 +02:00
|
|
|
static int spapr_xive_cpu_intc_create(SpaprInterruptController *intc,
|
|
|
|
PowerPCCPU *cpu, Error **errp)
|
|
|
|
{
|
|
|
|
SpaprXive *xive = SPAPR_XIVE(intc);
|
|
|
|
Object *obj;
|
|
|
|
SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
|
|
|
|
|
2020-01-06 15:56:41 +01:00
|
|
|
obj = xive_tctx_create(OBJECT(cpu), XIVE_PRESENTER(xive), errp);
|
2019-09-26 06:11:23 +02:00
|
|
|
if (!obj) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
spapr_cpu->tctx = XIVE_TCTX(obj);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-10-22 18:38:12 +02:00
|
|
|
static void xive_tctx_set_os_cam(XiveTCTX *tctx, uint32_t os_cam)
|
|
|
|
{
|
|
|
|
uint32_t qw1w2 = cpu_to_be32(TM_QW1W2_VO | os_cam);
|
|
|
|
memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1w2, 4);
|
|
|
|
}
|
|
|
|
|
2019-10-22 18:38:10 +02:00
|
|
|
static void spapr_xive_cpu_intc_reset(SpaprInterruptController *intc,
|
|
|
|
PowerPCCPU *cpu)
|
|
|
|
{
|
|
|
|
XiveTCTX *tctx = spapr_cpu_state(cpu)->tctx;
|
2019-10-22 18:38:12 +02:00
|
|
|
uint8_t nvt_blk;
|
|
|
|
uint32_t nvt_idx;
|
2019-10-22 18:38:10 +02:00
|
|
|
|
|
|
|
xive_tctx_reset(tctx);
|
2019-10-22 18:38:12 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* When a Virtual Processor is scheduled to run on a HW thread,
|
|
|
|
* the hypervisor pushes its identifier in the OS CAM line.
|
|
|
|
* Emulate the same behavior under QEMU.
|
|
|
|
*/
|
|
|
|
spapr_xive_cpu_to_nvt(cpu, &nvt_blk, &nvt_idx);
|
|
|
|
|
|
|
|
xive_tctx_set_os_cam(tctx, xive_nvt_cam_line(nvt_blk, nvt_idx));
|
2019-10-22 18:38:10 +02:00
|
|
|
}
|
|
|
|
|
2019-10-24 16:27:22 +02:00
|
|
|
static void spapr_xive_cpu_intc_destroy(SpaprInterruptController *intc,
|
|
|
|
PowerPCCPU *cpu)
|
|
|
|
{
|
|
|
|
SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
|
|
|
|
|
|
|
|
xive_tctx_destroy(spapr_cpu->tctx);
|
|
|
|
spapr_cpu->tctx = NULL;
|
|
|
|
}
|
|
|
|
|
2019-09-26 08:09:46 +02:00
|
|
|
static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int val)
|
|
|
|
{
|
|
|
|
SpaprXive *xive = SPAPR_XIVE(intc);
|
|
|
|
|
2020-11-23 17:37:17 +01:00
|
|
|
trace_spapr_xive_set_irq(irq, val);
|
|
|
|
|
2020-08-07 13:32:14 +02:00
|
|
|
if (spapr_xive_in_kernel(xive)) {
|
2019-09-26 08:09:46 +02:00
|
|
|
kvmppc_xive_source_set_irq(&xive->source, irq, val);
|
|
|
|
} else {
|
|
|
|
xive_source_set_irq(&xive->source, irq, val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-26 08:12:05 +02:00
|
|
|
static void spapr_xive_print_info(SpaprInterruptController *intc, Monitor *mon)
|
|
|
|
{
|
|
|
|
SpaprXive *xive = SPAPR_XIVE(intc);
|
|
|
|
CPUState *cs;
|
|
|
|
|
|
|
|
CPU_FOREACH(cs) {
|
|
|
|
PowerPCCPU *cpu = POWERPC_CPU(cs);
|
|
|
|
|
|
|
|
xive_tctx_pic_print_info(spapr_cpu_state(cpu)->tctx, mon);
|
|
|
|
}
|
|
|
|
|
|
|
|
spapr_xive_pic_print_info(xive, mon);
|
|
|
|
}
|
|
|
|
|
2019-09-30 04:35:06 +02:00
|
|
|
static void spapr_xive_dt(SpaprInterruptController *intc, uint32_t nr_servers,
|
|
|
|
void *fdt, uint32_t phandle)
|
|
|
|
{
|
|
|
|
SpaprXive *xive = SPAPR_XIVE(intc);
|
|
|
|
int node;
|
|
|
|
uint64_t timas[2 * 2];
|
|
|
|
/* Interrupt number ranges for the IPIs */
|
|
|
|
uint32_t lisn_ranges[] = {
|
2020-03-06 13:33:07 +01:00
|
|
|
cpu_to_be32(SPAPR_IRQ_IPI),
|
|
|
|
cpu_to_be32(SPAPR_IRQ_IPI + nr_servers),
|
2019-09-30 04:35:06 +02:00
|
|
|
};
|
|
|
|
/*
|
|
|
|
* EQ size - the sizes of pages supported by the system 4K, 64K,
|
|
|
|
* 2M, 16M. We only advertise 64K for the moment.
|
|
|
|
*/
|
|
|
|
uint32_t eq_sizes[] = {
|
|
|
|
cpu_to_be32(16), /* 64K */
|
|
|
|
};
|
|
|
|
/*
|
2020-08-19 15:08:36 +02:00
|
|
|
* QEMU/KVM only needs to define a single range to reserve the
|
|
|
|
* escalation priority. A priority bitmask would have been more
|
|
|
|
* appropriate.
|
2019-09-30 04:35:06 +02:00
|
|
|
*/
|
|
|
|
uint32_t plat_res_int_priorities[] = {
|
2020-08-19 15:08:36 +02:00
|
|
|
cpu_to_be32(xive->hv_prio), /* start */
|
|
|
|
cpu_to_be32(0xff - xive->hv_prio), /* count */
|
2019-09-30 04:35:06 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Thread Interrupt Management Area : User (ring 3) and OS (ring 2) */
|
|
|
|
timas[0] = cpu_to_be64(xive->tm_base +
|
|
|
|
XIVE_TM_USER_PAGE * (1ull << TM_SHIFT));
|
|
|
|
timas[1] = cpu_to_be64(1ull << TM_SHIFT);
|
|
|
|
timas[2] = cpu_to_be64(xive->tm_base +
|
|
|
|
XIVE_TM_OS_PAGE * (1ull << TM_SHIFT));
|
|
|
|
timas[3] = cpu_to_be64(1ull << TM_SHIFT);
|
|
|
|
|
|
|
|
_FDT(node = fdt_add_subnode(fdt, 0, xive->nodename));
|
|
|
|
|
|
|
|
_FDT(fdt_setprop_string(fdt, node, "device_type", "power-ivpe"));
|
|
|
|
_FDT(fdt_setprop(fdt, node, "reg", timas, sizeof(timas)));
|
|
|
|
|
|
|
|
_FDT(fdt_setprop_string(fdt, node, "compatible", "ibm,power-ivpe"));
|
|
|
|
_FDT(fdt_setprop(fdt, node, "ibm,xive-eq-sizes", eq_sizes,
|
|
|
|
sizeof(eq_sizes)));
|
|
|
|
_FDT(fdt_setprop(fdt, node, "ibm,xive-lisn-ranges", lisn_ranges,
|
|
|
|
sizeof(lisn_ranges)));
|
|
|
|
|
|
|
|
/* For Linux to link the LSIs to the interrupt controller. */
|
|
|
|
_FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0));
|
|
|
|
_FDT(fdt_setprop_cell(fdt, node, "#interrupt-cells", 2));
|
|
|
|
|
|
|
|
/* For SLOF */
|
|
|
|
_FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle));
|
|
|
|
_FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The "ibm,plat-res-int-priorities" property defines the priority
|
|
|
|
* ranges reserved by the hypervisor
|
|
|
|
*/
|
|
|
|
_FDT(fdt_setprop(fdt, 0, "ibm,plat-res-int-priorities",
|
|
|
|
plat_res_int_priorities, sizeof(plat_res_int_priorities)));
|
|
|
|
}
|
|
|
|
|
2019-11-26 17:46:23 +01:00
|
|
|
static int spapr_xive_activate(SpaprInterruptController *intc,
|
|
|
|
uint32_t nr_servers, Error **errp)
|
2019-09-26 15:58:36 +02:00
|
|
|
{
|
|
|
|
SpaprXive *xive = SPAPR_XIVE(intc);
|
|
|
|
|
|
|
|
if (kvm_enabled()) {
|
2019-11-26 17:46:23 +01:00
|
|
|
int rc = spapr_irq_init_kvm(kvmppc_xive_connect, intc, nr_servers,
|
|
|
|
errp);
|
2019-09-26 15:58:36 +02:00
|
|
|
if (rc < 0) {
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Activate the XIVE MMIOs */
|
|
|
|
spapr_xive_mmio_set_enabled(xive, true);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void spapr_xive_deactivate(SpaprInterruptController *intc)
|
|
|
|
{
|
|
|
|
SpaprXive *xive = SPAPR_XIVE(intc);
|
|
|
|
|
|
|
|
spapr_xive_mmio_set_enabled(xive, false);
|
|
|
|
|
2020-08-07 13:32:14 +02:00
|
|
|
if (spapr_xive_in_kernel(xive)) {
|
2019-09-26 15:58:36 +02:00
|
|
|
kvmppc_xive_disconnect(intc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-07 13:32:14 +02:00
|
|
|
static bool spapr_xive_in_kernel_xptr(const XivePresenter *xptr)
|
|
|
|
{
|
|
|
|
return spapr_xive_in_kernel(SPAPR_XIVE(xptr));
|
|
|
|
}
|
|
|
|
|
2018-12-09 20:45:56 +01:00
|
|
|
static void spapr_xive_class_init(ObjectClass *klass, void *data)
|
|
|
|
{
|
|
|
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
|
|
|
XiveRouterClass *xrc = XIVE_ROUTER_CLASS(klass);
|
2019-09-26 06:11:23 +02:00
|
|
|
SpaprInterruptControllerClass *sicc = SPAPR_INTC_CLASS(klass);
|
2019-11-25 07:58:02 +01:00
|
|
|
XivePresenterClass *xpc = XIVE_PRESENTER_CLASS(klass);
|
2019-12-19 19:11:47 +01:00
|
|
|
SpaprXiveClass *sxc = SPAPR_XIVE_CLASS(klass);
|
2018-12-09 20:45:56 +01:00
|
|
|
|
|
|
|
dc->desc = "sPAPR XIVE Interrupt Controller";
|
2020-01-10 16:30:32 +01:00
|
|
|
device_class_set_props(dc, spapr_xive_properties);
|
2019-12-19 19:11:47 +01:00
|
|
|
device_class_set_parent_realize(dc, spapr_xive_realize,
|
|
|
|
&sxc->parent_realize);
|
2018-12-09 20:45:56 +01:00
|
|
|
dc->vmsd = &vmstate_spapr_xive;
|
|
|
|
|
|
|
|
xrc->get_eas = spapr_xive_get_eas;
|
2022-03-02 06:51:39 +01:00
|
|
|
xrc->get_pq = spapr_xive_get_pq;
|
|
|
|
xrc->set_pq = spapr_xive_set_pq;
|
2018-12-09 20:45:56 +01:00
|
|
|
xrc->get_end = spapr_xive_get_end;
|
|
|
|
xrc->write_end = spapr_xive_write_end;
|
2018-12-09 20:45:57 +01:00
|
|
|
xrc->get_nvt = spapr_xive_get_nvt;
|
|
|
|
xrc->write_nvt = spapr_xive_write_nvt;
|
2019-11-25 07:58:19 +01:00
|
|
|
xrc->get_block_id = spapr_xive_get_block_id;
|
2019-09-26 06:11:23 +02:00
|
|
|
|
2019-09-26 15:58:36 +02:00
|
|
|
sicc->activate = spapr_xive_activate;
|
|
|
|
sicc->deactivate = spapr_xive_deactivate;
|
2019-09-26 06:11:23 +02:00
|
|
|
sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
|
2019-10-22 18:38:10 +02:00
|
|
|
sicc->cpu_intc_reset = spapr_xive_cpu_intc_reset;
|
2019-10-24 16:27:22 +02:00
|
|
|
sicc->cpu_intc_destroy = spapr_xive_cpu_intc_destroy;
|
2019-09-26 06:31:13 +02:00
|
|
|
sicc->claim_irq = spapr_xive_claim_irq;
|
|
|
|
sicc->free_irq = spapr_xive_free_irq;
|
2019-09-26 08:09:46 +02:00
|
|
|
sicc->set_irq = spapr_xive_set_irq;
|
2019-09-26 08:12:05 +02:00
|
|
|
sicc->print_info = spapr_xive_print_info;
|
2019-09-30 04:35:06 +02:00
|
|
|
sicc->dt = spapr_xive_dt;
|
2019-09-27 02:53:53 +02:00
|
|
|
sicc->post_load = spapr_xive_post_load;
|
2019-11-25 07:58:02 +01:00
|
|
|
|
|
|
|
xpc->match_nvt = spapr_xive_match_nvt;
|
2023-06-22 18:25:26 +02:00
|
|
|
xpc->get_config = spapr_xive_presenter_get_config;
|
2020-08-07 13:32:14 +02:00
|
|
|
xpc->in_kernel = spapr_xive_in_kernel_xptr;
|
2018-12-09 20:45:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static const TypeInfo spapr_xive_info = {
|
|
|
|
.name = TYPE_SPAPR_XIVE,
|
|
|
|
.parent = TYPE_XIVE_ROUTER,
|
|
|
|
.instance_init = spapr_xive_instance_init,
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
.instance_size = sizeof(SpaprXive),
|
2018-12-09 20:45:56 +01:00
|
|
|
.class_init = spapr_xive_class_init,
|
2019-12-19 19:11:47 +01:00
|
|
|
.class_size = sizeof(SpaprXiveClass),
|
2019-09-24 08:25:08 +02:00
|
|
|
.interfaces = (InterfaceInfo[]) {
|
|
|
|
{ TYPE_SPAPR_INTC },
|
|
|
|
{ }
|
|
|
|
},
|
2018-12-09 20:45:56 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
static void spapr_xive_register_types(void)
|
|
|
|
{
|
|
|
|
type_register_static(&spapr_xive_info);
|
|
|
|
}
|
|
|
|
|
|
|
|
type_init(spapr_xive_register_types)
|
|
|
|
|
2018-12-11 23:38:13 +01:00
|
|
|
/*
|
|
|
|
* XIVE hcalls
|
|
|
|
*
|
|
|
|
* The terminology used by the XIVE hcalls is the following :
|
|
|
|
*
|
|
|
|
* TARGET vCPU number
|
|
|
|
* EQ Event Queue assigned by OS to receive event data
|
|
|
|
* ESB page for source interrupt management
|
|
|
|
* LISN Logical Interrupt Source Number identifying a source in the
|
|
|
|
* machine
|
|
|
|
* EISN Effective Interrupt Source Number used by guest OS to
|
|
|
|
* identify source in the guest
|
|
|
|
*
|
|
|
|
* The EAS, END, NVT structures are not exposed.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2020-08-19 15:08:36 +02:00
|
|
|
* On POWER9, the KVM XIVE device uses priority 7 for the escalation
|
|
|
|
* interrupts. So we only allow the guest to use priorities [0..6].
|
2018-12-11 23:38:13 +01:00
|
|
|
*/
|
2020-08-19 15:08:36 +02:00
|
|
|
static bool spapr_xive_priority_is_reserved(SpaprXive *xive, uint8_t priority)
|
2018-12-11 23:38:13 +01:00
|
|
|
{
|
2020-08-19 15:08:36 +02:00
|
|
|
return priority >= xive->hv_prio;
|
2018-12-11 23:38:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The H_INT_GET_SOURCE_INFO hcall() is used to obtain the logical
|
|
|
|
* real address of the MMIO page through which the Event State Buffer
|
|
|
|
* entry associated with the value of the "lisn" parameter is managed.
|
|
|
|
*
|
|
|
|
* Parameters:
|
|
|
|
* Input
|
|
|
|
* - R4: "flags"
|
|
|
|
* Bits 0-63 reserved
|
|
|
|
* - R5: "lisn" is per "interrupts", "interrupt-map", or
|
|
|
|
* "ibm,xive-lisn-ranges" properties, or as returned by the
|
|
|
|
* ibm,query-interrupt-source-number RTAS call, or as returned
|
|
|
|
* by the H_ALLOCATE_VAS_WINDOW hcall
|
|
|
|
*
|
|
|
|
* Output
|
|
|
|
* - R4: "flags"
|
|
|
|
* Bits 0-59: Reserved
|
|
|
|
* Bit 60: H_INT_ESB must be used for Event State Buffer
|
|
|
|
* management
|
|
|
|
* Bit 61: 1 == LSI 0 == MSI
|
|
|
|
* Bit 62: the full function page supports trigger
|
|
|
|
* Bit 63: Store EOI Supported
|
|
|
|
* - R5: Logical Real address of full function Event State Buffer
|
|
|
|
* management page, -1 if H_INT_ESB hcall flag is set to 1.
|
|
|
|
* - R6: Logical Real Address of trigger only Event State Buffer
|
|
|
|
* management page or -1.
|
|
|
|
* - R7: Power of 2 page size for the ESB management pages returned in
|
|
|
|
* R5 and R6.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define SPAPR_XIVE_SRC_H_INT_ESB PPC_BIT(60) /* ESB manage with H_INT_ESB */
|
|
|
|
#define SPAPR_XIVE_SRC_LSI PPC_BIT(61) /* Virtual LSI type */
|
|
|
|
#define SPAPR_XIVE_SRC_TRIGGER PPC_BIT(62) /* Trigger and management
|
|
|
|
on same page */
|
|
|
|
#define SPAPR_XIVE_SRC_STORE_EOI PPC_BIT(63) /* Store EOI support */
|
|
|
|
|
|
|
|
static target_ulong h_int_get_source_info(PowerPCCPU *cpu,
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprMachineState *spapr,
|
2018-12-11 23:38:13 +01:00
|
|
|
target_ulong opcode,
|
|
|
|
target_ulong *args)
|
|
|
|
{
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprXive *xive = spapr->xive;
|
2018-12-11 23:38:13 +01:00
|
|
|
XiveSource *xsrc = &xive->source;
|
|
|
|
target_ulong flags = args[0];
|
|
|
|
target_ulong lisn = args[1];
|
|
|
|
|
2020-11-23 17:37:17 +01:00
|
|
|
trace_spapr_xive_get_source_info(flags, lisn);
|
|
|
|
|
2018-12-11 23:38:13 +01:00
|
|
|
if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
|
|
|
|
return H_FUNCTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flags) {
|
|
|
|
return H_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lisn >= xive->nr_irqs) {
|
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Unknown LISN " TARGET_FMT_lx "\n",
|
|
|
|
lisn);
|
|
|
|
return H_P2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!xive_eas_is_valid(&xive->eat[lisn])) {
|
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid LISN " TARGET_FMT_lx "\n",
|
|
|
|
lisn);
|
|
|
|
return H_P2;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* All sources are emulated under the main XIVE object and share
|
|
|
|
* the same characteristics.
|
|
|
|
*/
|
|
|
|
args[0] = 0;
|
|
|
|
if (!xive_source_esb_has_2page(xsrc)) {
|
|
|
|
args[0] |= SPAPR_XIVE_SRC_TRIGGER;
|
|
|
|
}
|
|
|
|
if (xsrc->esb_flags & XIVE_SRC_STORE_EOI) {
|
|
|
|
args[0] |= SPAPR_XIVE_SRC_STORE_EOI;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Force the use of the H_INT_ESB hcall in case of an LSI
|
|
|
|
* interrupt. This is necessary under KVM to re-trigger the
|
|
|
|
* interrupt if the level is still asserted
|
|
|
|
*/
|
|
|
|
if (xive_source_irq_is_lsi(xsrc, lisn)) {
|
|
|
|
args[0] |= SPAPR_XIVE_SRC_H_INT_ESB | SPAPR_XIVE_SRC_LSI;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(args[0] & SPAPR_XIVE_SRC_H_INT_ESB)) {
|
|
|
|
args[1] = xive->vc_base + xive_source_esb_mgmt(xsrc, lisn);
|
|
|
|
} else {
|
|
|
|
args[1] = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (xive_source_esb_has_2page(xsrc) &&
|
|
|
|
!(args[0] & SPAPR_XIVE_SRC_H_INT_ESB)) {
|
|
|
|
args[2] = xive->vc_base + xive_source_esb_page(xsrc, lisn);
|
|
|
|
} else {
|
|
|
|
args[2] = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (xive_source_esb_has_2page(xsrc)) {
|
|
|
|
args[3] = xsrc->esb_shift - 1;
|
|
|
|
} else {
|
|
|
|
args[3] = xsrc->esb_shift;
|
|
|
|
}
|
|
|
|
|
|
|
|
return H_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The H_INT_SET_SOURCE_CONFIG hcall() is used to assign a Logical
|
|
|
|
* Interrupt Source to a target. The Logical Interrupt Source is
|
|
|
|
* designated with the "lisn" parameter and the target is designated
|
|
|
|
* with the "target" and "priority" parameters. Upon return from the
|
|
|
|
* hcall(), no additional interrupts will be directed to the old EQ.
|
|
|
|
*
|
|
|
|
* Parameters:
|
|
|
|
* Input:
|
|
|
|
* - R4: "flags"
|
|
|
|
* Bits 0-61: Reserved
|
|
|
|
* Bit 62: set the "eisn" in the EAS
|
|
|
|
* Bit 63: masks the interrupt source in the hardware interrupt
|
|
|
|
* control structure. An interrupt masked by this mechanism will
|
|
|
|
* be dropped, but it's source state bits will still be
|
|
|
|
* set. There is no race-free way of unmasking and restoring the
|
|
|
|
* source. Thus this should only be used in interrupts that are
|
|
|
|
* also masked at the source, and only in cases where the
|
|
|
|
* interrupt is not meant to be used for a large amount of time
|
|
|
|
* because no valid target exists for it for example
|
|
|
|
* - R5: "lisn" is per "interrupts", "interrupt-map", or
|
|
|
|
* "ibm,xive-lisn-ranges" properties, or as returned by the
|
|
|
|
* ibm,query-interrupt-source-number RTAS call, or as returned by
|
|
|
|
* the H_ALLOCATE_VAS_WINDOW hcall
|
|
|
|
* - R6: "target" is per "ibm,ppc-interrupt-server#s" or
|
|
|
|
* "ibm,ppc-interrupt-gserver#s"
|
|
|
|
* - R7: "priority" is a valid priority not in
|
|
|
|
* "ibm,plat-res-int-priorities"
|
|
|
|
* - R8: "eisn" is the guest EISN associated with the "lisn"
|
|
|
|
*
|
|
|
|
* Output:
|
|
|
|
* - None
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define SPAPR_XIVE_SRC_SET_EISN PPC_BIT(62)
|
|
|
|
#define SPAPR_XIVE_SRC_MASK PPC_BIT(63)
|
|
|
|
|
|
|
|
static target_ulong h_int_set_source_config(PowerPCCPU *cpu,
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprMachineState *spapr,
|
2018-12-11 23:38:13 +01:00
|
|
|
target_ulong opcode,
|
|
|
|
target_ulong *args)
|
|
|
|
{
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprXive *xive = spapr->xive;
|
2018-12-11 23:38:13 +01:00
|
|
|
XiveEAS eas, new_eas;
|
|
|
|
target_ulong flags = args[0];
|
|
|
|
target_ulong lisn = args[1];
|
|
|
|
target_ulong target = args[2];
|
|
|
|
target_ulong priority = args[3];
|
|
|
|
target_ulong eisn = args[4];
|
|
|
|
uint8_t end_blk;
|
|
|
|
uint32_t end_idx;
|
|
|
|
|
2020-11-23 17:37:17 +01:00
|
|
|
trace_spapr_xive_set_source_config(flags, lisn, target, priority, eisn);
|
|
|
|
|
2018-12-11 23:38:13 +01:00
|
|
|
if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
|
|
|
|
return H_FUNCTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flags & ~(SPAPR_XIVE_SRC_SET_EISN | SPAPR_XIVE_SRC_MASK)) {
|
|
|
|
return H_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lisn >= xive->nr_irqs) {
|
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Unknown LISN " TARGET_FMT_lx "\n",
|
|
|
|
lisn);
|
|
|
|
return H_P2;
|
|
|
|
}
|
|
|
|
|
|
|
|
eas = xive->eat[lisn];
|
|
|
|
if (!xive_eas_is_valid(&eas)) {
|
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid LISN " TARGET_FMT_lx "\n",
|
|
|
|
lisn);
|
|
|
|
return H_P2;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* priority 0xff is used to reset the EAS */
|
|
|
|
if (priority == 0xff) {
|
|
|
|
new_eas.w = cpu_to_be64(EAS_VALID | EAS_MASKED);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flags & SPAPR_XIVE_SRC_MASK) {
|
|
|
|
new_eas.w = eas.w | cpu_to_be64(EAS_MASKED);
|
|
|
|
} else {
|
|
|
|
new_eas.w = eas.w & cpu_to_be64(~EAS_MASKED);
|
|
|
|
}
|
|
|
|
|
2020-08-19 15:08:36 +02:00
|
|
|
if (spapr_xive_priority_is_reserved(xive, priority)) {
|
2018-12-11 23:38:13 +01:00
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld
|
|
|
|
" is reserved\n", priority);
|
|
|
|
return H_P4;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Validate that "target" is part of the list of threads allocated
|
|
|
|
* to the partition. For that, find the END corresponding to the
|
|
|
|
* target.
|
|
|
|
*/
|
|
|
|
if (spapr_xive_target_to_end(target, priority, &end_blk, &end_idx)) {
|
|
|
|
return H_P3;
|
|
|
|
}
|
|
|
|
|
|
|
|
new_eas.w = xive_set_field64(EAS_END_BLOCK, new_eas.w, end_blk);
|
|
|
|
new_eas.w = xive_set_field64(EAS_END_INDEX, new_eas.w, end_idx);
|
|
|
|
|
|
|
|
if (flags & SPAPR_XIVE_SRC_SET_EISN) {
|
|
|
|
new_eas.w = xive_set_field64(EAS_END_DATA, new_eas.w, eisn);
|
|
|
|
}
|
|
|
|
|
2020-08-07 13:32:14 +02:00
|
|
|
if (spapr_xive_in_kernel(xive)) {
|
2019-05-13 10:42:34 +02:00
|
|
|
Error *local_err = NULL;
|
|
|
|
|
|
|
|
kvmppc_xive_set_source_config(xive, lisn, &new_eas, &local_err);
|
|
|
|
if (local_err) {
|
|
|
|
error_report_err(local_err);
|
|
|
|
return H_HARDWARE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-11 23:38:13 +01:00
|
|
|
out:
|
|
|
|
xive->eat[lisn] = new_eas;
|
|
|
|
return H_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The H_INT_GET_SOURCE_CONFIG hcall() is used to determine to which
|
|
|
|
* target/priority pair is assigned to the specified Logical Interrupt
|
|
|
|
* Source.
|
|
|
|
*
|
|
|
|
* Parameters:
|
|
|
|
* Input:
|
|
|
|
* - R4: "flags"
|
|
|
|
* Bits 0-63 Reserved
|
|
|
|
* - R5: "lisn" is per "interrupts", "interrupt-map", or
|
|
|
|
* "ibm,xive-lisn-ranges" properties, or as returned by the
|
|
|
|
* ibm,query-interrupt-source-number RTAS call, or as
|
|
|
|
* returned by the H_ALLOCATE_VAS_WINDOW hcall
|
|
|
|
*
|
|
|
|
* Output:
|
|
|
|
* - R4: Target to which the specified Logical Interrupt Source is
|
|
|
|
* assigned
|
|
|
|
* - R5: Priority to which the specified Logical Interrupt Source is
|
|
|
|
* assigned
|
|
|
|
* - R6: EISN for the specified Logical Interrupt Source (this will be
|
|
|
|
* equivalent to the LISN if not changed by H_INT_SET_SOURCE_CONFIG)
|
|
|
|
*/
|
|
|
|
static target_ulong h_int_get_source_config(PowerPCCPU *cpu,
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprMachineState *spapr,
|
2018-12-11 23:38:13 +01:00
|
|
|
target_ulong opcode,
|
|
|
|
target_ulong *args)
|
|
|
|
{
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprXive *xive = spapr->xive;
|
2018-12-11 23:38:13 +01:00
|
|
|
target_ulong flags = args[0];
|
|
|
|
target_ulong lisn = args[1];
|
|
|
|
XiveEAS eas;
|
|
|
|
XiveEND *end;
|
|
|
|
uint8_t nvt_blk;
|
|
|
|
uint32_t end_idx, nvt_idx;
|
|
|
|
|
2020-11-23 17:37:17 +01:00
|
|
|
trace_spapr_xive_get_source_config(flags, lisn);
|
|
|
|
|
2018-12-11 23:38:13 +01:00
|
|
|
if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
|
|
|
|
return H_FUNCTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flags) {
|
|
|
|
return H_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lisn >= xive->nr_irqs) {
|
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Unknown LISN " TARGET_FMT_lx "\n",
|
|
|
|
lisn);
|
|
|
|
return H_P2;
|
|
|
|
}
|
|
|
|
|
|
|
|
eas = xive->eat[lisn];
|
|
|
|
if (!xive_eas_is_valid(&eas)) {
|
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid LISN " TARGET_FMT_lx "\n",
|
|
|
|
lisn);
|
|
|
|
return H_P2;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* EAS_END_BLOCK is unused on sPAPR */
|
|
|
|
end_idx = xive_get_field64(EAS_END_INDEX, eas.w);
|
|
|
|
|
|
|
|
assert(end_idx < xive->nr_ends);
|
|
|
|
end = &xive->endt[end_idx];
|
|
|
|
|
|
|
|
nvt_blk = xive_get_field32(END_W6_NVT_BLOCK, end->w6);
|
|
|
|
nvt_idx = xive_get_field32(END_W6_NVT_INDEX, end->w6);
|
|
|
|
args[0] = spapr_xive_nvt_to_target(nvt_blk, nvt_idx);
|
|
|
|
|
|
|
|
if (xive_eas_is_masked(&eas)) {
|
|
|
|
args[1] = 0xff;
|
|
|
|
} else {
|
|
|
|
args[1] = xive_get_field32(END_W7_F0_PRIORITY, end->w7);
|
|
|
|
}
|
|
|
|
|
|
|
|
args[2] = xive_get_field64(EAS_END_DATA, eas.w);
|
|
|
|
|
|
|
|
return H_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The H_INT_GET_QUEUE_INFO hcall() is used to get the logical real
|
|
|
|
* address of the notification management page associated with the
|
|
|
|
* specified target and priority.
|
|
|
|
*
|
|
|
|
* Parameters:
|
|
|
|
* Input:
|
|
|
|
* - R4: "flags"
|
|
|
|
* Bits 0-63 Reserved
|
|
|
|
* - R5: "target" is per "ibm,ppc-interrupt-server#s" or
|
|
|
|
* "ibm,ppc-interrupt-gserver#s"
|
|
|
|
* - R6: "priority" is a valid priority not in
|
|
|
|
* "ibm,plat-res-int-priorities"
|
|
|
|
*
|
|
|
|
* Output:
|
|
|
|
* - R4: Logical real address of notification page
|
|
|
|
* - R5: Power of 2 page size of the notification page
|
|
|
|
*/
|
|
|
|
static target_ulong h_int_get_queue_info(PowerPCCPU *cpu,
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprMachineState *spapr,
|
2018-12-11 23:38:13 +01:00
|
|
|
target_ulong opcode,
|
|
|
|
target_ulong *args)
|
|
|
|
{
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprXive *xive = spapr->xive;
|
2018-12-11 23:38:13 +01:00
|
|
|
XiveENDSource *end_xsrc = &xive->end_source;
|
|
|
|
target_ulong flags = args[0];
|
|
|
|
target_ulong target = args[1];
|
|
|
|
target_ulong priority = args[2];
|
|
|
|
XiveEND *end;
|
|
|
|
uint8_t end_blk;
|
|
|
|
uint32_t end_idx;
|
|
|
|
|
2020-11-23 17:37:17 +01:00
|
|
|
trace_spapr_xive_get_queue_info(flags, target, priority);
|
|
|
|
|
2018-12-11 23:38:13 +01:00
|
|
|
if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
|
|
|
|
return H_FUNCTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flags) {
|
|
|
|
return H_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* H_STATE should be returned if a H_INT_RESET is in progress.
|
|
|
|
* This is not needed when running the emulation under QEMU
|
|
|
|
*/
|
|
|
|
|
2020-08-19 15:08:36 +02:00
|
|
|
if (spapr_xive_priority_is_reserved(xive, priority)) {
|
2018-12-11 23:38:13 +01:00
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld
|
|
|
|
" is reserved\n", priority);
|
|
|
|
return H_P3;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Validate that "target" is part of the list of threads allocated
|
|
|
|
* to the partition. For that, find the END corresponding to the
|
|
|
|
* target.
|
|
|
|
*/
|
|
|
|
if (spapr_xive_target_to_end(target, priority, &end_blk, &end_idx)) {
|
|
|
|
return H_P2;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(end_idx < xive->nr_ends);
|
|
|
|
end = &xive->endt[end_idx];
|
|
|
|
|
|
|
|
args[0] = xive->end_base + (1ull << (end_xsrc->esb_shift + 1)) * end_idx;
|
|
|
|
if (xive_end_is_enqueue(end)) {
|
|
|
|
args[1] = xive_get_field32(END_W0_QSIZE, end->w0) + 12;
|
|
|
|
} else {
|
|
|
|
args[1] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return H_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The H_INT_SET_QUEUE_CONFIG hcall() is used to set or reset a EQ for
|
|
|
|
* a given "target" and "priority". It is also used to set the
|
|
|
|
* notification config associated with the EQ. An EQ size of 0 is
|
|
|
|
* used to reset the EQ config for a given target and priority. If
|
|
|
|
* resetting the EQ config, the END associated with the given "target"
|
|
|
|
* and "priority" will be changed to disable queueing.
|
|
|
|
*
|
|
|
|
* Upon return from the hcall(), no additional interrupts will be
|
|
|
|
* directed to the old EQ (if one was set). The old EQ (if one was
|
|
|
|
* set) should be investigated for interrupts that occurred prior to
|
|
|
|
* or during the hcall().
|
|
|
|
*
|
|
|
|
* Parameters:
|
|
|
|
* Input:
|
|
|
|
* - R4: "flags"
|
|
|
|
* Bits 0-62: Reserved
|
|
|
|
* Bit 63: Unconditional Notify (n) per the XIVE spec
|
|
|
|
* - R5: "target" is per "ibm,ppc-interrupt-server#s" or
|
|
|
|
* "ibm,ppc-interrupt-gserver#s"
|
|
|
|
* - R6: "priority" is a valid priority not in
|
|
|
|
* "ibm,plat-res-int-priorities"
|
|
|
|
* - R7: "eventQueue": The logical real address of the start of the EQ
|
|
|
|
* - R8: "eventQueueSize": The power of 2 EQ size per "ibm,xive-eq-sizes"
|
|
|
|
*
|
|
|
|
* Output:
|
|
|
|
* - None
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define SPAPR_XIVE_END_ALWAYS_NOTIFY PPC_BIT(63)
|
|
|
|
|
|
|
|
static target_ulong h_int_set_queue_config(PowerPCCPU *cpu,
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprMachineState *spapr,
|
2018-12-11 23:38:13 +01:00
|
|
|
target_ulong opcode,
|
|
|
|
target_ulong *args)
|
|
|
|
{
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprXive *xive = spapr->xive;
|
2018-12-11 23:38:13 +01:00
|
|
|
target_ulong flags = args[0];
|
|
|
|
target_ulong target = args[1];
|
|
|
|
target_ulong priority = args[2];
|
|
|
|
target_ulong qpage = args[3];
|
|
|
|
target_ulong qsize = args[4];
|
|
|
|
XiveEND end;
|
|
|
|
uint8_t end_blk, nvt_blk;
|
|
|
|
uint32_t end_idx, nvt_idx;
|
|
|
|
|
2020-11-23 17:37:17 +01:00
|
|
|
trace_spapr_xive_set_queue_config(flags, target, priority, qpage, qsize);
|
|
|
|
|
2018-12-11 23:38:13 +01:00
|
|
|
if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
|
|
|
|
return H_FUNCTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flags & ~SPAPR_XIVE_END_ALWAYS_NOTIFY) {
|
|
|
|
return H_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* H_STATE should be returned if a H_INT_RESET is in progress.
|
|
|
|
* This is not needed when running the emulation under QEMU
|
|
|
|
*/
|
|
|
|
|
2020-08-19 15:08:36 +02:00
|
|
|
if (spapr_xive_priority_is_reserved(xive, priority)) {
|
2018-12-11 23:38:13 +01:00
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld
|
|
|
|
" is reserved\n", priority);
|
|
|
|
return H_P3;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Validate that "target" is part of the list of threads allocated
|
|
|
|
* to the partition. For that, find the END corresponding to the
|
|
|
|
* target.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (spapr_xive_target_to_end(target, priority, &end_blk, &end_idx)) {
|
|
|
|
return H_P2;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(end_idx < xive->nr_ends);
|
|
|
|
memcpy(&end, &xive->endt[end_idx], sizeof(XiveEND));
|
|
|
|
|
|
|
|
switch (qsize) {
|
|
|
|
case 12:
|
|
|
|
case 16:
|
|
|
|
case 21:
|
|
|
|
case 24:
|
2019-05-08 19:19:44 +02:00
|
|
|
if (!QEMU_IS_ALIGNED(qpage, 1ul << qsize)) {
|
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: EQ @0x%" HWADDR_PRIx
|
|
|
|
" is not naturally aligned with %" HWADDR_PRIx "\n",
|
|
|
|
qpage, (hwaddr)1 << qsize);
|
|
|
|
return H_P4;
|
|
|
|
}
|
2018-12-11 23:38:13 +01:00
|
|
|
end.w2 = cpu_to_be32((qpage >> 32) & 0x0fffffff);
|
|
|
|
end.w3 = cpu_to_be32(qpage & 0xffffffff);
|
|
|
|
end.w0 |= cpu_to_be32(END_W0_ENQUEUE);
|
|
|
|
end.w0 = xive_set_field32(END_W0_QSIZE, end.w0, qsize - 12);
|
|
|
|
break;
|
|
|
|
case 0:
|
|
|
|
/* reset queue and disable queueing */
|
|
|
|
spapr_xive_end_reset(&end);
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
default:
|
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid EQ size %"PRIx64"\n",
|
|
|
|
qsize);
|
|
|
|
return H_P5;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (qsize) {
|
|
|
|
hwaddr plen = 1 << qsize;
|
|
|
|
void *eq;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Validate the guest EQ. We should also check that the queue
|
|
|
|
* has been zeroed by the OS.
|
|
|
|
*/
|
|
|
|
eq = address_space_map(CPU(cpu)->as, qpage, &plen, true,
|
|
|
|
MEMTXATTRS_UNSPECIFIED);
|
|
|
|
if (plen != 1 << qsize) {
|
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: failed to map EQ @0x%"
|
|
|
|
HWADDR_PRIx "\n", qpage);
|
|
|
|
return H_P4;
|
|
|
|
}
|
|
|
|
address_space_unmap(CPU(cpu)->as, eq, plen, true, plen);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* "target" should have been validated above */
|
|
|
|
if (spapr_xive_target_to_nvt(target, &nvt_blk, &nvt_idx)) {
|
|
|
|
g_assert_not_reached();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Ensure the priority and target are correctly set (they will not
|
|
|
|
* be right after allocation)
|
|
|
|
*/
|
|
|
|
end.w6 = xive_set_field32(END_W6_NVT_BLOCK, 0ul, nvt_blk) |
|
|
|
|
xive_set_field32(END_W6_NVT_INDEX, 0ul, nvt_idx);
|
|
|
|
end.w7 = xive_set_field32(END_W7_F0_PRIORITY, 0ul, priority);
|
|
|
|
|
|
|
|
if (flags & SPAPR_XIVE_END_ALWAYS_NOTIFY) {
|
|
|
|
end.w0 |= cpu_to_be32(END_W0_UCOND_NOTIFY);
|
|
|
|
} else {
|
|
|
|
end.w0 &= cpu_to_be32((uint32_t)~END_W0_UCOND_NOTIFY);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The generation bit for the END starts at 1 and The END page
|
|
|
|
* offset counter starts at 0.
|
|
|
|
*/
|
|
|
|
end.w1 = cpu_to_be32(END_W1_GENERATION) |
|
|
|
|
xive_set_field32(END_W1_PAGE_OFF, 0ul, 0ul);
|
|
|
|
end.w0 |= cpu_to_be32(END_W0_VALID);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* TODO: issue syncs required to ensure all in-flight interrupts
|
|
|
|
* are complete on the old END
|
|
|
|
*/
|
|
|
|
|
|
|
|
out:
|
2020-08-07 13:32:14 +02:00
|
|
|
if (spapr_xive_in_kernel(xive)) {
|
2019-05-13 10:42:34 +02:00
|
|
|
Error *local_err = NULL;
|
|
|
|
|
|
|
|
kvmppc_xive_set_queue_config(xive, end_blk, end_idx, &end, &local_err);
|
|
|
|
if (local_err) {
|
|
|
|
error_report_err(local_err);
|
|
|
|
return H_HARDWARE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-11 23:38:13 +01:00
|
|
|
/* Update END */
|
|
|
|
memcpy(&xive->endt[end_idx], &end, sizeof(XiveEND));
|
|
|
|
return H_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The H_INT_GET_QUEUE_CONFIG hcall() is used to get a EQ for a given
|
|
|
|
* target and priority.
|
|
|
|
*
|
|
|
|
* Parameters:
|
|
|
|
* Input:
|
|
|
|
* - R4: "flags"
|
|
|
|
* Bits 0-62: Reserved
|
|
|
|
* Bit 63: Debug: Return debug data
|
|
|
|
* - R5: "target" is per "ibm,ppc-interrupt-server#s" or
|
|
|
|
* "ibm,ppc-interrupt-gserver#s"
|
|
|
|
* - R6: "priority" is a valid priority not in
|
|
|
|
* "ibm,plat-res-int-priorities"
|
|
|
|
*
|
|
|
|
* Output:
|
|
|
|
* - R4: "flags":
|
|
|
|
* Bits 0-61: Reserved
|
|
|
|
* Bit 62: The value of Event Queue Generation Number (g) per
|
|
|
|
* the XIVE spec if "Debug" = 1
|
|
|
|
* Bit 63: The value of Unconditional Notify (n) per the XIVE spec
|
|
|
|
* - R5: The logical real address of the start of the EQ
|
|
|
|
* - R6: The power of 2 EQ size per "ibm,xive-eq-sizes"
|
|
|
|
* - R7: The value of Event Queue Offset Counter per XIVE spec
|
|
|
|
* if "Debug" = 1, else 0
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define SPAPR_XIVE_END_DEBUG PPC_BIT(63)
|
|
|
|
|
|
|
|
static target_ulong h_int_get_queue_config(PowerPCCPU *cpu,
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprMachineState *spapr,
|
2018-12-11 23:38:13 +01:00
|
|
|
target_ulong opcode,
|
|
|
|
target_ulong *args)
|
|
|
|
{
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprXive *xive = spapr->xive;
|
2018-12-11 23:38:13 +01:00
|
|
|
target_ulong flags = args[0];
|
|
|
|
target_ulong target = args[1];
|
|
|
|
target_ulong priority = args[2];
|
|
|
|
XiveEND *end;
|
|
|
|
uint8_t end_blk;
|
|
|
|
uint32_t end_idx;
|
|
|
|
|
2020-11-23 17:37:17 +01:00
|
|
|
trace_spapr_xive_get_queue_config(flags, target, priority);
|
|
|
|
|
2018-12-11 23:38:13 +01:00
|
|
|
if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
|
|
|
|
return H_FUNCTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flags & ~SPAPR_XIVE_END_DEBUG) {
|
|
|
|
return H_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* H_STATE should be returned if a H_INT_RESET is in progress.
|
|
|
|
* This is not needed when running the emulation under QEMU
|
|
|
|
*/
|
|
|
|
|
2020-08-19 15:08:36 +02:00
|
|
|
if (spapr_xive_priority_is_reserved(xive, priority)) {
|
2018-12-11 23:38:13 +01:00
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld
|
|
|
|
" is reserved\n", priority);
|
|
|
|
return H_P3;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Validate that "target" is part of the list of threads allocated
|
|
|
|
* to the partition. For that, find the END corresponding to the
|
|
|
|
* target.
|
|
|
|
*/
|
|
|
|
if (spapr_xive_target_to_end(target, priority, &end_blk, &end_idx)) {
|
|
|
|
return H_P2;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(end_idx < xive->nr_ends);
|
|
|
|
end = &xive->endt[end_idx];
|
|
|
|
|
|
|
|
args[0] = 0;
|
|
|
|
if (xive_end_is_notify(end)) {
|
|
|
|
args[0] |= SPAPR_XIVE_END_ALWAYS_NOTIFY;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (xive_end_is_enqueue(end)) {
|
2019-05-08 19:19:45 +02:00
|
|
|
args[1] = xive_end_qaddr(end);
|
2018-12-11 23:38:13 +01:00
|
|
|
args[2] = xive_get_field32(END_W0_QSIZE, end->w0) + 12;
|
|
|
|
} else {
|
|
|
|
args[1] = 0;
|
|
|
|
args[2] = 0;
|
|
|
|
}
|
|
|
|
|
2020-08-07 13:32:14 +02:00
|
|
|
if (spapr_xive_in_kernel(xive)) {
|
2019-05-13 10:42:34 +02:00
|
|
|
Error *local_err = NULL;
|
|
|
|
|
|
|
|
kvmppc_xive_get_queue_config(xive, end_blk, end_idx, end, &local_err);
|
|
|
|
if (local_err) {
|
|
|
|
error_report_err(local_err);
|
|
|
|
return H_HARDWARE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-11 23:38:13 +01:00
|
|
|
/* TODO: do we need any locking on the END ? */
|
|
|
|
if (flags & SPAPR_XIVE_END_DEBUG) {
|
|
|
|
/* Load the event queue generation number into the return flags */
|
|
|
|
args[0] |= (uint64_t)xive_get_field32(END_W1_GENERATION, end->w1) << 62;
|
|
|
|
|
|
|
|
/* Load R7 with the event queue offset counter */
|
|
|
|
args[3] = xive_get_field32(END_W1_PAGE_OFF, end->w1);
|
|
|
|
} else {
|
|
|
|
args[3] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return H_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The H_INT_SET_OS_REPORTING_LINE hcall() is used to set the
|
|
|
|
* reporting cache line pair for the calling thread. The reporting
|
|
|
|
* cache lines will contain the OS interrupt context when the OS
|
|
|
|
* issues a CI store byte to @TIMA+0xC10 to acknowledge the OS
|
|
|
|
* interrupt. The reporting cache lines can be reset by inputting -1
|
|
|
|
* in "reportingLine". Issuing the CI store byte without reporting
|
|
|
|
* cache lines registered will result in the data not being accessible
|
|
|
|
* to the OS.
|
|
|
|
*
|
|
|
|
* Parameters:
|
|
|
|
* Input:
|
|
|
|
* - R4: "flags"
|
|
|
|
* Bits 0-63: Reserved
|
|
|
|
* - R5: "reportingLine": The logical real address of the reporting cache
|
|
|
|
* line pair
|
|
|
|
*
|
|
|
|
* Output:
|
|
|
|
* - None
|
|
|
|
*/
|
|
|
|
static target_ulong h_int_set_os_reporting_line(PowerPCCPU *cpu,
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprMachineState *spapr,
|
2018-12-11 23:38:13 +01:00
|
|
|
target_ulong opcode,
|
|
|
|
target_ulong *args)
|
|
|
|
{
|
2020-11-23 17:37:17 +01:00
|
|
|
target_ulong flags = args[0];
|
|
|
|
|
|
|
|
trace_spapr_xive_set_os_reporting_line(flags);
|
|
|
|
|
2018-12-11 23:38:13 +01:00
|
|
|
if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
|
|
|
|
return H_FUNCTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* H_STATE should be returned if a H_INT_RESET is in progress.
|
|
|
|
* This is not needed when running the emulation under QEMU
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* TODO: H_INT_SET_OS_REPORTING_LINE */
|
|
|
|
return H_FUNCTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The H_INT_GET_OS_REPORTING_LINE hcall() is used to get the logical
|
|
|
|
* real address of the reporting cache line pair set for the input
|
|
|
|
* "target". If no reporting cache line pair has been set, -1 is
|
|
|
|
* returned.
|
|
|
|
*
|
|
|
|
* Parameters:
|
|
|
|
* Input:
|
|
|
|
* - R4: "flags"
|
|
|
|
* Bits 0-63: Reserved
|
|
|
|
* - R5: "target" is per "ibm,ppc-interrupt-server#s" or
|
|
|
|
* "ibm,ppc-interrupt-gserver#s"
|
|
|
|
* - R6: "reportingLine": The logical real address of the reporting
|
|
|
|
* cache line pair
|
|
|
|
*
|
|
|
|
* Output:
|
|
|
|
* - R4: The logical real address of the reporting line if set, else -1
|
|
|
|
*/
|
|
|
|
static target_ulong h_int_get_os_reporting_line(PowerPCCPU *cpu,
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprMachineState *spapr,
|
2018-12-11 23:38:13 +01:00
|
|
|
target_ulong opcode,
|
|
|
|
target_ulong *args)
|
|
|
|
{
|
2020-11-23 17:37:17 +01:00
|
|
|
target_ulong flags = args[0];
|
|
|
|
|
|
|
|
trace_spapr_xive_get_os_reporting_line(flags);
|
|
|
|
|
2018-12-11 23:38:13 +01:00
|
|
|
if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
|
|
|
|
return H_FUNCTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* H_STATE should be returned if a H_INT_RESET is in progress.
|
|
|
|
* This is not needed when running the emulation under QEMU
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* TODO: H_INT_GET_OS_REPORTING_LINE */
|
|
|
|
return H_FUNCTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The H_INT_ESB hcall() is used to issue a load or store to the ESB
|
|
|
|
* page for the input "lisn". This hcall is only supported for LISNs
|
|
|
|
* that have the ESB hcall flag set to 1 when returned from hcall()
|
|
|
|
* H_INT_GET_SOURCE_INFO.
|
|
|
|
*
|
|
|
|
* Parameters:
|
|
|
|
* Input:
|
|
|
|
* - R4: "flags"
|
|
|
|
* Bits 0-62: Reserved
|
|
|
|
* bit 63: Store: Store=1, store operation, else load operation
|
|
|
|
* - R5: "lisn" is per "interrupts", "interrupt-map", or
|
|
|
|
* "ibm,xive-lisn-ranges" properties, or as returned by the
|
|
|
|
* ibm,query-interrupt-source-number RTAS call, or as
|
|
|
|
* returned by the H_ALLOCATE_VAS_WINDOW hcall
|
|
|
|
* - R6: "esbOffset" is the offset into the ESB page for the load or
|
|
|
|
* store operation
|
|
|
|
* - R7: "storeData" is the data to write for a store operation
|
|
|
|
*
|
|
|
|
* Output:
|
|
|
|
* - R4: The value of the load if load operation, else -1
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define SPAPR_XIVE_ESB_STORE PPC_BIT(63)
|
|
|
|
|
|
|
|
static target_ulong h_int_esb(PowerPCCPU *cpu,
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprMachineState *spapr,
|
2018-12-11 23:38:13 +01:00
|
|
|
target_ulong opcode,
|
|
|
|
target_ulong *args)
|
|
|
|
{
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprXive *xive = spapr->xive;
|
2018-12-11 23:38:13 +01:00
|
|
|
XiveEAS eas;
|
|
|
|
target_ulong flags = args[0];
|
|
|
|
target_ulong lisn = args[1];
|
|
|
|
target_ulong offset = args[2];
|
|
|
|
target_ulong data = args[3];
|
|
|
|
hwaddr mmio_addr;
|
|
|
|
XiveSource *xsrc = &xive->source;
|
|
|
|
|
2020-11-23 17:37:17 +01:00
|
|
|
trace_spapr_xive_esb(flags, lisn, offset, data);
|
|
|
|
|
2018-12-11 23:38:13 +01:00
|
|
|
if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
|
|
|
|
return H_FUNCTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flags & ~SPAPR_XIVE_ESB_STORE) {
|
|
|
|
return H_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lisn >= xive->nr_irqs) {
|
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Unknown LISN " TARGET_FMT_lx "\n",
|
|
|
|
lisn);
|
|
|
|
return H_P2;
|
|
|
|
}
|
|
|
|
|
|
|
|
eas = xive->eat[lisn];
|
|
|
|
if (!xive_eas_is_valid(&eas)) {
|
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid LISN " TARGET_FMT_lx "\n",
|
|
|
|
lisn);
|
|
|
|
return H_P2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (offset > (1ull << xsrc->esb_shift)) {
|
|
|
|
return H_P3;
|
|
|
|
}
|
|
|
|
|
2020-08-07 13:32:14 +02:00
|
|
|
if (spapr_xive_in_kernel(xive)) {
|
2019-05-13 10:42:34 +02:00
|
|
|
args[0] = kvmppc_xive_esb_rw(xsrc, lisn, offset, data,
|
|
|
|
flags & SPAPR_XIVE_ESB_STORE);
|
|
|
|
} else {
|
|
|
|
mmio_addr = xive->vc_base + xive_source_esb_mgmt(xsrc, lisn) + offset;
|
2018-12-11 23:38:13 +01:00
|
|
|
|
2019-05-13 10:42:34 +02:00
|
|
|
if (dma_memory_rw(&address_space_memory, mmio_addr, &data, 8,
|
2020-09-03 09:37:43 +02:00
|
|
|
(flags & SPAPR_XIVE_ESB_STORE),
|
|
|
|
MEMTXATTRS_UNSPECIFIED)) {
|
2019-05-13 10:42:34 +02:00
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: failed to access ESB @0x%"
|
|
|
|
HWADDR_PRIx "\n", mmio_addr);
|
|
|
|
return H_HARDWARE;
|
|
|
|
}
|
|
|
|
args[0] = (flags & SPAPR_XIVE_ESB_STORE) ? -1 : data;
|
2018-12-11 23:38:13 +01:00
|
|
|
}
|
|
|
|
return H_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The H_INT_SYNC hcall() is used to issue hardware syncs that will
|
|
|
|
* ensure any in flight events for the input lisn are in the event
|
|
|
|
* queue.
|
|
|
|
*
|
|
|
|
* Parameters:
|
|
|
|
* Input:
|
|
|
|
* - R4: "flags"
|
|
|
|
* Bits 0-63: Reserved
|
|
|
|
* - R5: "lisn" is per "interrupts", "interrupt-map", or
|
|
|
|
* "ibm,xive-lisn-ranges" properties, or as returned by the
|
|
|
|
* ibm,query-interrupt-source-number RTAS call, or as
|
|
|
|
* returned by the H_ALLOCATE_VAS_WINDOW hcall
|
|
|
|
*
|
|
|
|
* Output:
|
|
|
|
* - None
|
|
|
|
*/
|
|
|
|
static target_ulong h_int_sync(PowerPCCPU *cpu,
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprMachineState *spapr,
|
2018-12-11 23:38:13 +01:00
|
|
|
target_ulong opcode,
|
|
|
|
target_ulong *args)
|
|
|
|
{
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprXive *xive = spapr->xive;
|
2018-12-11 23:38:13 +01:00
|
|
|
XiveEAS eas;
|
|
|
|
target_ulong flags = args[0];
|
|
|
|
target_ulong lisn = args[1];
|
|
|
|
|
2020-11-23 17:37:17 +01:00
|
|
|
trace_spapr_xive_sync(flags, lisn);
|
|
|
|
|
2018-12-11 23:38:13 +01:00
|
|
|
if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
|
|
|
|
return H_FUNCTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flags) {
|
|
|
|
return H_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lisn >= xive->nr_irqs) {
|
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Unknown LISN " TARGET_FMT_lx "\n",
|
|
|
|
lisn);
|
|
|
|
return H_P2;
|
|
|
|
}
|
|
|
|
|
|
|
|
eas = xive->eat[lisn];
|
|
|
|
if (!xive_eas_is_valid(&eas)) {
|
|
|
|
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid LISN " TARGET_FMT_lx "\n",
|
|
|
|
lisn);
|
|
|
|
return H_P2;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* H_STATE should be returned if a H_INT_RESET is in progress.
|
|
|
|
* This is not needed when running the emulation under QEMU
|
|
|
|
*/
|
|
|
|
|
2019-05-13 10:42:34 +02:00
|
|
|
/*
|
|
|
|
* This is not real hardware. Nothing to be done unless when
|
|
|
|
* under KVM
|
|
|
|
*/
|
|
|
|
|
2020-08-07 13:32:14 +02:00
|
|
|
if (spapr_xive_in_kernel(xive)) {
|
2019-05-13 10:42:34 +02:00
|
|
|
Error *local_err = NULL;
|
|
|
|
|
|
|
|
kvmppc_xive_sync_source(xive, lisn, &local_err);
|
|
|
|
if (local_err) {
|
|
|
|
error_report_err(local_err);
|
|
|
|
return H_HARDWARE;
|
|
|
|
}
|
|
|
|
}
|
2018-12-11 23:38:13 +01:00
|
|
|
return H_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The H_INT_RESET hcall() is used to reset all of the partition's
|
|
|
|
* interrupt exploitation structures to their initial state. This
|
|
|
|
* means losing all previously set interrupt state set via
|
|
|
|
* H_INT_SET_SOURCE_CONFIG and H_INT_SET_QUEUE_CONFIG.
|
|
|
|
*
|
|
|
|
* Parameters:
|
|
|
|
* Input:
|
|
|
|
* - R4: "flags"
|
|
|
|
* Bits 0-63: Reserved
|
|
|
|
*
|
|
|
|
* Output:
|
|
|
|
* - None
|
|
|
|
*/
|
|
|
|
static target_ulong h_int_reset(PowerPCCPU *cpu,
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprMachineState *spapr,
|
2018-12-11 23:38:13 +01:00
|
|
|
target_ulong opcode,
|
|
|
|
target_ulong *args)
|
|
|
|
{
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
SpaprXive *xive = spapr->xive;
|
2018-12-11 23:38:13 +01:00
|
|
|
target_ulong flags = args[0];
|
|
|
|
|
2020-11-23 17:37:17 +01:00
|
|
|
trace_spapr_xive_reset(flags);
|
|
|
|
|
2018-12-11 23:38:13 +01:00
|
|
|
if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
|
|
|
|
return H_FUNCTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flags) {
|
|
|
|
return H_PARAMETER;
|
|
|
|
}
|
|
|
|
|
2021-05-03 17:18:47 +02:00
|
|
|
device_cold_reset(DEVICE(xive));
|
2019-05-13 10:42:34 +02:00
|
|
|
|
2020-08-07 13:32:14 +02:00
|
|
|
if (spapr_xive_in_kernel(xive)) {
|
2019-05-13 10:42:34 +02:00
|
|
|
Error *local_err = NULL;
|
|
|
|
|
|
|
|
kvmppc_xive_reset(xive, &local_err);
|
|
|
|
if (local_err) {
|
|
|
|
error_report_err(local_err);
|
|
|
|
return H_HARDWARE;
|
|
|
|
}
|
|
|
|
}
|
2018-12-11 23:38:13 +01:00
|
|
|
return H_SUCCESS;
|
|
|
|
}
|
|
|
|
|
spapr: Use CamelCase properly
The qemu coding standard is to use CamelCase for type and structure names,
and the pseries code follows that... sort of. There are quite a lot of
places where we bend the rules in order to preserve the capitalization of
internal acronyms like "PHB", "TCE", "DIMM" and most commonly "sPAPR".
That was a bad idea - it frequently leads to names ending up with hard to
read clusters of capital letters, and means they don't catch the eye as
type identifiers, which is kind of the point of the CamelCase convention in
the first place.
In short, keeping type identifiers look like CamelCase is more important
than preserving standard capitalization of internal "words". So, this
patch renames a heap of spapr internal type names to a more standard
CamelCase.
In addition to case changes, we also make some other identifier renames:
VIOsPAPR* -> SpaprVio*
The reverse word ordering was only ever used to mitigate the capital
cluster, so revert to the natural ordering.
VIOsPAPRVTYDevice -> SpaprVioVty
VIOsPAPRVLANDevice -> SpaprVioVlan
Brevity, since the "Device" didn't add useful information
sPAPRDRConnector -> SpaprDrc
sPAPRDRConnectorClass -> SpaprDrcClass
Brevity, and makes it clearer this is the same thing as a "DRC"
mentioned in many other places in the code
This is 100% a mechanical search-and-replace patch. It will, however,
conflict with essentially any and all outstanding patches touching the
spapr code.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2019-03-06 05:35:37 +01:00
|
|
|
void spapr_xive_hcall_init(SpaprMachineState *spapr)
|
2018-12-11 23:38:13 +01:00
|
|
|
{
|
|
|
|
spapr_register_hypercall(H_INT_GET_SOURCE_INFO, h_int_get_source_info);
|
|
|
|
spapr_register_hypercall(H_INT_SET_SOURCE_CONFIG, h_int_set_source_config);
|
|
|
|
spapr_register_hypercall(H_INT_GET_SOURCE_CONFIG, h_int_get_source_config);
|
|
|
|
spapr_register_hypercall(H_INT_GET_QUEUE_INFO, h_int_get_queue_info);
|
|
|
|
spapr_register_hypercall(H_INT_SET_QUEUE_CONFIG, h_int_set_queue_config);
|
|
|
|
spapr_register_hypercall(H_INT_GET_QUEUE_CONFIG, h_int_get_queue_config);
|
|
|
|
spapr_register_hypercall(H_INT_SET_OS_REPORTING_LINE,
|
|
|
|
h_int_set_os_reporting_line);
|
|
|
|
spapr_register_hypercall(H_INT_GET_OS_REPORTING_LINE,
|
|
|
|
h_int_get_os_reporting_line);
|
|
|
|
spapr_register_hypercall(H_INT_ESB, h_int_esb);
|
|
|
|
spapr_register_hypercall(H_INT_SYNC, h_int_sync);
|
|
|
|
spapr_register_hypercall(H_INT_RESET, h_int_reset);
|
|
|
|
}
|