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
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEdfRlhq5hpmzETofcbDjKyiDZs5IFAmAjelUACgkQbDjKyiDZ
 s5JmcBAAjtwD51w82MLCN7dqC6Har/i40tcoxRPafMk6aOn1Sxif58PQF270hDGv
 Y3fYJ7q4XB1DHK+lpGw+KgEciKukRLnISTSyXCw6T1gE4PSc+xkf+AGzrKgJHcs4
 vbS8JaGysgWogW+uDJttxteYAhoYCB3UqgpXwkINXydd7dhkL80OtypjhSemQ9K9
 nF8AatUkdRrsE2fFCJXaxplm9l1SN3jNB+pA0VOhOyjE9fAH9j4dpE/EwIn27O/k
 32Yw2psxe51LY8RmhuP2OO8qp3VfnlLODioLvnU2BVrUSdP6f9IURfMBbAfQ3Ege
 i1OOw7IFfcX1PDuDuvjD2TI11fpLl3O4hS9wtxIdg/fHZtZlApz6MTDtGkB53agD
 5/UKBhZqvJfyBlZYbWl51Yp2pmFSlLmjAOynZWyx8jpy0uwghXETebXyFdE82ZVW
 YhHqx9XOttbeY2F/6HyZ0f5MKNFvWcUcYI+MsiZgORQVD2gVly1dN8P/yUJUkeWI
 ZwkYT3AhJK8Cg0hQepIJ2jO/raoSp7JyoseBh3suC1cYBZrT9tXzmJWsKbFeaLbi
 /BGiIpag/d3EXi8AJKO47CbAaAz+PYaof7v1dIgJxdpmgBgduteNZNdp7te6zgMv
 mEeAPM3Y02IZFXUtB1dIK9LLYBRwOuhR73YJn2NMzkfy9M+Uf/0=
 =udvb
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/dg-gitlab/tags/ppc-for-6.0-20210210' 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>
This commit is contained in:
Peter Maydell 2021-02-10 13:38:27 +00:00
commit 7b2c4cdd79
20 changed files with 150 additions and 77 deletions

View File

@ -24,6 +24,7 @@
#include "hw/ppc/xive_regs.h" #include "hw/ppc/xive_regs.h"
#include "hw/qdev-properties.h" #include "hw/qdev-properties.h"
#include "hw/ppc/ppc.h" #include "hw/ppc/ppc.h"
#include "trace.h"
#include <libfdt.h> #include <libfdt.h>
@ -1319,6 +1320,8 @@ static void pnv_xive_ic_hw_trigger(PnvXive *xive, hwaddr addr, uint64_t val)
uint8_t blk; uint8_t blk;
uint32_t idx; uint32_t idx;
trace_pnv_xive_ic_hw_trigger(addr, val);
if (val & XIVE_TRIGGER_END) { if (val & XIVE_TRIGGER_END) {
xive_error(xive, "IC: END trigger at @0x%"HWADDR_PRIx" data 0x%"PRIx64, xive_error(xive, "IC: END trigger at @0x%"HWADDR_PRIx" data 0x%"PRIx64,
addr, val); addr, val);

View File

@ -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_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_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 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

View File

@ -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); 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, end_idx,
pq & XIVE_ESB_VAL_P ? 'P' : '-', pq & XIVE_ESB_VAL_P ? 'P' : '-',
pq & XIVE_ESB_VAL_Q ? 'Q' : '-', pq & XIVE_ESB_VAL_Q ? 'Q' : '-',
@ -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_escalate(end) ? 'e' : '-',
xive_end_is_uncond_escalation(end) ? 'u' : '-', xive_end_is_uncond_escalation(end) ? 'u' : '-',
xive_end_is_silent_escalation(end) ? 's' : '-', xive_end_is_silent_escalation(end) ? 's' : '-',
xive_end_is_firmware(end) ? 'f' : '-',
priority, nvt_blk, nvt_idx); priority, nvt_blk, nvt_idx);
if (qaddr_base) { if (qaddr_base) {

View File

@ -502,7 +502,7 @@ ssize_t etsec_rx_ring_write(eTSEC *etsec, const uint8_t *buf, size_t size)
return -1; 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 */ /* CRC is not in the packet yet, so short frame is below 60 bytes */
RING_DEBUG("%s: Drop short frame\n", __func__); RING_DEBUG("%s: Drop short frame\n", __func__);
return -1; return -1;

View File

@ -22,6 +22,7 @@
#include "hw/irq.h" #include "hw/irq.h"
#include "hw/qdev-properties.h" #include "hw/qdev-properties.h"
#include "qom/object.h" #include "qom/object.h"
#include "trace.h"
#define phb_error(phb, fmt, ...) \ #define phb_error(phb, fmt, ...) \
qemu_log_mask(LOG_GUEST_ERROR, "phb4[%d:%d]: " fmt "\n", \ qemu_log_mask(LOG_GUEST_ERROR, "phb4[%d:%d]: " fmt "\n", \
@ -1257,6 +1258,8 @@ static void pnv_phb4_xive_notify(XiveNotifier *xf, uint32_t srcno)
uint64_t data = XIVE_TRIGGER_PQ | offset | srcno; uint64_t data = XIVE_TRIGGER_PQ | offset | srcno;
MemTxResult result; MemTxResult result;
trace_pnv_phb4_xive_notify(notif_port, data);
address_space_stq_be(&address_space_memory, notif_port, data, address_space_stq_be(&address_space_memory, notif_port, data,
MEMTXATTRS_UNSPECIFIED, &result); MEMTXATTRS_UNSPECIFIED, &result);
if (result != MEMTX_OK) { if (result != MEMTX_OK) {

View File

@ -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_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_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 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

View File

@ -74,6 +74,8 @@
#define MPC8544_I2C_IRQ 43 #define MPC8544_I2C_IRQ 43
#define RTC_REGS_OFFSET 0x68 #define RTC_REGS_OFFSET 0x68
#define PLATFORM_CLK_FREQ_HZ (400 * 1000 * 1000)
struct boot_info struct boot_info
{ {
uint32_t dt_base; uint32_t dt_base;
@ -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_string(fdt, ser, "compatible", "ns16550");
qemu_fdt_setprop_cells(fdt, ser, "reg", offset, 0x100); qemu_fdt_setprop_cells(fdt, ser, "reg", offset, 0x100);
qemu_fdt_setprop_cell(fdt, ser, "cell-index", idx); 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_cells(fdt, ser, "interrupts", 42, 2);
qemu_fdt_setprop_phandle(fdt, ser, "interrupt-parent", mpic); qemu_fdt_setprop_phandle(fdt, ser, "interrupt-parent", mpic);
qemu_fdt_setprop_string(fdt, "/aliases", alias, ser); qemu_fdt_setprop_string(fdt, "/aliases", alias, ser);
@ -320,8 +322,8 @@ static int ppce500_load_device_tree(PPCE500MachineState *pms,
int fdt_size; int fdt_size;
void *fdt; void *fdt;
uint8_t hypercall[16]; uint8_t hypercall[16];
uint32_t clock_freq = 400000000; uint32_t clock_freq = PLATFORM_CLK_FREQ_HZ;
uint32_t tb_freq = 400000000; uint32_t tb_freq = PLATFORM_CLK_FREQ_HZ;
int i; int i;
char compatible_sb[] = "fsl,mpc8544-immr\0simple-bus"; char compatible_sb[] = "fsl,mpc8544-immr\0simple-bus";
char *soc; char *soc;
@ -890,7 +892,7 @@ void ppce500_init(MachineState *machine)
env->spr_cb[SPR_BOOKE_PIR].default_value = cs->cpu_index = i; env->spr_cb[SPR_BOOKE_PIR].default_value = cs->cpu_index = i;
env->mpic_iack = pmc->ccsrbar_base + MPC8544_MPIC_REGS_OFFSET + 0xa0; 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 */ /* Register reset handler */
if (!i) { if (!i) {

View File

@ -21,6 +21,7 @@
#include "qemu-common.h" #include "qemu-common.h"
#include "qemu/datadir.h" #include "qemu/datadir.h"
#include "qemu/units.h" #include "qemu/units.h"
#include "qemu/cutils.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "sysemu/qtest.h" #include "sysemu/qtest.h"
#include "sysemu/sysemu.h" #include "sysemu/sysemu.h"
@ -65,9 +66,9 @@
#define FW_MAX_SIZE (16 * MiB) #define FW_MAX_SIZE (16 * MiB)
#define KERNEL_LOAD_ADDR 0x20000000 #define KERNEL_LOAD_ADDR 0x20000000
#define KERNEL_MAX_SIZE (256 * MiB) #define KERNEL_MAX_SIZE (128 * MiB)
#define INITRD_LOAD_ADDR 0x60000000 #define INITRD_LOAD_ADDR 0x28000000
#define INITRD_MAX_SIZE (256 * MiB) #define INITRD_MAX_SIZE (128 * MiB)
static const char *pnv_chip_core_typename(const PnvChip *o) static const char *pnv_chip_core_typename(const PnvChip *o)
{ {
@ -725,8 +726,11 @@ static void pnv_init(MachineState *machine)
DeviceState *dev; DeviceState *dev;
/* allocate RAM */ /* allocate RAM */
if (machine->ram_size < (1 * GiB)) { if (machine->ram_size < mc->default_ram_size) {
warn_report("skiboot may not work with < 1GB of RAM"); 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); memory_region_add_subregion(get_system_memory(), 0, machine->ram);
@ -871,6 +875,14 @@ static void pnv_init(MachineState *machine)
pnv_ipmi_bt_init(pnv->isa_bus, pnv->bmc, 10); 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 * OpenPOWER systems use a IPMI SEL Event message to notify the
* host to powerdown * host to powerdown
@ -1150,6 +1162,7 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp)
qdev_realize(DEVICE(&chip8->lpc), NULL, &error_fatal); qdev_realize(DEVICE(&chip8->lpc), NULL, &error_fatal);
pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, &chip8->lpc.xscom_regs); 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", chip->dt_isa_nodename = g_strdup_printf("/xscom@%" PRIx64 "/isa@%x",
(uint64_t) PNV_XSCOM_BASE(chip), (uint64_t) PNV_XSCOM_BASE(chip),
PNV_XSCOM_LPC_BASE); PNV_XSCOM_LPC_BASE);
@ -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), memory_region_add_subregion(get_system_memory(), PNV9_LPCM_BASE(chip),
&chip9->lpc.xscom_regs); &chip9->lpc.xscom_regs);
chip->fw_mr = &chip9->lpc.isa_fw;
chip->dt_isa_nodename = g_strdup_printf("/lpcm-opb@%" PRIx64 "/lpc@0", chip->dt_isa_nodename = g_strdup_printf("/lpcm-opb@%" PRIx64 "/lpc@0",
(uint64_t) PNV9_LPCM_BASE(chip)); (uint64_t) PNV9_LPCM_BASE(chip));
@ -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), memory_region_add_subregion(get_system_memory(), PNV10_LPCM_BASE(chip),
&chip10->lpc.xscom_regs); &chip10->lpc.xscom_regs);
chip->fw_mr = &chip10->lpc.isa_fw;
chip->dt_isa_nodename = g_strdup_printf("/lpcm-opb@%" PRIx64 "/lpc@0", chip->dt_isa_nodename = g_strdup_printf("/lpcm-opb@%" PRIx64 "/lpc@0",
(uint64_t) PNV10_LPCM_BASE(chip)); (uint64_t) PNV10_LPCM_BASE(chip));
} }
@ -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 * RAM defaults to less than 2048 for 32-bit hosts, and large
* enough to fit the maximum initrd size at it's load address * 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"; mc->default_ram_id = "pnv.ram";
ispc->print_info = pnv_pic_print_info; ispc->print_info = pnv_pic_print_info;
nc->nmi_monitor_handler = pnv_nmi; nc->nmi_monitor_handler = pnv_nmi;

View File

@ -51,6 +51,11 @@ typedef struct OemSel {
#define SOFT_OFF 0x00 #define SOFT_OFF 0x00
#define SOFT_REBOOT 0x01 #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) static void pnv_gen_oem_sel(IPMIBmc *bmc, uint8_t reboot)
{ {
/* IPMI SEL Event are 16 bytes long */ /* IPMI SEL Event are 16 bytes long */
@ -79,6 +84,10 @@ void pnv_dt_bmc_sensors(IPMIBmc *bmc, void *fdt)
const struct ipmi_sdr_compact *sdr; const struct ipmi_sdr_compact *sdr;
uint16_t nextrec; uint16_t nextrec;
if (!pnv_bmc_is_simulator(bmc)) {
return;
}
offset = fdt_add_subnode(fdt, 0, "bmc"); offset = fdt_add_subnode(fdt, 0, "bmc");
_FDT(offset); _FDT(offset);
@ -243,6 +252,10 @@ static const IPMINetfn hiomap_netfn = {
void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor) void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor)
{ {
if (!pnv_bmc_is_simulator(bmc)) {
return;
}
object_ref(OBJECT(pnor)); object_ref(OBJECT(pnor));
object_property_add_const_link(OBJECT(bmc), "pnor", OBJECT(pnor)); object_property_add_const_link(OBJECT(bmc), "pnor", OBJECT(pnor));
@ -260,13 +273,8 @@ IPMIBmc *pnv_bmc_create(PnvPnor *pnor)
Object *obj; Object *obj;
obj = object_new(TYPE_IPMI_BMC_SIMULATOR); 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); qdev_realize(DEVICE(obj), NULL, &error_fatal);
pnv_bmc_set_pnor(IPMI_BMC(obj), pnor);
/* Install the HIOMAP protocol handlers to access the PNOR */
ipmi_sim_register_netfn(IPMI_BMC_SIMULATOR(obj), IPMI_NETFN_OEM,
&hiomap_netfn);
return IPMI_BMC(obj); return IPMI_BMC(obj);
} }
@ -291,7 +299,7 @@ static int bmc_find(Object *child, void *opaque)
IPMIBmc *pnv_bmc_find(Error **errp) IPMIBmc *pnv_bmc_find(Error **errp)
{ {
ForeachArgs args = { TYPE_IPMI_BMC_SIMULATOR, NULL }; ForeachArgs args = { TYPE_IPMI_BMC, NULL };
int ret; int ret;
ret = object_child_foreach_recursive(object_get_root(), bmc_find, &args); ret = object_child_foreach_recursive(object_get_root(), bmc_find, &args);

View File

@ -824,8 +824,6 @@ ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool use_cpld, Error **errp)
ISABus *isa_bus; ISABus *isa_bus;
qemu_irq *irqs; qemu_irq *irqs;
qemu_irq_handler handler; 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 /* let isa_bus_new() create its own bridge on SysBus otherwise
* devices specified on the command line won't find the bus and * devices specified on the command line won't find the bus and
@ -851,18 +849,5 @@ ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool use_cpld, Error **errp)
isa_bus_irqs(isa_bus, irqs); 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; return isa_bus;
} }

View File

@ -296,15 +296,6 @@ static hwaddr spapr_node0_size(MachineState *machine)
return machine->ram_size; 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) static void add_str(GString *s, const gchar *s1)
{ {
g_string_append_len(s, s1, strlen(s1) + 1); g_string_append_len(s, s1, strlen(s1) + 1);
@ -791,7 +782,6 @@ static void spapr_dt_cpus(void *fdt, SpaprMachineState *spapr)
CPUState *cs; CPUState *cs;
int n_cpus; int n_cpus;
int cpus_offset; int cpus_offset;
char *nodename;
int i; int i;
cpus_offset = fdt_add_subnode(fdt, 0, "cpus"); cpus_offset = fdt_add_subnode(fdt, 0, "cpus");
@ -819,6 +809,7 @@ static void spapr_dt_cpus(void *fdt, SpaprMachineState *spapr)
PowerPCCPU *cpu = POWERPC_CPU(cs); PowerPCCPU *cpu = POWERPC_CPU(cs);
int index = spapr_get_vcpu_id(cpu); int index = spapr_get_vcpu_id(cpu);
DeviceClass *dc = DEVICE_GET_CLASS(cs); DeviceClass *dc = DEVICE_GET_CLASS(cs);
g_autofree char *nodename = NULL;
int offset; int offset;
if (!spapr_is_thread0_in_vcore(spapr, cpu)) { if (!spapr_is_thread0_in_vcore(spapr, cpu)) {
@ -827,7 +818,6 @@ static void spapr_dt_cpus(void *fdt, SpaprMachineState *spapr)
nodename = g_strdup_printf("%s@%x", dc->fw_name, index); nodename = g_strdup_printf("%s@%x", dc->fw_name, index);
offset = fdt_add_subnode(fdt, cpus_offset, nodename); offset = fdt_add_subnode(fdt, cpus_offset, nodename);
g_free(nodename);
_FDT(offset); _FDT(offset);
spapr_dt_cpu(cs, fdt, offset, spapr); spapr_dt_cpu(cs, fdt, offset, spapr);
} }
@ -2780,16 +2770,7 @@ static void spapr_machine_init(MachineState *machine)
} }
/* spapr->gpu_numa_id = spapr_numa_initial_nvgpu_numa_id(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);
/* Init numa_assoc_array */ /* Init numa_assoc_array */
spapr_numa_associativity_init(spapr, machine); spapr_numa_associativity_init(spapr, machine);
@ -3055,6 +3036,7 @@ static char *spapr_get_fw_dev_path(FWPathProvider *p, BusState *bus,
SCSIDevice *d = CAST(SCSIDevice, dev, TYPE_SCSI_DEVICE); SCSIDevice *d = CAST(SCSIDevice, dev, TYPE_SCSI_DEVICE);
SpaprPhbState *phb = CAST(SpaprPhbState, dev, TYPE_SPAPR_PCI_HOST_BRIDGE); SpaprPhbState *phb = CAST(SpaprPhbState, dev, TYPE_SPAPR_PCI_HOST_BRIDGE);
VHostSCSICommon *vsc = CAST(VHostSCSICommon, dev, TYPE_VHOST_SCSI_COMMON); VHostSCSICommon *vsc = CAST(VHostSCSICommon, dev, TYPE_VHOST_SCSI_COMMON);
PCIDevice *pcidev = CAST(PCIDevice, dev, TYPE_PCI_DEVICE);
if (d) { if (d) {
void *spapr = CAST(void, bus->parent, "spapr-vscsi"); void *spapr = CAST(void, bus->parent, "spapr-vscsi");
@ -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)); return g_strdup_printf("pci@%x", PCI_SLOT(pcidev->devfn));
} }
if (pcidev) {
return spapr_pci_fw_dev_name(pcidev);
}
return NULL; return NULL;
} }
@ -3749,15 +3735,27 @@ int spapr_core_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr,
PowerPCCPU *cpu = POWERPC_CPU(cs); PowerPCCPU *cpu = POWERPC_CPU(cs);
DeviceClass *dc = DEVICE_GET_CLASS(cs); DeviceClass *dc = DEVICE_GET_CLASS(cs);
int id = spapr_get_vcpu_id(cpu); int id = spapr_get_vcpu_id(cpu);
char *nodename; g_autofree char *nodename = NULL;
int offset; int offset;
nodename = g_strdup_printf("%s@%x", dc->fw_name, id); nodename = g_strdup_printf("%s@%x", dc->fw_name, id);
offset = fdt_add_subnode(fdt, 0, nodename); offset = fdt_add_subnode(fdt, 0, nodename);
g_free(nodename);
spapr_dt_cpu(cs, fdt, offset, spapr); 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; *fdt_start_offset = offset;
return 0; return 0;
} }

View File

@ -19,6 +19,15 @@
/* Moved from hw/ppc/spapr_pci_nvlink2.c */ /* Moved from hw/ppc/spapr_pci_nvlink2.c */
#define SPAPR_GPU_NUMA_ID (cpu_to_be32(1)) #define SPAPR_GPU_NUMA_ID (cpu_to_be32(1))
static 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 bool spapr_numa_is_symmetrical(MachineState *ms) static bool spapr_numa_is_symmetrical(MachineState *ms)
{ {
int src, dst; int src, dst;
@ -37,6 +46,20 @@ static bool spapr_numa_is_symmetrical(MachineState *ms)
return true; return true;
} }
/*
* 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().
*/
unsigned int spapr_numa_initial_nvgpu_numa_id(MachineState *machine)
{
return MAX(1, machine->numa_state->num_nodes);
}
/* /*
* This function will translate the user distances into * This function will translate the user distances into
* what the kernel understand as possible values: 10 * what the kernel understand as possible values: 10
@ -288,6 +311,8 @@ void spapr_numa_write_rtas_dt(SpaprMachineState *spapr, void *fdt, int rtas)
{ {
MachineState *ms = MACHINE(spapr); MachineState *ms = MACHINE(spapr);
SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
uint32_t number_nvgpus_nodes = spapr->gpu_numa_id -
spapr_numa_initial_nvgpu_numa_id(ms);
uint32_t refpoints[] = { uint32_t refpoints[] = {
cpu_to_be32(0x4), cpu_to_be32(0x4),
cpu_to_be32(0x3), cpu_to_be32(0x3),
@ -295,7 +320,7 @@ void spapr_numa_write_rtas_dt(SpaprMachineState *spapr, void *fdt, int rtas)
cpu_to_be32(0x1), cpu_to_be32(0x1),
}; };
uint32_t nr_refpoints = ARRAY_SIZE(refpoints); uint32_t nr_refpoints = ARRAY_SIZE(refpoints);
uint32_t maxdomain = ms->numa_state->num_nodes + spapr->gpu_numa_id; uint32_t maxdomain = ms->numa_state->num_nodes + number_nvgpus_nodes;
uint32_t maxdomains[] = { uint32_t maxdomains[] = {
cpu_to_be32(4), cpu_to_be32(4),
cpu_to_be32(maxdomain), cpu_to_be32(maxdomain),

View File

@ -1344,15 +1344,29 @@ static int spapr_dt_pci_bus(SpaprPhbState *sphb, PCIBus *bus,
return offset; return offset;
} }
char *spapr_pci_fw_dev_name(PCIDevice *dev)
{
const gchar *basename;
int slot = PCI_SLOT(dev->devfn);
int func = PCI_FUNC(dev->devfn);
uint32_t ccode = pci_default_read_config(dev, PCI_CLASS_PROG, 3);
basename = dt_name_from_class((ccode >> 16) & 0xff, (ccode >> 8) & 0xff,
ccode & 0xff);
if (func != 0) {
return g_strdup_printf("%s@%x,%x", basename, slot, func);
} else {
return g_strdup_printf("%s@%x", basename, slot);
}
}
/* create OF node for pci device and required OF DT properties */ /* create OF node for pci device and required OF DT properties */
static int spapr_dt_pci_device(SpaprPhbState *sphb, PCIDevice *dev, static int spapr_dt_pci_device(SpaprPhbState *sphb, PCIDevice *dev,
void *fdt, int parent_offset) void *fdt, int parent_offset)
{ {
int offset; int offset;
const gchar *basename; g_autofree gchar *nodename = spapr_pci_fw_dev_name(dev);
gchar *nodename;
int slot = PCI_SLOT(dev->devfn);
int func = PCI_FUNC(dev->devfn);
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
ResourceProps rp; ResourceProps rp;
SpaprDrc *drc = drc_from_dev(sphb, dev); SpaprDrc *drc = drc_from_dev(sphb, dev);
@ -1369,19 +1383,8 @@ static int spapr_dt_pci_device(SpaprPhbState *sphb, PCIDevice *dev,
uint32_t pci_status = pci_default_read_config(dev, PCI_STATUS, 2); uint32_t pci_status = pci_default_read_config(dev, PCI_STATUS, 2);
gchar *loc_code; gchar *loc_code;
basename = dt_name_from_class((ccode >> 16) & 0xff, (ccode >> 8) & 0xff,
ccode & 0xff);
if (func != 0) {
nodename = g_strdup_printf("%s@%x,%x", basename, slot, func);
} else {
nodename = g_strdup_printf("%s@%x", basename, slot);
}
_FDT(offset = fdt_add_subnode(fdt, parent_offset, nodename)); _FDT(offset = fdt_add_subnode(fdt, parent_offset, nodename));
g_free(nodename);
/* in accordance with PAPR+ v2.7 13.6.3, Table 181 */ /* in accordance with PAPR+ v2.7 13.6.3, Table 181 */
_FDT(fdt_setprop_cell(fdt, offset, "vendor-id", vendor_id)); _FDT(fdt_setprop_cell(fdt, offset, "vendor-id", vendor_id));
_FDT(fdt_setprop_cell(fdt, offset, "device-id", device_id)); _FDT(fdt_setprop_cell(fdt, offset, "device-id", device_id));

View File

@ -210,4 +210,6 @@ static inline unsigned spapr_phb_windows_supported(SpaprPhbState *sphb)
return sphb->ddw_enabled ? SPAPR_PCI_DMA_MAX_WINDOWS : 1; return sphb->ddw_enabled ? SPAPR_PCI_DMA_MAX_WINDOWS : 1;
} }
char *spapr_pci_fw_dev_name(PCIDevice *dev);
#endif /* PCI_HOST_SPAPR_H */ #endif /* PCI_HOST_SPAPR_H */

View File

@ -58,6 +58,7 @@ struct PnvChip {
MemoryRegion xscom; MemoryRegion xscom;
AddressSpace xscom_as; AddressSpace xscom_as;
MemoryRegion *fw_mr;
gchar *dt_isa_nodename; gchar *dt_isa_nodename;
}; };

View File

@ -851,7 +851,6 @@ int spapr_max_server_number(SpaprMachineState *spapr);
void spapr_store_hpte(PowerPCCPU *cpu, hwaddr ptex, void spapr_store_hpte(PowerPCCPU *cpu, hwaddr ptex,
uint64_t pte0, uint64_t pte1); uint64_t pte0, uint64_t pte1);
void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered); void spapr_mce_req_event(PowerPCCPU *cpu, bool recovered);
bool spapr_machine_using_legacy_numa(SpaprMachineState *spapr);
/* DRC callbacks. */ /* DRC callbacks. */
void spapr_core_release(DeviceState *dev); void spapr_core_release(DeviceState *dev);

View File

@ -31,5 +31,6 @@ int spapr_numa_fixup_cpu_dt(SpaprMachineState *spapr, void *fdt,
int offset, PowerPCCPU *cpu); int offset, PowerPCCPU *cpu);
int spapr_numa_write_assoc_lookup_arrays(SpaprMachineState *spapr, void *fdt, int spapr_numa_write_assoc_lookup_arrays(SpaprMachineState *spapr, void *fdt,
int offset); int offset);
unsigned int spapr_numa_initial_nvgpu_numa_id(MachineState *machine);
#endif /* HW_SPAPR_NUMA_H */ #endif /* HW_SPAPR_NUMA_H */

View File

@ -236,6 +236,8 @@ typedef struct XiveEND {
(be32_to_cpu((end)->w0) & END_W0_UNCOND_ESCALATE) (be32_to_cpu((end)->w0) & END_W0_UNCOND_ESCALATE)
#define xive_end_is_silent_escalation(end) \ #define xive_end_is_silent_escalation(end) \
(be32_to_cpu((end)->w0) & END_W0_SILENT_ESCALATE) (be32_to_cpu((end)->w0) & END_W0_SILENT_ESCALATE)
#define xive_end_is_firmware(end) \
(be32_to_cpu((end)->w0) & END_W0_FIRMWARE)
static inline uint64_t xive_end_qaddr(XiveEND *end) static inline uint64_t xive_end_qaddr(XiveEND *end)
{ {

View File

@ -1919,6 +1919,7 @@ typedef PowerPCCPU ArchCPU;
#define SPR_750FX_HID2 (0x3F8) #define SPR_750FX_HID2 (0x3F8)
#define SPR_Exxx_L1FINV0 (0x3F8) #define SPR_Exxx_L1FINV0 (0x3F8)
#define SPR_L2CR (0x3F9) #define SPR_L2CR (0x3F9)
#define SPR_Exxx_L2CSR0 (0x3F9)
#define SPR_L3CR (0x3FA) #define SPR_L3CR (0x3FA)
#define SPR_750_TDCH (0x3FA) #define SPR_750_TDCH (0x3FA)
#define SPR_IABR2 (0x3FA) #define SPR_IABR2 (0x3FA)
@ -1974,6 +1975,11 @@ typedef PowerPCCPU ArchCPU;
#define L1CSR1_ICFI 0x00000002 /* Instruction Cache Flash Invalidate */ #define L1CSR1_ICFI 0x00000002 /* Instruction Cache Flash Invalidate */
#define L1CSR1_ICE 0x00000001 /* Instruction Cache Enable */ #define L1CSR1_ICE 0x00000001 /* Instruction Cache Enable */
/* E500 L2CSR0 */
#define E500_L2CSR0_L2FI (1 << 21) /* L2 cache flash invalidate */
#define E500_L2CSR0_L2FL (1 << 11) /* L2 cache flush */
#define E500_L2CSR0_L2LFC (1 << 10) /* L2 cache lock flash clear */
/* HID0 bits */ /* HID0 bits */
#define HID0_DEEPNAP (1 << 24) /* pre-2.06 */ #define HID0_DEEPNAP (1 << 24) /* pre-2.06 */
#define HID0_DOZE (1 << 23) /* pre-2.06 */ #define HID0_DOZE (1 << 23) /* pre-2.06 */
@ -2205,9 +2211,6 @@ enum {
* may be needed for precise access rights control and precise exceptions. * may be needed for precise access rights control and precise exceptions.
*/ */
enum { enum {
/* 1 bit to define user level / supervisor access */
ACCESS_USER = 0x00,
ACCESS_SUPER = 0x01,
/* Type of instruction that generated the access */ /* Type of instruction that generated the access */
ACCESS_CODE = 0x10, /* Code fetch access */ ACCESS_CODE = 0x10, /* Code fetch access */
ACCESS_INT = 0x20, /* Integer load/store access */ ACCESS_INT = 0x20, /* Integer load/store access */

View File

@ -1735,6 +1735,16 @@ static void spr_write_e500_l1csr1(DisasContext *ctx, int sprn, int gprn)
tcg_temp_free(t0); tcg_temp_free(t0);
} }
static void spr_write_e500_l2csr0(DisasContext *ctx, int sprn, int gprn)
{
TCGv t0 = tcg_temp_new();
tcg_gen_andi_tl(t0, cpu_gpr[gprn],
~(E500_L2CSR0_L2FI | E500_L2CSR0_L2FL | E500_L2CSR0_L2LFC));
gen_store_spr(sprn, t0);
tcg_temp_free(t0);
}
static void spr_write_booke206_mmucsr0(DisasContext *ctx, int sprn, int gprn) static void spr_write_booke206_mmucsr0(DisasContext *ctx, int sprn, int gprn)
{ {
gen_helper_booke206_tlbflush(cpu_env, cpu_gpr[gprn]); gen_helper_booke206_tlbflush(cpu_env, cpu_gpr[gprn]);
@ -5029,6 +5039,12 @@ static void init_proc_e500(CPUPPCState *env, int version)
SPR_NOACCESS, SPR_NOACCESS, SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_e500_l1csr1, &spr_read_generic, &spr_write_e500_l1csr1,
0x00000000); 0x00000000);
if (version != fsl_e500v1 && version != fsl_e500v2) {
spr_register(env, SPR_Exxx_L2CSR0, "L2CSR0",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_e500_l2csr0,
0x00000000);
}
spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0", spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
SPR_NOACCESS, SPR_NOACCESS, SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic, &spr_read_generic, &spr_write_generic,