Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/dg-gitlab/tags/ppc-for-6.0-2021…
Browse files Browse the repository at this point in the history
…0210' into staging

ppc patch queue for 20201-02-10

Here's the latest batch of patches for the ppc target and machine
types.  Highlights are:
 * Several fixes for E500 from Bin Meng
 * Fixes and cleanups for PowerNV from Cédric Le Goater
 * Assorted other fixes and cleanups

# gpg: Signature made Wed 10 Feb 2021 06:16:53 GMT
# 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.0-20210210:
  target/ppc: Add E500 L2CSR0 write helper
  hw/net: fsl_etsec: Reverse the RCTRL.RSF logic
  hw/ppc: e500: Fill in correct <clock-frequency> for the serial nodes
  hw/ppc: e500: Use a macro for the platform clock frequency
  ppc/pnv: Set default RAM size to 1 GB
  spapr_numa.c: fix ibm,max-associativity-domains calculation
  spapr_numa.c: create spapr_numa_initial_nvgpu_numa_id() helper
  spapr: move spapr_machine_using_legacy_numa() to spapr_numa.c
  ppc/pnv: Introduce a LPC FW memory region attribute to map the PNOR
  ppc/pnv: Remove default disablement of the PNOR contents
  ppc/pnv: Discard internal BMC initialization when BMC is external
  ppc/pnv: Simplify pnv_bmc_create()
  ppc/pnv: Use skiboot addresses to load kernel and ramfs
  ppc/xive: Add firmware bit when dumping the ENDs
  ppc/pnv: Add trace events for PCI event notification
  target/ppc: Remove unused MMU definitions
  spapr: Adjust firmware path of PCI devices
  spapr.c: add 'name' property for hotplugged CPUs nodes
  spapr.c: use g_auto* with 'nodename' in CPU DT functions

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Feb 10, 2021
2 parents 1214d55 + 298091f commit 7b2c4cd
Show file tree
Hide file tree
Showing 20 changed files with 150 additions and 77 deletions.
3 changes: 3 additions & 0 deletions hw/intc/pnv_xive.c
Expand Up @@ -24,6 +24,7 @@
#include "hw/ppc/xive_regs.h"
#include "hw/qdev-properties.h"
#include "hw/ppc/ppc.h"
#include "trace.h"

#include <libfdt.h>

Expand Down Expand Up @@ -1319,6 +1320,8 @@ static void pnv_xive_ic_hw_trigger(PnvXive *xive, hwaddr addr, uint64_t val)
uint8_t blk;
uint32_t idx;

trace_pnv_xive_ic_hw_trigger(addr, val);

if (val & XIVE_TRIGGER_END) {
xive_error(xive, "IC: END trigger at @0x%"HWADDR_PRIx" data 0x%"PRIx64,
addr, val);
Expand Down
3 changes: 3 additions & 0 deletions hw/intc/trace-events
Expand Up @@ -236,3 +236,6 @@ xive_tctx_tm_write(uint64_t offset, unsigned int size, uint64_t value) "@0x0x%"P
xive_tctx_tm_read(uint64_t offset, unsigned int size, uint64_t value) "@0x0x%"PRIx64" sz=%d val=0x%" PRIx64
xive_presenter_notify(uint8_t nvt_blk, uint32_t nvt_idx, uint8_t ring) "found NVT 0x%x/0x%x ring=0x%x"
xive_end_source_read(uint8_t end_blk, uint32_t end_idx, uint64_t addr) "END 0x%x/0x%x @0x0x%"PRIx64

# pnv_xive.c
pnv_xive_ic_hw_trigger(uint64_t addr, uint64_t val) "@0x%"PRIx64" val=0x%"PRIx64
3 changes: 2 additions & 1 deletion hw/intc/xive.c
Expand Up @@ -1294,7 +1294,7 @@ void xive_end_pic_print_info(XiveEND *end, uint32_t end_idx, Monitor *mon)

pq = xive_get_field32(END_W1_ESn, end->w1);

monitor_printf(mon, " %08x %c%c %c%c%c%c%c%c%c prio:%d nvt:%02x/%04x",
monitor_printf(mon, " %08x %c%c %c%c%c%c%c%c%c%c prio:%d nvt:%02x/%04x",
end_idx,
pq & XIVE_ESB_VAL_P ? 'P' : '-',
pq & XIVE_ESB_VAL_Q ? 'Q' : '-',
Expand All @@ -1305,6 +1305,7 @@ void xive_end_pic_print_info(XiveEND *end, uint32_t end_idx, Monitor *mon)
xive_end_is_escalate(end) ? 'e' : '-',
xive_end_is_uncond_escalation(end) ? 'u' : '-',
xive_end_is_silent_escalation(end) ? 's' : '-',
xive_end_is_firmware(end) ? 'f' : '-',
priority, nvt_blk, nvt_idx);

if (qaddr_base) {
Expand Down
2 changes: 1 addition & 1 deletion hw/net/fsl_etsec/rings.c
Expand Up @@ -502,7 +502,7 @@ ssize_t etsec_rx_ring_write(eTSEC *etsec, const uint8_t *buf, size_t size)
return -1;
}

if ((etsec->regs[RCTRL].value & RCTRL_RSF) && (size < 60)) {
if (!(etsec->regs[RCTRL].value & RCTRL_RSF) && (size < 60)) {
/* CRC is not in the packet yet, so short frame is below 60 bytes */
RING_DEBUG("%s: Drop short frame\n", __func__);
return -1;
Expand Down
3 changes: 3 additions & 0 deletions hw/pci-host/pnv_phb4.c
Expand Up @@ -22,6 +22,7 @@
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "qom/object.h"
#include "trace.h"

#define phb_error(phb, fmt, ...) \
qemu_log_mask(LOG_GUEST_ERROR, "phb4[%d:%d]: " fmt "\n", \
Expand Down Expand Up @@ -1257,6 +1258,8 @@ static void pnv_phb4_xive_notify(XiveNotifier *xf, uint32_t srcno)
uint64_t data = XIVE_TRIGGER_PQ | offset | srcno;
MemTxResult result;

trace_pnv_phb4_xive_notify(notif_port, data);

address_space_stq_be(&address_space_memory, notif_port, data,
MEMTXATTRS_UNSPECIFIED, &result);
if (result != MEMTX_OK) {
Expand Down
3 changes: 3 additions & 0 deletions hw/pci-host/trace-events
Expand Up @@ -20,3 +20,6 @@ unin_data_write(uint64_t addr, unsigned len, uint64_t val) "write addr 0x%"PRIx6
unin_data_read(uint64_t addr, unsigned len, uint64_t val) "read addr 0x%"PRIx64 " len %d val 0x%"PRIx64
unin_write(uint64_t addr, uint64_t value) "addr=0x%" PRIx64 " val=0x%"PRIx64
unin_read(uint64_t addr, uint64_t value) "addr=0x%" PRIx64 " val=0x%"PRIx64

# pnv_phb4.c
pnv_phb4_xive_notify(uint64_t notif_port, uint64_t data) "notif=@0x%"PRIx64" data=0x%"PRIx64
10 changes: 6 additions & 4 deletions hw/ppc/e500.c
Expand Up @@ -74,6 +74,8 @@
#define MPC8544_I2C_IRQ 43
#define RTC_REGS_OFFSET 0x68

#define PLATFORM_CLK_FREQ_HZ (400 * 1000 * 1000)

struct boot_info
{
uint32_t dt_base;
Expand Down Expand Up @@ -124,7 +126,7 @@ static void dt_serial_create(void *fdt, unsigned long long offset,
qemu_fdt_setprop_string(fdt, ser, "compatible", "ns16550");
qemu_fdt_setprop_cells(fdt, ser, "reg", offset, 0x100);
qemu_fdt_setprop_cell(fdt, ser, "cell-index", idx);
qemu_fdt_setprop_cell(fdt, ser, "clock-frequency", 0);
qemu_fdt_setprop_cell(fdt, ser, "clock-frequency", PLATFORM_CLK_FREQ_HZ);
qemu_fdt_setprop_cells(fdt, ser, "interrupts", 42, 2);
qemu_fdt_setprop_phandle(fdt, ser, "interrupt-parent", mpic);
qemu_fdt_setprop_string(fdt, "/aliases", alias, ser);
Expand Down Expand Up @@ -320,8 +322,8 @@ static int ppce500_load_device_tree(PPCE500MachineState *pms,
int fdt_size;
void *fdt;
uint8_t hypercall[16];
uint32_t clock_freq = 400000000;
uint32_t tb_freq = 400000000;
uint32_t clock_freq = PLATFORM_CLK_FREQ_HZ;
uint32_t tb_freq = PLATFORM_CLK_FREQ_HZ;
int i;
char compatible_sb[] = "fsl,mpc8544-immr\0simple-bus";
char *soc;
Expand Down Expand Up @@ -890,7 +892,7 @@ void ppce500_init(MachineState *machine)
env->spr_cb[SPR_BOOKE_PIR].default_value = cs->cpu_index = i;
env->mpic_iack = pmc->ccsrbar_base + MPC8544_MPIC_REGS_OFFSET + 0xa0;

ppc_booke_timers_init(cpu, 400000000, PPC_TIMER_E500);
ppc_booke_timers_init(cpu, PLATFORM_CLK_FREQ_HZ, PPC_TIMER_E500);

/* Register reset handler */
if (!i) {
Expand Down
27 changes: 21 additions & 6 deletions hw/ppc/pnv.c
Expand Up @@ -21,6 +21,7 @@
#include "qemu-common.h"
#include "qemu/datadir.h"
#include "qemu/units.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
#include "sysemu/qtest.h"
#include "sysemu/sysemu.h"
Expand Down Expand Up @@ -65,9 +66,9 @@
#define FW_MAX_SIZE (16 * MiB)

#define KERNEL_LOAD_ADDR 0x20000000
#define KERNEL_MAX_SIZE (256 * MiB)
#define INITRD_LOAD_ADDR 0x60000000
#define INITRD_MAX_SIZE (256 * MiB)
#define KERNEL_MAX_SIZE (128 * MiB)
#define INITRD_LOAD_ADDR 0x28000000
#define INITRD_MAX_SIZE (128 * MiB)

static const char *pnv_chip_core_typename(const PnvChip *o)
{
Expand Down Expand Up @@ -725,8 +726,11 @@ static void pnv_init(MachineState *machine)
DeviceState *dev;

/* allocate RAM */
if (machine->ram_size < (1 * GiB)) {
warn_report("skiboot may not work with < 1GB of RAM");
if (machine->ram_size < mc->default_ram_size) {
char *sz = size_to_str(mc->default_ram_size);
error_report("Invalid RAM size, should be bigger than %s", sz);
g_free(sz);
exit(EXIT_FAILURE);
}
memory_region_add_subregion(get_system_memory(), 0, machine->ram);

Expand Down Expand Up @@ -871,6 +875,14 @@ static void pnv_init(MachineState *machine)
pnv_ipmi_bt_init(pnv->isa_bus, pnv->bmc, 10);
}

/*
* The PNOR is mapped on the LPC FW address space by the BMC.
* Since we can not reach the remote BMC machine with LPC memops,
* map it always for now.
*/
memory_region_add_subregion(pnv->chips[0]->fw_mr, PNOR_SPI_OFFSET,
&pnv->pnor->mmio);

/*
* OpenPOWER systems use a IPMI SEL Event message to notify the
* host to powerdown
Expand Down Expand Up @@ -1150,6 +1162,7 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
qdev_realize(DEVICE(&chip8->lpc), NULL, &error_fatal);
pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, &chip8->lpc.xscom_regs);

chip->fw_mr = &chip8->lpc.isa_fw;
chip->dt_isa_nodename = g_strdup_printf("/xscom@%" PRIx64 "/isa@%x",
(uint64_t) PNV_XSCOM_BASE(chip),
PNV_XSCOM_LPC_BASE);
Expand Down Expand Up @@ -1479,6 +1492,7 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
memory_region_add_subregion(get_system_memory(), PNV9_LPCM_BASE(chip),
&chip9->lpc.xscom_regs);

chip->fw_mr = &chip9->lpc.isa_fw;
chip->dt_isa_nodename = g_strdup_printf("/lpcm-opb@%" PRIx64 "/lpc@0",
(uint64_t) PNV9_LPCM_BASE(chip));

Expand Down Expand Up @@ -1592,6 +1606,7 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
memory_region_add_subregion(get_system_memory(), PNV10_LPCM_BASE(chip),
&chip10->lpc.xscom_regs);

chip->fw_mr = &chip10->lpc.isa_fw;
chip->dt_isa_nodename = g_strdup_printf("/lpcm-opb@%" PRIx64 "/lpc@0",
(uint64_t) PNV10_LPCM_BASE(chip));
}
Expand Down Expand Up @@ -1983,7 +1998,7 @@ static void pnv_machine_class_init(ObjectClass *oc, void *data)
* RAM defaults to less than 2048 for 32-bit hosts, and large
* enough to fit the maximum initrd size at it's load address
*/
mc->default_ram_size = INITRD_LOAD_ADDR + INITRD_MAX_SIZE;
mc->default_ram_size = 1 * GiB;
mc->default_ram_id = "pnv.ram";
ispc->print_info = pnv_pic_print_info;
nc->nmi_monitor_handler = pnv_nmi;
Expand Down
22 changes: 15 additions & 7 deletions hw/ppc/pnv_bmc.c
Expand Up @@ -51,6 +51,11 @@ typedef struct OemSel {
#define SOFT_OFF 0x00
#define SOFT_REBOOT 0x01

static bool pnv_bmc_is_simulator(IPMIBmc *bmc)
{
return object_dynamic_cast(OBJECT(bmc), TYPE_IPMI_BMC_SIMULATOR);
}

static void pnv_gen_oem_sel(IPMIBmc *bmc, uint8_t reboot)
{
/* IPMI SEL Event are 16 bytes long */
Expand Down Expand Up @@ -79,6 +84,10 @@ void pnv_dt_bmc_sensors(IPMIBmc *bmc, void *fdt)
const struct ipmi_sdr_compact *sdr;
uint16_t nextrec;

if (!pnv_bmc_is_simulator(bmc)) {
return;
}

offset = fdt_add_subnode(fdt, 0, "bmc");
_FDT(offset);

Expand Down Expand Up @@ -243,6 +252,10 @@ static const IPMINetfn hiomap_netfn = {

void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor)
{
if (!pnv_bmc_is_simulator(bmc)) {
return;
}

object_ref(OBJECT(pnor));
object_property_add_const_link(OBJECT(bmc), "pnor", OBJECT(pnor));

Expand All @@ -260,13 +273,8 @@ IPMIBmc *pnv_bmc_create(PnvPnor *pnor)
Object *obj;

obj = object_new(TYPE_IPMI_BMC_SIMULATOR);
object_ref(OBJECT(pnor));
object_property_add_const_link(obj, "pnor", OBJECT(pnor));
qdev_realize(DEVICE(obj), NULL, &error_fatal);

/* Install the HIOMAP protocol handlers to access the PNOR */
ipmi_sim_register_netfn(IPMI_BMC_SIMULATOR(obj), IPMI_NETFN_OEM,
&hiomap_netfn);
pnv_bmc_set_pnor(IPMI_BMC(obj), pnor);

return IPMI_BMC(obj);
}
Expand All @@ -291,7 +299,7 @@ static int bmc_find(Object *child, void *opaque)

IPMIBmc *pnv_bmc_find(Error **errp)
{
ForeachArgs args = { TYPE_IPMI_BMC_SIMULATOR, NULL };
ForeachArgs args = { TYPE_IPMI_BMC, NULL };
int ret;

ret = object_child_foreach_recursive(object_get_root(), bmc_find, &args);
Expand Down
15 changes: 0 additions & 15 deletions hw/ppc/pnv_lpc.c
Expand Up @@ -824,8 +824,6 @@ ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool use_cpld, Error **errp)
ISABus *isa_bus;
qemu_irq *irqs;
qemu_irq_handler handler;
PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
bool hostboot_mode = !!pnv->fw_load_addr;

/* let isa_bus_new() create its own bridge on SysBus otherwise
* devices specified on the command line won't find the bus and
Expand All @@ -851,18 +849,5 @@ ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool use_cpld, Error **errp)

isa_bus_irqs(isa_bus, irqs);

/*
* TODO: Map PNOR on the LPC FW address space on demand ?
*/
memory_region_add_subregion(&lpc->isa_fw, PNOR_SPI_OFFSET,
&pnv->pnor->mmio);
/*
* Start disabled. The HIOMAP protocol will activate the mapping
* with HIOMAP_C_CREATE_WRITE_WINDOW
*/
if (!hostboot_mode) {
memory_region_set_enabled(&pnv->pnor->mmio, false);
}

return isa_bus;
}
44 changes: 21 additions & 23 deletions hw/ppc/spapr.c
Expand Up @@ -296,15 +296,6 @@ static hwaddr spapr_node0_size(MachineState *machine)
return machine->ram_size;
}

bool spapr_machine_using_legacy_numa(SpaprMachineState *spapr)
{
MachineState *machine = MACHINE(spapr);
SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);

return smc->pre_5_2_numa_associativity ||
machine->numa_state->num_nodes <= 1;
}

static void add_str(GString *s, const gchar *s1)
{
g_string_append_len(s, s1, strlen(s1) + 1);
Expand Down Expand Up @@ -791,7 +782,6 @@ static void spapr_dt_cpus(void *fdt, SpaprMachineState *spapr)
CPUState *cs;
int n_cpus;
int cpus_offset;
char *nodename;
int i;

cpus_offset = fdt_add_subnode(fdt, 0, "cpus");
Expand Down Expand Up @@ -819,6 +809,7 @@ static void spapr_dt_cpus(void *fdt, SpaprMachineState *spapr)
PowerPCCPU *cpu = POWERPC_CPU(cs);
int index = spapr_get_vcpu_id(cpu);
DeviceClass *dc = DEVICE_GET_CLASS(cs);
g_autofree char *nodename = NULL;
int offset;

if (!spapr_is_thread0_in_vcore(spapr, cpu)) {
Expand All @@ -827,7 +818,6 @@ static void spapr_dt_cpus(void *fdt, SpaprMachineState *spapr)

nodename = g_strdup_printf("%s@%x", dc->fw_name, index);
offset = fdt_add_subnode(fdt, cpus_offset, nodename);
g_free(nodename);
_FDT(offset);
spapr_dt_cpu(cs, fdt, offset, spapr);
}
Expand Down Expand Up @@ -2780,16 +2770,7 @@ static void spapr_machine_init(MachineState *machine)

}

/*
* NVLink2-connected GPU RAM needs to be placed on a separate NUMA node.
* We assign a new numa ID per GPU in spapr_pci_collect_nvgpu() which is
* called from vPHB reset handler so we initialize the counter here.
* If no NUMA is configured from the QEMU side, we start from 1 as GPU RAM
* must be equally distant from any other node.
* The final value of spapr->gpu_numa_id is going to be written to
* max-associativity-domains in spapr_build_fdt().
*/
spapr->gpu_numa_id = MAX(1, machine->numa_state->num_nodes);
spapr->gpu_numa_id = spapr_numa_initial_nvgpu_numa_id(machine);

/* Init numa_assoc_array */
spapr_numa_associativity_init(spapr, machine);
Expand Down Expand Up @@ -3055,6 +3036,7 @@ static char *spapr_get_fw_dev_path(FWPathProvider *p, BusState *bus,
SCSIDevice *d = CAST(SCSIDevice, dev, TYPE_SCSI_DEVICE);
SpaprPhbState *phb = CAST(SpaprPhbState, dev, TYPE_SPAPR_PCI_HOST_BRIDGE);
VHostSCSICommon *vsc = CAST(VHostSCSICommon, dev, TYPE_VHOST_SCSI_COMMON);
PCIDevice *pcidev = CAST(PCIDevice, dev, TYPE_PCI_DEVICE);

if (d) {
void *spapr = CAST(void, bus->parent, "spapr-vscsi");
Expand Down Expand Up @@ -3128,6 +3110,10 @@ static char *spapr_get_fw_dev_path(FWPathProvider *p, BusState *bus,
return g_strdup_printf("pci@%x", PCI_SLOT(pcidev->devfn));
}

if (pcidev) {
return spapr_pci_fw_dev_name(pcidev);
}

return NULL;
}

Expand Down Expand Up @@ -3749,15 +3735,27 @@ int spapr_core_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
PowerPCCPU *cpu = POWERPC_CPU(cs);
DeviceClass *dc = DEVICE_GET_CLASS(cs);
int id = spapr_get_vcpu_id(cpu);
char *nodename;
g_autofree char *nodename = NULL;
int offset;

nodename = g_strdup_printf("%s@%x", dc->fw_name, id);
offset = fdt_add_subnode(fdt, 0, nodename);
g_free(nodename);

spapr_dt_cpu(cs, fdt, offset, spapr);

/*
* spapr_dt_cpu() does not fill the 'name' property in the
* CPU node. The function is called during boot process, before
* and after CAS, and overwriting the 'name' property written
* by SLOF is not allowed.
*
* Write it manually after spapr_dt_cpu(). This makes the hotplug
* CPUs more compatible with the coldplugged ones, which have
* the 'name' property. Linux Kernel also relies on this
* property to identify CPU nodes.
*/
_FDT((fdt_setprop_string(fdt, offset, "name", nodename)));

*fdt_start_offset = offset;
return 0;
}
Expand Down

0 comments on commit 7b2c4cd

Please sign in to comment.