Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-4.1-20190612' into staging

ppc patch queue 2019-06-12

Next pull request against qemu-4.1.  The big thing here is adding
support for hot plug of P2P bridges, and PCI devices under P2P bridges
on the "pseries" machine (which doesn't use SHPC).  Other than that
there's just a handful of fixes and small enhancements.

# gpg: Signature made Wed 12 Jun 2019 06:47:56 BST
# gpg:                using RSA key 75F46586AE61A66CC44E87DC6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" [full]
# gpg:                 aka "David Gibson (Red Hat) <dgibson@redhat.com>" [full]
# gpg:                 aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" [full]
# gpg:                 aka "David Gibson (kernel.org) <dwg@kernel.org>" [unknown]
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E  87DC 6C38 CACA 20D9 B392

* remotes/dgibson/tags/ppc-for-4.1-20190612:
  ppc/xive: Make XIVE generate the proper interrupt types
  ppc/pnv: activate the "dumpdtb" option on the powernv machine
  target/ppc: Use tcg_gen_gvec_bitsel
  spapr: Allow hot plug/unplug of PCI bridges and devices under PCI bridges
  spapr: Direct all PCI hotplug to host bridge, rather than P2P bridge
  spapr: Don't use bus number for building DRC ids
  spapr: Clean up DRC index construction
  spapr: Clean up spapr_drc_populate_dt()
  spapr: Clean up dt creation for PCI buses
  spapr: Clean up device tree construction for PCI devices
  spapr: Clean up device node name generation for PCI devices
  target/ppc: Fix lxvw4x, lxvh8x and lxvb16x
  spapr_pci: Improve error message

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2019-06-12 14:43:47 +01:00
9 changed files with 371 additions and 241 deletions
+19 -3
View File
@@ -62,13 +62,28 @@ static uint8_t exception_mask(uint8_t ring)
}
}
static qemu_irq xive_tctx_output(XiveTCTX *tctx, uint8_t ring)
{
switch (ring) {
case TM_QW0_USER:
return 0; /* Not supported */
case TM_QW1_OS:
return tctx->os_output;
case TM_QW2_HV_POOL:
case TM_QW3_HV_PHYS:
return tctx->hv_output;
default:
return 0;
}
}
static uint64_t xive_tctx_accept(XiveTCTX *tctx, uint8_t ring)
{
uint8_t *regs = &tctx->regs[ring];
uint8_t nsr = regs[TM_NSR];
uint8_t mask = exception_mask(ring);
qemu_irq_lower(tctx->output);
qemu_irq_lower(xive_tctx_output(tctx, ring));
if (regs[TM_NSR] & mask) {
uint8_t cppr = regs[TM_PIPR];
@@ -101,7 +116,7 @@ static void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring)
default:
g_assert_not_reached();
}
qemu_irq_raise(tctx->output);
qemu_irq_raise(xive_tctx_output(tctx, ring));
}
}
@@ -557,7 +572,8 @@ static void xive_tctx_realize(DeviceState *dev, Error **errp)
env = &cpu->env;
switch (PPC_INPUT(env)) {
case PPC_FLAGS_INPUT_POWER9:
tctx->output = env->irq_inputs[POWER9_INPUT_INT];
tctx->hv_output = env->irq_inputs[POWER9_INPUT_HINT];
tctx->os_output = env->irq_inputs[POWER9_INPUT_INT];
break;
default:
+2
View File
@@ -24,6 +24,7 @@
#include "sysemu/sysemu.h"
#include "sysemu/numa.h"
#include "sysemu/cpus.h"
#include "sysemu/device_tree.h"
#include "hw/hw.h"
#include "target/ppc/cpu.h"
#include "qemu/log.h"
@@ -555,6 +556,7 @@ static void pnv_reset(void)
/* Pack resulting tree */
_FDT((fdt_pack(fdt)));
qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt));
cpu_physical_memory_write(PNV_FDT_ADDR, fdt, fdt_totalsize(fdt));
}
+17 -8
View File
@@ -1310,8 +1310,7 @@ static void *spapr_build_fdt(SpaprMachineState *spapr)
}
QLIST_FOREACH(phb, &spapr->phbs, list) {
ret = spapr_populate_pci_dt(phb, PHANDLE_INTC, fdt,
spapr->irq->nr_msis, NULL);
ret = spapr_dt_phb(phb, PHANDLE_INTC, fdt, spapr->irq->nr_msis, NULL);
if (ret < 0) {
error_report("couldn't setup PCI devices in fdt");
exit(1);
@@ -1322,13 +1321,12 @@ static void *spapr_build_fdt(SpaprMachineState *spapr)
spapr_populate_cpus_dt_node(fdt, spapr);
if (smc->dr_lmb_enabled) {
_FDT(spapr_drc_populate_dt(fdt, 0, NULL, SPAPR_DR_CONNECTOR_TYPE_LMB));
_FDT(spapr_dt_drc(fdt, 0, NULL, SPAPR_DR_CONNECTOR_TYPE_LMB));
}
if (mc->has_hotpluggable_cpus) {
int offset = fdt_path_offset(fdt, "/cpus");
ret = spapr_drc_populate_dt(fdt, offset, NULL,
SPAPR_DR_CONNECTOR_TYPE_CPU);
ret = spapr_dt_drc(fdt, offset, NULL, SPAPR_DR_CONNECTOR_TYPE_CPU);
if (ret < 0) {
error_report("Couldn't set up CPU DR device tree properties");
exit(1);
@@ -1365,7 +1363,7 @@ static void *spapr_build_fdt(SpaprMachineState *spapr)
}
if (smc->dr_phb_enabled) {
ret = spapr_drc_populate_dt(fdt, 0, NULL, SPAPR_DR_CONNECTOR_TYPE_PHB);
ret = spapr_dt_drc(fdt, 0, NULL, SPAPR_DR_CONNECTOR_TYPE_PHB);
if (ret < 0) {
error_report("Couldn't set up PHB DR device tree properties");
exit(1);
@@ -3918,8 +3916,8 @@ int spapr_phb_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
return -1;
}
if (spapr_populate_pci_dt(sphb, intc_phandle, fdt, spapr->irq->nr_msis,
fdt_start_offset)) {
if (spapr_dt_phb(sphb, intc_phandle, fdt, spapr->irq->nr_msis,
fdt_start_offset)) {
error_setg(errp, "unable to create FDT node for PHB %d", sphb->index);
return -1;
}
@@ -4097,6 +4095,17 @@ static HotplugHandler *spapr_get_hotplug_handler(MachineState *machine,
object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_PCI_HOST_BRIDGE)) {
return HOTPLUG_HANDLER(machine);
}
if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
PCIDevice *pcidev = PCI_DEVICE(dev);
PCIBus *root = pci_device_root_bus(pcidev);
SpaprPhbState *phb =
(SpaprPhbState *)object_dynamic_cast(OBJECT(BUS(root)->parent),
TYPE_SPAPR_PCI_HOST_BRIDGE);
if (phb) {
return HOTPLUG_HANDLER(phb);
}
}
return NULL;
}
+6 -7
View File
@@ -781,7 +781,7 @@ SpaprDrc *spapr_drc_by_id(const char *type, uint32_t id)
}
/**
* spapr_drc_populate_dt
* spapr_dt_drc
*
* @fdt: libfdt device tree
* @path: path in the DT to generate properties
@@ -794,8 +794,7 @@ SpaprDrc *spapr_drc_by_id(const char *type, uint32_t id)
*
* as documented in PAPR+ v2.1, 13.5.2
*/
int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
uint32_t drc_type_mask)
int spapr_dt_drc(void *fdt, int offset, Object *owner, uint32_t drc_type_mask)
{
Object *root_container;
ObjectProperty *prop;
@@ -873,7 +872,7 @@ int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
*(uint32_t *)drc_names->str = cpu_to_be32(drc_count);
*(uint32_t *)drc_types->str = cpu_to_be32(drc_count);
ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-indexes",
ret = fdt_setprop(fdt, offset, "ibm,drc-indexes",
drc_indexes->data,
drc_indexes->len * sizeof(uint32_t));
if (ret) {
@@ -881,7 +880,7 @@ int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
goto out;
}
ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-power-domains",
ret = fdt_setprop(fdt, offset, "ibm,drc-power-domains",
drc_power_domains->data,
drc_power_domains->len * sizeof(uint32_t));
if (ret) {
@@ -889,14 +888,14 @@ int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
goto out;
}
ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-names",
ret = fdt_setprop(fdt, offset, "ibm,drc-names",
drc_names->str, drc_names->len);
if (ret) {
error_report("Couldn't finalize ibm,drc-names property");
goto out;
}
ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-types",
ret = fdt_setprop(fdt, offset, "ibm,drc-types",
drc_types->str, drc_types->len);
if (ret) {
error_report("Couldn't finalize ibm,drc-types property");
+313 -190
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -131,8 +131,8 @@ static inline qemu_irq spapr_phb_lsi_qirq(struct SpaprPhbState *phb, int pin)
return spapr_qirq(spapr, phb->lsi_table[pin].irq);
}
int spapr_populate_pci_dt(SpaprPhbState *phb, uint32_t intc_phandle, void *fdt,
uint32_t nr_msis, int *node_offset);
int spapr_dt_phb(SpaprPhbState *phb, uint32_t intc_phandle, void *fdt,
uint32_t nr_msis, int *node_offset);
void spapr_pci_rtas_init(void);
+1 -2
View File
@@ -266,8 +266,7 @@ SpaprDrc *spapr_dr_connector_new(Object *owner, const char *type,
uint32_t id);
SpaprDrc *spapr_drc_by_index(uint32_t index);
SpaprDrc *spapr_drc_by_id(const char *type, uint32_t id);
int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
uint32_t drc_type_mask);
int spapr_dt_drc(void *fdt, int offset, Object *owner, uint32_t drc_type_mask);
void spapr_drc_attach(SpaprDrc *drc, DeviceState *d, Error **errp);
void spapr_drc_detach(SpaprDrc *drc);
+2 -1
View File
@@ -317,7 +317,8 @@ typedef struct XiveTCTX {
DeviceState parent_obj;
CPUState *cs;
qemu_irq output;
qemu_irq hv_output;
qemu_irq os_output;
uint8_t regs[XIVE_TM_RING_COUNT * XIVE_TM_RING_SIZE];
} XiveTCTX;
+9 -28
View File
@@ -102,8 +102,7 @@ static void gen_lxvw4x(DisasContext *ctx)
}
xth = tcg_temp_new_i64();
xtl = tcg_temp_new_i64();
get_cpu_vsrh(xth, xT(ctx->opcode));
get_cpu_vsrl(xtl, xT(ctx->opcode));
gen_set_access_type(ctx, ACCESS_INT);
EA = tcg_temp_new();
@@ -126,6 +125,8 @@ static void gen_lxvw4x(DisasContext *ctx)
tcg_gen_addi_tl(EA, EA, 8);
tcg_gen_qemu_ld_i64(xtl, EA, ctx->mem_idx, MO_BEQ);
}
set_cpu_vsrh(xT(ctx->opcode), xth);
set_cpu_vsrl(xT(ctx->opcode), xtl);
tcg_temp_free(EA);
tcg_temp_free_i64(xth);
tcg_temp_free_i64(xtl);
@@ -185,8 +186,6 @@ static void gen_lxvh8x(DisasContext *ctx)
}
xth = tcg_temp_new_i64();
xtl = tcg_temp_new_i64();
get_cpu_vsrh(xth, xT(ctx->opcode));
get_cpu_vsrl(xtl, xT(ctx->opcode));
gen_set_access_type(ctx, ACCESS_INT);
EA = tcg_temp_new();
@@ -197,6 +196,8 @@ static void gen_lxvh8x(DisasContext *ctx)
if (ctx->le_mode) {
gen_bswap16x8(xth, xtl, xth, xtl);
}
set_cpu_vsrh(xT(ctx->opcode), xth);
set_cpu_vsrl(xT(ctx->opcode), xtl);
tcg_temp_free(EA);
tcg_temp_free_i64(xth);
tcg_temp_free_i64(xtl);
@@ -214,14 +215,14 @@ static void gen_lxvb16x(DisasContext *ctx)
}
xth = tcg_temp_new_i64();
xtl = tcg_temp_new_i64();
get_cpu_vsrh(xth, xT(ctx->opcode));
get_cpu_vsrl(xtl, xT(ctx->opcode));
gen_set_access_type(ctx, ACCESS_INT);
EA = tcg_temp_new();
gen_addr_reg_index(ctx, EA);
tcg_gen_qemu_ld_i64(xth, EA, ctx->mem_idx, MO_BEQ);
tcg_gen_addi_tl(EA, EA, 8);
tcg_gen_qemu_ld_i64(xtl, EA, ctx->mem_idx, MO_BEQ);
set_cpu_vsrh(xT(ctx->opcode), xth);
set_cpu_vsrl(xT(ctx->opcode), xtl);
tcg_temp_free(EA);
tcg_temp_free_i64(xth);
tcg_temp_free_i64(xtl);
@@ -1338,28 +1339,8 @@ static void glue(gen_, name)(DisasContext *ctx) \
VSX_XXMRG(xxmrghw, 1)
VSX_XXMRG(xxmrglw, 0)
static void xxsel_i64(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b, TCGv_i64 c)
{
tcg_gen_and_i64(b, b, c);
tcg_gen_andc_i64(a, a, c);
tcg_gen_or_i64(t, a, b);
}
static void xxsel_vec(unsigned vece, TCGv_vec t, TCGv_vec a,
TCGv_vec b, TCGv_vec c)
{
tcg_gen_and_vec(vece, b, b, c);
tcg_gen_andc_vec(vece, a, a, c);
tcg_gen_or_vec(vece, t, a, b);
}
static void gen_xxsel(DisasContext *ctx)
{
static const GVecGen4 g = {
.fni8 = xxsel_i64,
.fniv = xxsel_vec,
.vece = MO_64,
};
int rt = xT(ctx->opcode);
int ra = xA(ctx->opcode);
int rb = xB(ctx->opcode);
@@ -1369,8 +1350,8 @@ static void gen_xxsel(DisasContext *ctx)
gen_exception(ctx, POWERPC_EXCP_VSXU);
return;
}
tcg_gen_gvec_4(vsr_full_offset(rt), vsr_full_offset(ra),
vsr_full_offset(rb), vsr_full_offset(rc), 16, 16, &g);
tcg_gen_gvec_bitsel(MO_64, vsr_full_offset(rt), vsr_full_offset(rc),
vsr_full_offset(rb), vsr_full_offset(ra), 16, 16);
}
static void gen_xxspltw(DisasContext *ctx)