mirror of
https://github.com/qemu/qemu.git
synced 2026-07-08 17:46:17 +00:00
Merge tag 'pull-ppc-for-11.1-sf-20260706' of https://gitlab.com/harshpb/qemu into staging
PPC PR for 11.1 Soft-freeze # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEEa4EM1tK+EPOIPSFCRUTplPnWj7sFAmpLZTwACgkQRUTplPnW # j7vb/w//XmleEwlL+p+YKndc4Su+qj9c3lApEFEiFi78biATrXpFTNbOxhOpWdv4 # jaI1kWyINrTPgnXgHEKNJuhhsSjy5/HURCgkivPnnvhK95mWMi/0f1SzICmc9DCo # hjDeQfHw5zhF6hu6QknTfcworpsdA9uVtbx0+8s0lMMDmWze2WLg6f9OXioxhseN # vJoRaJoEo1f/vwwDFOdGngz36p0xD+eUynPTRlOymMJfW271KtNlZqouCCryI92I # ksaYa+jorE16l608SyG1Yhf/oDSlj9BufFHmgAngvlDwPFglhoJx0kPeKIrT7QE0 # oGzwnOwXJH0lGuwQwISvgrtquD8unY9gTZvrF6NPIPtpMJSE+TGluoNdf/Sr2c3l # xMG/+yIwHehgXa/Lh4UN3G7yALaIjVdkcSdexuo1pfFemUCwLYPDMGoaksda+SZd # m4Xd05ZCvp2RZHRNbWheu6TxZKEHKWO8UV8U0zNgKZTz7muVURrtLpoQJFLRq9V7 # krqyeLOePZtGC15a8unAbIVJVK2vOOnoqQPbuqZ57GTVqcmmcTSIEkRDcbMTADKo # Qv8WEqOWo9OYQvGF/BMP+ed1UiNzGXY2WnVrF40D3K/I/wT11mHbuKZY3gbFZ5At # 1y2I59EvV/xYHdjBmDoT8smzuQwywSKZnzeKptbIVGFbuPPVFFs= # =icWo # -----END PGP SIGNATURE----- # gpg: Signature made Mon 06 Jul 2026 10:20:12 CEST # gpg: using RSA key 6B810CD6D2BE10F3883D21424544E994F9D68FBB # gpg: Good signature from "Harsh Prateek Bora <harsh.prateek.bora@gmail.com>" [full] # gpg: aka "Harsh Prateek Bora <harshpb@linux.ibm.com>" [full] # Primary key fingerprint: 6B81 0CD6 D2BE 10F3 883D 2142 4544 E994 F9D6 8FBB * tag 'pull-ppc-for-11.1-sf-20260706' of https://gitlab.com/harshpb/qemu: MAINTAINERS: Add self as maintainer for PowerNV ppc/pnv: Remove Power8E and Power8NVL CPUs ppc/pnv: Remove Power8E and Power8NVL pnv chips ppc/pnv: Replace Power8E with Power11 for 'none' machine test tests/functional: Use default powernv machine instead of power10 tests/qtest: Add Power11 chip & machine to qtests tests/qtest/pnv_spi: Test Power11 PNV_SPI tests/functional: Add remote interrupts test for PowerNV Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
@@ -1663,7 +1663,7 @@ F: tests/functional/ppc64/test_tuxrun.py
|
||||
|
||||
PowerNV (Non-Virtualized)
|
||||
M: Nicholas Piggin <npiggin@gmail.com>
|
||||
R: Aditya Gupta <adityag@linux.ibm.com>
|
||||
M: Aditya Gupta <adityag@linux.ibm.com>
|
||||
R: Glenn Miles <milesg@linux.ibm.com>
|
||||
R: Harsh Prateek Bora <harshpb@linux.ibm.com>
|
||||
L: qemu-ppc@nongnu.org
|
||||
|
||||
@@ -206,15 +206,6 @@ in the QEMU object model anymore. ``Sun-UltraSparc-IIIi+`` and
|
||||
but for consistency these will get removed in a future release, too.
|
||||
Use ``Sun-UltraSparc-IIIi-plus`` and ``Sun-UltraSparc-IV-plus`` instead.
|
||||
|
||||
Power8E and Power8NVL CPUs and corresponding Pnv chips (since 10.1)
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
The Power8E and Power8NVL variants of Power8 are not really useful anymore
|
||||
in qemu, and are old and unmaintained now.
|
||||
|
||||
The CPUs as well as corresponding Power8NVL and Power8E PnvChips will also
|
||||
be considered deprecated.
|
||||
|
||||
System emulator machines
|
||||
------------------------
|
||||
|
||||
|
||||
@@ -1038,6 +1038,14 @@ initial RISC-V QEMU port. Its usage was always been unclear: users don't know
|
||||
what to expect from a CPU called 'any', and in fact the CPU does not do anything
|
||||
special that isn't already done by the default CPUs rv32/rv64.
|
||||
|
||||
Power8E and Power8NVL CPUs (removed in 11.1)
|
||||
''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
The Power8E and Power8NVL variants of Power8 are not really useful anymore
|
||||
in qemu, and are old and unmaintained.
|
||||
Hence, the CPUs as well as corresponding Power8NVL and Power8E PnvChips have
|
||||
been removed
|
||||
|
||||
System accelerators
|
||||
-------------------
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ beyond the scope of what QEMU addresses today.
|
||||
Supported devices
|
||||
-----------------
|
||||
|
||||
* Multi processor support for POWER8, POWER8NVL, POWER9, Power10 and Power11.
|
||||
* Multi processor support for POWER8, POWER9, Power10 and Power11.
|
||||
* XSCOM, serial communication sideband bus to configure chiplets.
|
||||
* Simple LPC Controller.
|
||||
* Processor Service Interface (PSI) Controller.
|
||||
|
||||
@@ -16,7 +16,7 @@ Supported devices
|
||||
|
||||
* Multi processor support for many Power processors generations:
|
||||
- POWER7, POWER7+
|
||||
- POWER8, POWER8NVL
|
||||
- POWER8
|
||||
- POWER9
|
||||
- Power10
|
||||
- Power11
|
||||
|
||||
62
hw/ppc/pnv.c
62
hw/ppc/pnv.c
@@ -869,16 +869,6 @@ static ISABus *pnv_chip_power8_isa_create(PnvChip *chip, Error **errp)
|
||||
return pnv_lpc_isa_create(&chip8->lpc, true, errp);
|
||||
}
|
||||
|
||||
static ISABus *pnv_chip_power8nvl_isa_create(PnvChip *chip, Error **errp)
|
||||
{
|
||||
Pnv8Chip *chip8 = PNV8_CHIP(chip);
|
||||
qemu_irq irq = qdev_get_gpio_in(DEVICE(&chip8->psi), PSIHB_IRQ_LPC_I2C);
|
||||
|
||||
qdev_connect_gpio_out_named(DEVICE(&chip8->lpc), "LPCHC", 0, irq);
|
||||
|
||||
return pnv_lpc_isa_create(&chip8->lpc, false, errp);
|
||||
}
|
||||
|
||||
static ISABus *pnv_chip_power9_isa_create(PnvChip *chip, Error **errp)
|
||||
{
|
||||
Pnv9Chip *chip9 = PNV9_CHIP(chip);
|
||||
@@ -1646,7 +1636,6 @@ static void *pnv_chip_power11_intc_get(PnvChip *chip)
|
||||
* EX14
|
||||
* <EX15 reserved>
|
||||
*/
|
||||
#define POWER8E_CORE_MASK (0x7070ull)
|
||||
#define POWER8_CORE_MASK (0x7e7eull)
|
||||
|
||||
/*
|
||||
@@ -1827,30 +1816,6 @@ static uint32_t pnv_chip_power8_xscom_pcba(PnvChip *chip, uint64_t addr)
|
||||
return ((addr >> 4) & ~0xfull) | ((addr >> 3) & 0xf);
|
||||
}
|
||||
|
||||
static void pnv_chip_power8e_class_init(ObjectClass *klass, const void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PnvChipClass *k = PNV_CHIP_CLASS(klass);
|
||||
|
||||
k->chip_cfam_id = 0x221ef04980000000ull; /* P8 Murano DD2.1 */
|
||||
k->cores_mask = POWER8E_CORE_MASK;
|
||||
k->num_phbs = 3;
|
||||
k->get_pir_tir = pnv_get_pir_tir_p8;
|
||||
k->intc_create = pnv_chip_power8_intc_create;
|
||||
k->intc_reset = pnv_chip_power8_intc_reset;
|
||||
k->intc_destroy = pnv_chip_power8_intc_destroy;
|
||||
k->intc_print_info = pnv_chip_power8_intc_print_info;
|
||||
k->isa_create = pnv_chip_power8_isa_create;
|
||||
k->dt_populate = pnv_chip_power8_dt_populate;
|
||||
k->pic_print_info = pnv_chip_power8_pic_print_info;
|
||||
k->xscom_core_base = pnv_chip_power8_xscom_core_base;
|
||||
k->xscom_pcba = pnv_chip_power8_xscom_pcba;
|
||||
dc->desc = "PowerNV Chip POWER8E";
|
||||
|
||||
device_class_set_parent_realize(dc, pnv_chip_power8_realize,
|
||||
&k->parent_realize);
|
||||
}
|
||||
|
||||
static void pnv_chip_power8_class_init(ObjectClass *klass, const void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
@@ -1875,30 +1840,6 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, const void *data)
|
||||
&k->parent_realize);
|
||||
}
|
||||
|
||||
static void pnv_chip_power8nvl_class_init(ObjectClass *klass, const void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PnvChipClass *k = PNV_CHIP_CLASS(klass);
|
||||
|
||||
k->chip_cfam_id = 0x120d304980000000ull; /* P8 Naples DD1.0 */
|
||||
k->cores_mask = POWER8_CORE_MASK;
|
||||
k->num_phbs = 4;
|
||||
k->get_pir_tir = pnv_get_pir_tir_p8;
|
||||
k->intc_create = pnv_chip_power8_intc_create;
|
||||
k->intc_reset = pnv_chip_power8_intc_reset;
|
||||
k->intc_destroy = pnv_chip_power8_intc_destroy;
|
||||
k->intc_print_info = pnv_chip_power8_intc_print_info;
|
||||
k->isa_create = pnv_chip_power8nvl_isa_create;
|
||||
k->dt_populate = pnv_chip_power8_dt_populate;
|
||||
k->pic_print_info = pnv_chip_power8_pic_print_info;
|
||||
k->xscom_core_base = pnv_chip_power8_xscom_core_base;
|
||||
k->xscom_pcba = pnv_chip_power8_xscom_pcba;
|
||||
dc->desc = "PowerNV Chip POWER8NVL";
|
||||
|
||||
device_class_set_parent_realize(dc, pnv_chip_power8_realize,
|
||||
&k->parent_realize);
|
||||
}
|
||||
|
||||
static void pnv_chip_power9_instance_init(Object *obj)
|
||||
{
|
||||
PnvChip *chip = PNV_CHIP(obj);
|
||||
@@ -3785,9 +3726,6 @@ static const TypeInfo types[] = {
|
||||
.instance_size = sizeof(Pnv8Chip),
|
||||
},
|
||||
DEFINE_PNV8_CHIP_TYPE(TYPE_PNV_CHIP_POWER8, pnv_chip_power8_class_init),
|
||||
DEFINE_PNV8_CHIP_TYPE(TYPE_PNV_CHIP_POWER8E, pnv_chip_power8e_class_init),
|
||||
DEFINE_PNV8_CHIP_TYPE(TYPE_PNV_CHIP_POWER8NVL,
|
||||
pnv_chip_power8nvl_class_init),
|
||||
};
|
||||
|
||||
DEFINE_TYPES(types)
|
||||
|
||||
@@ -515,9 +515,7 @@ static const TypeInfo pnv_core_infos[] = {
|
||||
.class_init = pnv_core_class_init,
|
||||
.abstract = true,
|
||||
},
|
||||
DEFINE_PNV_CORE_TYPE(power8, "power8e_v2.1"),
|
||||
DEFINE_PNV_CORE_TYPE(power8, "power8_v2.0"),
|
||||
DEFINE_PNV_CORE_TYPE(power8, "power8nvl_v1.0"),
|
||||
DEFINE_PNV_CORE_TYPE(power9, "power9_v2.2"),
|
||||
DEFINE_PNV_CORE_TYPE(power10, "power10_v2.0"),
|
||||
DEFINE_PNV_CORE_TYPE(power11, "power11_v2.0"),
|
||||
|
||||
@@ -408,8 +408,6 @@ static const TypeInfo spapr_cpu_core_type_infos[] = {
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("power7_v2.3"),
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("power7p_v2.1"),
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("power8_v2.0"),
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("power8e_v2.1"),
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("power8nvl_v1.0"),
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("power9_v2.0"),
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("power9_v2.2"),
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("power10_v2.0"),
|
||||
|
||||
@@ -39,18 +39,10 @@ typedef struct Pnv10Chip Pnv11Chip;
|
||||
#define PNV_CHIP_TYPE_SUFFIX "-" TYPE_PNV_CHIP
|
||||
#define PNV_CHIP_TYPE_NAME(cpu_model) cpu_model PNV_CHIP_TYPE_SUFFIX
|
||||
|
||||
#define TYPE_PNV_CHIP_POWER8E PNV_CHIP_TYPE_NAME("power8e_v2.1")
|
||||
DECLARE_INSTANCE_CHECKER(PnvChip, PNV_CHIP_POWER8E,
|
||||
TYPE_PNV_CHIP_POWER8E)
|
||||
|
||||
#define TYPE_PNV_CHIP_POWER8 PNV_CHIP_TYPE_NAME("power8_v2.0")
|
||||
DECLARE_INSTANCE_CHECKER(PnvChip, PNV_CHIP_POWER8,
|
||||
TYPE_PNV_CHIP_POWER8)
|
||||
|
||||
#define TYPE_PNV_CHIP_POWER8NVL PNV_CHIP_TYPE_NAME("power8nvl_v1.0")
|
||||
DECLARE_INSTANCE_CHECKER(PnvChip, PNV_CHIP_POWER8NVL,
|
||||
TYPE_PNV_CHIP_POWER8NVL)
|
||||
|
||||
#define TYPE_PNV_CHIP_POWER9 PNV_CHIP_TYPE_NAME("power9_v2.2")
|
||||
DECLARE_INSTANCE_CHECKER(PnvChip, PNV_CHIP_POWER9,
|
||||
TYPE_PNV_CHIP_POWER9)
|
||||
|
||||
@@ -734,12 +734,8 @@
|
||||
"POWER7 v2.3")
|
||||
POWERPC_DEF("power7p_v2.1", CPU_POWERPC_POWER7P_v21, POWER7,
|
||||
"POWER7+ v2.1")
|
||||
POWERPC_DEPRECATED_CPU("power8e_v2.1", CPU_POWERPC_POWER8E_v21, POWER8,
|
||||
"POWER8E v2.1", "CPU is unmaintained.")
|
||||
POWERPC_DEF("power8_v2.0", CPU_POWERPC_POWER8_v20, POWER8,
|
||||
"POWER8 v2.0")
|
||||
POWERPC_DEPRECATED_CPU("power8nvl_v1.0", CPU_POWERPC_POWER8NVL_v10, POWER8,
|
||||
"POWER8NVL v1.0", "CPU is unmaintained.")
|
||||
POWERPC_DEF("power9_v2.0", CPU_POWERPC_POWER9_DD20, POWER9,
|
||||
"POWER9 v2.0")
|
||||
POWERPC_DEF("power9_v2.2", CPU_POWERPC_POWER9_DD22, POWER9,
|
||||
@@ -918,9 +914,7 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
|
||||
{ "power7", "power7_v2.3" },
|
||||
{ "power7+", "power7p_v2.1" },
|
||||
{ "power7+_v2.1", "power7p_v2.1" },
|
||||
{ "power8e", "power8e_v2.1" },
|
||||
{ "power8", "power8_v2.0" },
|
||||
{ "power8nvl", "power8nvl_v1.0" },
|
||||
{ "power9", "power9_v2.2" },
|
||||
{ "power10", "power10_v2.0" },
|
||||
{ "power11", "power11_v2.0" },
|
||||
|
||||
@@ -341,12 +341,8 @@ enum {
|
||||
CPU_POWERPC_POWER7_v23 = 0x003F0203,
|
||||
CPU_POWERPC_POWER7P_BASE = 0x004A0000,
|
||||
CPU_POWERPC_POWER7P_v21 = 0x004A0201,
|
||||
CPU_POWERPC_POWER8E_BASE = 0x004B0000,
|
||||
CPU_POWERPC_POWER8E_v21 = 0x004B0201,
|
||||
CPU_POWERPC_POWER8_BASE = 0x004D0000,
|
||||
CPU_POWERPC_POWER8_v20 = 0x004D0200,
|
||||
CPU_POWERPC_POWER8NVL_BASE = 0x004C0000,
|
||||
CPU_POWERPC_POWER8NVL_v10 = 0x004C0100,
|
||||
CPU_POWERPC_POWER9_BASE = 0x004E0000,
|
||||
CPU_POWERPC_POWER9_DD1 = 0x004E1100,
|
||||
CPU_POWERPC_POWER9_DD20 = 0x004E1200,
|
||||
|
||||
@@ -6311,12 +6311,6 @@ static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr, bool best)
|
||||
if (base == CPU_POWERPC_POWER8_BASE) {
|
||||
return true;
|
||||
}
|
||||
if (base == CPU_POWERPC_POWER8E_BASE) {
|
||||
return true;
|
||||
}
|
||||
if (base == CPU_POWERPC_POWER8NVL_BASE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (base != pcc_base) {
|
||||
return false;
|
||||
|
||||
@@ -2437,9 +2437,7 @@ static bool kvmppc_power8_host(void)
|
||||
#ifdef TARGET_PPC64
|
||||
{
|
||||
uint32_t base_pvr = CPU_POWERPC_POWER_SERVER_MASK & mfpvr();
|
||||
ret = (base_pvr == CPU_POWERPC_POWER8E_BASE) ||
|
||||
(base_pvr == CPU_POWERPC_POWER8NVL_BASE) ||
|
||||
(base_pvr == CPU_POWERPC_POWER8_BASE);
|
||||
ret = (base_pvr == CPU_POWERPC_POWER8_BASE);
|
||||
}
|
||||
#endif /* TARGET_PPC64 */
|
||||
return ret;
|
||||
|
||||
@@ -53,7 +53,7 @@ class QEMUFadump(LinuxKernelTest):
|
||||
self.require_accelerator("tcg")
|
||||
|
||||
if is_powernv:
|
||||
self.set_machine("powernv10")
|
||||
self.set_machine("powernv")
|
||||
else:
|
||||
# SLOF takes upto >20s in startup time, use VOF
|
||||
self.set_machine("pseries")
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
from qemu_test import LinuxKernelTest, Asset
|
||||
from qemu_test import wait_for_console_pattern
|
||||
from qemu_test import exec_command_and_wait_for_pattern
|
||||
|
||||
class PowernvMachine(LinuxKernelTest):
|
||||
|
||||
@@ -32,6 +33,17 @@ class PowernvMachine(LinuxKernelTest):
|
||||
('https://github.com/roz3x/qemu/raw/refs/heads/sample-dtb/qemu-powernv11.dtb'),
|
||||
'ea1271516264eea1eb58a067a99d0c2ca9528be8dc7d4e46bb2d5ae0d42fc568')
|
||||
|
||||
def shell_exec_command_check_fail(self, command):
|
||||
fail_msg="Fail"
|
||||
self.shell_exec_command(f"export __FAIL_MSG={fail_msg}")
|
||||
|
||||
# If the exit code for the command is non 0, print fail message
|
||||
command = command + " || echo $__FAIL_MSG"
|
||||
exec_command_and_wait_for_pattern(self, command, '#', fail_msg)
|
||||
|
||||
def shell_exec_command(self, command):
|
||||
exec_command_and_wait_for_pattern(self, command, '#', self.panic_message)
|
||||
|
||||
def do_test_linux_boot(self, command_line = KERNEL_COMMON_COMMAND_LINE):
|
||||
self.require_accelerator("tcg")
|
||||
kernel_path = self.ASSET_KERNEL.fetch()
|
||||
@@ -76,6 +88,89 @@ class PowernvMachine(LinuxKernelTest):
|
||||
wait_for_console_pattern(self, console_pattern, self.panic_message)
|
||||
wait_for_console_pattern(self, self.good_message, self.panic_message)
|
||||
|
||||
def test_linux_remote_interrupts(self):
|
||||
self.require_accelerator("tcg")
|
||||
self.set_machine('powernv')
|
||||
|
||||
# Have below setup in this test:
|
||||
# 1. e1000e attached to pcie.6, which is from 7th PHB, belonging to 2nd
|
||||
# socket (chip 1), in a powernv boot with default 6 PHBs per socket
|
||||
# 2. CPU on 2nd socket (chip 1) disabled
|
||||
# 3. RX IRQ's affinity to chip 2, and TX IRQ's affinity to chip 3
|
||||
#
|
||||
# Then ping is done, to generate interrupts from e1000e which should go
|
||||
# to IRQ server on the remote sockets
|
||||
self.vm.add_args('-smp', '4,sockets=4,cores=1,threads=1')
|
||||
self.vm.add_args('-netdev', 'user,id=net0')
|
||||
self.vm.add_args('-device', 'e1000e,netdev=net0,bus=pcie.6')
|
||||
|
||||
kernel_path = self.ASSET_KERNEL.fetch()
|
||||
rootfs_path = self.ASSET_INITRD.fetch()
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-kernel', kernel_path,
|
||||
'-drive',
|
||||
f'file={rootfs_path},format=raw,if=none,id=drive0,readonly=on',
|
||||
'-append', 'root=/dev/nvme0n1 console=hvc0',
|
||||
'-device', 'nvme,drive=drive0,bus=pcie.2,addr=0x0,serial=1234')
|
||||
self.vm.launch()
|
||||
|
||||
# Wait for boot to complete
|
||||
console_pattern = 'CPU maps initialized for 1 thread per core'
|
||||
wait_for_console_pattern(self, console_pattern, self.panic_message)
|
||||
console_pattern = 'smp: Brought up 4 nodes, 4 CPUs'
|
||||
wait_for_console_pattern(self, console_pattern, self.panic_message)
|
||||
wait_for_console_pattern(self, 'Run /sbin/init as init process',
|
||||
self.panic_message)
|
||||
|
||||
# Wait for login prompt and login as root (no password in buildroot)
|
||||
wait_for_console_pattern(self, 'login:', self.panic_message)
|
||||
exec_command_and_wait_for_pattern(self, 'root', '#', self.panic_message)
|
||||
|
||||
# e1000e is connected to socket 1, disable the CPU on socket 1
|
||||
self.shell_exec_command("echo 0 > /sys/devices/system/cpu/cpu1/online")
|
||||
self.shell_exec_command(
|
||||
"export CPU1_STATE=$(cat /sys/devices/system/cpu/cpu1/online)")
|
||||
self.shell_exec_command_check_fail("[ $CPU1_STATE -eq 0 ]")
|
||||
|
||||
# RX, TX interrupts to chip/cpu 2 & 3 respectively
|
||||
self.shell_exec_command(
|
||||
"export RX_IRQ=$(awk '/eth0-rx/ {print $1}' /proc/interrupts | tr -d ':')")
|
||||
self.shell_exec_command(
|
||||
"export TX_IRQ=$(awk '/eth0-tx/ {print $1}' /proc/interrupts | tr -d ':')")
|
||||
self.shell_exec_command("echo 2 > /proc/irq/$RX_IRQ/smp_affinity_list")
|
||||
self.shell_exec_command("echo 3 > /proc/irq/$TX_IRQ/smp_affinity_list")
|
||||
|
||||
# Capture interrupt counts before generating traffic
|
||||
self.shell_exec_command(
|
||||
"export RX_BEFORE=$(awk '/eth0-rx/ {print $3}' /proc/interrupts)")
|
||||
self.shell_exec_command(
|
||||
"export TX_BEFORE=$(awk '/eth0-tx/ {print $4}' /proc/interrupts)")
|
||||
|
||||
# Wait up to 15 seconds for eth0 link to come up
|
||||
self.shell_exec_command(
|
||||
"c=0; while ! ip addr show eth0 | grep 'inet 10.0.2'; do "
|
||||
"sleep 1; c=$((c+1)); [ $c -gt 15 ] && break; done")
|
||||
|
||||
self.shell_exec_command_check_fail(
|
||||
"ip addr show eth0 | grep 'inet 10.0.2'")
|
||||
|
||||
# Generate network traffic to trigger remote interrupts
|
||||
# Ping QEMU's user-mode network gateway (10.0.2.2)
|
||||
self.shell_exec_command("ping -W2 -c5 10.0.2.2")
|
||||
|
||||
# Show final interrupt counts to verify remote interrupts occurred
|
||||
self.shell_exec_command("cat /proc/interrupts | grep eth0")
|
||||
|
||||
# Verify interrupt counts increased (whether interrupts were delivered)
|
||||
self.shell_exec_command(
|
||||
"export RX_AFTER=$(awk '/eth0-rx/ {print $3}' /proc/interrupts)")
|
||||
self.shell_exec_command(
|
||||
"export TX_AFTER=$(awk '/eth0-tx/ {print $4}' /proc/interrupts)")
|
||||
|
||||
# Check that interrupt counts increased
|
||||
self.shell_exec_command_check_fail("[ $RX_AFTER -gt $RX_BEFORE ]")
|
||||
self.shell_exec_command_check_fail("[ $TX_AFTER -gt $TX_BEFORE ]")
|
||||
|
||||
def test_linux_big_boot(self):
|
||||
self.set_machine('powernv')
|
||||
self.vm.add_args('-smp', '16,threads=4,cores=2,sockets=2')
|
||||
|
||||
@@ -38,7 +38,7 @@ static struct arch2cpu cpus_map[] = {
|
||||
{ "mips64el", "I6500" },
|
||||
{ "or1k", "or1200" },
|
||||
{ "ppc", "604" },
|
||||
{ "ppc64", "power8e_v2.1" },
|
||||
{ "ppc64", "power11_v2.0" },
|
||||
{ "s390x", "qemu" },
|
||||
{ "sh4", "sh7750r" },
|
||||
{ "sh4eb", "sh7751r" },
|
||||
|
||||
@@ -402,15 +402,14 @@ static void reset_all(QTestState *qts, const PnvChip *chip)
|
||||
static void test_host_i2c(const void *data)
|
||||
{
|
||||
const PnvChip *chip = data;
|
||||
const char *machine = pnv_get_machine_type(chip->chip_type);
|
||||
QTestState *qts;
|
||||
const char *machine = "powernv8";
|
||||
PnvI2cCtlr ctlr;
|
||||
PnvI2cDev pca9552;
|
||||
PnvI2cDev pca9554;
|
||||
|
||||
if (chip->chip_type == PNV_CHIP_POWER9) {
|
||||
machine = "powernv9";
|
||||
} else if (chip->chip_type == PNV_CHIP_POWER10) {
|
||||
/* i2c is initialised for rainier in case of P10 */
|
||||
if (chip->chip_type == PNV_CHIP_POWER10) {
|
||||
machine = "powernv10-rainier";
|
||||
}
|
||||
|
||||
@@ -473,10 +472,9 @@ static void add_test(const char *name, void (*test)(const void *data))
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(pnv_chips); i++) {
|
||||
char *tname = g_strdup_printf("pnv-xscom/%s/%s", name,
|
||||
g_autofree char *tname = g_strdup_printf("pnv-xscom/%s/%s", name,
|
||||
pnv_chips[i].cpu_model);
|
||||
qtest_add_data_func(tname, &pnv_chips[i], test);
|
||||
g_free(tname);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ static void test_spi_seeprom(const void *data)
|
||||
const PnvChip *chip = data;
|
||||
QTestState *qts = NULL;
|
||||
g_autofree char *tmp_path = NULL;
|
||||
const char *machine = pnv_get_machine_type(chip->chip_type);
|
||||
int ret;
|
||||
int fd;
|
||||
|
||||
@@ -87,11 +88,11 @@ static void test_spi_seeprom(const void *data)
|
||||
g_assert(ret == 0);
|
||||
close(fd);
|
||||
|
||||
qts = qtest_initf("-machine powernv10 -smp 2,cores=2,"
|
||||
qts = qtest_initf("-machine %s -smp 2,cores=2,"
|
||||
"threads=1 -accel tcg,thread=single -nographic "
|
||||
"-blockdev node-name=pib_spic2,driver=file,"
|
||||
"filename=%s -device 25csm04,bus=chip0.spi.2,cs=0,"
|
||||
"drive=pib_spic2", tmp_path);
|
||||
"drive=pib_spic2", machine, tmp_path);
|
||||
spi_seeprom_transaction(qts, chip);
|
||||
qtest_quit(qts);
|
||||
unlink(tmp_path);
|
||||
@@ -100,9 +101,16 @@ static void test_spi_seeprom(const void *data)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
char *tname = g_strdup_printf("pnv-xscom/spi-seeprom/%s",
|
||||
pnv_chips[3].cpu_model);
|
||||
qtest_add_data_func(tname, &pnv_chips[3], test_spi_seeprom);
|
||||
g_free(tname);
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(pnv_chips); i++) {
|
||||
/* TYPE_PNV_SPI is not instantiated for older Power8/9 machines */
|
||||
if (pnv_chips[i].chip_type < PNV_CHIP_POWER10) {
|
||||
continue;
|
||||
}
|
||||
|
||||
g_autofree char *tname = g_strdup_printf("pnv-xscom/spi-seeprom/%s",
|
||||
pnv_chips[i].cpu_model);
|
||||
qtest_add_data_func(tname, &pnv_chips[i], test_spi_seeprom);
|
||||
}
|
||||
return g_test_run();
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "libqtest.h"
|
||||
|
||||
#include "pnv-xive2-common.h"
|
||||
#include "pnv-xscom.h"
|
||||
#include "hw/intc/pnv_xive2_regs.h"
|
||||
#include "hw/ppc/xive_regs.h"
|
||||
#include "hw/ppc/xive2_regs.h"
|
||||
@@ -544,14 +545,16 @@ static void test_hw_group_irq_backlog(QTestState *qts)
|
||||
g_assert_cmphex(lsmfb, ==, 0xFF);
|
||||
}
|
||||
|
||||
static void test_xive(void)
|
||||
static void test_xive(const void *data)
|
||||
{
|
||||
const PnvChip *chip = data;
|
||||
const char *machine = pnv_get_machine_type(chip->chip_type);
|
||||
QTestState *qts;
|
||||
|
||||
qts = qtest_initf("-M powernv10 -smp %d,cores=1,threads=%d -nographic "
|
||||
qts = qtest_initf("-M %s -smp %d,cores=1,threads=%d -nographic "
|
||||
"-nodefaults -serial mon:stdio -S "
|
||||
"-d guest_errors -trace '*xive*'",
|
||||
SMT, SMT);
|
||||
machine, SMT, SMT);
|
||||
init_xive(qts);
|
||||
|
||||
test_hw_irq(qts);
|
||||
@@ -580,6 +583,16 @@ static void test_xive(void)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
qtest_add_func("xive2", test_xive);
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(pnv_chips); i++) {
|
||||
/* xive2 exists from Power10 onwards */
|
||||
if (pnv_chips[i].chip_type < PNV_CHIP_POWER10) {
|
||||
continue;
|
||||
}
|
||||
|
||||
g_autofree char *tname = g_strdup_printf("pnv-xive2/%s",
|
||||
pnv_chips[i].cpu_model);
|
||||
qtest_add_data_func(tname, &pnv_chips[i], test_xive);
|
||||
}
|
||||
return g_test_run();
|
||||
}
|
||||
|
||||
@@ -28,15 +28,9 @@ static void test_xscom_cfam_id(QTestState *qts, const PnvChip *chip)
|
||||
static void test_cfam_id(const void *data)
|
||||
{
|
||||
const PnvChip *chip = data;
|
||||
const char *machine = "powernv8";
|
||||
const char *machine = pnv_get_machine_type(chip->chip_type);
|
||||
QTestState *qts;
|
||||
|
||||
if (chip->chip_type == PNV_CHIP_POWER9) {
|
||||
machine = "powernv9";
|
||||
} else if (chip->chip_type == PNV_CHIP_POWER10) {
|
||||
machine = "powernv10";
|
||||
}
|
||||
|
||||
qts = qtest_initf("-M %s -accel tcg -cpu %s",
|
||||
machine, chip->cpu_model);
|
||||
test_xscom_cfam_id(qts, chip);
|
||||
@@ -57,7 +51,8 @@ static void test_cfam_id(const void *data)
|
||||
|
||||
static void test_xscom_core(QTestState *qts, const PnvChip *chip)
|
||||
{
|
||||
if (chip->chip_type == PNV_CHIP_POWER10) {
|
||||
if ((chip->chip_type == PNV_CHIP_POWER10) ||
|
||||
(chip->chip_type == PNV_CHIP_POWER11)) {
|
||||
uint32_t first_core_thread_state =
|
||||
PNV_XSCOM_P10_EC_BASE(chip->first_core) + 0x412;
|
||||
uint64_t thread_state;
|
||||
@@ -84,14 +79,8 @@ static void test_xscom_core(QTestState *qts, const PnvChip *chip)
|
||||
static void test_core(const void *data)
|
||||
{
|
||||
const PnvChip *chip = data;
|
||||
const char *machine = pnv_get_machine_type(chip->chip_type);
|
||||
QTestState *qts;
|
||||
const char *machine = "powernv8";
|
||||
|
||||
if (chip->chip_type == PNV_CHIP_POWER9) {
|
||||
machine = "powernv9";
|
||||
} else if (chip->chip_type == PNV_CHIP_POWER10) {
|
||||
machine = "powernv10";
|
||||
}
|
||||
|
||||
qts = qtest_initf("-M %s -accel tcg -cpu %s",
|
||||
machine, chip->cpu_model);
|
||||
@@ -104,10 +93,9 @@ static void add_test(const char *name, void (*test)(const void *data))
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(pnv_chips); i++) {
|
||||
char *tname = g_strdup_printf("pnv-xscom/%s/%s", name,
|
||||
g_autofree char *tname = g_strdup_printf("pnv-xscom/%s/%s", name,
|
||||
pnv_chips[i].cpu_model);
|
||||
qtest_add_data_func(tname, &pnv_chips[i], test);
|
||||
g_free(tname);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,11 +12,10 @@
|
||||
#define SMT 4 /* some tests will break if less than 4 */
|
||||
|
||||
typedef enum PnvChipType {
|
||||
PNV_CHIP_POWER8E, /* AKA Murano (default) */
|
||||
PNV_CHIP_POWER8, /* AKA Venice */
|
||||
PNV_CHIP_POWER8NVL, /* AKA Naples */
|
||||
PNV_CHIP_POWER9, /* AKA Nimbus */
|
||||
PNV_CHIP_POWER10,
|
||||
PNV_CHIP_POWER11,
|
||||
} PnvChipType;
|
||||
|
||||
typedef struct PnvChip {
|
||||
@@ -36,13 +35,6 @@ static const PnvChip pnv_chips[] = {
|
||||
.cfam_id = 0x220ea04980000000ull,
|
||||
.first_core = 0x1,
|
||||
.num_i2c = 0,
|
||||
}, {
|
||||
.chip_type = PNV_CHIP_POWER8NVL,
|
||||
.cpu_model = "POWER8NVL",
|
||||
.xscom_base = 0x0003fc0000000000ull,
|
||||
.cfam_id = 0x120d304980000000ull,
|
||||
.first_core = 0x1,
|
||||
.num_i2c = 0,
|
||||
},
|
||||
{
|
||||
.chip_type = PNV_CHIP_POWER9,
|
||||
@@ -60,15 +52,23 @@ static const PnvChip pnv_chips[] = {
|
||||
.first_core = 0x0,
|
||||
.num_i2c = 4,
|
||||
},
|
||||
{
|
||||
.chip_type = PNV_CHIP_POWER11,
|
||||
.cpu_model = "Power11",
|
||||
.xscom_base = 0x000603fc00000000ull,
|
||||
.cfam_id = 0x220da04980000000ull,
|
||||
.first_core = 0x0,
|
||||
.num_i2c = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static inline uint64_t pnv_xscom_addr(const PnvChip *chip, uint32_t pcba)
|
||||
{
|
||||
uint64_t addr = chip->xscom_base;
|
||||
|
||||
if (chip->chip_type == PNV_CHIP_POWER10) {
|
||||
addr |= ((uint64_t) pcba << 3);
|
||||
} else if (chip->chip_type == PNV_CHIP_POWER9) {
|
||||
if ((chip->chip_type == PNV_CHIP_POWER11) ||
|
||||
(chip->chip_type == PNV_CHIP_POWER10) ||
|
||||
(chip->chip_type == PNV_CHIP_POWER9)) {
|
||||
addr |= ((uint64_t) pcba << 3);
|
||||
} else {
|
||||
addr |= (((uint64_t) pcba << 4) & ~0xffull) |
|
||||
@@ -77,4 +77,18 @@ static inline uint64_t pnv_xscom_addr(const PnvChip *chip, uint32_t pcba)
|
||||
return addr;
|
||||
}
|
||||
|
||||
static const char *pnv_get_machine_type(enum PnvChipType chip_type)
|
||||
{
|
||||
static const char *const machine_types[] = {
|
||||
[PNV_CHIP_POWER8] = "powernv8",
|
||||
[PNV_CHIP_POWER9] = "powernv9",
|
||||
[PNV_CHIP_POWER10] = "powernv10",
|
||||
[PNV_CHIP_POWER11] = "powernv11",
|
||||
};
|
||||
|
||||
g_assert(chip_type <= PNV_CHIP_POWER11);
|
||||
|
||||
return machine_types[chip_type];
|
||||
}
|
||||
|
||||
#endif /* PNV_XSCOM_H */
|
||||
|
||||
Reference in New Issue
Block a user