Skip to content

Commit

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

ppc patch queue for 2023-06-10:

This queue includes several assorted fixes for target/ppc emulation and
XIVE2. It also includes an openpic fix, an avocado fix for ppc64
binaries without slipr and a Kconfig change for MAC_NEWWORLD.

# -----BEGIN PGP SIGNATURE-----
#
# iIwEABYKADQWIQQX6/+ZI9AYAK8oOBk82cqW3gMxZAUCZIR6uhYcZGFuaWVsaGI0
# MTNAZ21haWwuY29tAAoJEDzZypbeAzFksQsA/jucd+qsZ9mmJ9SYVd4umMnC/4bC
# i4CHo/XcHb0DzyBXAQCLxMA+KSTkP+yKv3edra4I5K9qjTW1H+pEOWamh1lvDw==
# =EezE
# -----END PGP SIGNATURE-----
# gpg: Signature made Sat 10 Jun 2023 06:29:30 AM PDT
# gpg:                using EDDSA key 17EBFF9923D01800AF2838193CD9CA96DE033164
# gpg:                issuer "danielhb413@gmail.com"
# gpg: Good signature from "Daniel Henrique Barboza <danielhb413@gmail.com>" [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: 17EB FF99 23D0 1800 AF28  3819 3CD9 CA96 DE03 3164

* tag 'pull-ppc-20230610' of https://gitlab.com/danielhb/qemu: (29 commits)
  hw/ppc/Kconfig: MAC_NEWWORLD should always select USB_OHCI_PCI
  target/ppc: Implement gathering irq statistics
  tests/avocado/tuxrun_baselines: Fix ppc64 tests for binaries without slirp
  hw/ppc/openpic: Do not open-code ROUND_UP() macro
  target/ppc: Decrementer fix BookE semantics
  target/ppc: Fix decrementer time underflow and infinite timer loop
  target/ppc: Rework store conditional to avoid branch
  target/ppc: Remove larx/stcx. memory barrier semantics
  target/ppc: Ensure stcx size matches larx
  target/ppc: Fix lqarx to set cpu_reserve
  target/ppc: Eliminate goto in mmubooke_check_tlb()
  target/ppc: Change ppcemb_tlb_check() to return bool
  target/ppc: Simplify ppcemb_tlb_search()
  target/ppc: Remove some unneded line breaks
  target/ppc: Move ppcemb_tlb_search() to mmu_common.c
  target/ppc: Remove "ext" parameter of ppcemb_tlb_check()
  target/ppc: Remove single use function
  target/ppc: PMU implement PERFM interrupts
  target/ppc: Support directed privileged doorbell interrupt (SDOOR)
  target/ppc: Fix msgclrp interrupt type
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
  • Loading branch information
rth7680 committed Jun 10, 2023
2 parents 374db3c + 9ec08f3 commit fdd0df5
Show file tree
Hide file tree
Showing 19 changed files with 289 additions and 196 deletions.
24 changes: 23 additions & 1 deletion hw/intc/pnv_xive2.c
Expand Up @@ -163,7 +163,9 @@ static uint64_t pnv_xive2_vst_addr_indirect(PnvXive2 *xive, uint32_t type,
ldq_be_dma(&address_space_memory, vsd_addr, &vsd, MEMTXATTRS_UNSPECIFIED);

if (!(vsd & VSD_ADDRESS_MASK)) {
#ifdef XIVE2_DEBUG
xive2_error(xive, "VST: invalid %s entry %x !?", info->name, idx);
#endif
return 0;
}

Expand All @@ -185,7 +187,9 @@ static uint64_t pnv_xive2_vst_addr_indirect(PnvXive2 *xive, uint32_t type,
MEMTXATTRS_UNSPECIFIED);

if (!(vsd & VSD_ADDRESS_MASK)) {
#ifdef XIVE2_DEBUG
xive2_error(xive, "VST: invalid %s entry %x !?", info->name, idx);
#endif
return 0;
}

Expand Down Expand Up @@ -955,6 +959,10 @@ static uint64_t pnv_xive2_ic_vc_read(void *opaque, hwaddr offset,
val = xive->vc_regs[reg];
break;

case VC_ESBC_CFG:
val = xive->vc_regs[reg];
break;

/*
* EAS cache updates (not modeled)
*/
Expand Down Expand Up @@ -1046,6 +1054,9 @@ static void pnv_xive2_ic_vc_write(void *opaque, hwaddr offset,
/* ESB update */
break;

case VC_ESBC_CFG:
break;

/*
* EAS cache updates (not modeled)
*/
Expand Down Expand Up @@ -1265,6 +1276,9 @@ static uint64_t pnv_xive2_ic_tctxt_read(void *opaque, hwaddr offset,
case TCTXT_EN1_RESET:
val = xive->tctxt_regs[TCTXT_EN1 >> 3];
break;
case TCTXT_CFG:
val = xive->tctxt_regs[reg];
break;
default:
xive2_error(xive, "TCTXT: invalid read @%"HWADDR_PRIx, offset);
}
Expand All @@ -1276,13 +1290,15 @@ static void pnv_xive2_ic_tctxt_write(void *opaque, hwaddr offset,
uint64_t val, unsigned size)
{
PnvXive2 *xive = PNV_XIVE2(opaque);
uint32_t reg = offset >> 3;

switch (offset) {
/*
* XIVE2 hardware thread enablement
*/
case TCTXT_EN0: /* Physical Thread Enable */
case TCTXT_EN1: /* Physical Thread Enable (fused core) */
xive->tctxt_regs[reg] = val;
break;

case TCTXT_EN0_SET:
Expand All @@ -1297,7 +1313,9 @@ static void pnv_xive2_ic_tctxt_write(void *opaque, hwaddr offset,
case TCTXT_EN1_RESET:
xive->tctxt_regs[TCTXT_EN1 >> 3] &= ~val;
break;

case TCTXT_CFG:
xive->tctxt_regs[reg] = val;
break;
default:
xive2_error(xive, "TCTXT: invalid write @%"HWADDR_PRIx, offset);
return;
Expand Down Expand Up @@ -1648,6 +1666,8 @@ static void pnv_xive2_tm_write(void *opaque, hwaddr offset,
bool gen1_tima_os =
xive->cq_regs[CQ_XIVE_CFG >> 3] & CQ_XIVE_CFG_GEN1_TIMA_OS;

offset &= TM_ADDRESS_MASK;

/* TODO: should we switch the TM ops table instead ? */
if (!gen1_tima_os && offset == HV_PUSH_OS_CTX_OFFSET) {
xive2_tm_push_os_ctx(xptr, tctx, offset, value, size);
Expand All @@ -1667,6 +1687,8 @@ static uint64_t pnv_xive2_tm_read(void *opaque, hwaddr offset, unsigned size)
bool gen1_tima_os =
xive->cq_regs[CQ_XIVE_CFG >> 3] & CQ_XIVE_CFG_GEN1_TIMA_OS;

offset &= TM_ADDRESS_MASK;

/* TODO: should we switch the TM ops table instead ? */
if (!gen1_tima_os && offset == HV_PULL_OS_CTX_OFFSET) {
return xive2_tm_pull_os_ctx(xptr, tctx, offset, size);
Expand Down
8 changes: 8 additions & 0 deletions hw/intc/pnv_xive2_regs.h
Expand Up @@ -232,6 +232,10 @@
#define VC_ESBC_FLUSH_POLL_BLOCK_ID_MASK PPC_BITMASK(32, 35)
#define VC_ESBC_FLUSH_POLL_OFFSET_MASK PPC_BITMASK(36, 63) /* 28-bit */

/* ESBC configuration */
#define X_VC_ESBC_CFG 0x148
#define VC_ESBC_CFG 0x240

/* EASC flush control register */
#define X_VC_EASC_FLUSH_CTRL 0x160
#define VC_EASC_FLUSH_CTRL 0x300
Expand Down Expand Up @@ -405,6 +409,10 @@
#define X_TCTXT_EN1_RESET 0x307
#define TCTXT_EN1_RESET 0x038

/* TCTXT Config register */
#define X_TCTXT_CFG 0x328
#define TCTXT_CFG 0x140

/*
* VSD Tables
*/
Expand Down
16 changes: 8 additions & 8 deletions hw/intc/xive.c
Expand Up @@ -249,7 +249,7 @@ static const uint8_t *xive_tm_views[] = {
static uint64_t xive_tm_mask(hwaddr offset, unsigned size, bool write)
{
uint8_t page_offset = (offset >> TM_SHIFT) & 0x3;
uint8_t reg_offset = offset & 0x3F;
uint8_t reg_offset = offset & TM_REG_OFFSET;
uint8_t reg_mask = write ? 0x1 : 0x2;
uint64_t mask = 0x0;
int i;
Expand All @@ -266,8 +266,8 @@ static uint64_t xive_tm_mask(hwaddr offset, unsigned size, bool write)
static void xive_tm_raw_write(XiveTCTX *tctx, hwaddr offset, uint64_t value,
unsigned size)
{
uint8_t ring_offset = offset & 0x30;
uint8_t reg_offset = offset & 0x3F;
uint8_t ring_offset = offset & TM_RING_OFFSET;
uint8_t reg_offset = offset & TM_REG_OFFSET;
uint64_t mask = xive_tm_mask(offset, size, true);
int i;

Expand Down Expand Up @@ -296,8 +296,8 @@ static void xive_tm_raw_write(XiveTCTX *tctx, hwaddr offset, uint64_t value,

static uint64_t xive_tm_raw_read(XiveTCTX *tctx, hwaddr offset, unsigned size)
{
uint8_t ring_offset = offset & 0x30;
uint8_t reg_offset = offset & 0x3F;
uint8_t ring_offset = offset & TM_RING_OFFSET;
uint8_t reg_offset = offset & TM_REG_OFFSET;
uint64_t mask = xive_tm_mask(offset, size, false);
uint64_t ret;
int i;
Expand Down Expand Up @@ -500,7 +500,7 @@ static const XiveTmOp xive_tm_operations[] = {
static const XiveTmOp *xive_tm_find_op(hwaddr offset, unsigned size, bool write)
{
uint8_t page_offset = (offset >> TM_SHIFT) & 0x3;
uint32_t op_offset = offset & 0xFFF;
uint32_t op_offset = offset & TM_ADDRESS_MASK;
int i;

for (i = 0; i < ARRAY_SIZE(xive_tm_operations); i++) {
Expand Down Expand Up @@ -534,7 +534,7 @@ void xive_tctx_tm_write(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
/*
* First, check for special operations in the 2K region
*/
if (offset & 0x800) {
if (offset & TM_SPECIAL_OP) {
xto = xive_tm_find_op(offset, size, true);
if (!xto) {
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid write access at TIMA "
Expand Down Expand Up @@ -573,7 +573,7 @@ uint64_t xive_tctx_tm_read(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset,
/*
* First, check for special operations in the 2K region
*/
if (offset & 0x800) {
if (offset & TM_SPECIAL_OP) {
xto = xive_tm_find_op(offset, size, false);
if (!xto) {
qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid read access to TIMA"
Expand Down
1 change: 1 addition & 0 deletions hw/ppc/Kconfig
Expand Up @@ -115,6 +115,7 @@ config MAC_NEWWORLD
select MAC_PMU
select UNIN_PCI
select FW_CFG_PPC
select USB_OHCI_PCI

config E500
bool
Expand Down
11 changes: 4 additions & 7 deletions hw/ppc/ppc.c
Expand Up @@ -798,6 +798,8 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp,
int64_t signed_decr;

/* Truncate value to decr_width and sign extend for simplicity */
value = extract64(value, 0, nr_bits);
decr = extract64(decr, 0, nr_bits);
signed_value = sextract64(value, 0, nr_bits);
signed_decr = sextract64(decr, 0, nr_bits);

Expand All @@ -809,20 +811,15 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp,
}

/*
* Going from 2 -> 1, 1 -> 0 or 0 -> -1 is the event to generate a DEC
* interrupt.
*
* If we get a really small DEC value, we can assume that by the time we
* handled it we should inject an interrupt already.
* Going from 1 -> 0 or 0 -> -1 is the event to generate a DEC interrupt.
*
* On MSB level based DEC implementations the MSB always means the interrupt
* is pending, so raise it on those.
*
* On MSB edge based DEC implementations the MSB going from 0 -> 1 triggers
* an edge interrupt, so raise it here too.
*/
if ((value < 3) ||
((tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL) && signed_value < 0) ||
if (((tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL) && signed_value < 0) ||
((tb_env->flags & PPC_DECR_UNDERFLOW_TRIGGERED) && signed_value < 0
&& signed_decr >= 0)) {
(*raise_excp)(cpu);
Expand Down
2 changes: 1 addition & 1 deletion include/hw/ppc/openpic.h
Expand Up @@ -55,7 +55,7 @@ typedef enum IRQType {
* Round up to the nearest 64 IRQs so that the queue length
* won't change when moving between 32 and 64 bit hosts.
*/
#define IRQQUEUE_SIZE_BITS ((OPENPIC_MAX_IRQ + 63) & ~63)
#define IRQQUEUE_SIZE_BITS ROUND_UP(OPENPIC_MAX_IRQ, 64)

typedef struct IRQQueue {
unsigned long *queue;
Expand Down
16 changes: 16 additions & 0 deletions include/hw/ppc/xive_regs.h
Expand Up @@ -48,6 +48,22 @@

#define TM_SHIFT 16

/*
* TIMA addresses are 12-bits (4k page).
* The MSB indicates a special op with side effect, which can be
* refined with bit 10 (see below).
* The registers, logically grouped in 4 rings (a quad-word each), are
* defined on the 6 LSBs (offset below 0x40)
* In between, we can add a cache line index from 0...3 (ie, 0, 0x80,
* 0x100, 0x180) to select a specific snooper. Those 'snoop port
* address' bits should be dropped when processing the operations as
* they are all equivalent.
*/
#define TM_ADDRESS_MASK 0xC3F
#define TM_SPECIAL_OP 0x800
#define TM_RING_OFFSET 0x30
#define TM_REG_OFFSET 0x3F

/* TM register offsets */
#define TM_QW0_USER 0x000 /* All rings */
#define TM_QW1_OS 0x010 /* Ring 0..2 */
Expand Down
19 changes: 8 additions & 11 deletions target/ppc/cpu.h
Expand Up @@ -1114,8 +1114,9 @@ struct CPUArchState {
target_ulong ov32;
target_ulong ca32;

target_ulong reserve_addr; /* Reservation address */
target_ulong reserve_val; /* Reservation value */
target_ulong reserve_addr; /* Reservation address */
target_ulong reserve_length; /* Reservation larx op size (bytes) */
target_ulong reserve_val; /* Reservation value */
target_ulong reserve_val2;

/* These are used in supervisor mode only */
Expand Down Expand Up @@ -1194,6 +1195,7 @@ struct CPUArchState {
int error_code;
uint32_t pending_interrupts;
#if !defined(CONFIG_USER_ONLY)
uint64_t excp_stats[POWERPC_EXCP_NB];
/*
* This is the IRQ controller, which is implementation dependent and only
* relevant when emulating a complete machine. Note that this isn't used
Expand Down Expand Up @@ -1424,15 +1426,10 @@ void store_booke_tsr(CPUPPCState *env, target_ulong val);
void ppc_tlb_invalidate_all(CPUPPCState *env);
void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr);
void cpu_ppc_set_vhyp(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp);
int ppcmas_tlb_check(CPUPPCState *env, ppcmas_tlb_t *tlb,
hwaddr *raddrp, target_ulong address,
uint32_t pid);
int ppcemb_tlb_check(CPUPPCState *env, ppcemb_tlb_t *tlb,
hwaddr *raddrp,
target_ulong address, uint32_t pid, int ext,
int i);
hwaddr booke206_tlb_to_page_size(CPUPPCState *env,
ppcmas_tlb_t *tlb);
int ppcmas_tlb_check(CPUPPCState *env, ppcmas_tlb_t *tlb, hwaddr *raddrp,
target_ulong address, uint32_t pid);
int ppcemb_tlb_search(CPUPPCState *env, target_ulong address, uint32_t pid);
hwaddr booke206_tlb_to_page_size(CPUPPCState *env, ppcmas_tlb_t *tlb);
#endif

void ppc_store_fpscr(CPUPPCState *env, target_ulong val);
Expand Down
24 changes: 21 additions & 3 deletions target/ppc/cpu_init.c
Expand Up @@ -48,6 +48,7 @@

#ifndef CONFIG_USER_ONLY
#include "hw/boards.h"
#include "hw/intc/intc.h"
#endif

/* #define PPC_DEBUG_SPR */
Expand Down Expand Up @@ -7083,7 +7084,7 @@ static void ppc_cpu_reset_hold(Object *obj)
if (env->mmu_model != POWERPC_MMU_REAL) {
ppc_tlb_invalidate_all(env);
}
pmu_update_summaries(env);
pmu_mmcr01_updated(env);
}

/* clean any pending stop state */
Expand Down Expand Up @@ -7123,6 +7124,16 @@ static bool ppc_cpu_is_big_endian(CPUState *cs)
return !FIELD_EX64(env->msr, MSR, LE);
}

static bool ppc_get_irq_stats(InterruptStatsProvider *obj,
uint64_t **irq_counts, unsigned int *nb_irqs)
{
CPUPPCState *env = &POWERPC_CPU(obj)->env;

*irq_counts = env->excp_stats;
*nb_irqs = ARRAY_SIZE(env->excp_stats);
return true;
}

#ifdef CONFIG_TCG
static void ppc_cpu_exec_enter(CPUState *cs)
{
Expand Down Expand Up @@ -7286,6 +7297,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
cc->gdb_write_register = ppc_cpu_gdb_write_register;
#ifndef CONFIG_USER_ONLY
cc->sysemu_ops = &ppc_sysemu_ops;
INTERRUPT_STATS_PROVIDER_CLASS(oc)->get_statistics = ppc_get_irq_stats;
#endif

cc->gdb_num_core_regs = 71;
Expand Down Expand Up @@ -7323,6 +7335,12 @@ static const TypeInfo ppc_cpu_type_info = {
.abstract = true,
.class_size = sizeof(PowerPCCPUClass),
.class_init = ppc_cpu_class_init,
#ifndef CONFIG_USER_ONLY
.interfaces = (InterfaceInfo[]) {
{ TYPE_INTERRUPT_STATS_PROVIDER },
{ }
},
#endif
};

#ifndef CONFIG_USER_ONLY
Expand Down Expand Up @@ -7392,8 +7410,8 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
}
qemu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
}
qemu_fprintf(f, " ] RES " TARGET_FMT_lx "\n",
env->reserve_addr);
qemu_fprintf(f, " ] RES %03x@" TARGET_FMT_lx "\n",
(int)env->reserve_length, env->reserve_addr);

if (flags & CPU_DUMP_FPU) {
for (i = 0; i < 32; i++) {
Expand Down

0 comments on commit fdd0df5

Please sign in to comment.