aboutsummaryrefslogtreecommitdiff
path: root/target/ppc/arch_dump.c
diff options
context:
space:
mode:
authorGreg Kurz <groug@kaod.org>2021-06-22 16:09:25 +0200
committerDavid Gibson <david@gibson.dropbear.id.au>2021-07-09 10:38:18 +1000
commitc11dc15d3aabb9dab04d9d2767e1b227d2b9085d (patch)
treea6c6040013c01fa9d784ad82977ec6a19c606253 /target/ppc/arch_dump.c
parent9db3065c62a983286d06c207f4981408cf42184d (diff)
target/ppc: Introduce ppc_interrupts_little_endian()
PowerPC CPUs use big endian by default but starting with POWER7, server grade CPUs use the ILE bit of the LPCR special purpose register to decide on the endianness to use when handling interrupts. This gives a clue to QEMU on the endianness the guest kernel is running, which is needed when generating an ELF dump of the guest or when delivering an FWNMI machine check interrupt. Commit 382d2db62bcb ("target-ppc: Introduce callback for interrupt endianness") added a class method to PowerPCCPUClass to modelize this : default implementation returns a fixed "big endian" value, while POWER7 and newer do the LPCR_ILE check. This is suboptimal as it forces to implement the method for every new CPU family, and it is very unlikely that this will ever be different than what we have today. We basically only have three cases to consider: a) CPU doesn't have an LPCR => big endian b) CPU has an LPCR but doesn't support the ILE bit => big endian c) CPU has an LPCR and supports the ILE bit => little or big endian Instead of class methods, introduce an inline helper that checks the ILE bit in the LPCR_MASK to decide on the outcome. The new helper words little endian instead of big endian. This allows to drop a ! operator in ppc_cpu_do_fwnmi_machine_check(). Signed-off-by: Greg Kurz <groug@kaod.org> Message-Id: <20210622140926.677618-2-groug@kaod.org> Reviewed-by: Fabiano Rosas <farosas@linux.ibm.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'target/ppc/arch_dump.c')
-rw-r--r--target/ppc/arch_dump.c8
1 files changed, 3 insertions, 5 deletions
diff --git a/target/ppc/arch_dump.c b/target/ppc/arch_dump.c
index 9210e61ef4..bb392f6d88 100644
--- a/target/ppc/arch_dump.c
+++ b/target/ppc/arch_dump.c
@@ -227,22 +227,20 @@ int cpu_get_dump_info(ArchDumpInfo *info,
const struct GuestPhysBlockList *guest_phys_blocks)
{
PowerPCCPU *cpu;
- PowerPCCPUClass *pcc;
if (first_cpu == NULL) {
return -1;
}
cpu = POWERPC_CPU(first_cpu);
- pcc = POWERPC_CPU_GET_CLASS(cpu);
info->d_machine = PPC_ELF_MACHINE;
info->d_class = ELFCLASS;
- if ((*pcc->interrupts_big_endian)(cpu)) {
- info->d_endian = ELFDATA2MSB;
- } else {
+ if (ppc_interrupts_little_endian(cpu)) {
info->d_endian = ELFDATA2LSB;
+ } else {
+ info->d_endian = ELFDATA2MSB;
}
/* 64KB is the max page size for pseries kernel */
if (strncmp(object_get_typename(qdev_get_machine()),