ppc patch queue 2021-08-27
First ppc pull request for qemu-6.2. As usual, there's a fair bit here, since it's been queued during the 6.1 freeze. Highlights are: * Some fixes for 128 bit arithmetic and some vector opcodes that use them * Significant improvements to the powernv to support POWER10 cpus (more to come though) * Several cleanups to the ppc softmmu code * A few other assorted fixes -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEdfRlhq5hpmzETofcbDjKyiDZs5IFAmEoj5gACgkQbDjKyiDZ s5JFPw/+JOmi1G6eY3u/kYJ8TJhe65s6TJDQhGQiQSBoBShRBJ1+bro3fPGA8pkT 48NAb9RnTnLqys+vhScF7qt2wIxXJFVoVyMhAj2Xv11VQzDPpbLGg6+2Qt7WFraQ zyeEKBQQTV29RtV7UBUEmx4ZGmnoc0cmzl3QGO3Jq17ucOHNTSW19QpxU60wClU1 PZIUDoWdt7FBS8lvj/55736H3z6ZRnBqZtW9m64ln+CBQuuKo5UkAkaooaJhEFJx OUZYeo+zky8YaYSWwTFGIxBYhwptnAWCsqkzeJUxPw1ICAzwj/kQX7ckVhbgTpbE CADpgkATXTbQzLFipzxJ45UMP0yMsk5IOPZ6FS9G+JfsP2T92RMwy7XhqPfWCoov WKqX/xpmGTnJONuQ7SO/bWUyPH4K7hYgSPPlLAcwDYCg4szWRIbTCs9Yr9rzAPhk KqKUGLb7D7Rbi1ulSC2ieqsTqVmp6plfnjxR2gPcbp0FltqGln6tVZEHEyPjTEv0 5b7w+3AHDwh9a4NyzULaxxBKktNU1KXKe74/U86qhJtx4kXFSkAhoeztcR30zmUX W1xjb5eoRgFbHnoDTCtDYAUwuz2w1/I2OLA5kfnSQnRQS0YiqUeicbBkW6iIE61z oM86ZwEQX1lyf7agECRgpfdcPa6uyAQ72QUR5wgvXDW59PSNNxk= =C5XY -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/dg-gitlab/tags/ppc-for-6.2-20210827' into staging ppc patch queue 2021-08-27 First ppc pull request for qemu-6.2. As usual, there's a fair bit here, since it's been queued during the 6.1 freeze. Highlights are: * Some fixes for 128 bit arithmetic and some vector opcodes that use them * Significant improvements to the powernv to support POWER10 cpus (more to come though) * Several cleanups to the ppc softmmu code * A few other assorted fixes # gpg: Signature made Fri 27 Aug 2021 08:09:12 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.2-20210827: target/ppc: fix vector registers access in gdbstub for little-endian include/qemu/int128.h: introduce bswap128s target/ppc: fix vextu[bhw][lr]x helpers include/qemu/int128.h: define struct Int128 according to the host endianness ppc/xive: Export xive_presenter_notify() ppc/xive: Export PQ get/set routines ppc/pnv: add a chip topology index for POWER10 ppc/pnv: Distribute RAM among the chips ppc/pnv: Use a simple incrementing index for the chip-id ppc/pnv: powerpc_excp: Do not discard HDECR exception when entering power-saving mode ppc/pnv: Change the POWER10 machine to support DD2 only ppc: Add a POWER10 DD2 CPU ppc/pnv: update skiboot to commit 820d43c0a775. target/ppc: moved store_40x_sler to helper_regs.c target/ppc: moved ppc_store_sdr1 to mmu_common.c target/ppc: divided mmu_helper.c in 2 files spapr_pci: Fix leak in spapr_phb_vfio_get_loc_code() with g_autofree xive: Remove extra '0x' prefix in trace events Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
ad22d05833
@ -297,7 +297,7 @@ static uint8_t xive_esb_read(XiveSource *xsrc, int srcno, uint32_t offset)
|
||||
return xive_esb_rw(xsrc, srcno, offset, 0, 0) & 0x3;
|
||||
}
|
||||
|
||||
static void xive_esb_trigger(XiveSource *xsrc, int srcno)
|
||||
static void kvmppc_xive_esb_trigger(XiveSource *xsrc, int srcno)
|
||||
{
|
||||
uint64_t *addr = xsrc->esb_mmap + xive_source_esb_page(xsrc, srcno);
|
||||
|
||||
@ -322,7 +322,7 @@ uint64_t kvmppc_xive_esb_rw(XiveSource *xsrc, int srcno, uint32_t offset,
|
||||
offset == XIVE_ESB_LOAD_EOI) {
|
||||
xive_esb_read(xsrc, srcno, XIVE_ESB_SET_PQ_00);
|
||||
if (xsrc->status[srcno] & XIVE_STATUS_ASSERTED) {
|
||||
xive_esb_trigger(xsrc, srcno);
|
||||
kvmppc_xive_esb_trigger(xsrc, srcno);
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
@ -366,7 +366,7 @@ void kvmppc_xive_source_set_irq(void *opaque, int srcno, int val)
|
||||
}
|
||||
}
|
||||
|
||||
xive_esb_trigger(xsrc, srcno);
|
||||
kvmppc_xive_esb_trigger(xsrc, srcno);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -533,7 +533,7 @@ static void kvmppc_xive_change_state_handler(void *opaque, bool running,
|
||||
* generate a trigger.
|
||||
*/
|
||||
if (pq == XIVE_ESB_RESET && old_pq == XIVE_ESB_QUEUED) {
|
||||
xive_esb_trigger(xsrc, i);
|
||||
kvmppc_xive_esb_trigger(xsrc, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,14 +219,14 @@ kvm_xive_source_reset(uint32_t srcno) "IRQ 0x%x"
|
||||
xive_tctx_accept(uint32_t index, uint8_t ring, uint8_t ipb, uint8_t pipr, uint8_t cppr, uint8_t nsr) "target=%d ring=0x%x IBP=0x%02x PIPR=0x%02x CPPR=0x%02x NSR=0x%02x ACK"
|
||||
xive_tctx_notify(uint32_t index, uint8_t ring, uint8_t ipb, uint8_t pipr, uint8_t cppr, uint8_t nsr) "target=%d ring=0x%x IBP=0x%02x PIPR=0x%02x CPPR=0x%02x NSR=0x%02x raise !"
|
||||
xive_tctx_set_cppr(uint32_t index, uint8_t ring, uint8_t ipb, uint8_t pipr, uint8_t cppr, uint8_t nsr) "target=%d ring=0x%x IBP=0x%02x PIPR=0x%02x new CPPR=0x%02x NSR=0x%02x"
|
||||
xive_source_esb_read(uint64_t addr, uint32_t srcno, uint64_t value) "@0x0x%"PRIx64" IRQ 0x%x val=0x0x%"PRIx64
|
||||
xive_source_esb_write(uint64_t addr, uint32_t srcno, uint64_t value) "@0x0x%"PRIx64" IRQ 0x%x val=0x0x%"PRIx64
|
||||
xive_source_esb_read(uint64_t addr, uint32_t srcno, uint64_t value) "@0x%"PRIx64" IRQ 0x%x val=0x%"PRIx64
|
||||
xive_source_esb_write(uint64_t addr, uint32_t srcno, uint64_t value) "@0x%"PRIx64" IRQ 0x%x val=0x%"PRIx64
|
||||
xive_router_end_notify(uint8_t end_blk, uint32_t end_idx, uint32_t end_data) "END 0x%02x/0x%04x -> enqueue 0x%08x"
|
||||
xive_router_end_escalate(uint8_t end_blk, uint32_t end_idx, uint8_t esc_blk, uint32_t esc_idx, uint32_t end_data) "END 0x%02x/0x%04x -> escalate END 0x%02x/0x%04x data 0x%08x"
|
||||
xive_tctx_tm_write(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_tctx_tm_write(uint64_t offset, unsigned int size, uint64_t value) "@0x%"PRIx64" sz=%d val=0x%" PRIx64
|
||||
xive_tctx_tm_read(uint64_t offset, unsigned int size, uint64_t value) "@0x%"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
|
||||
xive_end_source_read(uint8_t end_blk, uint32_t end_idx, uint64_t addr) "END 0x%x/0x%x @0x%"PRIx64
|
||||
|
||||
# pnv_xive.c
|
||||
pnv_xive_ic_hw_trigger(uint64_t addr, uint64_t val) "@0x%"PRIx64" val=0x%"PRIx64
|
||||
|
@ -816,7 +816,7 @@ void xive_tctx_destroy(XiveTCTX *tctx)
|
||||
* XIVE ESB helpers
|
||||
*/
|
||||
|
||||
static uint8_t xive_esb_set(uint8_t *pq, uint8_t value)
|
||||
uint8_t xive_esb_set(uint8_t *pq, uint8_t value)
|
||||
{
|
||||
uint8_t old_pq = *pq & 0x3;
|
||||
|
||||
@ -826,7 +826,7 @@ static uint8_t xive_esb_set(uint8_t *pq, uint8_t value)
|
||||
return old_pq;
|
||||
}
|
||||
|
||||
static bool xive_esb_trigger(uint8_t *pq)
|
||||
bool xive_esb_trigger(uint8_t *pq)
|
||||
{
|
||||
uint8_t old_pq = *pq & 0x3;
|
||||
|
||||
@ -846,7 +846,7 @@ static bool xive_esb_trigger(uint8_t *pq)
|
||||
}
|
||||
}
|
||||
|
||||
static bool xive_esb_eoi(uint8_t *pq)
|
||||
bool xive_esb_eoi(uint8_t *pq)
|
||||
{
|
||||
uint8_t old_pq = *pq & 0x3;
|
||||
|
||||
@ -1514,10 +1514,10 @@ int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
|
||||
*
|
||||
* The parameters represent what is sent on the PowerBus
|
||||
*/
|
||||
static bool xive_presenter_notify(XiveFabric *xfb, uint8_t format,
|
||||
uint8_t nvt_blk, uint32_t nvt_idx,
|
||||
bool cam_ignore, uint8_t priority,
|
||||
uint32_t logic_serv)
|
||||
bool xive_presenter_notify(XiveFabric *xfb, uint8_t format,
|
||||
uint8_t nvt_blk, uint32_t nvt_idx,
|
||||
bool cam_ignore, uint8_t priority,
|
||||
uint32_t logic_serv)
|
||||
{
|
||||
XiveFabricClass *xfc = XIVE_FABRIC_GET_CLASS(xfb);
|
||||
XiveTCTXMatch match = { .tctx = NULL, .ring = 0 };
|
||||
|
48
hw/ppc/pnv.c
48
hw/ppc/pnv.c
@ -710,6 +710,23 @@ static void pnv_chip_power10_pic_print_info(PnvChip *chip, Monitor *mon)
|
||||
pnv_psi_pic_print_info(&chip10->psi, mon);
|
||||
}
|
||||
|
||||
/* Always give the first 1GB to chip 0 else we won't boot */
|
||||
static uint64_t pnv_chip_get_ram_size(PnvMachineState *pnv, int chip_id)
|
||||
{
|
||||
MachineState *machine = MACHINE(pnv);
|
||||
uint64_t ram_per_chip;
|
||||
|
||||
assert(machine->ram_size >= 1 * GiB);
|
||||
|
||||
ram_per_chip = machine->ram_size / pnv->num_chips;
|
||||
if (ram_per_chip >= 1 * GiB) {
|
||||
return QEMU_ALIGN_DOWN(ram_per_chip, 1 * MiB);
|
||||
}
|
||||
|
||||
ram_per_chip = (machine->ram_size - 1 * GiB) / (pnv->num_chips - 1);
|
||||
return chip_id == 0 ? 1 * GiB : QEMU_ALIGN_DOWN(ram_per_chip, 1 * MiB);
|
||||
}
|
||||
|
||||
static void pnv_init(MachineState *machine)
|
||||
{
|
||||
const char *bios_name = machine->firmware ?: FW_FILE_NAME;
|
||||
@ -717,6 +734,7 @@ static void pnv_init(MachineState *machine)
|
||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||
char *fw_filename;
|
||||
long fw_size;
|
||||
uint64_t chip_ram_start = 0;
|
||||
int i;
|
||||
char *chip_typename;
|
||||
DriveInfo *pnor = drive_get(IF_MTD, 0, 0);
|
||||
@ -809,9 +827,10 @@ static void pnv_init(MachineState *machine)
|
||||
* TODO: should we decide on how many chips we can create based
|
||||
* on #cores and Venice vs. Murano vs. Naples chip type etc...,
|
||||
*/
|
||||
if (!is_power_of_2(pnv->num_chips) || pnv->num_chips > 4) {
|
||||
if (!is_power_of_2(pnv->num_chips) || pnv->num_chips > 16) {
|
||||
error_report("invalid number of chips: '%d'", pnv->num_chips);
|
||||
error_printf("Try '-smp sockets=N'. Valid values are : 1, 2 or 4.\n");
|
||||
error_printf(
|
||||
"Try '-smp sockets=N'. Valid values are : 1, 2, 4, 8 and 16.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -819,22 +838,21 @@ static void pnv_init(MachineState *machine)
|
||||
for (i = 0; i < pnv->num_chips; i++) {
|
||||
char chip_name[32];
|
||||
Object *chip = OBJECT(qdev_new(chip_typename));
|
||||
int chip_id = i;
|
||||
uint64_t chip_ram_size = pnv_chip_get_ram_size(pnv, chip_id);
|
||||
|
||||
pnv->chips[i] = PNV_CHIP(chip);
|
||||
|
||||
/*
|
||||
* TODO: put all the memory in one node on chip 0 until we find a
|
||||
* way to specify different ranges for each chip
|
||||
*/
|
||||
if (i == 0) {
|
||||
object_property_set_int(chip, "ram-size", machine->ram_size,
|
||||
&error_fatal);
|
||||
}
|
||||
|
||||
snprintf(chip_name, sizeof(chip_name), "chip[%d]", PNV_CHIP_HWID(i));
|
||||
object_property_add_child(OBJECT(pnv), chip_name, chip);
|
||||
object_property_set_int(chip, "chip-id", PNV_CHIP_HWID(i),
|
||||
/* Distribute RAM among the chips */
|
||||
object_property_set_int(chip, "ram-start", chip_ram_start,
|
||||
&error_fatal);
|
||||
object_property_set_int(chip, "ram-size", chip_ram_size,
|
||||
&error_fatal);
|
||||
chip_ram_start += chip_ram_size;
|
||||
|
||||
snprintf(chip_name, sizeof(chip_name), "chip[%d]", chip_id);
|
||||
object_property_add_child(OBJECT(pnv), chip_name, chip);
|
||||
object_property_set_int(chip, "chip-id", chip_id, &error_fatal);
|
||||
object_property_set_int(chip, "nr-cores", machine->smp.cores,
|
||||
&error_fatal);
|
||||
object_property_set_int(chip, "nr-threads", machine->smp.threads,
|
||||
@ -1916,7 +1934,7 @@ static void pnv_machine_power10_class_init(ObjectClass *oc, void *data)
|
||||
static const char compat[] = "qemu,powernv10\0ibm,powernv";
|
||||
|
||||
mc->desc = "IBM PowerNV (Non-Virtualized) POWER10";
|
||||
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power10_v1.0");
|
||||
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power10_v2.0");
|
||||
|
||||
pmc->compat = compat;
|
||||
pmc->compat_size = sizeof(compat);
|
||||
|
@ -347,7 +347,7 @@ static const TypeInfo pnv_core_infos[] = {
|
||||
DEFINE_PNV_CORE_TYPE(power8, "power8_v2.0"),
|
||||
DEFINE_PNV_CORE_TYPE(power8, "power8nvl_v1.0"),
|
||||
DEFINE_PNV_CORE_TYPE(power9, "power9_v2.0"),
|
||||
DEFINE_PNV_CORE_TYPE(power10, "power10_v1.0"),
|
||||
DEFINE_PNV_CORE_TYPE(power10, "power10_v2.0"),
|
||||
};
|
||||
|
||||
DEFINE_TYPES(pnv_core_infos)
|
||||
|
@ -284,6 +284,8 @@ int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset,
|
||||
_FDT(xscom_offset);
|
||||
g_free(name);
|
||||
_FDT((fdt_setprop_cell(fdt, xscom_offset, "ibm,chip-id", chip->chip_id)));
|
||||
_FDT((fdt_setprop_cell(fdt, xscom_offset, "ibm,primary-topology-index",
|
||||
chip->chip_id)));
|
||||
_FDT((fdt_setprop_cell(fdt, xscom_offset, "#address-cells", 1)));
|
||||
_FDT((fdt_setprop_cell(fdt, xscom_offset, "#size-cells", 1)));
|
||||
_FDT((fdt_setprop(fdt, xscom_offset, "reg", reg, sizeof(reg))));
|
||||
|
@ -782,33 +782,29 @@ static AddressSpace *spapr_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
|
||||
|
||||
static char *spapr_phb_vfio_get_loc_code(SpaprPhbState *sphb, PCIDevice *pdev)
|
||||
{
|
||||
char *path = NULL, *buf = NULL, *host = NULL;
|
||||
g_autofree char *path = NULL;
|
||||
g_autofree char *host = NULL;
|
||||
g_autofree char *devspec = NULL;
|
||||
char *buf = NULL;
|
||||
|
||||
/* Get the PCI VFIO host id */
|
||||
host = object_property_get_str(OBJECT(pdev), "host", NULL);
|
||||
if (!host) {
|
||||
goto err_out;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Construct the path of the file that will give us the DT location */
|
||||
path = g_strdup_printf("/sys/bus/pci/devices/%s/devspec", host);
|
||||
g_free(host);
|
||||
if (!g_file_get_contents(path, &buf, NULL, NULL)) {
|
||||
goto err_out;
|
||||
if (!g_file_get_contents(path, &devspec, NULL, NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
g_free(path);
|
||||
|
||||
/* Construct and read from host device tree the loc-code */
|
||||
path = g_strdup_printf("/proc/device-tree%s/ibm,loc-code", buf);
|
||||
g_free(buf);
|
||||
path = g_strdup_printf("/proc/device-tree%s/ibm,loc-code", devspec);
|
||||
if (!g_file_get_contents(path, &buf, NULL, NULL)) {
|
||||
goto err_out;
|
||||
return NULL;
|
||||
}
|
||||
return buf;
|
||||
|
||||
err_out:
|
||||
g_free(path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *spapr_phb_get_loc_code(SpaprPhbState *sphb, PCIDevice *pdev)
|
||||
|
@ -170,29 +170,10 @@ DECLARE_INSTANCE_CHECKER(PnvChip, PNV_CHIP_POWER8NVL,
|
||||
DECLARE_INSTANCE_CHECKER(PnvChip, PNV_CHIP_POWER9,
|
||||
TYPE_PNV_CHIP_POWER9)
|
||||
|
||||
#define TYPE_PNV_CHIP_POWER10 PNV_CHIP_TYPE_NAME("power10_v1.0")
|
||||
#define TYPE_PNV_CHIP_POWER10 PNV_CHIP_TYPE_NAME("power10_v2.0")
|
||||
DECLARE_INSTANCE_CHECKER(PnvChip, PNV_CHIP_POWER10,
|
||||
TYPE_PNV_CHIP_POWER10)
|
||||
|
||||
/*
|
||||
* This generates a HW chip id depending on an index, as found on a
|
||||
* two socket system with dual chip modules :
|
||||
*
|
||||
* 0x0, 0x1, 0x10, 0x11
|
||||
*
|
||||
* 4 chips should be the maximum
|
||||
*
|
||||
* TODO: use a machine property to define the chip ids
|
||||
*/
|
||||
#define PNV_CHIP_HWID(i) ((((i) & 0x3e) << 3) | ((i) & 0x1))
|
||||
|
||||
/*
|
||||
* Converts back a HW chip id to an index. This is useful to calculate
|
||||
* the MMIO addresses of some controllers which depend on the chip id.
|
||||
*/
|
||||
#define PNV_CHIP_INDEX(chip) \
|
||||
(((chip)->chip_id >> 2) * 2 + ((chip)->chip_id & 0x3))
|
||||
|
||||
PowerPCCPU *pnv_chip_find_cpu(PnvChip *chip, uint32_t pir);
|
||||
|
||||
#define TYPE_PNV_MACHINE MACHINE_TYPE_NAME("powernv")
|
||||
@ -256,11 +237,11 @@ void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor);
|
||||
#define PNV_OCC_COMMON_AREA_SIZE 0x0000000000800000ull
|
||||
#define PNV_OCC_COMMON_AREA_BASE 0x7fff800000ull
|
||||
#define PNV_OCC_SENSOR_BASE(chip) (PNV_OCC_COMMON_AREA_BASE + \
|
||||
PNV_OCC_SENSOR_DATA_BLOCK_BASE(PNV_CHIP_INDEX(chip)))
|
||||
PNV_OCC_SENSOR_DATA_BLOCK_BASE((chip)->chip_id))
|
||||
|
||||
#define PNV_HOMER_SIZE 0x0000000000400000ull
|
||||
#define PNV_HOMER_BASE(chip) \
|
||||
(0x7ffd800000ull + ((uint64_t)PNV_CHIP_INDEX(chip)) * PNV_HOMER_SIZE)
|
||||
(0x7ffd800000ull + ((uint64_t)(chip)->chip_id) * PNV_HOMER_SIZE)
|
||||
|
||||
|
||||
/*
|
||||
@ -279,16 +260,16 @@ void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor);
|
||||
*/
|
||||
#define PNV_ICP_SIZE 0x0000000000100000ull
|
||||
#define PNV_ICP_BASE(chip) \
|
||||
(0x0003ffff80000000ull + (uint64_t) PNV_CHIP_INDEX(chip) * PNV_ICP_SIZE)
|
||||
(0x0003ffff80000000ull + (uint64_t) (chip)->chip_id * PNV_ICP_SIZE)
|
||||
|
||||
|
||||
#define PNV_PSIHB_SIZE 0x0000000000100000ull
|
||||
#define PNV_PSIHB_BASE(chip) \
|
||||
(0x0003fffe80000000ull + (uint64_t)PNV_CHIP_INDEX(chip) * PNV_PSIHB_SIZE)
|
||||
(0x0003fffe80000000ull + (uint64_t)(chip)->chip_id * PNV_PSIHB_SIZE)
|
||||
|
||||
#define PNV_PSIHB_FSP_SIZE 0x0000000100000000ull
|
||||
#define PNV_PSIHB_FSP_BASE(chip) \
|
||||
(0x0003ffe000000000ull + (uint64_t)PNV_CHIP_INDEX(chip) * \
|
||||
(0x0003ffe000000000ull + (uint64_t)(chip)->chip_id * \
|
||||
PNV_PSIHB_FSP_SIZE)
|
||||
|
||||
/*
|
||||
@ -324,11 +305,11 @@ void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor);
|
||||
#define PNV9_OCC_COMMON_AREA_SIZE 0x0000000000800000ull
|
||||
#define PNV9_OCC_COMMON_AREA_BASE 0x203fff800000ull
|
||||
#define PNV9_OCC_SENSOR_BASE(chip) (PNV9_OCC_COMMON_AREA_BASE + \
|
||||
PNV_OCC_SENSOR_DATA_BLOCK_BASE(PNV_CHIP_INDEX(chip)))
|
||||
PNV_OCC_SENSOR_DATA_BLOCK_BASE((chip)->chip_id))
|
||||
|
||||
#define PNV9_HOMER_SIZE 0x0000000000400000ull
|
||||
#define PNV9_HOMER_BASE(chip) \
|
||||
(0x203ffd800000ull + ((uint64_t)PNV_CHIP_INDEX(chip)) * PNV9_HOMER_SIZE)
|
||||
(0x203ffd800000ull + ((uint64_t)(chip)->chip_id) * PNV9_HOMER_SIZE)
|
||||
|
||||
/*
|
||||
* POWER10 MMIO base addresses - 16TB stride per chip
|
||||
|
@ -261,6 +261,10 @@ static inline hwaddr xive_source_esb_mgmt(XiveSource *xsrc, int srcno)
|
||||
#define XIVE_ESB_QUEUED (XIVE_ESB_VAL_P | XIVE_ESB_VAL_Q)
|
||||
#define XIVE_ESB_OFF XIVE_ESB_VAL_Q
|
||||
|
||||
bool xive_esb_trigger(uint8_t *pq);
|
||||
bool xive_esb_eoi(uint8_t *pq);
|
||||
uint8_t xive_esb_set(uint8_t *pq, uint8_t value);
|
||||
|
||||
/*
|
||||
* "magic" Event State Buffer (ESB) MMIO offsets.
|
||||
*
|
||||
@ -404,6 +408,10 @@ int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx,
|
||||
uint8_t format,
|
||||
uint8_t nvt_blk, uint32_t nvt_idx,
|
||||
bool cam_ignore, uint32_t logic_serv);
|
||||
bool xive_presenter_notify(XiveFabric *xfb, uint8_t format,
|
||||
uint8_t nvt_blk, uint32_t nvt_idx,
|
||||
bool cam_ignore, uint8_t priority,
|
||||
uint32_t logic_serv);
|
||||
|
||||
/*
|
||||
* XIVE Fabric (Interface between Interrupt Controller and Machine)
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef INT128_H
|
||||
#define INT128_H
|
||||
|
||||
#ifdef CONFIG_INT128
|
||||
#include "qemu/bswap.h"
|
||||
|
||||
#ifdef CONFIG_INT128
|
||||
typedef __int128_t Int128;
|
||||
|
||||
static inline Int128 int128_make64(uint64_t a)
|
||||
@ -155,31 +155,48 @@ static inline void int128_subfrom(Int128 *a, Int128 b)
|
||||
|
||||
static inline Int128 bswap128(Int128 a)
|
||||
{
|
||||
#if __has_builtin(__builtin_bswap128)
|
||||
return __builtin_bswap128(a);
|
||||
#else
|
||||
return int128_make128(bswap64(int128_gethi(a)), bswap64(int128_getlo(a)));
|
||||
#endif
|
||||
}
|
||||
|
||||
#else /* !CONFIG_INT128 */
|
||||
|
||||
typedef struct Int128 Int128;
|
||||
|
||||
/*
|
||||
* We guarantee that the in-memory byte representation of an
|
||||
* Int128 is that of a host-endian-order 128-bit integer
|
||||
* (whether using this struct or the __int128_t version of the type).
|
||||
* Some code using this type relies on this (eg when copying it into
|
||||
* guest memory or a gdb protocol buffer, or by using Int128 in
|
||||
* a union with other integer types).
|
||||
*/
|
||||
struct Int128 {
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
int64_t hi;
|
||||
uint64_t lo;
|
||||
#else
|
||||
uint64_t lo;
|
||||
int64_t hi;
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline Int128 int128_make64(uint64_t a)
|
||||
{
|
||||
return (Int128) { a, 0 };
|
||||
return (Int128) { .lo = a, .hi = 0 };
|
||||
}
|
||||
|
||||
static inline Int128 int128_makes64(int64_t a)
|
||||
{
|
||||
return (Int128) { a, a >> 63 };
|
||||
return (Int128) { .lo = a, .hi = a >> 63 };
|
||||
}
|
||||
|
||||
static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
|
||||
{
|
||||
return (Int128) { lo, hi };
|
||||
return (Int128) { .lo = lo, .hi = hi };
|
||||
}
|
||||
|
||||
static inline uint64_t int128_get64(Int128 a)
|
||||
@ -210,22 +227,22 @@ static inline Int128 int128_one(void)
|
||||
|
||||
static inline Int128 int128_2_64(void)
|
||||
{
|
||||
return (Int128) { 0, 1 };
|
||||
return int128_make128(0, 1);
|
||||
}
|
||||
|
||||
static inline Int128 int128_exts64(int64_t a)
|
||||
{
|
||||
return (Int128) { .lo = a, .hi = (a < 0) ? -1 : 0 };
|
||||
return int128_make128(a, (a < 0) ? -1 : 0);
|
||||
}
|
||||
|
||||
static inline Int128 int128_and(Int128 a, Int128 b)
|
||||
{
|
||||
return (Int128) { a.lo & b.lo, a.hi & b.hi };
|
||||
return int128_make128(a.lo & b.lo, a.hi & b.hi);
|
||||
}
|
||||
|
||||
static inline Int128 int128_or(Int128 a, Int128 b)
|
||||
{
|
||||
return (Int128) { a.lo | b.lo, a.hi | b.hi };
|
||||
return int128_make128(a.lo | b.lo, a.hi | b.hi);
|
||||
}
|
||||
|
||||
static inline Int128 int128_rshift(Int128 a, int n)
|
||||
@ -337,5 +354,16 @@ static inline void int128_subfrom(Int128 *a, Int128 b)
|
||||
*a = int128_sub(*a, b);
|
||||
}
|
||||
|
||||
static inline Int128 bswap128(Int128 a)
|
||||
{
|
||||
return int128_make128(bswap64(a.hi), bswap64(a.lo));
|
||||
}
|
||||
|
||||
#endif /* CONFIG_INT128 */
|
||||
|
||||
static inline void bswap128s(Int128 *s)
|
||||
{
|
||||
*s = bswap128(*s);
|
||||
}
|
||||
|
||||
#endif /* INT128_H */
|
||||
|
Binary file not shown.
@ -1 +1 @@
|
||||
Subproject commit 3a6fdede6ce117facec0108afe716cf5d0472c3f
|
||||
Subproject commit 820d43c0a7751e75a8830561f35535dfffd522bd
|
@ -776,6 +776,8 @@
|
||||
"POWER9 v2.0")
|
||||
POWERPC_DEF("power10_v1.0", CPU_POWERPC_POWER10_DD1, POWER10,
|
||||
"POWER10 v1.0")
|
||||
POWERPC_DEF("power10_v2.0", CPU_POWERPC_POWER10_DD20, POWER10,
|
||||
"POWER10 v2.0")
|
||||
#endif /* defined (TARGET_PPC64) */
|
||||
|
||||
/***************************************************************************/
|
||||
@ -952,7 +954,7 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
|
||||
{ "power8", "power8_v2.0" },
|
||||
{ "power8nvl", "power8nvl_v1.0" },
|
||||
{ "power9", "power9_v2.0" },
|
||||
{ "power10", "power10_v1.0" },
|
||||
{ "power10", "power10_v2.0" },
|
||||
#endif
|
||||
|
||||
/* Generic PowerPCs */
|
||||
|
@ -375,6 +375,7 @@ enum {
|
||||
CPU_POWERPC_POWER9_DD20 = 0x004E1200,
|
||||
CPU_POWERPC_POWER10_BASE = 0x00800000,
|
||||
CPU_POWERPC_POWER10_DD1 = 0x00800100,
|
||||
CPU_POWERPC_POWER10_DD20 = 0x00800200,
|
||||
CPU_POWERPC_970_v22 = 0x00390202,
|
||||
CPU_POWERPC_970FX_v10 = 0x00391100,
|
||||
CPU_POWERPC_970FX_v20 = 0x003C0200,
|
||||
|
@ -67,34 +67,6 @@ uint32_t ppc_get_vscr(CPUPPCState *env)
|
||||
return env->vscr | (sat << VSCR_SAT);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SOFTMMU
|
||||
void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
|
||||
{
|
||||
PowerPCCPU *cpu = env_archcpu(env);
|
||||
qemu_log_mask(CPU_LOG_MMU, "%s: " TARGET_FMT_lx "\n", __func__, value);
|
||||
assert(!cpu->env.has_hv_mode || !cpu->vhyp);
|
||||
#if defined(TARGET_PPC64)
|
||||
if (mmu_is_64bit(env->mmu_model)) {
|
||||
target_ulong sdr_mask = SDR_64_HTABORG | SDR_64_HTABSIZE;
|
||||
target_ulong htabsize = value & SDR_64_HTABSIZE;
|
||||
|
||||
if (value & ~sdr_mask) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "Invalid bits 0x"TARGET_FMT_lx
|
||||
" set in SDR1", value & ~sdr_mask);
|
||||
value &= sdr_mask;
|
||||
}
|
||||
if (htabsize > 28) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "Invalid HTABSIZE 0x" TARGET_FMT_lx
|
||||
" stored in SDR1", htabsize);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif /* defined(TARGET_PPC64) */
|
||||
/* FIXME: Should check for valid HTABMASK values in 32-bit case */
|
||||
env->spr[SPR_SDR1] = value;
|
||||
}
|
||||
#endif /* CONFIG_SOFTMMU */
|
||||
|
||||
/* GDBstub can read and write MSR... */
|
||||
void ppc_store_msr(CPUPPCState *env, target_ulong value)
|
||||
{
|
||||
|
@ -1330,6 +1330,15 @@ void store_booke_tsr(CPUPPCState *env, target_ulong val);
|
||||
void ppc_tlb_invalidate_all(CPUPPCState *env);
|
||||
void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr);
|
||||
void cpu_ppc_set_vhyp(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp);
|
||||
int ppcmas_tlb_check(CPUPPCState *env, ppcmas_tlb_t *tlb,
|
||||
hwaddr *raddrp, target_ulong address,
|
||||
uint32_t pid);
|
||||
int ppcemb_tlb_check(CPUPPCState *env, ppcemb_tlb_t *tlb,
|
||||
hwaddr *raddrp,
|
||||
target_ulong address, uint32_t pid, int ext,
|
||||
int i);
|
||||
hwaddr booke206_tlb_to_page_size(CPUPPCState *env,
|
||||
ppcmas_tlb_t *tlb);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -8269,6 +8269,9 @@ POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data)
|
||||
LPCR_DEE | LPCR_OEE))
|
||||
| LPCR_MER | LPCR_GTSE | LPCR_TC |
|
||||
LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE;
|
||||
/* DD2 adds an extra HAIL bit */
|
||||
pcc->lpcr_mask |= LPCR_HAIL;
|
||||
|
||||
pcc->lpcr_pm = LPCR_PDEE | LPCR_HDEE | LPCR_EEE | LPCR_DEE | LPCR_OEE;
|
||||
pcc->mmu_model = POWERPC_MMU_3_00;
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
|
@ -1211,12 +1211,6 @@ void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t insn)
|
||||
cs = env_cpu(env);
|
||||
cs->halted = 1;
|
||||
|
||||
/*
|
||||
* The architecture specifies that HDEC interrupts are discarded
|
||||
* in PM states
|
||||
*/
|
||||
env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
|
||||
|
||||
/* Condition for waking up at 0x100 */
|
||||
env->resume_as_sreset = (insn != PPC_PM_STOP) ||
|
||||
(env->spr[SPR_PSSCR] & PSSCR_EC);
|
||||
|
@ -101,6 +101,8 @@ void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len)
|
||||
bswap32s((uint32_t *)mem_buf);
|
||||
} else if (len == 8) {
|
||||
bswap64s((uint64_t *)mem_buf);
|
||||
} else if (len == 16) {
|
||||
bswap128s((Int128 *)mem_buf);
|
||||
} else {
|
||||
g_assert_not_reached();
|
||||
}
|
||||
@ -389,15 +391,6 @@ const char *ppc_gdb_get_dynamic_xml(CPUState *cs, const char *xml_name)
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool avr_need_swap(CPUPPCState *env)
|
||||
{
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
return msr_le;
|
||||
#else
|
||||
return !msr_le;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
static int gdb_find_spr_idx(CPUPPCState *env, int n)
|
||||
{
|
||||
@ -486,14 +479,9 @@ static int gdb_get_avr_reg(CPUPPCState *env, GByteArray *buf, int n)
|
||||
|
||||
if (n < 32) {
|
||||
ppc_avr_t *avr = cpu_avr_ptr(env, n);
|
||||
if (!avr_need_swap(env)) {
|
||||
gdb_get_reg128(buf, avr->u64[0] , avr->u64[1]);
|
||||
} else {
|
||||
gdb_get_reg128(buf, avr->u64[1] , avr->u64[0]);
|
||||
}
|
||||
gdb_get_reg128(buf, avr->VsrD(0), avr->VsrD(1));
|
||||
mem_buf = gdb_get_reg_ptr(buf, 16);
|
||||
ppc_maybe_bswap_register(env, mem_buf, 8);
|
||||
ppc_maybe_bswap_register(env, mem_buf + 8, 8);
|
||||
ppc_maybe_bswap_register(env, mem_buf, 16);
|
||||
return 16;
|
||||
}
|
||||
if (n == 32) {
|
||||
@ -515,15 +503,9 @@ static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
|
||||
{
|
||||
if (n < 32) {
|
||||
ppc_avr_t *avr = cpu_avr_ptr(env, n);
|
||||
ppc_maybe_bswap_register(env, mem_buf, 8);
|
||||
ppc_maybe_bswap_register(env, mem_buf + 8, 8);
|
||||
if (!avr_need_swap(env)) {
|
||||
avr->u64[0] = ldq_p(mem_buf);
|
||||
avr->u64[1] = ldq_p(mem_buf + 8);
|
||||
} else {
|
||||
avr->u64[1] = ldq_p(mem_buf);
|
||||
avr->u64[0] = ldq_p(mem_buf + 8);
|
||||
}
|
||||
ppc_maybe_bswap_register(env, mem_buf, 16);
|
||||
avr->VsrD(0) = ldq_p(mem_buf);
|
||||
avr->VsrD(1) = ldq_p(mem_buf + 8);
|
||||
return 16;
|
||||
}
|
||||
if (n == 32) {
|
||||
|
@ -258,6 +258,18 @@ int hreg_store_msr(CPUPPCState *env, target_ulong value, int alter_hv)
|
||||
return excp;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SOFTMMU
|
||||
void store_40x_sler(CPUPPCState *env, uint32_t val)
|
||||
{
|
||||
/* XXX: TO BE FIXED */
|
||||
if (val != 0x00000000) {
|
||||
cpu_abort(env_cpu(env),
|
||||
"Little-endian regions are not supported by now\n");
|
||||
}
|
||||
env->spr[SPR_405_SLER] = val;
|
||||
}
|
||||
#endif /* CONFIG_SOFTMMU */
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
void check_tlb_flush(CPUPPCState *env, bool global)
|
||||
{
|
||||
|
@ -1492,34 +1492,16 @@ void helper_vlogefp(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *b)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HOST_WORDS_BIGENDIAN)
|
||||
#define VEXTU_X_DO(name, size, left) \
|
||||
target_ulong glue(helper_, name)(target_ulong a, ppc_avr_t *b) \
|
||||
{ \
|
||||
int index; \
|
||||
if (left) { \
|
||||
index = (a & 0xf) * 8; \
|
||||
} else { \
|
||||
index = ((15 - (a & 0xf) + 1) * 8) - size; \
|
||||
} \
|
||||
return int128_getlo(int128_rshift(b->s128, index)) & \
|
||||
MAKE_64BIT_MASK(0, size); \
|
||||
}
|
||||
#else
|
||||
#define VEXTU_X_DO(name, size, left) \
|
||||
target_ulong glue(helper_, name)(target_ulong a, ppc_avr_t *b) \
|
||||
{ \
|
||||
int index; \
|
||||
if (left) { \
|
||||
index = ((15 - (a & 0xf) + 1) * 8) - size; \
|
||||
} else { \
|
||||
index = (a & 0xf) * 8; \
|
||||
} \
|
||||
return int128_getlo(int128_rshift(b->s128, index)) & \
|
||||
MAKE_64BIT_MASK(0, size); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define VEXTU_X_DO(name, size, left) \
|
||||
target_ulong glue(helper_, name)(target_ulong a, ppc_avr_t *b) \
|
||||
{ \
|
||||
int index = (a & 0xf) * 8; \
|
||||
if (left) { \
|
||||
index = 128 - index - size; \
|
||||
} \
|
||||
return int128_getlo(int128_rshift(b->s128, index)) & \
|
||||
MAKE_64BIT_MASK(0, size); \
|
||||
}
|
||||
VEXTU_X_DO(vextublx, 8, 1)
|
||||
VEXTU_X_DO(vextuhlx, 16, 1)
|
||||
VEXTU_X_DO(vextuwlx, 32, 1)
|
||||
|
@ -245,4 +245,43 @@ static inline int prot_for_access_type(MMUAccessType access_type)
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
/* PowerPC MMU emulation */
|
||||
|
||||
typedef struct mmu_ctx_t mmu_ctx_t;
|
||||
bool ppc_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
|
||||
hwaddr *raddrp, int *psizep, int *protp,
|
||||
int mmu_idx, bool guest_visible);
|
||||
int get_physical_address_wtlb(CPUPPCState *env, mmu_ctx_t *ctx,
|
||||
target_ulong eaddr,
|
||||
MMUAccessType access_type, int type,
|
||||
int mmu_idx);
|
||||
/* Software driven TLB helpers */
|
||||
int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr,
|
||||
int way, int is_code);
|
||||
/* Context used internally during MMU translations */
|
||||
struct mmu_ctx_t {
|
||||
hwaddr raddr; /* Real address */
|
||||
hwaddr eaddr; /* Effective address */
|
||||
int prot; /* Protection bits */
|
||||
hwaddr hash[2]; /* Pagetable hash values */
|
||||
target_ulong ptem; /* Virtual segment ID | API */
|
||||
int key; /* Access key */
|
||||
int nx; /* Non-execute area */
|
||||
};
|
||||
|
||||
/* Common routines used by software and hardware TLBs emulation */
|
||||
static inline int pte_is_valid(target_ulong pte0)
|
||||
{
|
||||
return pte0 & 0x80000000 ? 1 : 0;
|
||||
}
|
||||
|
||||
static inline void pte_invalidate(target_ulong *pte0)
|
||||
{
|
||||
*pte0 &= ~0x80000000;
|
||||
}
|
||||
|
||||
#define PTE_PTEM_MASK 0x7FFFFFBF
|
||||
#define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
|
||||
|
||||
|
||||
#endif /* PPC_INTERNAL_H */
|
||||
|
@ -37,11 +37,13 @@ ppc_softmmu_ss.add(files(
|
||||
'arch_dump.c',
|
||||
'machine.c',
|
||||
'mmu-hash32.c',
|
||||
'mmu_helper.c',
|
||||
'mmu_common.c',
|
||||
'monitor.c',
|
||||
))
|
||||
ppc_softmmu_ss.add(when: 'CONFIG_TCG', if_false: files(
|
||||
'tcg-stub.c'
|
||||
ppc_softmmu_ss.add(when: 'CONFIG_TCG', if_true: files(
|
||||
'mmu_helper.c',
|
||||
), if_false: files(
|
||||
'tcg-stub.c',
|
||||
))
|
||||
|
||||
ppc_softmmu_ss.add(when: 'TARGET_PPC64', if_true: files(
|
||||
|
1620
target/ppc/mmu_common.c
Normal file
1620
target/ppc/mmu_common.c
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user