mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-27 21:40:49 +00:00
ppc patch queue 2018-01-21
This request supersedes the one from 2018-01-19. The only difference is that the patch deprecating ppcemb-softmmu, and thereby creating many annying warnings from make check has been removed. Highlights are: * Significant TCG speedup by optimizing cmp generation * Fix a regression caused by recent change to set compat mode on hotplugged cpus * Cleanup of default configs * Some implementation of msgsnd/msgrcv instructions for server chips -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEdfRlhq5hpmzETofcbDjKyiDZs5IFAlpkJY4ACgkQbDjKyiDZ s5KIjxAAxlPbUprnSe4f2heYGRjHivlXjdeVYK1ngMUULpRTyRQzq87qOC2qh8FR l6X0JTlzdgHX0Zb+oysG6ksflNc1fgriDN00AQvFgpMXp0WZXkOoyMHj/E4pRr02 b3tMGDZmyTOFGOG6uiQNFnUitaXuap+u3orH0sqdKaN035azAXIB09iHnKLzBrjl VzrJJSJH9sWMVCJDHfLEbccfhJPx9uQ/eexccesfxpscFgpqoQOeS+ASq0iXm/DC 1OM/JEu5J9s94YKRia4IE/t3z0ZTUvh6Ep451Wt4sx/fdF9ricvQoucoYuPF241W L8Op+8yKeNYz/vTs/nVk9WWowy3V+N/BtZ8pEJsTcZph3EsF7UR8pVz8A/Q74dUN ztXjesoxX9BB8Gh1wYstMxvCDfhmL2x41cCDs2QOBzPc2WorngtGLEU5XA36uYLi wstLTXZ9sGqJgWcXk1oQc/O5Vpq6KBkj4z2XfoHI7iQzSWiFRew4BWTBXinXA0xz PbmMZNL6cZl21hSK8TLpQ8ENFbUBhNXlB/JDbXAxcFW5YLTU3iItH+WByn7HVvhu Pr8eAPfGBRtFNys9UdD+jYa1v4AQXMpv8TAcrW00OyfvMkRJDdHI8H9UwF0lRepW Pm3iHDtEA8NBQEbw5SpTWzlJzD4mDSMGoX3VONofBSFhzGVgoiE= =Y+Y+ -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.12-20180121' into staging ppc patch queue 2018-01-21 This request supersedes the one from 2018-01-19. The only difference is that the patch deprecating ppcemb-softmmu, and thereby creating many annying warnings from make check has been removed. Highlights are: * Significant TCG speedup by optimizing cmp generation * Fix a regression caused by recent change to set compat mode on hotplugged cpus * Cleanup of default configs * Some implementation of msgsnd/msgrcv instructions for server chips # gpg: Signature made Sun 21 Jan 2018 05:30:54 GMT # gpg: using RSA key 0x6C38CACA20D9B392 # gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" # gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>" # gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" # gpg: aka "David Gibson (kernel.org) <dwg@kernel.org>" # Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392 * remotes/dgibson/tags/ppc-for-2.12-20180121: target/ppc/spapr_caps: Add macro to generate spapr_caps migration vmstate target/ppc: add support for hypervisor doorbells on book3s CPUs sii3112: Add explicit type casts to avoid unintended sign extension sm501: Add missing break to case target-ppc: optimize cmp translation spapr: fix device tree properties when using compatibility mode spapr: drop duplicate variable in spapr_core_plug() target/ppc: msgsnd and msgclr instructions need hypervisor privilege target/ppc: fix doorbell and hypervisor doorbell definitions hw/ppc/Makefile: Add a way to disable the PPC4xx boards default-configs/ppc-softmmu: Restructure the switches according to the machines default-configs/ppc64-softmmu: Include 32-bit configs instead of copying them Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
ee264eb32c
@ -3,24 +3,32 @@
|
||||
include pci.mak
|
||||
include sound.mak
|
||||
include usb.mak
|
||||
|
||||
# For embedded PPCs:
|
||||
CONFIG_PPC4XX=y
|
||||
CONFIG_ESCC=y
|
||||
CONFIG_M48T59=y
|
||||
CONFIG_SERIAL=y
|
||||
CONFIG_PARALLEL=y
|
||||
CONFIG_I8254=y
|
||||
CONFIG_PCKBD=y
|
||||
CONFIG_FDC=y
|
||||
CONFIG_I8257=y
|
||||
CONFIG_I82374=y
|
||||
CONFIG_OPENPIC=y
|
||||
CONFIG_PREP_PCI=y
|
||||
CONFIG_I82378=y
|
||||
CONFIG_PC87312=y
|
||||
CONFIG_PPCE500_PCI=y
|
||||
CONFIG_PFLASH_CFI01=y
|
||||
CONFIG_PFLASH_CFI02=y
|
||||
CONFIG_PTIMER=y
|
||||
CONFIG_I8259=y
|
||||
CONFIG_XILINX=y
|
||||
CONFIG_XILINX_ETHLITE=y
|
||||
CONFIG_E500=y
|
||||
CONFIG_OPENPIC_KVM=$(call land,$(CONFIG_E500),$(CONFIG_KVM))
|
||||
CONFIG_PLATFORM_BUS=y
|
||||
CONFIG_ETSEC=y
|
||||
CONFIG_SM501=y
|
||||
CONFIG_IDE_SII3112=y
|
||||
|
||||
# For Macs
|
||||
CONFIG_MAC=y
|
||||
CONFIG_ESCC=y
|
||||
CONFIG_MACIO=y
|
||||
CONFIG_SUNGEM=y
|
||||
CONFIG_PCSPK=y
|
||||
CONFIG_CS4231A=y
|
||||
CONFIG_CUDA=y
|
||||
CONFIG_ADB=y
|
||||
CONFIG_MAC_NVRAM=y
|
||||
@ -29,26 +37,23 @@ CONFIG_HEATHROW_PIC=y
|
||||
CONFIG_GRACKLE_PCI=y
|
||||
CONFIG_UNIN_PCI=y
|
||||
CONFIG_DEC_PCI=y
|
||||
CONFIG_PPCE500_PCI=y
|
||||
CONFIG_IDE_ISA=y
|
||||
CONFIG_IDE_CMD646=y
|
||||
CONFIG_IDE_MACIO=y
|
||||
CONFIG_NE2000_ISA=y
|
||||
CONFIG_PFLASH_CFI01=y
|
||||
CONFIG_PFLASH_CFI02=y
|
||||
CONFIG_PTIMER=y
|
||||
CONFIG_I8259=y
|
||||
CONFIG_XILINX=y
|
||||
CONFIG_XILINX_ETHLITE=y
|
||||
CONFIG_PREP=y
|
||||
CONFIG_MAC=y
|
||||
CONFIG_E500=y
|
||||
CONFIG_OPENPIC_KVM=$(call land,$(CONFIG_E500),$(CONFIG_KVM))
|
||||
CONFIG_PLATFORM_BUS=y
|
||||
CONFIG_ETSEC=y
|
||||
CONFIG_SM501=y
|
||||
|
||||
# For PReP
|
||||
CONFIG_PREP=y
|
||||
CONFIG_PREP_PCI=y
|
||||
CONFIG_SERIAL_ISA=y
|
||||
CONFIG_MC146818RTC=y
|
||||
CONFIG_ISA_TESTDEV=y
|
||||
CONFIG_RS6000_MC=y
|
||||
CONFIG_PARALLEL=y
|
||||
CONFIG_I82374=y
|
||||
CONFIG_I82378=y
|
||||
CONFIG_I8254=y
|
||||
CONFIG_PCKBD=y
|
||||
CONFIG_FDC=y
|
||||
CONFIG_NE2000_ISA=y
|
||||
CONFIG_PC87312=y
|
||||
CONFIG_PCSPK=y
|
||||
CONFIG_IDE_ISA=y
|
||||
CONFIG_CS4231A=y
|
||||
|
@ -1,64 +1,19 @@
|
||||
# Default configuration for ppc64-softmmu
|
||||
|
||||
include pci.mak
|
||||
include sound.mak
|
||||
include usb.mak
|
||||
CONFIG_PPC4XX=y
|
||||
CONFIG_VIRTIO_VGA=y
|
||||
CONFIG_ESCC=y
|
||||
CONFIG_M48T59=y
|
||||
# Include all 32-bit boards
|
||||
include ppc-softmmu.mak
|
||||
|
||||
# For PowerNV
|
||||
CONFIG_POWERNV=y
|
||||
CONFIG_IPMI=y
|
||||
CONFIG_IPMI_LOCAL=y
|
||||
CONFIG_IPMI_EXTERN=y
|
||||
CONFIG_ISA_IPMI_BT=y
|
||||
CONFIG_SERIAL=y
|
||||
CONFIG_PARALLEL=y
|
||||
CONFIG_I8254=y
|
||||
CONFIG_PCKBD=y
|
||||
CONFIG_FDC=y
|
||||
CONFIG_I8257=y
|
||||
CONFIG_I82374=y
|
||||
CONFIG_OPENPIC=y
|
||||
CONFIG_PREP_PCI=y
|
||||
CONFIG_I82378=y
|
||||
CONFIG_PC87312=y
|
||||
CONFIG_MACIO=y
|
||||
CONFIG_PCSPK=y
|
||||
CONFIG_CUDA=y
|
||||
CONFIG_ADB=y
|
||||
CONFIG_MAC_NVRAM=y
|
||||
CONFIG_MAC_DBDMA=y
|
||||
CONFIG_HEATHROW_PIC=y
|
||||
CONFIG_GRACKLE_PCI=y
|
||||
CONFIG_UNIN_PCI=y
|
||||
CONFIG_DEC_PCI=y
|
||||
CONFIG_PPCE500_PCI=y
|
||||
CONFIG_IDE_ISA=y
|
||||
CONFIG_IDE_CMD646=y
|
||||
CONFIG_IDE_MACIO=y
|
||||
CONFIG_NE2000_ISA=y
|
||||
CONFIG_PFLASH_CFI01=y
|
||||
CONFIG_PFLASH_CFI02=y
|
||||
CONFIG_PTIMER=y
|
||||
CONFIG_I8259=y
|
||||
CONFIG_XILINX=y
|
||||
CONFIG_XILINX_ETHLITE=y
|
||||
CONFIG_PSERIES=y
|
||||
CONFIG_POWERNV=y
|
||||
CONFIG_PREP=y
|
||||
CONFIG_MAC=y
|
||||
CONFIG_E500=y
|
||||
CONFIG_OPENPIC_KVM=$(call land,$(CONFIG_E500),$(CONFIG_KVM))
|
||||
CONFIG_PLATFORM_BUS=y
|
||||
CONFIG_ETSEC=y
|
||||
CONFIG_SM501=y
|
||||
|
||||
# For pSeries
|
||||
CONFIG_PSERIES=y
|
||||
CONFIG_VIRTIO_VGA=y
|
||||
CONFIG_XICS=$(CONFIG_PSERIES)
|
||||
CONFIG_XICS_SPAPR=$(CONFIG_PSERIES)
|
||||
CONFIG_XICS_KVM=$(call land,$(CONFIG_PSERIES),$(CONFIG_KVM))
|
||||
# For PReP
|
||||
CONFIG_SERIAL_ISA=y
|
||||
CONFIG_MC146818RTC=y
|
||||
CONFIG_ISA_TESTDEV=y
|
||||
CONFIG_MEM_HOTPLUG=y
|
||||
CONFIG_RS6000_MC=y
|
||||
|
@ -797,6 +797,7 @@ static uint64_t sm501_system_config_read(void *opaque, hwaddr addr,
|
||||
break;
|
||||
case SM501_COMMAND_LIST_STATUS:
|
||||
ret = 0x00180002; /* FIFOs are empty, everything idle */
|
||||
break;
|
||||
case SM501_IRQ_MASK:
|
||||
ret = s->irq_mask;
|
||||
break;
|
||||
|
@ -79,13 +79,13 @@ static uint64_t sii3112_reg_read(void *opaque, hwaddr addr,
|
||||
val |= (d->regs[0].confstat & (1UL << 11) ? (1 << 4) : 0); /*SATAINT0*/
|
||||
val |= (d->regs[1].confstat & (1UL << 11) ? (1 << 6) : 0); /*SATAINT1*/
|
||||
val |= (d->i.bmdma[1].status & BM_STATUS_INT ? (1 << 14) : 0);
|
||||
val |= d->i.bmdma[0].status << 16;
|
||||
val |= d->i.bmdma[1].status << 24;
|
||||
val |= (uint32_t)d->i.bmdma[0].status << 16;
|
||||
val |= (uint32_t)d->i.bmdma[1].status << 24;
|
||||
break;
|
||||
case 0x18:
|
||||
val = d->i.bmdma[1].cmd;
|
||||
val |= (d->regs[1].confstat & (1UL << 11) ? (1 << 4) : 0);
|
||||
val |= d->i.bmdma[1].status << 16;
|
||||
val |= (uint32_t)d->i.bmdma[1].status << 16;
|
||||
break;
|
||||
case 0x80 ... 0x87:
|
||||
if (size == 1) {
|
||||
@ -128,7 +128,7 @@ static uint64_t sii3112_reg_read(void *opaque, hwaddr addr,
|
||||
val = (d->i.bus[0].ifs[0].blk) ? 0x113 : 0;
|
||||
break;
|
||||
case 0x148:
|
||||
val = d->regs[0].sien << 16;
|
||||
val = (uint32_t)d->regs[0].sien << 16;
|
||||
break;
|
||||
case 0x180:
|
||||
val = d->regs[1].scontrol;
|
||||
@ -137,7 +137,7 @@ static uint64_t sii3112_reg_read(void *opaque, hwaddr addr,
|
||||
val = (d->i.bus[1].ifs[0].blk) ? 0x113 : 0;
|
||||
break;
|
||||
case 0x1c8:
|
||||
val = d->regs[1].sien << 16;
|
||||
val = (uint32_t)d->regs[1].sien << 16;
|
||||
break;
|
||||
default:
|
||||
val = 0;
|
||||
|
@ -12,8 +12,8 @@ obj-y += spapr_pci_vfio.o
|
||||
endif
|
||||
obj-$(CONFIG_PSERIES) += spapr_rtas_ddw.o
|
||||
# PowerPC 4xx boards
|
||||
obj-y += ppc405_boards.o ppc4xx_devs.o ppc405_uc.o ppc440_bamboo.o
|
||||
obj-y += ppc4xx_pci.o
|
||||
obj-y += ppc4xx_devs.o ppc405_uc.o
|
||||
obj-$(CONFIG_PPC4XX) += ppc4xx_pci.o ppc405_boards.o ppc440_bamboo.o
|
||||
# PReP
|
||||
obj-$(CONFIG_PREP) += prep.o
|
||||
obj-$(CONFIG_PREP) += prep_systemio.o
|
||||
|
@ -1484,6 +1484,15 @@ static void spapr_machine_reset(void)
|
||||
spapr_setup_hpt_and_vrma(spapr);
|
||||
}
|
||||
|
||||
/* if this reset wasn't generated by CAS, we should reset our
|
||||
* negotiated options and start from scratch */
|
||||
if (!spapr->cas_reboot) {
|
||||
spapr_ovec_cleanup(spapr->ov5_cas);
|
||||
spapr->ov5_cas = spapr_ovec_new();
|
||||
|
||||
ppc_set_compat(first_ppc_cpu, spapr->max_compat_pvr, &error_fatal);
|
||||
}
|
||||
|
||||
qemu_devices_reset();
|
||||
|
||||
/* DRC reset may cause a device to be unplugged. This will cause troubles
|
||||
@ -1504,15 +1513,6 @@ static void spapr_machine_reset(void)
|
||||
rtas_addr = rtas_limit - RTAS_MAX_SIZE;
|
||||
fdt_addr = rtas_addr - FDT_MAX_SIZE;
|
||||
|
||||
/* if this reset wasn't generated by CAS, we should reset our
|
||||
* negotiated options and start from scratch */
|
||||
if (!spapr->cas_reboot) {
|
||||
spapr_ovec_cleanup(spapr->ov5_cas);
|
||||
spapr->ov5_cas = spapr_ovec_new();
|
||||
|
||||
ppc_set_compat(first_ppc_cpu, spapr->max_compat_pvr, &error_fatal);
|
||||
}
|
||||
|
||||
fdt = spapr_build_fdt(spapr, rtas_addr, spapr->rtas_size);
|
||||
|
||||
spapr_load_rtas(spapr, fdt, rtas_addr);
|
||||
@ -3357,9 +3357,7 @@ static void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
int i;
|
||||
|
||||
for (i = 0; i < cc->nr_threads; i++) {
|
||||
sPAPRCPUCore *sc = SPAPR_CPU_CORE(dev);
|
||||
|
||||
cs = CPU(sc->threads[i]);
|
||||
cs = CPU(core->threads[i]);
|
||||
pre_2_10_vmstate_unregister_dummy_icp(cs->cpu_index);
|
||||
}
|
||||
}
|
||||
|
@ -228,62 +228,32 @@ int spapr_caps_post_migration(sPAPRMachineState *spapr)
|
||||
return ok ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
static bool spapr_cap_htm_needed(void *opaque)
|
||||
{
|
||||
sPAPRMachineState *spapr = opaque;
|
||||
|
||||
return spapr->cmd_line_caps[SPAPR_CAP_HTM] &&
|
||||
(spapr->eff.caps[SPAPR_CAP_HTM] != spapr->def.caps[SPAPR_CAP_HTM]);
|
||||
/* Used to generate the migration field and needed function for a spapr cap */
|
||||
#define SPAPR_CAP_MIG_STATE(cap, ccap) \
|
||||
static bool spapr_cap_##cap##_needed(void *opaque) \
|
||||
{ \
|
||||
sPAPRMachineState *spapr = opaque; \
|
||||
\
|
||||
return spapr->cmd_line_caps[SPAPR_CAP_##ccap] && \
|
||||
(spapr->eff.caps[SPAPR_CAP_##ccap] != \
|
||||
spapr->def.caps[SPAPR_CAP_##ccap]); \
|
||||
} \
|
||||
\
|
||||
const VMStateDescription vmstate_spapr_cap_##cap = { \
|
||||
.name = "spapr/cap/" #cap, \
|
||||
.version_id = 1, \
|
||||
.minimum_version_id = 1, \
|
||||
.needed = spapr_cap_##cap##_needed, \
|
||||
.fields = (VMStateField[]) { \
|
||||
VMSTATE_UINT8(mig.caps[SPAPR_CAP_##ccap], \
|
||||
sPAPRMachineState), \
|
||||
VMSTATE_END_OF_LIST() \
|
||||
}, \
|
||||
}
|
||||
|
||||
const VMStateDescription vmstate_spapr_cap_htm = {
|
||||
.name = "spapr/cap/htm",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.needed = spapr_cap_htm_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT8(mig.caps[SPAPR_CAP_HTM], sPAPRMachineState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
};
|
||||
|
||||
static bool spapr_cap_vsx_needed(void *opaque)
|
||||
{
|
||||
sPAPRMachineState *spapr = opaque;
|
||||
|
||||
return spapr->cmd_line_caps[SPAPR_CAP_VSX] &&
|
||||
(spapr->eff.caps[SPAPR_CAP_VSX] != spapr->def.caps[SPAPR_CAP_VSX]);
|
||||
}
|
||||
|
||||
const VMStateDescription vmstate_spapr_cap_vsx = {
|
||||
.name = "spapr/cap/vsx",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.needed = spapr_cap_vsx_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT8(mig.caps[SPAPR_CAP_VSX], sPAPRMachineState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
};
|
||||
|
||||
static bool spapr_cap_dfp_needed(void *opaque)
|
||||
{
|
||||
sPAPRMachineState *spapr = opaque;
|
||||
|
||||
return spapr->cmd_line_caps[SPAPR_CAP_DFP] &&
|
||||
(spapr->eff.caps[SPAPR_CAP_DFP] != spapr->def.caps[SPAPR_CAP_DFP]);
|
||||
}
|
||||
|
||||
const VMStateDescription vmstate_spapr_cap_dfp = {
|
||||
.name = "spapr/cap/dfp",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.needed = spapr_cap_dfp_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT8(mig.caps[SPAPR_CAP_DFP], sPAPRMachineState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
};
|
||||
SPAPR_CAP_MIG_STATE(htm, HTM);
|
||||
SPAPR_CAP_MIG_STATE(vsx, VSX);
|
||||
SPAPR_CAP_MIG_STATE(dfp, DFP);
|
||||
|
||||
void spapr_caps_reset(sPAPRMachineState *spapr)
|
||||
{
|
||||
|
@ -44,6 +44,13 @@ static void spapr_cpu_reset(void *opaque)
|
||||
if (cs != first_cpu) {
|
||||
env->spr[SPR_LPCR] &= ~pcc->lpcr_pm;
|
||||
}
|
||||
|
||||
/* Set compatibility mode to match the boot CPU, which was either set
|
||||
* by the machine reset code or by CAS. This should never fail.
|
||||
*/
|
||||
if (cs != first_cpu) {
|
||||
ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &error_abort);
|
||||
}
|
||||
}
|
||||
|
||||
static void spapr_cpu_destroy(PowerPCCPU *cpu)
|
||||
|
@ -163,7 +163,6 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPRMachineState *spapr,
|
||||
CPUState *cs = CPU(cpu);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
|
||||
Error *local_err = NULL;
|
||||
|
||||
if (!cs->halted) {
|
||||
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
|
||||
@ -175,14 +174,6 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPRMachineState *spapr,
|
||||
* new cpu enters */
|
||||
kvm_cpu_synchronize_state(cs);
|
||||
|
||||
/* Set compatibility mode to match existing cpus */
|
||||
ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &local_err);
|
||||
if (local_err) {
|
||||
error_report_err(local_err);
|
||||
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME);
|
||||
|
||||
/* Enable Power-saving mode Exit Cause exceptions for the new CPU */
|
||||
|
@ -140,9 +140,6 @@ enum {
|
||||
POWERPC_EXCP_HYPPRIV = 41, /* Embedded hypervisor priv instruction */
|
||||
/* Vectors 42 to 63 are reserved */
|
||||
/* Exceptions defined in the PowerPC server specification */
|
||||
/* Server doorbell variants */
|
||||
#define POWERPC_EXCP_SDOOR POWERPC_EXCP_GDOORI
|
||||
#define POWERPC_EXCP_SDOOR_HV POWERPC_EXCP_DOORI
|
||||
POWERPC_EXCP_RESET = 64, /* System reset exception */
|
||||
POWERPC_EXCP_DSEG = 65, /* Data segment exception */
|
||||
POWERPC_EXCP_ISEG = 66, /* Instruction segment exception */
|
||||
@ -189,8 +186,11 @@ enum {
|
||||
POWERPC_EXCP_HV_EMU = 96, /* HV emulation assistance */
|
||||
POWERPC_EXCP_HV_MAINT = 97, /* HMI */
|
||||
POWERPC_EXCP_HV_FU = 98, /* Hypervisor Facility unavailable */
|
||||
/* Server doorbell variants */
|
||||
POWERPC_EXCP_SDOOR = 99,
|
||||
POWERPC_EXCP_SDOOR_HV = 100,
|
||||
/* EOL */
|
||||
POWERPC_EXCP_NB = 99,
|
||||
POWERPC_EXCP_NB = 101,
|
||||
/* QEMU exceptions: used internally during code translation */
|
||||
POWERPC_EXCP_STOP = 0x200, /* stop translation */
|
||||
POWERPC_EXCP_BRANCH = 0x201, /* branch instruction */
|
||||
@ -930,7 +930,7 @@ enum {
|
||||
#define BOOKE206_MAX_TLBN 4
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Embedded.Processor Control */
|
||||
/* Server and Embedded Processor Control */
|
||||
|
||||
#define DBELL_TYPE_SHIFT 27
|
||||
#define DBELL_TYPE_MASK (0x1f << DBELL_TYPE_SHIFT)
|
||||
@ -940,11 +940,15 @@ enum {
|
||||
#define DBELL_TYPE_G_DBELL_CRIT (0x03 << DBELL_TYPE_SHIFT)
|
||||
#define DBELL_TYPE_G_DBELL_MC (0x04 << DBELL_TYPE_SHIFT)
|
||||
|
||||
#define DBELL_BRDCAST (1 << 26)
|
||||
#define DBELL_TYPE_DBELL_SERVER (0x05 << DBELL_TYPE_SHIFT)
|
||||
|
||||
#define DBELL_BRDCAST PPC_BIT(37)
|
||||
#define DBELL_LPIDTAG_SHIFT 14
|
||||
#define DBELL_LPIDTAG_MASK (0xfff << DBELL_LPIDTAG_SHIFT)
|
||||
#define DBELL_PIRTAG_MASK 0x3fff
|
||||
|
||||
#define DBELL_PROCIDTAG_MASK PPC_BITMASK(44, 63)
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Segment page size information, used by recent hash MMUs
|
||||
* The format of this structure mirrors kvm_ppc_smmu_info
|
||||
|
@ -417,6 +417,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
|
||||
case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */
|
||||
case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */
|
||||
case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment exception */
|
||||
case POWERPC_EXCP_SDOOR_HV: /* Hypervisor Doorbell interrupt */
|
||||
case POWERPC_EXCP_HV_EMU:
|
||||
srr0 = SPR_HSRR0;
|
||||
srr1 = SPR_HSRR1;
|
||||
@ -846,6 +847,11 @@ static void ppc_hw_interrupt(CPUPPCState *env)
|
||||
powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORI);
|
||||
return;
|
||||
}
|
||||
if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDOORBELL)) {
|
||||
env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL);
|
||||
powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_SDOOR_HV);
|
||||
return;
|
||||
}
|
||||
if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) {
|
||||
env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM);
|
||||
powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_PERFM);
|
||||
@ -1145,4 +1151,50 @@ void helper_msgsnd(target_ulong rb)
|
||||
}
|
||||
qemu_mutex_unlock_iothread();
|
||||
}
|
||||
|
||||
/* Server Processor Control */
|
||||
static int book3s_dbell2irq(target_ulong rb)
|
||||
{
|
||||
int msg = rb & DBELL_TYPE_MASK;
|
||||
|
||||
/* A Directed Hypervisor Doorbell message is sent only if the
|
||||
* message type is 5. All other types are reserved and the
|
||||
* instruction is a no-op */
|
||||
return msg == DBELL_TYPE_DBELL_SERVER ? PPC_INTERRUPT_HDOORBELL : -1;
|
||||
}
|
||||
|
||||
void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb)
|
||||
{
|
||||
int irq = book3s_dbell2irq(rb);
|
||||
|
||||
if (irq < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
env->pending_interrupts &= ~(1 << irq);
|
||||
}
|
||||
|
||||
void helper_book3s_msgsnd(target_ulong rb)
|
||||
{
|
||||
int irq = book3s_dbell2irq(rb);
|
||||
int pir = rb & DBELL_PROCIDTAG_MASK;
|
||||
CPUState *cs;
|
||||
|
||||
if (irq < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
qemu_mutex_lock_iothread();
|
||||
CPU_FOREACH(cs) {
|
||||
PowerPCCPU *cpu = POWERPC_CPU(cs);
|
||||
CPUPPCState *cenv = &cpu->env;
|
||||
|
||||
/* TODO: broadcast message to all threads of the same processor */
|
||||
if (cenv->spr_cb[SPR_PIR].default_value == pir) {
|
||||
cenv->pending_interrupts |= 1 << irq;
|
||||
cpu_interrupt(cs, CPU_INTERRUPT_HARD);
|
||||
}
|
||||
}
|
||||
qemu_mutex_unlock_iothread();
|
||||
}
|
||||
#endif
|
||||
|
@ -679,6 +679,8 @@ DEF_HELPER_FLAGS_3(store_sr, TCG_CALL_NO_RWG, void, env, tl, tl)
|
||||
DEF_HELPER_FLAGS_1(602_mfrom, TCG_CALL_NO_RWG_SE, tl, tl)
|
||||
DEF_HELPER_1(msgsnd, void, tl)
|
||||
DEF_HELPER_2(msgclr, void, env, tl)
|
||||
DEF_HELPER_1(book3s_msgsnd, void, tl)
|
||||
DEF_HELPER_2(book3s_msgclr, void, env, tl)
|
||||
#endif
|
||||
|
||||
DEF_HELPER_4(dlmzb, tl, env, tl, tl, i32)
|
||||
|
@ -605,27 +605,22 @@ static opc_handler_t invalid_handler = {
|
||||
static inline void gen_op_cmp(TCGv arg0, TCGv arg1, int s, int crf)
|
||||
{
|
||||
TCGv t0 = tcg_temp_new();
|
||||
TCGv_i32 t1 = tcg_temp_new_i32();
|
||||
TCGv t1 = tcg_temp_new();
|
||||
TCGv_i32 t = tcg_temp_new_i32();
|
||||
|
||||
tcg_gen_movi_tl(t0, CRF_EQ);
|
||||
tcg_gen_movi_tl(t1, CRF_LT);
|
||||
tcg_gen_movcond_tl((s ? TCG_COND_LT : TCG_COND_LTU), t0, arg0, arg1, t1, t0);
|
||||
tcg_gen_movi_tl(t1, CRF_GT);
|
||||
tcg_gen_movcond_tl((s ? TCG_COND_GT : TCG_COND_GTU), t0, arg0, arg1, t1, t0);
|
||||
|
||||
tcg_gen_trunc_tl_i32(t, t0);
|
||||
tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_so);
|
||||
|
||||
tcg_gen_setcond_tl((s ? TCG_COND_LT: TCG_COND_LTU), t0, arg0, arg1);
|
||||
tcg_gen_trunc_tl_i32(t1, t0);
|
||||
tcg_gen_shli_i32(t1, t1, CRF_LT_BIT);
|
||||
tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
|
||||
|
||||
tcg_gen_setcond_tl((s ? TCG_COND_GT: TCG_COND_GTU), t0, arg0, arg1);
|
||||
tcg_gen_trunc_tl_i32(t1, t0);
|
||||
tcg_gen_shli_i32(t1, t1, CRF_GT_BIT);
|
||||
tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
|
||||
|
||||
tcg_gen_setcond_tl(TCG_COND_EQ, t0, arg0, arg1);
|
||||
tcg_gen_trunc_tl_i32(t1, t0);
|
||||
tcg_gen_shli_i32(t1, t1, CRF_EQ_BIT);
|
||||
tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
|
||||
tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t);
|
||||
|
||||
tcg_temp_free(t0);
|
||||
tcg_temp_free_i32(t1);
|
||||
tcg_temp_free(t1);
|
||||
tcg_temp_free_i32(t);
|
||||
}
|
||||
|
||||
static inline void gen_op_cmpi(TCGv arg0, target_ulong arg1, int s, int crf)
|
||||
@ -6174,8 +6169,13 @@ static void gen_msgclr(DisasContext *ctx)
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
GEN_PRIV;
|
||||
#else
|
||||
CHK_SV;
|
||||
gen_helper_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]);
|
||||
CHK_HV;
|
||||
/* 64-bit server processors compliant with arch 2.x */
|
||||
if (ctx->insns_flags & PPC_SEGMENT_64B) {
|
||||
gen_helper_book3s_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]);
|
||||
} else {
|
||||
gen_helper_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]);
|
||||
}
|
||||
#endif /* defined(CONFIG_USER_ONLY) */
|
||||
}
|
||||
|
||||
@ -6184,11 +6184,25 @@ static void gen_msgsnd(DisasContext *ctx)
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
GEN_PRIV;
|
||||
#else
|
||||
CHK_SV;
|
||||
gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]);
|
||||
CHK_HV;
|
||||
/* 64-bit server processors compliant with arch 2.x */
|
||||
if (ctx->insns_flags & PPC_SEGMENT_64B) {
|
||||
gen_helper_book3s_msgsnd(cpu_gpr[rB(ctx->opcode)]);
|
||||
} else {
|
||||
gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]);
|
||||
}
|
||||
#endif /* defined(CONFIG_USER_ONLY) */
|
||||
}
|
||||
|
||||
static void gen_msgsync(DisasContext *ctx)
|
||||
{
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
GEN_PRIV;
|
||||
#else
|
||||
CHK_HV;
|
||||
#endif /* defined(CONFIG_USER_ONLY) */
|
||||
/* interpreted as no-op */
|
||||
}
|
||||
|
||||
#if defined(TARGET_PPC64)
|
||||
static void gen_maddld(DisasContext *ctx)
|
||||
@ -6669,6 +6683,8 @@ GEN_HANDLER2_E(msgsnd, "msgsnd", 0x1F, 0x0E, 0x06, 0x03ff0001,
|
||||
PPC_NONE, PPC2_PRCNTL),
|
||||
GEN_HANDLER2_E(msgclr, "msgclr", 0x1F, 0x0E, 0x07, 0x03ff0001,
|
||||
PPC_NONE, PPC2_PRCNTL),
|
||||
GEN_HANDLER2_E(msgsync, "msgsync", 0x1F, 0x16, 0x1B, 0x00000000,
|
||||
PPC_NONE, PPC2_PRCNTL),
|
||||
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE),
|
||||
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE),
|
||||
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC),
|
||||
|
@ -8866,7 +8866,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
|
||||
PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
|
||||
PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
|
||||
PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
|
||||
PPC2_TM | PPC2_PM_ISA206 | PPC2_ISA300;
|
||||
PPC2_TM | PPC2_PM_ISA206 | PPC2_ISA300 | PPC2_PRCNTL;
|
||||
pcc->msr_mask = (1ull << MSR_SF) |
|
||||
(1ull << MSR_TM) |
|
||||
(1ull << MSR_VR) |
|
||||
|
Loading…
Reference in New Issue
Block a user