Skip to content

Commit

Permalink
Merge tag 'pull-ppc-20230904' of https://github.com/legoater/qemu int…
Browse files Browse the repository at this point in the history
…o staging

ppc queue :

* debug facility improvements
* timebase and decrementer fixes
* record-replay fixes
* TCG fixes
* XIVE model improvements for multichip

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEEoPZlSPBIlev+awtgUaNDx8/77KEFAmT1jwIACgkQUaNDx8/7
# 7KH2EQ/+LIO5LMSE2CJAEyeZMqThWwRMMl7CQsfgFFj9BxHVSUvs8xdTWieD9cm+
# GlGwxiM+wEPc/aGdLbVeaOdfh/xB4gqpG3fmjCHRen8vvC4jThcLNvjZqbn8iRvm
# 50di9mVe2Cfa4A7yOtv81Z03NDyPmBIODSSFhs4GbAp81iAGhThan/f1eC6EzjxD
# Xa+TelCZfA2MWVZeuanEfcp+MrJHUbEiwmiDhNYgfHJdNHKVkJxsJKd7YvMKFH8v
# SFpzfbwonvtJrZyn5Mc54ovC3f0j/ztw9PxvJJpKLGuLSz4zM7CaeHMuMIpaMTqg
# MtRUZIhZB1O1qzRDWHK37FJMfL5/ThEMQOceJwxJZ8dqCvyv0L6uxmRC56G8djM8
# 7GKm7YXUF4fX3viZ6s7F4E/SelCSvz5ak/G/YEWl6ONv44UAdnJINH63OoRSj07I
# KGFoybJtP+RxjhpXqd1V4HZIstHYywjUYhZtLY/M9nKSQ2AtN09NR2eeUCt5ZVKl
# mKVcTgU2bX8S02UaYgQIAg5GkV6HyP3GQVzgPSPqdQKBKeroGkjBkv6IIZkoaxL2
# iOXM6fVXNo4LLsVq20kLRR3Ok5xyDRwtjlOlv/wNz6Y47AkKbzDDMhbjQnPuPzA3
# WPp59fiCkiMWvvMCfYVmA6t714Unq5Uqw90RWb+LzRDQnfBmPI8=
# =/LFO
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 04 Sep 2023 04:02:10 EDT
# gpg:                using RSA key A0F66548F04895EBFE6B0B6051A343C7CFFBECA1
# gpg: Good signature from "Cédric Le Goater <clg@redhat.com>" [unknown]
# gpg:                 aka "Cédric Le Goater <clg@kaod.org>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: A0F6 6548 F048 95EB FE6B  0B60 51A3 43C7 CFFB ECA1

* tag 'pull-ppc-20230904' of https://github.com/legoater/qemu: (35 commits)
  ppc/xive: Add support for the PC MMIOs
  ppc/xive: Handle END triggers between chips with MMIOs
  ppc/xive: Introduce a new XiveRouter end_notify() handler
  ppc/xive: Use address_space routines to access the machine RAM
  target/ppc: Fix the order of kvm_enable judgment about kvmppc_set_interrupt()
  hw/ppc/e500: fix broken snapshot replay
  target/ppc: Flush inputs to zero with NJ in ppc_store_vscr
  target/ppc: Fix LQ, STQ register-pair order for big-endian
  tests/avocado: ppc64 reverse debugging tests for pseries and powernv
  tests/avocado: reverse-debugging cope with re-executing breakpoints
  tests/avocado: boot ppc64 pseries replay-record test to Linux VFS mount
  spapr: Fix record-replay machine reset consuming too many events
  spapr: Fix machine reset deadlock from replay-record
  target/ppc: Fix timebase reset with record-replay
  target/ppc: Fix CPU reservation migration for record-replay
  hw/ppc: Read time only once to perform decrementer write
  hw/ppc: Reset timebase facilities on machine reset
  target/ppc: Migrate DECR SPR
  hw/ppc: Always store the decrementer value
  target/ppc: Sign-extend large decrementer to 64-bits
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
  • Loading branch information
stefanhaRH committed Sep 6, 2023
2 parents f3e3151 + 6ed4705 commit 39e007d
Show file tree
Hide file tree
Showing 34 changed files with 926 additions and 205 deletions.
170 changes: 133 additions & 37 deletions hw/intc/pnv_xive.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,28 +84,6 @@ static uint8_t pnv_xive_block_id(PnvXive *xive)
return blk;
}

/*
* Remote access to controllers. HW uses MMIOs. For now, a simple scan
* of the chips is good enough.
*
* TODO: Block scope support
*/
static PnvXive *pnv_xive_get_remote(uint8_t blk)
{
PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
int i;

for (i = 0; i < pnv->num_chips; i++) {
Pnv9Chip *chip9 = PNV9_CHIP(pnv->chips[i]);
PnvXive *xive = &chip9->xive;

if (pnv_xive_block_id(xive) == blk) {
return xive;
}
}
return NULL;
}

/*
* VST accessors for SBE, EAT, ENDT, NVT
*
Expand Down Expand Up @@ -209,6 +187,42 @@ static uint64_t pnv_xive_vst_addr_indirect(PnvXive *xive, uint32_t type,
return pnv_xive_vst_addr_direct(xive, type, vsd, (idx % vst_per_page));
}

/*
* This is a simplified model of operation forwarding on a remote IC.
*
* A PC MMIO address is built to identify the NVT structure. The load
* on the remote IC will return the address of the structure in RAM,
* which will then be used by pnv_xive_vst_write/read to perform the
* RAM operation.
*/
static uint64_t pnv_xive_vst_addr_remote(PnvXive *xive, uint32_t type,
uint64_t vsd, uint8_t blk,
uint32_t idx)
{
const XiveVstInfo *info = &vst_infos[type];
uint64_t remote_addr = vsd & VSD_ADDRESS_MASK;
uint64_t vst_addr;
MemTxResult result;

if (type != VST_TSEL_VPDT) {
xive_error(xive, "VST: invalid access on remote VST %s %x/%x !?",
info->name, blk, idx);
return 0;
}

remote_addr |= idx << xive->pc_shift;

vst_addr = address_space_ldq_be(&address_space_memory, remote_addr,
MEMTXATTRS_UNSPECIFIED, &result);
if (result != MEMTX_OK) {
xive_error(xive, "VST: read failed at @0x%" HWADDR_PRIx
" for NVT %x/%x\n", remote_addr, blk, idx);
return 0;
}

return vst_addr;
}

static uint64_t pnv_xive_vst_addr(PnvXive *xive, uint32_t type, uint8_t blk,
uint32_t idx)
{
Expand All @@ -225,9 +239,7 @@ static uint64_t pnv_xive_vst_addr(PnvXive *xive, uint32_t type, uint8_t blk,

/* Remote VST access */
if (GETFIELD(VSD_MODE, vsd) == VSD_MODE_FORWARD) {
xive = pnv_xive_get_remote(blk);

return xive ? pnv_xive_vst_addr(xive, type, blk, idx) : 0;
return pnv_xive_vst_addr_remote(xive, type, vsd, blk, idx);
}

if (VSD_INDIRECT & vsd) {
Expand All @@ -242,12 +254,20 @@ static int pnv_xive_vst_read(PnvXive *xive, uint32_t type, uint8_t blk,
{
const XiveVstInfo *info = &vst_infos[type];
uint64_t addr = pnv_xive_vst_addr(xive, type, blk, idx);
MemTxResult result;

if (!addr) {
return -1;
}

cpu_physical_memory_read(addr, data, info->size);
result = address_space_read(&address_space_memory, addr,
MEMTXATTRS_UNSPECIFIED, data,
info->size);
if (result != MEMTX_OK) {
xive_error(xive, "VST: read failed at @0x%" HWADDR_PRIx
" for VST %s %x/%x\n", addr, info->name, blk, idx);
return -1;
}
return 0;
}

Expand All @@ -258,29 +278,54 @@ static int pnv_xive_vst_write(PnvXive *xive, uint32_t type, uint8_t blk,
{
const XiveVstInfo *info = &vst_infos[type];
uint64_t addr = pnv_xive_vst_addr(xive, type, blk, idx);
MemTxResult result;

if (!addr) {
return -1;
}

if (word_number == XIVE_VST_WORD_ALL) {
cpu_physical_memory_write(addr, data, info->size);
result = address_space_write(&address_space_memory, addr,
MEMTXATTRS_UNSPECIFIED, data,
info->size);
} else {
cpu_physical_memory_write(addr + word_number * 4,
data + word_number * 4, 4);
result = address_space_write(&address_space_memory,
addr + word_number * 4,
MEMTXATTRS_UNSPECIFIED,
data + word_number * 4, 4);
}

if (result != MEMTX_OK) {
xive_error(xive, "VST: write failed at @0x%" HWADDR_PRIx
"for VST %s %x/%x\n", addr, info->name, blk, idx);
return -1;
}
return 0;
}

static int pnv_xive_get_end(XiveRouter *xrtr, uint8_t blk, uint32_t idx,
XiveEND *end)
{
PnvXive *xive = PNV_XIVE(xrtr);

if (pnv_xive_block_id(xive) != blk) {
xive_error(xive, "VST: END %x/%x is remote !?", blk, idx);
return -1;
}

return pnv_xive_vst_read(PNV_XIVE(xrtr), VST_TSEL_EQDT, blk, idx, end);
}

static int pnv_xive_write_end(XiveRouter *xrtr, uint8_t blk, uint32_t idx,
XiveEND *end, uint8_t word_number)
{
PnvXive *xive = PNV_XIVE(xrtr);

if (pnv_xive_block_id(xive) != blk) {
xive_error(xive, "VST: END %x/%x is remote !?", blk, idx);
return -1;
}

return pnv_xive_vst_write(PNV_XIVE(xrtr), VST_TSEL_EQDT, blk, idx, end,
word_number);
}
Expand Down Expand Up @@ -1349,6 +1394,50 @@ static const MemoryRegionOps pnv_xive_ic_reg_ops = {
#define PNV_XIVE_SYNC_PUSH 0xf00 /* Sync push context */
#define PNV_XIVE_SYNC_VPC 0xf80 /* Sync remove VPC store */

static void pnv_xive_end_notify(XiveRouter *xrtr, XiveEAS *eas)
{
PnvXive *xive = PNV_XIVE(xrtr);
uint8_t end_blk = xive_get_field64(EAS_END_BLOCK, eas->w);
uint32_t end_idx = xive_get_field64(EAS_END_INDEX, eas->w);
uint32_t end_data = xive_get_field64(EAS_END_DATA, eas->w);
uint64_t end_vsd = xive->vsds[VST_TSEL_EQDT][end_blk];

switch (GETFIELD(VSD_MODE, end_vsd)) {
case VSD_MODE_EXCLUSIVE:
/* Perform the END notification on the local IC. */
xive_router_end_notify(xrtr, eas);
break;

case VSD_MODE_FORWARD: {
MemTxResult result;
uint64_t notif_port = end_vsd & VSD_ADDRESS_MASK;
uint64_t data = XIVE_TRIGGER_END | XIVE_TRIGGER_PQ |
be64_to_cpu(eas->w);

/* Forward the store on the remote IC notify page. */
address_space_stq_be(&address_space_memory, notif_port, data,
MEMTXATTRS_UNSPECIFIED, &result);
if (result != MEMTX_OK) {
xive_error(xive, "IC: Forward notif END %x/%x [%x] failed @%"
HWADDR_PRIx, end_blk, end_idx, end_data, notif_port);
return;
}
break;
}

case VSD_MODE_INVALID:
default:
/* Set FIR */
xive_error(xive, "IC: Invalid END VSD for block %x", end_blk);
return;
}
}

/*
* The notify page can either be used to receive trigger events from
* the HW controllers (PHB, PSI) or to reroute interrupts between
* Interrupt controllers.
*/
static void pnv_xive_ic_hw_trigger(PnvXive *xive, hwaddr addr, uint64_t val)
{
uint8_t blk;
Expand All @@ -1357,8 +1446,8 @@ static void pnv_xive_ic_hw_trigger(PnvXive *xive, hwaddr addr, uint64_t val)
trace_pnv_xive_ic_hw_trigger(addr, val);

if (val & XIVE_TRIGGER_END) {
xive_error(xive, "IC: END trigger at @0x%"HWADDR_PRIx" data 0x%"PRIx64,
addr, val);
val = cpu_to_be64(val);
pnv_xive_end_notify(XIVE_ROUTER(xive), (XiveEAS *) &val);
return;
}

Expand Down Expand Up @@ -1703,16 +1792,20 @@ static const MemoryRegionOps pnv_xive_vc_ops = {
};

/*
* Presenter Controller MMIO region. The Virtualization Controller
* updates the IPB in the NVT table when required. Not modeled.
* Presenter Controller MMIO region. Points to the NVT sets.
*
* HW implements all possible mem ops to the underlying NVT structure
* but QEMU does not need to be so precise. The model implementation
* simply returns the RAM address of the NVT structure which is then
* used by pnv_xive_vst_write/read to perform the RAM operation.
*/
static uint64_t pnv_xive_pc_read(void *opaque, hwaddr addr,
unsigned size)
static uint64_t pnv_xive_pc_read(void *opaque, hwaddr offset, unsigned size)
{
PnvXive *xive = PNV_XIVE(opaque);
uint32_t nvt_idx = offset >> xive->pc_shift;
uint8_t blk = pnv_xive_block_id(xive); /* TODO: VDT -> block xlate */

xive_error(xive, "PC: invalid read @%"HWADDR_PRIx, addr);
return -1;
return pnv_xive_vst_addr(xive, VST_TSEL_VPDT, blk, nvt_idx);
}

static void pnv_xive_pc_write(void *opaque, hwaddr addr,
Expand Down Expand Up @@ -1898,6 +1991,7 @@ static void pnv_xive_realize(DeviceState *dev, Error **errp)
memory_region_init_io(&xive->ic_notify_mmio, OBJECT(dev),
&pnv_xive_ic_notify_ops,
xive, "xive-ic-notify", 1 << xive->ic_shift);
xive->ic_notify_mmio.disable_reentrancy_guard = true;

/* The Pervasive LSI trigger and EOI pages (not modeled) */
memory_region_init_io(&xive->ic_lsi_mmio, OBJECT(dev), &pnv_xive_ic_lsi_ops,
Expand Down Expand Up @@ -1933,6 +2027,7 @@ static void pnv_xive_realize(DeviceState *dev, Error **errp)
/* Presenter Controller MMIO region (not modeled) */
memory_region_init_io(&xive->pc_mmio, OBJECT(xive), &pnv_xive_pc_ops, xive,
"xive-pc", PNV9_XIVE_PC_SIZE);
xive->pc_mmio.disable_reentrancy_guard = true;

/* Thread Interrupt Management Area (Direct) */
memory_region_init_io(&xive->tm_mmio, OBJECT(xive), &pnv_xive_tm_ops,
Expand Down Expand Up @@ -1998,6 +2093,7 @@ static void pnv_xive_class_init(ObjectClass *klass, void *data)
xrc->get_nvt = pnv_xive_get_nvt;
xrc->write_nvt = pnv_xive_write_nvt;
xrc->get_block_id = pnv_xive_get_block_id;
xrc->end_notify = pnv_xive_end_notify;

xnc->notify = pnv_xive_notify;
xpc->match_nvt = pnv_xive_match_nvt;
Expand Down
27 changes: 23 additions & 4 deletions hw/intc/pnv_xive2.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,12 +240,20 @@ static int pnv_xive2_vst_read(PnvXive2 *xive, uint32_t type, uint8_t blk,
{
const XiveVstInfo *info = &vst_infos[type];
uint64_t addr = pnv_xive2_vst_addr(xive, type, blk, idx);
MemTxResult result;

if (!addr) {
return -1;
}

cpu_physical_memory_read(addr, data, info->size);
result = address_space_read(&address_space_memory, addr,
MEMTXATTRS_UNSPECIFIED, data,
info->size);
if (result != MEMTX_OK) {
xive2_error(xive, "VST: read failed at @0x%" HWADDR_PRIx
" for VST %s %x/%x\n", addr, info->name, blk, idx);
return -1;
}
return 0;
}

Expand All @@ -256,16 +264,27 @@ static int pnv_xive2_vst_write(PnvXive2 *xive, uint32_t type, uint8_t blk,
{
const XiveVstInfo *info = &vst_infos[type];
uint64_t addr = pnv_xive2_vst_addr(xive, type, blk, idx);
MemTxResult result;

if (!addr) {
return -1;
}

if (word_number == XIVE_VST_WORD_ALL) {
cpu_physical_memory_write(addr, data, info->size);
result = address_space_write(&address_space_memory, addr,
MEMTXATTRS_UNSPECIFIED, data,
info->size);
} else {
cpu_physical_memory_write(addr + word_number * 4,
data + word_number * 4, 4);
result = address_space_write(&address_space_memory,
addr + word_number * 4,
MEMTXATTRS_UNSPECIFIED,
data + word_number * 4, 4);
}

if (result != MEMTX_OK) {
xive2_error(xive, "VST: write failed at @0x%" HWADDR_PRIx
"for VST %s %x/%x\n", addr, info->name, blk, idx);
return -1;
}
return 0;
}
Expand Down
1 change: 1 addition & 0 deletions hw/intc/pnv_xive_regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@
* VSD and is only meant to be used in indirect mode !
*/
#define VSD_MODE PPC_BITMASK(0, 1)
#define VSD_MODE_INVALID 0
#define VSD_MODE_SHARED 1
#define VSD_MODE_EXCLUSIVE 2
#define VSD_MODE_FORWARD 3
Expand Down

0 comments on commit 39e007d

Please sign in to comment.