mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-07 09:43:56 -06:00
* PAPR nested hypervisor host implementation for spapr TCG
* excp_helper.c code cleanups and improvements * Move more ops to decodetree * Deprecate pseries-2.12 machines and P9 and P10 DD1.0 CPUs * Document running Linux on AmigaNG * Update dt feature advertising POWER CPUs. * Add P10 PMU SPRs * Improve pnv topology calculation for SMT8 CPUs. * Various bug fixes. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEETkN92lZhb0MpsKeVZ7MCdqhiHK4FAmXwiT8ACgkQZ7MCdqhi HK7C/w//XxEO2bQTFPLFDTrP/voq7pcX8XeQNVyXCkXYjvsbu05oQow50k+Y5UAE US4MFjt8jFz0vuIKuKyoA3kG41zDSOzoX4TQXMM+tyTWbuFF3KAyfizb1xE6SYAN xJEGvmiXv/EgoSBD7BTKQp1tMPdIGZLwSdYiA0lmOo7YaMCgYAXaujW5hnNjQecT 873sN+10pHtQY++mINtD9Nfb6AcDGMWw0b+bykqIXhNRkI8IGOS4WF4vAuMBrwfe UM00wDnNRb86Dk14bv2XVNDr6/i0VRtUMwM4yiptrQ1TQx18LZaPSQFYjQfPaan7 LwN4QkMFnBX54yJ7Npvjvu8BCBF47kwOVu4CIAFJ4sIm0WfTmozDpPttwcZ5w7Ve iXDOB9ECAB4pQ2rCgbSNG8MYUZgoHHOuThqolOP0Vh9NHRRJxpdw6CyAbmCGftc0 lvRDPFiKp8xmCNJ/j3XzoUdHoG7NMwpUmHv9ruGU18SdQ8hyJN9AcQGWYrB4v0RV /hs2RAbwntG7ahkcwd8uy5aFw88Wph/uGXPXc49EWj7i49vHeIV2y5+gtthMywje qqjFXkistXuF+JHVnyoYmqqCyXaHX5CEwtawMv4EQeaJs76bLhMeMTKKl9rRp8qB DtbIZphO8iMsocrBnje48sA5HR0PM+H4HTjw10i8R0fLlWitaIY= =XnY5 -----END PGP SIGNATURE----- Merge tag 'pull-ppc-for-9.0-2-20240313' of https://gitlab.com/npiggin/qemu into staging * PAPR nested hypervisor host implementation for spapr TCG * excp_helper.c code cleanups and improvements * Move more ops to decodetree * Deprecate pseries-2.12 machines and P9 and P10 DD1.0 CPUs * Document running Linux on AmigaNG * Update dt feature advertising POWER CPUs. * Add P10 PMU SPRs * Improve pnv topology calculation for SMT8 CPUs. * Various bug fixes. # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCgAdFiEETkN92lZhb0MpsKeVZ7MCdqhiHK4FAmXwiT8ACgkQZ7MCdqhi # HK7C/w//XxEO2bQTFPLFDTrP/voq7pcX8XeQNVyXCkXYjvsbu05oQow50k+Y5UAE # US4MFjt8jFz0vuIKuKyoA3kG41zDSOzoX4TQXMM+tyTWbuFF3KAyfizb1xE6SYAN # xJEGvmiXv/EgoSBD7BTKQp1tMPdIGZLwSdYiA0lmOo7YaMCgYAXaujW5hnNjQecT # 873sN+10pHtQY++mINtD9Nfb6AcDGMWw0b+bykqIXhNRkI8IGOS4WF4vAuMBrwfe # UM00wDnNRb86Dk14bv2XVNDr6/i0VRtUMwM4yiptrQ1TQx18LZaPSQFYjQfPaan7 # LwN4QkMFnBX54yJ7Npvjvu8BCBF47kwOVu4CIAFJ4sIm0WfTmozDpPttwcZ5w7Ve # iXDOB9ECAB4pQ2rCgbSNG8MYUZgoHHOuThqolOP0Vh9NHRRJxpdw6CyAbmCGftc0 # lvRDPFiKp8xmCNJ/j3XzoUdHoG7NMwpUmHv9ruGU18SdQ8hyJN9AcQGWYrB4v0RV # /hs2RAbwntG7ahkcwd8uy5aFw88Wph/uGXPXc49EWj7i49vHeIV2y5+gtthMywje # qqjFXkistXuF+JHVnyoYmqqCyXaHX5CEwtawMv4EQeaJs76bLhMeMTKKl9rRp8qB # DtbIZphO8iMsocrBnje48sA5HR0PM+H4HTjw10i8R0fLlWitaIY= # =XnY5 # -----END PGP SIGNATURE----- # gpg: Signature made Tue 12 Mar 2024 16:56:31 GMT # gpg: using RSA key 4E437DDA56616F4329B0A79567B30276A8621CAE # gpg: Good signature from "Nicholas Piggin <npiggin@gmail.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 4E43 7DDA 5661 6F43 29B0 A795 67B3 0276 A862 1CAE * tag 'pull-ppc-for-9.0-2-20240313' of https://gitlab.com/npiggin/qemu: (38 commits) spapr: nested: Introduce cap-nested-papr for Nested PAPR API spapr: nested: Introduce H_GUEST_RUN_VCPU hcall. spapr: nested: Use correct source for parttbl info for nested PAPR API. spapr: nested: Introduce H_GUEST_[GET|SET]_STATE hcalls. spapr: nested: Initialize the GSB elements lookup table. spapr: nested: Extend nested_ppc_state for nested PAPR API spapr: nested: Introduce H_GUEST_CREATE_VCPU hcall. spapr: nested: Introduce H_GUEST_[CREATE|DELETE] hcalls. spapr: nested: Introduce H_GUEST_[GET|SET]_CAPABILITIES hcalls. spapr: nested: Document Nested PAPR API spapr: nested: keep nested-hv related code restricted to its API. spapr: nested: Introduce SpaprMachineStateNested to store related info. spapr: nested: move nested part of spapr_get_pate into spapr_nested.c spapr: nested: register nested-hv api hcalls only for cap-nested-hv target/ppc: Remove interrupt handler wrapper functions target/ppc: Clean up ifdefs in excp_helper.c, part 3 target/ppc: Clean up ifdefs in excp_helper.c, part 2 target/ppc: Clean up ifdefs in excp_helper.c, part 1 target/ppc: Add gen_exception_err_nip() function target/ppc: Readability improvements in exception handlers ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
51e31f2140
28 changed files with 2883 additions and 563 deletions
175
hw/ppc/pnv.c
175
hw/ppc/pnv.c
|
@ -133,7 +133,7 @@ static int get_cpus_node(void *fdt)
|
|||
* device tree, used in XSCOM to address cores and in interrupt
|
||||
* servers.
|
||||
*/
|
||||
static void pnv_dt_core(PnvChip *chip, PnvCore *pc, void *fdt)
|
||||
static int pnv_dt_core(PnvChip *chip, PnvCore *pc, void *fdt)
|
||||
{
|
||||
PowerPCCPU *cpu = pc->threads[0];
|
||||
CPUState *cs = CPU(cpu);
|
||||
|
@ -141,32 +141,31 @@ static void pnv_dt_core(PnvChip *chip, PnvCore *pc, void *fdt)
|
|||
int smt_threads = CPU_CORE(pc)->nr_threads;
|
||||
CPUPPCState *env = &cpu->env;
|
||||
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
|
||||
PnvChipClass *pnv_cc = PNV_CHIP_GET_CLASS(chip);
|
||||
g_autofree uint32_t *servers_prop = g_new(uint32_t, smt_threads);
|
||||
int i;
|
||||
uint32_t pir;
|
||||
uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
|
||||
0xffffffff, 0xffffffff};
|
||||
uint32_t tbfreq = PNV_TIMEBASE_FREQ;
|
||||
uint32_t cpufreq = 1000000000;
|
||||
uint32_t page_sizes_prop[64];
|
||||
size_t page_sizes_prop_size;
|
||||
const uint8_t pa_features[] = { 24, 0,
|
||||
0xf6, 0x3f, 0xc7, 0xc0, 0x80, 0xf0,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
|
||||
0x80, 0x00, 0x80, 0x00, 0x80, 0x00 };
|
||||
int offset;
|
||||
char *nodename;
|
||||
int cpus_offset = get_cpus_node(fdt);
|
||||
|
||||
nodename = g_strdup_printf("%s@%x", dc->fw_name, pc->pir);
|
||||
pir = pnv_cc->chip_pir(chip, pc->hwid, 0);
|
||||
|
||||
nodename = g_strdup_printf("%s@%x", dc->fw_name, pir);
|
||||
offset = fdt_add_subnode(fdt, cpus_offset, nodename);
|
||||
_FDT(offset);
|
||||
g_free(nodename);
|
||||
|
||||
_FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id", chip->chip_id)));
|
||||
|
||||
_FDT((fdt_setprop_cell(fdt, offset, "reg", pc->pir)));
|
||||
_FDT((fdt_setprop_cell(fdt, offset, "ibm,pir", pc->pir)));
|
||||
_FDT((fdt_setprop_cell(fdt, offset, "reg", pir)));
|
||||
_FDT((fdt_setprop_cell(fdt, offset, "ibm,pir", pir)));
|
||||
_FDT((fdt_setprop_string(fdt, offset, "device_type", "cpu")));
|
||||
|
||||
_FDT((fdt_setprop_cell(fdt, offset, "cpu-version", env->spr[SPR_PVR])));
|
||||
|
@ -236,20 +235,21 @@ static void pnv_dt_core(PnvChip *chip, PnvCore *pc, void *fdt)
|
|||
page_sizes_prop, page_sizes_prop_size)));
|
||||
}
|
||||
|
||||
_FDT((fdt_setprop(fdt, offset, "ibm,pa-features",
|
||||
pa_features, sizeof(pa_features))));
|
||||
|
||||
/* Build interrupt servers properties */
|
||||
for (i = 0; i < smt_threads; i++) {
|
||||
servers_prop[i] = cpu_to_be32(pc->pir + i);
|
||||
servers_prop[i] = cpu_to_be32(pnv_cc->chip_pir(chip, pc->hwid, i));
|
||||
}
|
||||
_FDT((fdt_setprop(fdt, offset, "ibm,ppc-interrupt-server#s",
|
||||
servers_prop, sizeof(*servers_prop) * smt_threads)));
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static void pnv_dt_icp(PnvChip *chip, void *fdt, uint32_t pir,
|
||||
static void pnv_dt_icp(PnvChip *chip, void *fdt, uint32_t hwid,
|
||||
uint32_t nr_threads)
|
||||
{
|
||||
PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
|
||||
uint32_t pir = pcc->chip_pir(chip, hwid, 0);
|
||||
uint64_t addr = PNV_ICP_BASE(chip) | (pir << 12);
|
||||
char *name;
|
||||
const char compat[] = "IBM,power8-icp\0IBM,ppc-xicp";
|
||||
|
@ -263,6 +263,7 @@ static void pnv_dt_icp(PnvChip *chip, void *fdt, uint32_t pir,
|
|||
rsize = sizeof(uint64_t) * 2 * nr_threads;
|
||||
reg = g_malloc(rsize);
|
||||
for (i = 0; i < nr_threads; i++) {
|
||||
/* We know P8 PIR is linear with thread id */
|
||||
reg[i * 2] = cpu_to_be64(addr | ((pir + i) * 0x1000));
|
||||
reg[i * 2 + 1] = cpu_to_be64(0x1000);
|
||||
}
|
||||
|
@ -299,6 +300,17 @@ PnvChip *pnv_chip_add_phb(PnvChip *chip, PnvPHB *phb)
|
|||
return chip;
|
||||
}
|
||||
|
||||
/*
|
||||
* Same as spapr pa_features_207 except pnv always enables CI largepages bit.
|
||||
* HTM is always enabled because TCG does implement HTM, it's just a
|
||||
* degenerate implementation.
|
||||
*/
|
||||
static const uint8_t pa_features_207[] = { 24, 0,
|
||||
0xf6, 0x3f, 0xc7, 0xc0, 0x00, 0xf0,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
|
||||
0x80, 0x00, 0x80, 0x00, 0x80, 0x00 };
|
||||
|
||||
static void pnv_chip_power8_dt_populate(PnvChip *chip, void *fdt)
|
||||
{
|
||||
static const char compat[] = "ibm,power8-xscom\0ibm,xscom";
|
||||
|
@ -311,11 +323,15 @@ static void pnv_chip_power8_dt_populate(PnvChip *chip, void *fdt)
|
|||
|
||||
for (i = 0; i < chip->nr_cores; i++) {
|
||||
PnvCore *pnv_core = chip->cores[i];
|
||||
int offset;
|
||||
|
||||
pnv_dt_core(chip, pnv_core, fdt);
|
||||
offset = pnv_dt_core(chip, pnv_core, fdt);
|
||||
|
||||
_FDT((fdt_setprop(fdt, offset, "ibm,pa-features",
|
||||
pa_features_207, sizeof(pa_features_207))));
|
||||
|
||||
/* Interrupt Control Presenters (ICP). One per core. */
|
||||
pnv_dt_icp(chip, fdt, pnv_core->pir, CPU_CORE(pnv_core)->nr_threads);
|
||||
pnv_dt_icp(chip, fdt, pnv_core->hwid, CPU_CORE(pnv_core)->nr_threads);
|
||||
}
|
||||
|
||||
if (chip->ram_size) {
|
||||
|
@ -323,6 +339,35 @@ static void pnv_chip_power8_dt_populate(PnvChip *chip, void *fdt)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Same as spapr pa_features_300 except pnv always enables CI largepages bit.
|
||||
*/
|
||||
static const uint8_t pa_features_300[] = { 66, 0,
|
||||
/* 0: MMU|FPU|SLB|RUN|DABR|NX, 1: CILRG|fri[nzpm]|DABRX|SPRG3|SLB0|PP110 */
|
||||
/* 2: VPM|DS205|PPR|DS202|DS206, 3: LSD|URG, 5: LE|CFAR|EB|LSQ */
|
||||
0xf6, 0x3f, 0xc7, 0xc0, 0x00, 0xf0, /* 0 - 5 */
|
||||
/* 6: DS207 */
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* 6 - 11 */
|
||||
/* 16: Vector */
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 12 - 17 */
|
||||
/* 18: Vec. Scalar, 20: Vec. XOR, 22: HTM */
|
||||
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 18 - 23 */
|
||||
/* 24: Ext. Dec, 26: 64 bit ftrs, 28: PM ftrs */
|
||||
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 24 - 29 */
|
||||
/* 32: LE atomic, 34: EBB + ext EBB */
|
||||
0x00, 0x00, 0x80, 0x00, 0xC0, 0x00, /* 30 - 35 */
|
||||
/* 40: Radix MMU */
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 36 - 41 */
|
||||
/* 42: PM, 44: PC RA, 46: SC vec'd */
|
||||
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 42 - 47 */
|
||||
/* 48: SIMD, 50: QP BFP, 52: String */
|
||||
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 48 - 53 */
|
||||
/* 54: DecFP, 56: DecI, 58: SHA */
|
||||
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 54 - 59 */
|
||||
/* 60: NM atomic, 62: RNG */
|
||||
0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 60 - 65 */
|
||||
};
|
||||
|
||||
static void pnv_chip_power9_dt_populate(PnvChip *chip, void *fdt)
|
||||
{
|
||||
static const char compat[] = "ibm,power9-xscom\0ibm,xscom";
|
||||
|
@ -335,8 +380,12 @@ static void pnv_chip_power9_dt_populate(PnvChip *chip, void *fdt)
|
|||
|
||||
for (i = 0; i < chip->nr_cores; i++) {
|
||||
PnvCore *pnv_core = chip->cores[i];
|
||||
int offset;
|
||||
|
||||
pnv_dt_core(chip, pnv_core, fdt);
|
||||
offset = pnv_dt_core(chip, pnv_core, fdt);
|
||||
|
||||
_FDT((fdt_setprop(fdt, offset, "ibm,pa-features",
|
||||
pa_features_300, sizeof(pa_features_300))));
|
||||
}
|
||||
|
||||
if (chip->ram_size) {
|
||||
|
@ -346,6 +395,40 @@ static void pnv_chip_power9_dt_populate(PnvChip *chip, void *fdt)
|
|||
pnv_dt_lpc(chip, fdt, 0, PNV9_LPCM_BASE(chip), PNV9_LPCM_SIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Same as spapr pa_features_31 except pnv always enables CI largepages bit,
|
||||
* always disables copy/paste.
|
||||
*/
|
||||
static const uint8_t pa_features_31[] = { 74, 0,
|
||||
/* 0: MMU|FPU|SLB|RUN|DABR|NX, 1: CILRG|fri[nzpm]|DABRX|SPRG3|SLB0|PP110 */
|
||||
/* 2: VPM|DS205|PPR|DS202|DS206, 3: LSD|URG, 5: LE|CFAR|EB|LSQ */
|
||||
0xf6, 0x3f, 0xc7, 0xc0, 0x00, 0xf0, /* 0 - 5 */
|
||||
/* 6: DS207 */
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* 6 - 11 */
|
||||
/* 16: Vector */
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 12 - 17 */
|
||||
/* 18: Vec. Scalar, 20: Vec. XOR */
|
||||
0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 18 - 23 */
|
||||
/* 24: Ext. Dec, 26: 64 bit ftrs, 28: PM ftrs */
|
||||
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 24 - 29 */
|
||||
/* 32: LE atomic, 34: EBB + ext EBB */
|
||||
0x00, 0x00, 0x80, 0x00, 0xC0, 0x00, /* 30 - 35 */
|
||||
/* 40: Radix MMU */
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 36 - 41 */
|
||||
/* 42: PM, 44: PC RA, 46: SC vec'd */
|
||||
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 42 - 47 */
|
||||
/* 48: SIMD, 50: QP BFP, 52: String */
|
||||
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 48 - 53 */
|
||||
/* 54: DecFP, 56: DecI, 58: SHA */
|
||||
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 54 - 59 */
|
||||
/* 60: NM atomic, 62: RNG */
|
||||
0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 60 - 65 */
|
||||
/* 68: DEXCR[SBHE|IBRTPDUS|SRAPD|NPHIE|PHIE] */
|
||||
0x00, 0x00, 0xce, 0x00, 0x00, 0x00, /* 66 - 71 */
|
||||
/* 72: [P]HASHST/[P]HASHCHK */
|
||||
0x80, 0x00, /* 72 - 73 */
|
||||
};
|
||||
|
||||
static void pnv_chip_power10_dt_populate(PnvChip *chip, void *fdt)
|
||||
{
|
||||
static const char compat[] = "ibm,power10-xscom\0ibm,xscom";
|
||||
|
@ -358,8 +441,12 @@ static void pnv_chip_power10_dt_populate(PnvChip *chip, void *fdt)
|
|||
|
||||
for (i = 0; i < chip->nr_cores; i++) {
|
||||
PnvCore *pnv_core = chip->cores[i];
|
||||
int offset;
|
||||
|
||||
pnv_dt_core(chip, pnv_core, fdt);
|
||||
offset = pnv_dt_core(chip, pnv_core, fdt);
|
||||
|
||||
_FDT((fdt_setprop(fdt, offset, "ibm,pa-features",
|
||||
pa_features_31, sizeof(pa_features_31))));
|
||||
}
|
||||
|
||||
if (chip->ram_size) {
|
||||
|
@ -995,9 +1082,10 @@ static void pnv_init(MachineState *machine)
|
|||
* 25:28 Core number
|
||||
* 29:31 Thread ID
|
||||
*/
|
||||
static uint32_t pnv_chip_core_pir_p8(PnvChip *chip, uint32_t core_id)
|
||||
static uint32_t pnv_chip_pir_p8(PnvChip *chip, uint32_t core_id,
|
||||
uint32_t thread_id)
|
||||
{
|
||||
return (chip->chip_id << 7) | (core_id << 3);
|
||||
return (chip->chip_id << 7) | (core_id << 3) | thread_id;
|
||||
}
|
||||
|
||||
static void pnv_chip_power8_intc_create(PnvChip *chip, PowerPCCPU *cpu,
|
||||
|
@ -1049,14 +1137,37 @@ static void pnv_chip_power8_intc_print_info(PnvChip *chip, PowerPCCPU *cpu,
|
|||
*
|
||||
* We only care about the lower bits. uint32_t is fine for the moment.
|
||||
*/
|
||||
static uint32_t pnv_chip_core_pir_p9(PnvChip *chip, uint32_t core_id)
|
||||
static uint32_t pnv_chip_pir_p9(PnvChip *chip, uint32_t core_id,
|
||||
uint32_t thread_id)
|
||||
{
|
||||
return (chip->chip_id << 8) | (core_id << 2);
|
||||
if (chip->nr_threads == 8) {
|
||||
return (chip->chip_id << 8) | ((thread_id & 1) << 2) | (core_id << 3) |
|
||||
(thread_id >> 1);
|
||||
} else {
|
||||
return (chip->chip_id << 8) | (core_id << 2) | thread_id;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t pnv_chip_core_pir_p10(PnvChip *chip, uint32_t core_id)
|
||||
/*
|
||||
* 0:48 Reserved - Read as zeroes
|
||||
* 49:52 Node ID
|
||||
* 53:55 Chip ID
|
||||
* 56 Reserved - Read as zero
|
||||
* 57:59 Quad ID
|
||||
* 60 Core Chiplet Pair ID
|
||||
* 61:63 Thread/Core Chiplet ID t0-t2
|
||||
*
|
||||
* We only care about the lower bits. uint32_t is fine for the moment.
|
||||
*/
|
||||
static uint32_t pnv_chip_pir_p10(PnvChip *chip, uint32_t core_id,
|
||||
uint32_t thread_id)
|
||||
{
|
||||
return (chip->chip_id << 8) | (core_id << 2);
|
||||
if (chip->nr_threads == 8) {
|
||||
return (chip->chip_id << 8) | ((core_id / 4) << 4) |
|
||||
((core_id % 2) << 3) | thread_id;
|
||||
} else {
|
||||
return (chip->chip_id << 8) | (core_id << 2) | thread_id;
|
||||
}
|
||||
}
|
||||
|
||||
static void pnv_chip_power9_intc_create(PnvChip *chip, PowerPCCPU *cpu,
|
||||
|
@ -1235,7 +1346,7 @@ static void pnv_chip_icp_realize(Pnv8Chip *chip8, Error **errp)
|
|||
int core_hwid = CPU_CORE(pnv_core)->core_id;
|
||||
|
||||
for (j = 0; j < CPU_CORE(pnv_core)->nr_threads; j++) {
|
||||
uint32_t pir = pcc->core_pir(chip, core_hwid) + j;
|
||||
uint32_t pir = pcc->chip_pir(chip, core_hwid, j);
|
||||
PnvICPState *icp = PNV_ICP(xics_icp_get(chip8->xics, pir));
|
||||
|
||||
memory_region_add_subregion(&chip8->icp_mmio, pir << 12,
|
||||
|
@ -1348,7 +1459,7 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
|
|||
k->chip_cfam_id = 0x221ef04980000000ull; /* P8 Murano DD2.1 */
|
||||
k->cores_mask = POWER8E_CORE_MASK;
|
||||
k->num_phbs = 3;
|
||||
k->core_pir = pnv_chip_core_pir_p8;
|
||||
k->chip_pir = pnv_chip_pir_p8;
|
||||
k->intc_create = pnv_chip_power8_intc_create;
|
||||
k->intc_reset = pnv_chip_power8_intc_reset;
|
||||
k->intc_destroy = pnv_chip_power8_intc_destroy;
|
||||
|
@ -1372,7 +1483,7 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, void *data)
|
|||
k->chip_cfam_id = 0x220ea04980000000ull; /* P8 Venice DD2.0 */
|
||||
k->cores_mask = POWER8_CORE_MASK;
|
||||
k->num_phbs = 3;
|
||||
k->core_pir = pnv_chip_core_pir_p8;
|
||||
k->chip_pir = pnv_chip_pir_p8;
|
||||
k->intc_create = pnv_chip_power8_intc_create;
|
||||
k->intc_reset = pnv_chip_power8_intc_reset;
|
||||
k->intc_destroy = pnv_chip_power8_intc_destroy;
|
||||
|
@ -1396,7 +1507,7 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data)
|
|||
k->chip_cfam_id = 0x120d304980000000ull; /* P8 Naples DD1.0 */
|
||||
k->cores_mask = POWER8_CORE_MASK;
|
||||
k->num_phbs = 4;
|
||||
k->core_pir = pnv_chip_core_pir_p8;
|
||||
k->chip_pir = pnv_chip_pir_p8;
|
||||
k->intc_create = pnv_chip_power8_intc_create;
|
||||
k->intc_reset = pnv_chip_power8_intc_reset;
|
||||
k->intc_destroy = pnv_chip_power8_intc_destroy;
|
||||
|
@ -1669,7 +1780,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
|
|||
|
||||
k->chip_cfam_id = 0x220d104900008000ull; /* P9 Nimbus DD2.0 */
|
||||
k->cores_mask = POWER9_CORE_MASK;
|
||||
k->core_pir = pnv_chip_core_pir_p9;
|
||||
k->chip_pir = pnv_chip_pir_p9;
|
||||
k->intc_create = pnv_chip_power9_intc_create;
|
||||
k->intc_reset = pnv_chip_power9_intc_reset;
|
||||
k->intc_destroy = pnv_chip_power9_intc_destroy;
|
||||
|
@ -1981,7 +2092,7 @@ static void pnv_chip_power10_class_init(ObjectClass *klass, void *data)
|
|||
|
||||
k->chip_cfam_id = 0x120da04900008000ull; /* P10 DD1.0 (with NX) */
|
||||
k->cores_mask = POWER10_CORE_MASK;
|
||||
k->core_pir = pnv_chip_core_pir_p10;
|
||||
k->chip_pir = pnv_chip_pir_p10;
|
||||
k->intc_create = pnv_chip_power10_intc_create;
|
||||
k->intc_reset = pnv_chip_power10_intc_reset;
|
||||
k->intc_destroy = pnv_chip_power10_intc_destroy;
|
||||
|
@ -2071,8 +2182,8 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
|
|||
chip->nr_threads, &error_fatal);
|
||||
object_property_set_int(OBJECT(pnv_core), CPU_CORE_PROP_CORE_ID,
|
||||
core_hwid, &error_fatal);
|
||||
object_property_set_int(OBJECT(pnv_core), "pir",
|
||||
pcc->core_pir(chip, core_hwid), &error_fatal);
|
||||
object_property_set_int(OBJECT(pnv_core), "hwid", core_hwid,
|
||||
&error_fatal);
|
||||
object_property_set_int(OBJECT(pnv_core), "hrmor", pnv->fw_load_addr,
|
||||
&error_fatal);
|
||||
object_property_set_link(OBJECT(pnv_core), "chip", OBJECT(chip),
|
||||
|
|
|
@ -226,7 +226,7 @@ static void pnv_core_cpu_realize(PnvCore *pc, PowerPCCPU *cpu, Error **errp,
|
|||
int thread_index)
|
||||
{
|
||||
CPUPPCState *env = &cpu->env;
|
||||
int core_pir;
|
||||
int core_hwid;
|
||||
ppc_spr_t *pir = &env->spr_cb[SPR_PIR];
|
||||
ppc_spr_t *tir = &env->spr_cb[SPR_TIR];
|
||||
Error *local_err = NULL;
|
||||
|
@ -242,10 +242,10 @@ static void pnv_core_cpu_realize(PnvCore *pc, PowerPCCPU *cpu, Error **errp,
|
|||
return;
|
||||
}
|
||||
|
||||
core_pir = object_property_get_uint(OBJECT(pc), "pir", &error_abort);
|
||||
core_hwid = object_property_get_uint(OBJECT(pc), "hwid", &error_abort);
|
||||
|
||||
tir->default_value = thread_index;
|
||||
pir->default_value = core_pir + thread_index;
|
||||
pir->default_value = pcc->chip_pir(pc->chip, core_hwid, thread_index);
|
||||
|
||||
/* Set time-base frequency to 512 MHz */
|
||||
cpu_ppc_tb_init(env, PNV_TIMEBASE_FREQ);
|
||||
|
@ -342,7 +342,7 @@ static void pnv_core_unrealize(DeviceState *dev)
|
|||
}
|
||||
|
||||
static Property pnv_core_properties[] = {
|
||||
DEFINE_PROP_UINT32("pir", PnvCore, pir, 0),
|
||||
DEFINE_PROP_UINT32("hwid", PnvCore, hwid, 0),
|
||||
DEFINE_PROP_UINT64("hrmor", PnvCore, hrmor, 0),
|
||||
DEFINE_PROP_LINK("chip", PnvCore, chip, TYPE_PNV_CHIP, PnvChip *),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
|
|
10
hw/ppc/ppc.c
10
hw/ppc/ppc.c
|
@ -633,6 +633,16 @@ void cpu_ppc_store_atbu (CPUPPCState *env, uint32_t value)
|
|||
((uint64_t)value << 32) | tb);
|
||||
}
|
||||
|
||||
void cpu_ppc_increase_tb_by_offset(CPUPPCState *env, int64_t offset)
|
||||
{
|
||||
env->tb_env->tb_offset += offset;
|
||||
}
|
||||
|
||||
void cpu_ppc_decrease_tb_by_offset(CPUPPCState *env, int64_t offset)
|
||||
{
|
||||
env->tb_env->tb_offset -= offset;
|
||||
}
|
||||
|
||||
uint64_t cpu_ppc_load_vtb(CPUPPCState *env)
|
||||
{
|
||||
ppc_tb_t *tb_env = env->tb_env;
|
||||
|
|
|
@ -233,29 +233,40 @@ static void spapr_dt_pa_features(SpaprMachineState *spapr,
|
|||
PowerPCCPU *cpu,
|
||||
void *fdt, int offset)
|
||||
{
|
||||
/*
|
||||
* SSO (SAO) ordering is supported on KVM and thread=single hosts,
|
||||
* but not MTTCG, so disable it. To advertise it, a cap would have
|
||||
* to be added, or support implemented for MTTCG.
|
||||
*
|
||||
* Copy/paste is not supported by TCG, so it is not advertised. KVM
|
||||
* can execute them but it has no accelerator drivers which are usable,
|
||||
* so there isn't much need for it anyway.
|
||||
*/
|
||||
|
||||
/* These should be kept in sync with pnv */
|
||||
uint8_t pa_features_206[] = { 6, 0,
|
||||
0xf6, 0x1f, 0xc7, 0x00, 0x80, 0xc0 };
|
||||
0xf6, 0x1f, 0xc7, 0x00, 0x00, 0xc0 };
|
||||
uint8_t pa_features_207[] = { 24, 0,
|
||||
0xf6, 0x1f, 0xc7, 0xc0, 0x80, 0xf0,
|
||||
0xf6, 0x1f, 0xc7, 0xc0, 0x00, 0xf0,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
|
||||
0x80, 0x00, 0x80, 0x00, 0x00, 0x00 };
|
||||
uint8_t pa_features_300[] = { 66, 0,
|
||||
/* 0: MMU|FPU|SLB|RUN|DABR|NX, 1: fri[nzpm]|DABRX|SPRG3|SLB0|PP110 */
|
||||
/* 2: VPM|DS205|PPR|DS202|DS206, 3: LSD|URG, SSO, 5: LE|CFAR|EB|LSQ */
|
||||
0xf6, 0x1f, 0xc7, 0xc0, 0x80, 0xf0, /* 0 - 5 */
|
||||
/* 2: VPM|DS205|PPR|DS202|DS206, 3: LSD|URG, 5: LE|CFAR|EB|LSQ */
|
||||
0xf6, 0x1f, 0xc7, 0xc0, 0x00, 0xf0, /* 0 - 5 */
|
||||
/* 6: DS207 */
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* 6 - 11 */
|
||||
/* 16: Vector */
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 12 - 17 */
|
||||
/* 18: Vec. Scalar, 20: Vec. XOR, 22: HTM */
|
||||
/* 18: Vec. Scalar, 20: Vec. XOR */
|
||||
0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 18 - 23 */
|
||||
/* 24: Ext. Dec, 26: 64 bit ftrs, 28: PM ftrs */
|
||||
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 24 - 29 */
|
||||
/* 30: MMR, 32: LE atomic, 34: EBB + ext EBB */
|
||||
0x80, 0x00, 0x80, 0x00, 0xC0, 0x00, /* 30 - 35 */
|
||||
/* 36: SPR SO, 38: Copy/Paste, 40: Radix MMU */
|
||||
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 36 - 41 */
|
||||
/* 32: LE atomic, 34: EBB + ext EBB */
|
||||
0x00, 0x00, 0x80, 0x00, 0xC0, 0x00, /* 30 - 35 */
|
||||
/* 40: Radix MMU */
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 36 - 41 */
|
||||
/* 42: PM, 44: PC RA, 46: SC vec'd */
|
||||
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 42 - 47 */
|
||||
/* 48: SIMD, 50: QP BFP, 52: String */
|
||||
|
@ -265,6 +276,36 @@ static void spapr_dt_pa_features(SpaprMachineState *spapr,
|
|||
/* 60: NM atomic, 62: RNG */
|
||||
0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 60 - 65 */
|
||||
};
|
||||
/* 3.1 removes SAO, HTM support */
|
||||
uint8_t pa_features_31[] = { 74, 0,
|
||||
/* 0: MMU|FPU|SLB|RUN|DABR|NX, 1: fri[nzpm]|DABRX|SPRG3|SLB0|PP110 */
|
||||
/* 2: VPM|DS205|PPR|DS202|DS206, 3: LSD|URG, 5: LE|CFAR|EB|LSQ */
|
||||
0xf6, 0x1f, 0xc7, 0xc0, 0x00, 0xf0, /* 0 - 5 */
|
||||
/* 6: DS207 */
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* 6 - 11 */
|
||||
/* 16: Vector */
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 12 - 17 */
|
||||
/* 18: Vec. Scalar, 20: Vec. XOR */
|
||||
0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 18 - 23 */
|
||||
/* 24: Ext. Dec, 26: 64 bit ftrs, 28: PM ftrs */
|
||||
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 24 - 29 */
|
||||
/* 32: LE atomic, 34: EBB + ext EBB */
|
||||
0x00, 0x00, 0x80, 0x00, 0xC0, 0x00, /* 30 - 35 */
|
||||
/* 40: Radix MMU */
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 36 - 41 */
|
||||
/* 42: PM, 44: PC RA, 46: SC vec'd */
|
||||
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 42 - 47 */
|
||||
/* 48: SIMD, 50: QP BFP, 52: String */
|
||||
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 48 - 53 */
|
||||
/* 54: DecFP, 56: DecI, 58: SHA */
|
||||
0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 54 - 59 */
|
||||
/* 60: NM atomic, 62: RNG */
|
||||
0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 60 - 65 */
|
||||
/* 68: DEXCR[SBHE|IBRTPDUS|SRAPD|NPHIE|PHIE] */
|
||||
0x00, 0x00, 0xce, 0x00, 0x00, 0x00, /* 66 - 71 */
|
||||
/* 72: [P]HASHST/[P]HASHCHK */
|
||||
0x80, 0x00, /* 72 - 73 */
|
||||
};
|
||||
uint8_t *pa_features = NULL;
|
||||
size_t pa_size;
|
||||
|
||||
|
@ -280,6 +321,10 @@ static void spapr_dt_pa_features(SpaprMachineState *spapr,
|
|||
pa_features = pa_features_300;
|
||||
pa_size = sizeof(pa_features_300);
|
||||
}
|
||||
if (ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_3_10, 0, cpu->compat_pvr)) {
|
||||
pa_features = pa_features_31;
|
||||
pa_size = sizeof(pa_features_31);
|
||||
}
|
||||
if (!pa_features) {
|
||||
return;
|
||||
}
|
||||
|
@ -1362,7 +1407,6 @@ void spapr_init_all_lpcrs(target_ulong value, target_ulong mask)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static bool spapr_get_pate(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu,
|
||||
target_ulong lpid, ppc_v3_pate_t *entry)
|
||||
{
|
||||
|
@ -1375,33 +1419,16 @@ static bool spapr_get_pate(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu,
|
|||
/* Copy PATE1:GR into PATE0:HR */
|
||||
entry->dw0 = spapr->patb_entry & PATE0_HR;
|
||||
entry->dw1 = spapr->patb_entry;
|
||||
|
||||
return true;
|
||||
} else {
|
||||
uint64_t patb, pats;
|
||||
|
||||
assert(lpid != 0);
|
||||
|
||||
patb = spapr->nested_ptcr & PTCR_PATB;
|
||||
pats = spapr->nested_ptcr & PTCR_PATS;
|
||||
|
||||
/* Check if partition table is properly aligned */
|
||||
if (patb & MAKE_64BIT_MASK(0, pats + 12)) {
|
||||
return false;
|
||||
if (spapr_nested_api(spapr) == NESTED_API_KVM_HV) {
|
||||
return spapr_get_pate_nested_hv(spapr, cpu, lpid, entry);
|
||||
} else if (spapr_nested_api(spapr) == NESTED_API_PAPR) {
|
||||
return spapr_get_pate_nested_papr(spapr, cpu, lpid, entry);
|
||||
} else {
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
/* Calculate number of entries */
|
||||
pats = 1ull << (pats + 12 - 4);
|
||||
if (pats <= lpid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Grab entry */
|
||||
patb += 16 * lpid;
|
||||
entry->dw0 = ldq_phys(CPU(cpu)->as, patb);
|
||||
entry->dw1 = ldq_phys(CPU(cpu)->as, patb + 8);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define HPTE(_table, _i) (void *)(((uint64_t *)(_table)) + ((_i) * 2))
|
||||
|
@ -1689,6 +1716,7 @@ static void spapr_machine_reset(MachineState *machine, ShutdownCause reason)
|
|||
|
||||
pef_kvm_reset(machine->cgs, &error_fatal);
|
||||
spapr_caps_apply(spapr);
|
||||
spapr_nested_reset(spapr);
|
||||
|
||||
first_ppc_cpu = POWERPC_CPU(first_cpu);
|
||||
if (kvm_enabled() && kvmppc_has_cap_mmu_radix() &&
|
||||
|
@ -2138,6 +2166,7 @@ static const VMStateDescription vmstate_spapr = {
|
|||
&vmstate_spapr_cap_fwnmi,
|
||||
&vmstate_spapr_fwnmi,
|
||||
&vmstate_spapr_cap_rpt_invalidate,
|
||||
&vmstate_spapr_cap_nested_papr,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
@ -4702,6 +4731,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
|
|||
smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_WORKAROUND;
|
||||
smc->default_caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] = 16; /* 64kiB */
|
||||
smc->default_caps.caps[SPAPR_CAP_NESTED_KVM_HV] = SPAPR_CAP_OFF;
|
||||
smc->default_caps.caps[SPAPR_CAP_NESTED_PAPR] = SPAPR_CAP_OFF;
|
||||
smc->default_caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_ON;
|
||||
smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_ON;
|
||||
smc->default_caps.caps[SPAPR_CAP_FWNMI] = SPAPR_CAP_ON;
|
||||
|
|
|
@ -484,6 +484,50 @@ static void cap_nested_kvm_hv_apply(SpaprMachineState *spapr,
|
|||
error_append_hint(errp, "Try appending -machine cap-nested-hv=off "
|
||||
"or use threads=1 with -smp\n");
|
||||
}
|
||||
if (spapr_nested_api(spapr) &&
|
||||
spapr_nested_api(spapr) != NESTED_API_KVM_HV) {
|
||||
error_setg(errp, "Nested-HV APIs are mutually exclusive");
|
||||
error_append_hint(errp, "Please use either cap-nested-hv or "
|
||||
"cap-nested-papr to proceed.\n");
|
||||
return;
|
||||
} else {
|
||||
spapr->nested.api = NESTED_API_KVM_HV;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void cap_nested_papr_apply(SpaprMachineState *spapr,
|
||||
uint8_t val, Error **errp)
|
||||
{
|
||||
ERRP_GUARD();
|
||||
PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
|
||||
if (!val) {
|
||||
/* capability disabled by default */
|
||||
return;
|
||||
}
|
||||
|
||||
if (tcg_enabled()) {
|
||||
if (!(env->insns_flags2 & PPC2_ISA300)) {
|
||||
error_setg(errp, "Nested-PAPR only supported on POWER9 and later");
|
||||
error_append_hint(errp,
|
||||
"Try appending -machine cap-nested-papr=off\n");
|
||||
return;
|
||||
}
|
||||
if (spapr_nested_api(spapr) &&
|
||||
spapr_nested_api(spapr) != NESTED_API_PAPR) {
|
||||
error_setg(errp, "Nested-HV APIs are mutually exclusive");
|
||||
error_append_hint(errp, "Please use either cap-nested-hv or "
|
||||
"cap-nested-papr to proceed.\n");
|
||||
return;
|
||||
} else {
|
||||
spapr->nested.api = NESTED_API_PAPR;
|
||||
}
|
||||
} else if (kvm_enabled()) {
|
||||
error_setg(errp, "KVM implementation does not support Nested-PAPR");
|
||||
error_append_hint(errp,
|
||||
"Try appending -machine cap-nested-papr=off\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -732,6 +776,15 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
|
|||
.type = "bool",
|
||||
.apply = cap_nested_kvm_hv_apply,
|
||||
},
|
||||
[SPAPR_CAP_NESTED_PAPR] = {
|
||||
.name = "nested-papr",
|
||||
.description = "Allow Nested HV (PAPR API)",
|
||||
.index = SPAPR_CAP_NESTED_PAPR,
|
||||
.get = spapr_cap_get_bool,
|
||||
.set = spapr_cap_set_bool,
|
||||
.type = "bool",
|
||||
.apply = cap_nested_papr_apply,
|
||||
},
|
||||
[SPAPR_CAP_LARGE_DECREMENTER] = {
|
||||
.name = "large-decr",
|
||||
.description = "Allow Large Decrementer",
|
||||
|
@ -916,6 +969,7 @@ SPAPR_CAP_MIG_STATE(sbbc, SPAPR_CAP_SBBC);
|
|||
SPAPR_CAP_MIG_STATE(ibs, SPAPR_CAP_IBS);
|
||||
SPAPR_CAP_MIG_STATE(hpt_maxpagesize, SPAPR_CAP_HPT_MAXPAGESIZE);
|
||||
SPAPR_CAP_MIG_STATE(nested_kvm_hv, SPAPR_CAP_NESTED_KVM_HV);
|
||||
SPAPR_CAP_MIG_STATE(nested_papr, SPAPR_CAP_NESTED_PAPR);
|
||||
SPAPR_CAP_MIG_STATE(large_decr, SPAPR_CAP_LARGE_DECREMENTER);
|
||||
SPAPR_CAP_MIG_STATE(ccf_assist, SPAPR_CAP_CCF_ASSIST);
|
||||
SPAPR_CAP_MIG_STATE(fwnmi, SPAPR_CAP_FWNMI);
|
||||
|
|
|
@ -39,9 +39,13 @@ static void spapr_reset_vcpu(PowerPCCPU *cpu)
|
|||
|
||||
/*
|
||||
* "PowerPC Processor binding to IEEE 1275" defines the initial MSR state
|
||||
* as 32bit (MSR_SF=0) in "8.2.1. Initial Register Values".
|
||||
* as 32bit (MSR_SF=0) with MSR_ME=1 and MSR_FP=1 in "8.2.1. Initial
|
||||
* Register Values". This can also be found in "LoPAPR 1.1" "C.9.2.1
|
||||
* Initial Register Values".
|
||||
*/
|
||||
env->msr &= ~(1ULL << MSR_SF);
|
||||
env->msr |= (1ULL << MSR_ME) | (1ULL << MSR_FP);
|
||||
|
||||
env->spr[SPR_HIOR] = 0;
|
||||
|
||||
lpcr = env->spr[SPR_LPCR];
|
||||
|
@ -394,10 +398,8 @@ static const TypeInfo spapr_cpu_core_type_infos[] = {
|
|||
DEFINE_SPAPR_CPU_CORE_TYPE("power8_v2.0"),
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("power8e_v2.1"),
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("power8nvl_v1.0"),
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("power9_v1.0"),
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("power9_v2.0"),
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("power9_v2.2"),
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("power10_v1.0"),
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("power10_v2.0"),
|
||||
#ifdef CONFIG_KVM
|
||||
DEFINE_SPAPR_CPU_CORE_TYPE("host"),
|
||||
|
|
|
@ -1525,6 +1525,28 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn)
|
|||
*slot = fn;
|
||||
}
|
||||
|
||||
void spapr_unregister_hypercall(target_ulong opcode)
|
||||
{
|
||||
spapr_hcall_fn *slot;
|
||||
|
||||
if (opcode <= MAX_HCALL_OPCODE) {
|
||||
assert((opcode & 0x3) == 0);
|
||||
|
||||
slot = &papr_hypercall_table[opcode / 4];
|
||||
} else if (opcode >= SVM_HCALL_BASE && opcode <= SVM_HCALL_MAX) {
|
||||
/* we only have SVM-related hcall numbers assigned in multiples of 4 */
|
||||
assert((opcode & 0x3) == 0);
|
||||
|
||||
slot = &svm_hypercall_table[(opcode - SVM_HCALL_BASE) / 4];
|
||||
} else {
|
||||
assert((opcode >= KVMPPC_HCALL_BASE) && (opcode <= KVMPPC_HCALL_MAX));
|
||||
|
||||
slot = &kvmppc_hypercall_table[opcode - KVMPPC_HCALL_BASE];
|
||||
}
|
||||
|
||||
*slot = NULL;
|
||||
}
|
||||
|
||||
target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode,
|
||||
target_ulong *args)
|
||||
{
|
||||
|
@ -1638,8 +1660,6 @@ static void hypercall_register_types(void)
|
|||
spapr_register_hypercall(KVMPPC_H_CAS, h_client_architecture_support);
|
||||
|
||||
spapr_register_hypercall(KVMPPC_H_UPDATE_DT, h_update_dt);
|
||||
|
||||
spapr_register_nested();
|
||||
}
|
||||
|
||||
type_init(hypercall_register_types)
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue