Merge remote-tracking branch 'remotes/dg-gitlab/tags/ppc-for-6.1-20210504' into staging

ppc patch queue 2021-05-04

Here's the first ppc pull request for qemu-6.1.  It has a wide variety
of stuff accumulated during the 6.0 freeze.  Highlights are:

 * Multi-phase reset cleanups for PAPR
 * Preliminary cleanups towards allowing !CONFIG_TCG for the ppc target
 * Cleanup of AIL logic and extension to POWER10
 * Further improvements to handling of hot unplug failures on PAPR
 * Allow much larger numbers of CPU on pseries
 * Support for the H_SCM_HEALTH hypercall
 * Add support for the Pegasos II board
 * Substantial cleanup to hflag handling
 * Assorted minor fixes and cleanups

# gpg: Signature made Tue 04 May 2021 06:52:39 BST
# gpg:                using RSA key 75F46586AE61A66CC44E87DC6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" [full]
# gpg:                 aka "David Gibson (Red Hat) <dgibson@redhat.com>" [full]
# gpg:                 aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" [full]
# gpg:                 aka "David Gibson (kernel.org) <dwg@kernel.org>" [unknown]
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E  87DC 6C38 CACA 20D9 B392

* remotes/dg-gitlab/tags/ppc-for-6.1-20210504: (46 commits)
  hw/ppc/pnv_psi: Use device_cold_reset() instead of device_legacy_reset()
  hw/ppc/spapr_vio: Reset TCE table object with device_cold_reset()
  hw/intc/spapr_xive: Use device_cold_reset() instead of device_legacy_reset()
  target/ppc: removed VSCR from SPR registration
  target/ppc: Reduce the size of ppc_spr_t
  target/ppc: Clean up _spr_register et al
  target/ppc: Add POWER10 exception model
  target/ppc: rework AIL logic in interrupt delivery
  target/ppc: move opcode table logic to translate.c
  target/ppc: code motion from translate_init.c.inc to gdbstub.c
  spapr_drc.c: handle hotunplug errors in drc_unisolate_logical()
  spapr.h: increase FDT_MAX_SIZE
  spapr.c: do not use MachineClass::max_cpus to limit CPUs
  ppc: Rename current DAWR macros and variables
  target/ppc: POWER10 supports scv
  target/ppc: Fix POWER9 radix guest HV interrupt AIL behaviour
  docs/system: ppc: Add documentation for ppce500 machine
  roms/u-boot: Bump ppce500 u-boot to v2021.04 to fix broken pci support
  roms/Makefile: Update ppce500 u-boot build directory name
  ppc/spapr: Add support for implement support for H_SCM_HEALTH
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2021-05-05 20:29:14 +01:00
48 changed files with 4020 additions and 1208 deletions
+10
View File
@@ -1366,6 +1366,16 @@ F: pc-bios/canyonlands.dt[sb]
F: pc-bios/u-boot-sam460ex-20100605.bin
F: roms/u-boot-sam460ex
pegasos2
M: BALATON Zoltan <balaton@eik.bme.hu>
R: David Gibson <david@gibson.dropbear.id.au>
L: qemu-ppc@nongnu.org
S: Maintained
F: hw/ppc/pegasos2.c
F: hw/pci-host/mv64361.c
F: hw/pci-host/mv643xx.h
F: include/hw/pci-host/mv64361.h
RISC-V Machines
---------------
OpenTitan
+2
View File
@@ -14,5 +14,7 @@ CONFIG_SAM460EX=y
CONFIG_MAC_OLDWORLD=y
CONFIG_MAC_NEWWORLD=y
CONFIG_PEGASOS2=n
# For PReP
CONFIG_PREP=y
+156
View File
@@ -0,0 +1,156 @@
ppce500 generic platform (``ppce500``)
======================================
QEMU for PPC supports a special ``ppce500`` machine designed for emulation and
virtualization purposes.
Supported devices
-----------------
The ``ppce500`` machine supports the following devices:
* PowerPC e500 series core (e500v2/e500mc/e5500/e6500)
* Configuration, Control, and Status Register (CCSR)
* Multicore Programmable Interrupt Controller (MPIC) with MSI support
* 1 16550A UART device
* 1 Freescale MPC8xxx I2C controller
* 1 Pericom pt7c4338 RTC via I2C
* 1 Freescale MPC8xxx GPIO controller
* Power-off functionality via one GPIO pin
* 1 Freescale MPC8xxx PCI host controller
* VirtIO devices via PCI bus
Hardware configuration information
----------------------------------
The ``ppce500`` machine automatically generates a device tree blob ("dtb")
which it passes to the guest, if there is no ``-dtb`` option. This provides
information about the addresses, interrupt lines and other configuration of
the various devices in the system.
If users want to provide their own DTB, they can use the ``-dtb`` option.
These DTBs should have the following requirements:
* The number of subnodes under /cpus node should match QEMU's ``-smp`` option
* The /memory reg size should match QEMUs selected ram_size via ``-m``
Both ``qemu-system-ppc`` and ``qemu-system-ppc64`` provide emulation for the
following 32-bit PowerPC CPUs:
* e500v2
* e500mc
Additionally ``qemu-system-ppc64`` provides support for the following 64-bit
PowerPC CPUs:
* e5500
* e6500
The CPU type can be specified via the ``-cpu`` command line. If not specified,
it creates a machine with e500v2 core. The following example shows an e6500
based machine creation:
.. code-block:: bash
$ qemu-system-ppc64 -nographic -M ppce500 -cpu e6500
Boot options
------------
The ``ppce500`` machine can start using the standard -kernel functionality
for loading a payload like an OS kernel (e.g.: Linux), or U-Boot firmware.
When -bios is omitted, the default pc-bios/u-boot.e500 firmware image is used
as the BIOS. QEMU follows below truth table to select which payload to execute:
===== ========== =======
-bios -kernel payload
===== ========== =======
N N u-boot
N Y kernel
Y don't care u-boot
===== ========== =======
When both -bios and -kernel are present, QEMU loads U-Boot and U-Boot in turns
automatically loads the kernel image specified by the -kernel parameter via
U-Boot's built-in "bootm" command, hence a legacy uImage format is required in
such senario.
Running Linux kernel
--------------------
Linux mainline v5.11 release is tested at the time of writing. To build a
Linux mainline kernel that can be booted by the ``ppce500`` machine in
64-bit mode, simply configure the kernel using the defconfig configuration:
.. code-block:: bash
$ export ARCH=powerpc
$ export CROSS_COMPILE=powerpc-linux-
$ make corenet64_smp_defconfig
$ make menuconfig
then manually select the following configuration:
Platform support > Freescale Book-E Machine Type > QEMU generic e500 platform
To boot the newly built Linux kernel in QEMU with the ``ppce500`` machine:
.. code-block:: bash
$ qemu-system-ppc64 -M ppce500 -cpu e5500 -smp 4 -m 2G \
-display none -serial stdio \
-kernel vmlinux \
-initrd /path/to/rootfs.cpio \
-append "root=/dev/ram"
To build a Linux mainline kernel that can be booted by the ``ppce500`` machine
in 32-bit mode, use the same 64-bit configuration steps except the defconfig
file should use corenet32_smp_defconfig.
To boot the 32-bit Linux kernel:
.. code-block:: bash
$ qemu-system-ppc{64|32} -M ppce500 -cpu e500mc -smp 4 -m 2G \
-display none -serial stdio \
-kernel vmlinux \
-initrd /path/to/rootfs.cpio \
-append "root=/dev/ram"
Running U-Boot
--------------
U-Boot mainline v2021.04 release is tested at the time of writing. To build a
U-Boot mainline bootloader that can be booted by the ``ppce500`` machine, use
the qemu-ppce500_defconfig with similar commands as described above for Linux:
.. code-block:: bash
$ export CROSS_COMPILE=powerpc-linux-
$ make qemu-ppce500_defconfig
You will get u-boot file in the build tree.
When U-Boot boots, you will notice the following if using with ``-cpu e6500``:
.. code-block:: none
CPU: Unknown, Version: 0.0, (0x00000000)
Core: e6500, Version: 2.0, (0x80400020)
This is because we only specified a core name to QEMU and it does not have a
meaningful SVR value which represents an actual SoC that integrates such core.
You can specify a real world SoC device that QEMU has built-in support but all
these SoCs are e500v2 based MPC85xx series, hence you cannot test anything
built for P4080 (e500mc), P5020 (e5500) and T2080 (e6500).
By default a VirtIO standard PCI networking device is connected as an ethernet
interface at PCI address 0.1.0, but we can switch that to an e1000 NIC by:
.. code-block:: bash
$ qemu-system-ppc -M ppce500 -smp 4 -m 2G \
-display none -serial stdio \
-bios u-boot \
-nic tap,ifname=tap0,script=no,downscript=no,model=e1000
+1
View File
@@ -20,5 +20,6 @@ help``.
ppc/embedded
ppc/powermac
ppc/powernv
ppc/ppce500
ppc/prep
ppc/pseries
+1 -1
View File
@@ -1798,7 +1798,7 @@ static target_ulong h_int_reset(PowerPCCPU *cpu,
return H_PARAMETER;
}
device_legacy_reset(DEVICE(xive));
device_cold_reset(DEVICE(xive));
if (spapr_xive_in_kernel(xive)) {
Error *local_err = NULL;
+351 -89
View File
File diff suppressed because it is too large Load Diff
+4
View File
@@ -72,3 +72,7 @@ config REMOTE_PCIHOST
config SH_PCI
bool
select PCI
config MV64361
bool
select PCI
+2
View File
@@ -19,6 +19,8 @@ pci_ss.add(when: 'CONFIG_GRACKLE_PCI', if_true: files('grackle.c'))
pci_ss.add(when: 'CONFIG_UNIN_PCI', if_true: files('uninorth.c'))
# PowerPC E500 boards
pci_ss.add(when: 'CONFIG_PPCE500_PCI', if_true: files('ppce500.c'))
# Pegasos2
pci_ss.add(when: 'CONFIG_MV64361', if_true: files('mv64361.c'))
# ARM devices
pci_ss.add(when: 'CONFIG_VERSATILE_PCI', if_true: files('versatile.c'))
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+6
View File
@@ -3,6 +3,12 @@
# grackle.c
grackle_set_irq(int irq_num, int level) "set_irq num %d level %d"
# mv64361.c
mv64361_region_map(const char *name, uint64_t poffs, uint64_t size, uint64_t moffs) "Mapping %s 0x%"PRIx64"+0x%"PRIx64" @ 0x%"PRIx64
mv64361_region_enable(const char *op, int num) "Should %s region %d"
mv64361_reg_read(uint64_t addr, uint32_t val) "0x%"PRIx64" -> 0x%x"
mv64361_reg_write(uint64_t addr, uint64_t val) "0x%"PRIx64" <- 0x%"PRIx64
# sabre.c
sabre_set_request(int irq_num) "request irq %d"
sabre_clear_request(int irq_num) "clear request irq %d"
+9
View File
@@ -68,6 +68,15 @@ config SAM460EX
select USB_OHCI
select FDT_PPC
config PEGASOS2
bool
select MV64361
select VT82C686
select IDE_VIA
select SMBUS_EEPROM
# This should come with VT82C686
select ACPI_X86
config PREP
bool
imply PCI_DEVICES
+4
View File
@@ -155,6 +155,10 @@ static void ppc_core99_init(MachineState *machine)
}
/* allocate RAM */
if (machine->ram_size > 2 * GiB) {
error_report("RAM size more than 2 GiB is not supported");
exit(1);
}
memory_region_add_subregion(get_system_memory(), 0, machine->ram);
/* allocate and load firmware ROM */
+2
View File
@@ -78,5 +78,7 @@ ppc_ss.add(when: 'CONFIG_E500', if_true: files(
))
# PowerPC 440 Xilinx ML507 reference board.
ppc_ss.add(when: 'CONFIG_VIRTEX', if_true: files('virtex_ml507.c'))
# Pegasos2
ppc_ss.add(when: 'CONFIG_PEGASOS2', if_true: files('pegasos2.c'))
hw_arch += {'ppc': ppc_ss}
+144
View File
@@ -0,0 +1,144 @@
/*
* QEMU PowerPC CHRP (Genesi/bPlan Pegasos II) hardware System Emulator
*
* Copyright (c) 2018-2020 BALATON Zoltan
*
* This work is licensed under the GNU GPL license version 2 or later.
*
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "hw/hw.h"
#include "hw/ppc/ppc.h"
#include "hw/sysbus.h"
#include "hw/pci/pci_host.h"
#include "hw/irq.h"
#include "hw/pci-host/mv64361.h"
#include "hw/isa/vt82c686.h"
#include "hw/ide/pci.h"
#include "hw/i2c/smbus_eeprom.h"
#include "hw/qdev-properties.h"
#include "sysemu/reset.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "hw/fw-path-provider.h"
#include "elf.h"
#include "qemu/log.h"
#include "qemu/error-report.h"
#include "sysemu/kvm.h"
#include "kvm_ppc.h"
#include "exec/address-spaces.h"
#include "trace.h"
#include "qemu/datadir.h"
#include "sysemu/device_tree.h"
#define PROM_FILENAME "pegasos2.rom"
#define PROM_ADDR 0xfff00000
#define PROM_SIZE 0x80000
#define BUS_FREQ_HZ 133333333
static void pegasos2_cpu_reset(void *opaque)
{
PowerPCCPU *cpu = opaque;
cpu_reset(CPU(cpu));
cpu->env.spr[SPR_HID1] = 7ULL << 28;
}
static void pegasos2_init(MachineState *machine)
{
PowerPCCPU *cpu = NULL;
MemoryRegion *rom = g_new(MemoryRegion, 1);
DeviceState *mv;
PCIBus *pci_bus;
PCIDevice *dev;
I2CBus *i2c_bus;
const char *fwname = machine->firmware ?: PROM_FILENAME;
char *filename;
int sz;
uint8_t *spd_data;
/* init CPU */
cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
if (PPC_INPUT(&cpu->env) != PPC_FLAGS_INPUT_6xx) {
error_report("Incompatible CPU, only 6xx bus supported");
exit(1);
}
/* Set time-base frequency */
cpu_ppc_tb_init(&cpu->env, BUS_FREQ_HZ / 4);
qemu_register_reset(pegasos2_cpu_reset, cpu);
/* RAM */
memory_region_add_subregion(get_system_memory(), 0, machine->ram);
/* allocate and load firmware */
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, fwname);
if (!filename) {
error_report("Could not find firmware '%s'", fwname);
exit(1);
}
memory_region_init_rom(rom, NULL, "pegasos2.rom", PROM_SIZE, &error_fatal);
memory_region_add_subregion(get_system_memory(), PROM_ADDR, rom);
sz = load_elf(filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1,
PPC_ELF_MACHINE, 0, 0);
if (sz <= 0) {
sz = load_image_targphys(filename, PROM_ADDR, PROM_SIZE);
}
if (sz <= 0 || sz > PROM_SIZE) {
error_report("Could not load firmware '%s'", filename);
exit(1);
}
g_free(filename);
/* Marvell Discovery II system controller */
mv = DEVICE(sysbus_create_simple(TYPE_MV64361, -1,
((qemu_irq *)cpu->env.irq_inputs)[PPC6xx_INPUT_INT]));
pci_bus = mv64361_get_pci_bus(mv, 1);
/* VIA VT8231 South Bridge (multifunction PCI device) */
/* VT8231 function 0: PCI-to-ISA Bridge */
dev = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0), true,
TYPE_VT8231_ISA);
qdev_connect_gpio_out(DEVICE(dev), 0,
qdev_get_gpio_in_named(mv, "gpp", 31));
/* VT8231 function 1: IDE Controller */
dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 1), "via-ide");
pci_ide_create_devs(dev);
/* VT8231 function 2-3: USB Ports */
pci_create_simple(pci_bus, PCI_DEVFN(12, 2), "vt82c686b-usb-uhci");
pci_create_simple(pci_bus, PCI_DEVFN(12, 3), "vt82c686b-usb-uhci");
/* VT8231 function 4: Power Management Controller */
dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 4), TYPE_VT8231_PM);
i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c"));
spd_data = spd_data_generate(DDR, machine->ram_size);
smbus_eeprom_init_one(i2c_bus, 0x57, spd_data);
/* VT8231 function 5-6: AC97 Audio & Modem */
pci_create_simple(pci_bus, PCI_DEVFN(12, 5), TYPE_VIA_AC97);
pci_create_simple(pci_bus, PCI_DEVFN(12, 6), TYPE_VIA_MC97);
/* other PC hardware */
pci_vga_init(pci_bus);
}
static void pegasos2_machine(MachineClass *mc)
{
mc->desc = "Genesi/bPlan Pegasos II";
mc->init = pegasos2_init;
mc->block_default_type = IF_IDE;
mc->default_boot_order = "cd";
mc->default_display = "std";
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("7400_v2.9");
mc->default_ram_id = "pegasos2.ram";
mc->default_ram_size = 512 * MiB;
}
DEFINE_MACHINE("pegasos2", pegasos2_machine)
+2 -1
View File
@@ -29,6 +29,7 @@
#include "hw/ppc/pnv_xscom.h"
#include "hw/ppc/xics.h"
#include "hw/qdev-properties.h"
#include "helper_regs.h"
static const char *pnv_core_cpu_typename(PnvCore *pc)
{
@@ -55,8 +56,8 @@ static void pnv_core_cpu_reset(PnvCore *pc, PowerPCCPU *cpu)
env->gpr[3] = PNV_FDT_ADDR;
env->nip = 0x10;
env->msr |= MSR_HVB; /* Hypervisor mode */
env->spr[SPR_HRMOR] = pc->hrmor;
hreg_compute_hflags(env);
pcc->intc_reset(pc->chip, cpu);
}
+2 -2
View File
@@ -465,7 +465,7 @@ static void pnv_psi_reset(DeviceState *dev)
static void pnv_psi_reset_handler(void *dev)
{
device_legacy_reset(DEVICE(dev));
device_cold_reset(DEVICE(dev));
}
static void pnv_psi_realize(DeviceState *dev, Error **errp)
@@ -709,7 +709,7 @@ static void pnv_psi_p9_mmio_write(void *opaque, hwaddr addr,
break;
case PSIHB9_INTERRUPT_CONTROL:
if (val & PSIHB9_IRQ_RESET) {
device_legacy_reset(DEVICE(&psi9->source));
device_cold_reset(DEVICE(&psi9->source));
}
psi->regs[reg] = val;
break;
+14 -5
View File
@@ -98,7 +98,7 @@
*
* We load our kernel at 4M, leaving space for SLOF initial image
*/
#define RTAS_MAX_ADDR 0x80000000 /* RTAS must stay below that */
#define FDT_MAX_ADDR 0x80000000 /* FDT must stay below that */
#define FW_MAX_SIZE 0x400000
#define FW_FILE_NAME "slof.bin"
#define FW_OVERHEAD 0x2800000
@@ -1615,11 +1615,11 @@ static void spapr_machine_reset(MachineState *machine)
spapr_clear_pending_events(spapr);
/*
* We place the device tree and RTAS just below either the top of the RMA,
* We place the device tree just below either the top of the RMA,
* or just below 2GB, whichever is lower, so that it can be
* processed with 32-bit real mode code if necessary
*/
fdt_addr = MIN(spapr->rma_size, RTAS_MAX_ADDR) - FDT_MAX_SIZE;
fdt_addr = MIN(spapr->rma_size, FDT_MAX_ADDR) - FDT_MAX_SIZE;
fdt = spapr_build_fdt(spapr, true, FDT_MAX_SIZE);
@@ -2692,7 +2692,7 @@ static void spapr_machine_init(MachineState *machine)
spapr->rma_size = spapr_rma_size(spapr, &error_fatal);
/* Setup a load limit for the ramdisk leaving room for SLOF and FDT */
load_limit = MIN(spapr->rma_size, RTAS_MAX_ADDR) - FW_OVERHEAD;
load_limit = MIN(spapr->rma_size, FDT_MAX_ADDR) - FW_OVERHEAD;
/*
* VSMT must be set in order to be able to compute VCPU ids, ie to
@@ -4485,7 +4485,16 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
mc->init = spapr_machine_init;
mc->reset = spapr_machine_reset;
mc->block_default_type = IF_SCSI;
mc->max_cpus = 1024;
/*
* Setting max_cpus to INT32_MAX. Both KVM and TCG max_cpus values
* should be limited by the host capability instead of hardcoded.
* max_cpus for KVM guests will be checked in kvm_init(), and TCG
* guests are welcome to have as many CPUs as the host are capable
* of emulate.
*/
mc->max_cpus = INT32_MAX;
mc->no_parallel = 1;
mc->default_boot_order = "";
mc->default_ram_size = 512 * MiB;
+23
View File
@@ -150,9 +150,32 @@ static uint32_t drc_isolate_logical(SpaprDrc *drc)
static uint32_t drc_unisolate_logical(SpaprDrc *drc)
{
SpaprMachineState *spapr = NULL;
switch (drc->state) {
case SPAPR_DRC_STATE_LOGICAL_UNISOLATE:
case SPAPR_DRC_STATE_LOGICAL_CONFIGURED:
/*
* Unisolating a logical DRC that was marked for unplug
* means that the kernel is refusing the removal.
*/
if (drc->unplug_requested && drc->dev) {
if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_LMB) {
spapr = SPAPR_MACHINE(qdev_get_machine());
spapr_memory_unplug_rollback(spapr, drc->dev);
}
drc->unplug_requested = false;
error_report("Device hotunplug rejected by the guest "
"for device %s", drc->dev->id);
/*
* TODO: send a QAPI DEVICE_UNPLUG_ERROR event when
* it is implemented.
*/
}
return RTAS_OUT_SUCCESS; /* Nothing to do */
case SPAPR_DRC_STATE_LOGICAL_AVAILABLE:
break; /* see below */
+7 -1
View File
@@ -1394,7 +1394,13 @@ static target_ulong h_set_mode_resource_addr_trans_mode(PowerPCCPU *cpu,
return H_P4;
}
if (mflags == AIL_RESERVED) {
if (mflags == 1) {
/* AIL=1 is reserved in POWER8/POWER9/POWER10 */
return H_UNSUPPORTED_FLAG;
}
if (mflags == 2 && (pcc->insns_flags2 & PPC2_ISA310)) {
/* AIL=2 is reserved in POWER10 (ISA v3.1) */
return H_UNSUPPORTED_FLAG;
}

Some files were not shown because too many files have changed in this diff Show More