ppc patch queue 2019-11-15
Several fixes for 4.2.0-rc2: fix mos6522 performance issue, xive/xics issues, fix /chosen device-tree on reset and KVM default cpu-model for all machine classes -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEzS913cjjpNwuT1Fz8ww4vT8vvjwFAl3Sd+MTHGx2aXZpZXJA cmVkaGF0LmNvbQAKCRDzDDi9Py++PJV0EACL450uGT2R41he9H69sCH5x7KXcAt1 V2fFMySJdNnDZTbvFu3ou7CtXFZ9qw6Gy1N4dWam+PgKxgY2zP0NWe1dsW31N/+6 NiRBaCavMtqGGWdNbUY0SrpfmWnrXiVlv1/2EWn9dC8JsCPVCLDd7TdZqWvb7sLT MNrjAJh+Uqok/p4u8ap6of5gv/X3+iYqqY9967kQpeEA9nF0F/c5fKMqWHNRUxcW bYPcvBM4Ud+slUfPIQ9qjUaXj5UXQzgOtT4XOzF81z5JEO/cfHXFyFYt/r8KC6B8 gXl4X9vRAdcVJJk272UGLdDON3xXem+IfAsqE481Auh7LdqEW/El+m0njm6Zjyg2 I+JNs/GwHjhM9Ta7RwACn1ihr3figRHJiRpHlFIn6olvH3lQ0yqgPrp1BYH6XPoT hSGgTZ1hR8NZfkzEaU8tCE1F/EIGghfHGdUNMuN3QuBublUfacMQvpIN9s8g8K2S mm22lgpOrqgv0hmsQwlPgYzxO/KB2o2Xyt7yV83wVdutHMCqrmmeyIzoB1cJG3Ky k9CWS99fGWTngli+bzMumeKBgWdRpkehQNneoKJuZgJhZ/DpVs7X2SDvyBHXjjTN KLrph1cusEyzCP6eR8EsZNvABSfHv9i7alqpE7lHZOdM2Sg0KTl7C0NSxHGMm7uK c4sfoSLg0vjyyA== =Ykn6 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/vivier2/tags/ppc-for-4.2-pull-request' into staging ppc patch queue 2019-11-15 Several fixes for 4.2.0-rc2: fix mos6522 performance issue, xive/xics issues, fix /chosen device-tree on reset and KVM default cpu-model for all machine classes # gpg: Signature made Mon 18 Nov 2019 10:52:19 GMT # gpg: using RSA key CD2F75DDC8E3A4DC2E4F5173F30C38BD3F2FBE3C # gpg: issuer "lvivier@redhat.com" # gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [full] # gpg: aka "Laurent Vivier <laurent@vivier.eu>" [full] # gpg: aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [full] # Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F 5173 F30C 38BD 3F2F BE3C * remotes/vivier2/tags/ppc-for-4.2-pull-request: mos6522: fix T1 and T2 timers spapr/kvm: Set default cpu model for all machine classes spapr: Add /chosen to FDT only at reset time to preserve kernel and initramdisk ppc: Skip partially initialized vCPUs in 'info pic' xive, xics: Fix reference counting on CPU objects ppc: Add intc_destroy() handlers to SpaprInterruptController/PnvChip Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
bbe165740a
@ -555,6 +555,15 @@ static void spapr_xive_cpu_intc_reset(SpaprInterruptController *intc,
|
||||
xive_tctx_set_os_cam(tctx, xive_nvt_cam_line(nvt_blk, nvt_idx));
|
||||
}
|
||||
|
||||
static void spapr_xive_cpu_intc_destroy(SpaprInterruptController *intc,
|
||||
PowerPCCPU *cpu)
|
||||
{
|
||||
SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
|
||||
xive_tctx_destroy(spapr_cpu->tctx);
|
||||
spapr_cpu->tctx = NULL;
|
||||
}
|
||||
|
||||
static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int val)
|
||||
{
|
||||
SpaprXive *xive = SPAPR_XIVE(intc);
|
||||
@ -692,6 +701,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
|
||||
sicc->deactivate = spapr_xive_deactivate;
|
||||
sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
|
||||
sicc->cpu_intc_reset = spapr_xive_cpu_intc_reset;
|
||||
sicc->cpu_intc_destroy = spapr_xive_cpu_intc_destroy;
|
||||
sicc->claim_irq = spapr_xive_claim_irq;
|
||||
sicc->free_irq = spapr_xive_free_irq;
|
||||
sicc->set_irq = spapr_xive_set_irq;
|
||||
|
@ -44,7 +44,16 @@
|
||||
|
||||
void icp_pic_print_info(ICPState *icp, Monitor *mon)
|
||||
{
|
||||
int cpu_index = icp->cs ? icp->cs->cpu_index : -1;
|
||||
int cpu_index;
|
||||
|
||||
/* Skip partially initialized vCPUs. This can happen on sPAPR when vCPUs
|
||||
* are hot plugged or unplugged.
|
||||
*/
|
||||
if (!icp) {
|
||||
return;
|
||||
}
|
||||
|
||||
cpu_index = icp->cs ? icp->cs->cpu_index : -1;
|
||||
|
||||
if (!icp->output) {
|
||||
return;
|
||||
@ -388,8 +397,10 @@ Object *icp_create(Object *cpu, const char *type, XICSFabric *xi, Error **errp)
|
||||
obj = object_new(type);
|
||||
object_property_add_child(cpu, type, obj, &error_abort);
|
||||
object_unref(obj);
|
||||
object_ref(OBJECT(xi));
|
||||
object_property_add_const_link(obj, ICP_PROP_XICS, OBJECT(xi),
|
||||
&error_abort);
|
||||
object_ref(cpu);
|
||||
object_property_add_const_link(obj, ICP_PROP_CPU, cpu, &error_abort);
|
||||
object_property_set_bool(obj, true, "realized", &local_err);
|
||||
if (local_err) {
|
||||
@ -401,6 +412,15 @@ Object *icp_create(Object *cpu, const char *type, XICSFabric *xi, Error **errp)
|
||||
return obj;
|
||||
}
|
||||
|
||||
void icp_destroy(ICPState *icp)
|
||||
{
|
||||
Object *obj = OBJECT(icp);
|
||||
|
||||
object_unref(object_property_get_link(obj, ICP_PROP_CPU, &error_abort));
|
||||
object_unref(object_property_get_link(obj, ICP_PROP_XICS, &error_abort));
|
||||
object_unparent(obj);
|
||||
}
|
||||
|
||||
/*
|
||||
* ICS: Source layer
|
||||
*/
|
||||
|
@ -352,6 +352,15 @@ static void xics_spapr_cpu_intc_reset(SpaprInterruptController *intc,
|
||||
icp_reset(spapr_cpu_state(cpu)->icp);
|
||||
}
|
||||
|
||||
static void xics_spapr_cpu_intc_destroy(SpaprInterruptController *intc,
|
||||
PowerPCCPU *cpu)
|
||||
{
|
||||
SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
|
||||
|
||||
icp_destroy(spapr_cpu->icp);
|
||||
spapr_cpu->icp = NULL;
|
||||
}
|
||||
|
||||
static int xics_spapr_claim_irq(SpaprInterruptController *intc, int irq,
|
||||
bool lsi, Error **errp)
|
||||
{
|
||||
@ -440,6 +449,7 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data)
|
||||
sicc->deactivate = xics_spapr_deactivate;
|
||||
sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
|
||||
sicc->cpu_intc_reset = xics_spapr_cpu_intc_reset;
|
||||
sicc->cpu_intc_destroy = xics_spapr_cpu_intc_destroy;
|
||||
sicc->claim_irq = xics_spapr_claim_irq;
|
||||
sicc->free_irq = xics_spapr_free_irq;
|
||||
sicc->set_irq = xics_spapr_set_irq;
|
||||
|
@ -523,9 +523,18 @@ static const char * const xive_tctx_ring_names[] = {
|
||||
|
||||
void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon)
|
||||
{
|
||||
int cpu_index = tctx->cs ? tctx->cs->cpu_index : -1;
|
||||
int cpu_index;
|
||||
int i;
|
||||
|
||||
/* Skip partially initialized vCPUs. This can happen on sPAPR when vCPUs
|
||||
* are hot plugged or unplugged.
|
||||
*/
|
||||
if (!tctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
cpu_index = tctx->cs ? tctx->cs->cpu_index : -1;
|
||||
|
||||
if (kvm_irqchip_in_kernel()) {
|
||||
Error *local_err = NULL;
|
||||
|
||||
@ -682,6 +691,7 @@ Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp)
|
||||
obj = object_new(TYPE_XIVE_TCTX);
|
||||
object_property_add_child(cpu, TYPE_XIVE_TCTX, obj, &error_abort);
|
||||
object_unref(obj);
|
||||
object_ref(cpu);
|
||||
object_property_add_const_link(obj, "cpu", cpu, &error_abort);
|
||||
object_property_set_bool(obj, true, "realized", &local_err);
|
||||
if (local_err) {
|
||||
@ -696,6 +706,14 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void xive_tctx_destroy(XiveTCTX *tctx)
|
||||
{
|
||||
Object *obj = OBJECT(tctx);
|
||||
|
||||
object_unref(object_property_get_link(obj, "cpu", &error_abort));
|
||||
object_unparent(obj);
|
||||
}
|
||||
|
||||
/*
|
||||
* XIVE ESB helpers
|
||||
*/
|
||||
|
@ -38,8 +38,10 @@
|
||||
|
||||
/* XXX: implement all timer modes */
|
||||
|
||||
static void mos6522_timer_update(MOS6522State *s, MOS6522Timer *ti,
|
||||
int64_t current_time);
|
||||
static void mos6522_timer1_update(MOS6522State *s, MOS6522Timer *ti,
|
||||
int64_t current_time);
|
||||
static void mos6522_timer2_update(MOS6522State *s, MOS6522Timer *ti,
|
||||
int64_t current_time);
|
||||
|
||||
static void mos6522_update_irq(MOS6522State *s)
|
||||
{
|
||||
@ -98,7 +100,11 @@ static void set_counter(MOS6522State *s, MOS6522Timer *ti, unsigned int val)
|
||||
trace_mos6522_set_counter(1 + ti->index, val);
|
||||
ti->load_time = get_load_time(s, ti);
|
||||
ti->counter_value = val;
|
||||
mos6522_timer_update(s, ti, ti->load_time);
|
||||
if (ti->index == 0) {
|
||||
mos6522_timer1_update(s, ti, ti->load_time);
|
||||
} else {
|
||||
mos6522_timer2_update(s, ti, ti->load_time);
|
||||
}
|
||||
}
|
||||
|
||||
static int64_t get_next_irq_time(MOS6522State *s, MOS6522Timer *ti,
|
||||
@ -130,19 +136,34 @@ static int64_t get_next_irq_time(MOS6522State *s, MOS6522Timer *ti,
|
||||
trace_mos6522_get_next_irq_time(ti->latch, d, next_time - d);
|
||||
next_time = muldiv64(next_time, NANOSECONDS_PER_SECOND, ti->frequency) +
|
||||
ti->load_time;
|
||||
|
||||
if (next_time <= current_time) {
|
||||
next_time = current_time + 1;
|
||||
}
|
||||
return next_time;
|
||||
}
|
||||
|
||||
static void mos6522_timer_update(MOS6522State *s, MOS6522Timer *ti,
|
||||
static void mos6522_timer1_update(MOS6522State *s, MOS6522Timer *ti,
|
||||
int64_t current_time)
|
||||
{
|
||||
if (!ti->timer) {
|
||||
return;
|
||||
}
|
||||
if (ti->index == 0 && (s->acr & T1MODE) != T1MODE_CONT) {
|
||||
if ((s->ier & T1_INT) == 0 || (s->acr & T1MODE) != T1MODE_CONT) {
|
||||
timer_del(ti->timer);
|
||||
} else {
|
||||
ti->next_irq_time = get_next_irq_time(s, ti, current_time);
|
||||
timer_mod(ti->timer, ti->next_irq_time);
|
||||
}
|
||||
}
|
||||
|
||||
static void mos6522_timer2_update(MOS6522State *s, MOS6522Timer *ti,
|
||||
int64_t current_time)
|
||||
{
|
||||
if (!ti->timer) {
|
||||
return;
|
||||
}
|
||||
if ((s->ier & T2_INT) == 0) {
|
||||
timer_del(ti->timer);
|
||||
} else {
|
||||
ti->next_irq_time = get_next_irq_time(s, ti, current_time);
|
||||
@ -155,7 +176,7 @@ static void mos6522_timer1(void *opaque)
|
||||
MOS6522State *s = opaque;
|
||||
MOS6522Timer *ti = &s->timers[0];
|
||||
|
||||
mos6522_timer_update(s, ti, ti->next_irq_time);
|
||||
mos6522_timer1_update(s, ti, ti->next_irq_time);
|
||||
s->ifr |= T1_INT;
|
||||
mos6522_update_irq(s);
|
||||
}
|
||||
@ -165,7 +186,7 @@ static void mos6522_timer2(void *opaque)
|
||||
MOS6522State *s = opaque;
|
||||
MOS6522Timer *ti = &s->timers[1];
|
||||
|
||||
mos6522_timer_update(s, ti, ti->next_irq_time);
|
||||
mos6522_timer2_update(s, ti, ti->next_irq_time);
|
||||
s->ifr |= T2_INT;
|
||||
mos6522_update_irq(s);
|
||||
}
|
||||
@ -204,7 +225,16 @@ uint64_t mos6522_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
MOS6522State *s = opaque;
|
||||
uint32_t val;
|
||||
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
|
||||
if (now >= s->timers[0].next_irq_time) {
|
||||
mos6522_timer1_update(s, &s->timers[0], now);
|
||||
s->ifr |= T1_INT;
|
||||
}
|
||||
if (now >= s->timers[1].next_irq_time) {
|
||||
mos6522_timer2_update(s, &s->timers[1], now);
|
||||
s->ifr |= T2_INT;
|
||||
}
|
||||
switch (addr) {
|
||||
case VIA_REG_B:
|
||||
val = s->b;
|
||||
@ -299,8 +329,8 @@ void mos6522_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
|
||||
break;
|
||||
case VIA_REG_T1CL:
|
||||
s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
|
||||
mos6522_timer_update(s, &s->timers[0],
|
||||
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
|
||||
mos6522_timer1_update(s, &s->timers[0],
|
||||
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
|
||||
break;
|
||||
case VIA_REG_T1CH:
|
||||
s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
|
||||
@ -309,14 +339,14 @@ void mos6522_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
|
||||
break;
|
||||
case VIA_REG_T1LL:
|
||||
s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
|
||||
mos6522_timer_update(s, &s->timers[0],
|
||||
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
|
||||
mos6522_timer1_update(s, &s->timers[0],
|
||||
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
|
||||
break;
|
||||
case VIA_REG_T1LH:
|
||||
s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
|
||||
s->ifr &= ~T1_INT;
|
||||
mos6522_timer_update(s, &s->timers[0],
|
||||
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
|
||||
mos6522_timer1_update(s, &s->timers[0],
|
||||
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
|
||||
break;
|
||||
case VIA_REG_T2CL:
|
||||
s->timers[1].latch = (s->timers[1].latch & 0xff00) | val;
|
||||
@ -334,8 +364,8 @@ void mos6522_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
|
||||
break;
|
||||
case VIA_REG_ACR:
|
||||
s->acr = val;
|
||||
mos6522_timer_update(s, &s->timers[0],
|
||||
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
|
||||
mos6522_timer1_update(s, &s->timers[0],
|
||||
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
|
||||
break;
|
||||
case VIA_REG_PCR:
|
||||
s->pcr = val;
|
||||
@ -354,6 +384,11 @@ void mos6522_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
|
||||
s->ier &= ~val;
|
||||
}
|
||||
mos6522_update_irq(s);
|
||||
/* if IER is modified starts needed timers */
|
||||
mos6522_timer1_update(s, &s->timers[0],
|
||||
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
|
||||
mos6522_timer2_update(s, &s->timers[1],
|
||||
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
|
||||
break;
|
||||
default:
|
||||
case VIA_REG_ANH:
|
||||
@ -426,9 +461,11 @@ static void mos6522_reset(DeviceState *dev)
|
||||
s->timers[0].frequency = s->frequency;
|
||||
s->timers[0].latch = 0xffff;
|
||||
set_counter(s, &s->timers[0], 0xffff);
|
||||
timer_del(s->timers[0].timer);
|
||||
|
||||
s->timers[1].frequency = s->frequency;
|
||||
s->timers[1].latch = 0xffff;
|
||||
timer_del(s->timers[1].timer);
|
||||
}
|
||||
|
||||
static void mos6522_init(Object *obj)
|
||||
|
21
hw/ppc/pnv.c
21
hw/ppc/pnv.c
@ -778,6 +778,7 @@ static void pnv_chip_power8_intc_create(PnvChip *chip, PowerPCCPU *cpu,
|
||||
pnv_cpu->intc = obj;
|
||||
}
|
||||
|
||||
|
||||
static void pnv_chip_power8_intc_reset(PnvChip *chip, PowerPCCPU *cpu)
|
||||
{
|
||||
PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
|
||||
@ -785,6 +786,14 @@ static void pnv_chip_power8_intc_reset(PnvChip *chip, PowerPCCPU *cpu)
|
||||
icp_reset(ICP(pnv_cpu->intc));
|
||||
}
|
||||
|
||||
static void pnv_chip_power8_intc_destroy(PnvChip *chip, PowerPCCPU *cpu)
|
||||
{
|
||||
PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
|
||||
|
||||
icp_destroy(ICP(pnv_cpu->intc));
|
||||
pnv_cpu->intc = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* 0:48 Reserved - Read as zeroes
|
||||
* 49:52 Node ID
|
||||
@ -829,6 +838,14 @@ static void pnv_chip_power9_intc_reset(PnvChip *chip, PowerPCCPU *cpu)
|
||||
xive_tctx_reset(XIVE_TCTX(pnv_cpu->intc));
|
||||
}
|
||||
|
||||
static void pnv_chip_power9_intc_destroy(PnvChip *chip, PowerPCCPU *cpu)
|
||||
{
|
||||
PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
|
||||
|
||||
xive_tctx_destroy(XIVE_TCTX(pnv_cpu->intc));
|
||||
pnv_cpu->intc = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allowed core identifiers on a POWER8 Processor Chip :
|
||||
*
|
||||
@ -999,6 +1016,7 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
|
||||
k->core_pir = pnv_chip_core_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;
|
||||
k->isa_create = pnv_chip_power8_isa_create;
|
||||
k->dt_populate = pnv_chip_power8_dt_populate;
|
||||
k->pic_print_info = pnv_chip_power8_pic_print_info;
|
||||
@ -1019,6 +1037,7 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, void *data)
|
||||
k->core_pir = pnv_chip_core_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;
|
||||
k->isa_create = pnv_chip_power8_isa_create;
|
||||
k->dt_populate = pnv_chip_power8_dt_populate;
|
||||
k->pic_print_info = pnv_chip_power8_pic_print_info;
|
||||
@ -1039,6 +1058,7 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data)
|
||||
k->core_pir = pnv_chip_core_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;
|
||||
k->isa_create = pnv_chip_power8nvl_isa_create;
|
||||
k->dt_populate = pnv_chip_power8_dt_populate;
|
||||
k->pic_print_info = pnv_chip_power8_pic_print_info;
|
||||
@ -1209,6 +1229,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
|
||||
k->core_pir = pnv_chip_core_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;
|
||||
k->isa_create = pnv_chip_power9_isa_create;
|
||||
k->dt_populate = pnv_chip_power9_dt_populate;
|
||||
k->pic_print_info = pnv_chip_power9_pic_print_info;
|
||||
|
@ -269,11 +269,12 @@ err:
|
||||
error_propagate(errp, local_err);
|
||||
}
|
||||
|
||||
static void pnv_core_cpu_unrealize(PowerPCCPU *cpu)
|
||||
static void pnv_core_cpu_unrealize(PowerPCCPU *cpu, PnvChip *chip)
|
||||
{
|
||||
PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
|
||||
PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
|
||||
|
||||
object_unparent(OBJECT(pnv_cpu_state(cpu)->intc));
|
||||
pcc->intc_destroy(chip, cpu);
|
||||
cpu_remove_sync(CPU(cpu));
|
||||
cpu->machine_data = NULL;
|
||||
g_free(pnv_cpu);
|
||||
@ -289,7 +290,7 @@ static void pnv_core_unrealize(DeviceState *dev, Error **errp)
|
||||
qemu_unregister_reset(pnv_core_reset, pc);
|
||||
|
||||
for (i = 0; i < cc->nr_threads; i++) {
|
||||
pnv_core_cpu_unrealize(pc->threads[i]);
|
||||
pnv_core_cpu_unrealize(pc->threads[i], pc->chip);
|
||||
}
|
||||
g_free(pc->threads);
|
||||
}
|
||||
|
@ -917,7 +917,7 @@ static bool spapr_hotplugged_dev_before_cas(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
static void *spapr_build_fdt(SpaprMachineState *spapr);
|
||||
static void *spapr_build_fdt(SpaprMachineState *spapr, bool reset);
|
||||
|
||||
int spapr_h_cas_compose_response(SpaprMachineState *spapr,
|
||||
target_ulong addr, target_ulong size,
|
||||
@ -939,7 +939,7 @@ int spapr_h_cas_compose_response(SpaprMachineState *spapr,
|
||||
|
||||
size -= sizeof(hdr);
|
||||
|
||||
fdt = spapr_build_fdt(spapr);
|
||||
fdt = spapr_build_fdt(spapr, false);
|
||||
_FDT((fdt_pack(fdt)));
|
||||
|
||||
if (fdt_totalsize(fdt) + sizeof(hdr) > size) {
|
||||
@ -1197,7 +1197,7 @@ static void spapr_dt_hypervisor(SpaprMachineState *spapr, void *fdt)
|
||||
}
|
||||
}
|
||||
|
||||
static void *spapr_build_fdt(SpaprMachineState *spapr)
|
||||
static void *spapr_build_fdt(SpaprMachineState *spapr, bool reset)
|
||||
{
|
||||
MachineState *machine = MACHINE(spapr);
|
||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||
@ -1297,7 +1297,9 @@ static void *spapr_build_fdt(SpaprMachineState *spapr)
|
||||
spapr_dt_rtas(spapr, fdt);
|
||||
|
||||
/* /chosen */
|
||||
spapr_dt_chosen(spapr, fdt);
|
||||
if (reset) {
|
||||
spapr_dt_chosen(spapr, fdt);
|
||||
}
|
||||
|
||||
/* /hypervisor */
|
||||
if (kvm_enabled()) {
|
||||
@ -1305,11 +1307,14 @@ static void *spapr_build_fdt(SpaprMachineState *spapr)
|
||||
}
|
||||
|
||||
/* Build memory reserve map */
|
||||
if (spapr->kernel_size) {
|
||||
_FDT((fdt_add_mem_rsv(fdt, KERNEL_LOAD_ADDR, spapr->kernel_size)));
|
||||
}
|
||||
if (spapr->initrd_size) {
|
||||
_FDT((fdt_add_mem_rsv(fdt, spapr->initrd_base, spapr->initrd_size)));
|
||||
if (reset) {
|
||||
if (spapr->kernel_size) {
|
||||
_FDT((fdt_add_mem_rsv(fdt, KERNEL_LOAD_ADDR, spapr->kernel_size)));
|
||||
}
|
||||
if (spapr->initrd_size) {
|
||||
_FDT((fdt_add_mem_rsv(fdt, spapr->initrd_base,
|
||||
spapr->initrd_size)));
|
||||
}
|
||||
}
|
||||
|
||||
/* ibm,client-architecture-support updates */
|
||||
@ -1718,7 +1723,7 @@ static void spapr_machine_reset(MachineState *machine)
|
||||
*/
|
||||
fdt_addr = MIN(spapr->rma_size, RTAS_MAX_ADDR) - FDT_MAX_SIZE;
|
||||
|
||||
fdt = spapr_build_fdt(spapr);
|
||||
fdt = spapr_build_fdt(spapr, true);
|
||||
|
||||
rc = fdt_pack(fdt);
|
||||
|
||||
|
@ -195,12 +195,7 @@ static void spapr_unrealize_vcpu(PowerPCCPU *cpu, SpaprCpuCore *sc)
|
||||
if (!sc->pre_3_0_migration) {
|
||||
vmstate_unregister(NULL, &vmstate_spapr_cpu_state, cpu->machine_data);
|
||||
}
|
||||
if (spapr_cpu_state(cpu)->icp) {
|
||||
object_unparent(OBJECT(spapr_cpu_state(cpu)->icp));
|
||||
}
|
||||
if (spapr_cpu_state(cpu)->tctx) {
|
||||
object_unparent(OBJECT(spapr_cpu_state(cpu)->tctx));
|
||||
}
|
||||
spapr_irq_cpu_intc_destroy(SPAPR_MACHINE(qdev_get_machine()), cpu);
|
||||
cpu_remove_sync(CPU(cpu));
|
||||
object_unparent(OBJECT(cpu));
|
||||
}
|
||||
|
@ -234,6 +234,20 @@ void spapr_irq_cpu_intc_reset(SpaprMachineState *spapr, PowerPCCPU *cpu)
|
||||
}
|
||||
}
|
||||
|
||||
void spapr_irq_cpu_intc_destroy(SpaprMachineState *spapr, PowerPCCPU *cpu)
|
||||
{
|
||||
SpaprInterruptController *intcs[] = ALL_INTCS(spapr);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(intcs); i++) {
|
||||
SpaprInterruptController *intc = intcs[i];
|
||||
if (intc) {
|
||||
SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc);
|
||||
sicc->cpu_intc_destroy(intc, cpu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void spapr_set_irq(void *opaque, int irq, int level)
|
||||
{
|
||||
SpaprMachineState *spapr = SPAPR_MACHINE(opaque);
|
||||
|
@ -112,6 +112,7 @@ typedef struct PnvChipClass {
|
||||
uint32_t (*core_pir)(PnvChip *chip, uint32_t core_id);
|
||||
void (*intc_create)(PnvChip *chip, PowerPCCPU *cpu, Error **errp);
|
||||
void (*intc_reset)(PnvChip *chip, PowerPCCPU *cpu);
|
||||
void (*intc_destroy)(PnvChip *chip, PowerPCCPU *cpu);
|
||||
ISABus *(*isa_create)(PnvChip *chip, Error **errp);
|
||||
void (*dt_populate)(PnvChip *chip, void *fdt);
|
||||
void (*pic_print_info)(PnvChip *chip, Monitor *mon);
|
||||
|
@ -53,6 +53,7 @@ typedef struct SpaprInterruptControllerClass {
|
||||
int (*cpu_intc_create)(SpaprInterruptController *intc,
|
||||
PowerPCCPU *cpu, Error **errp);
|
||||
void (*cpu_intc_reset)(SpaprInterruptController *intc, PowerPCCPU *cpu);
|
||||
void (*cpu_intc_destroy)(SpaprInterruptController *intc, PowerPCCPU *cpu);
|
||||
int (*claim_irq)(SpaprInterruptController *intc, int irq, bool lsi,
|
||||
Error **errp);
|
||||
void (*free_irq)(SpaprInterruptController *intc, int irq);
|
||||
@ -70,6 +71,7 @@ void spapr_irq_update_active_intc(SpaprMachineState *spapr);
|
||||
int spapr_irq_cpu_intc_create(SpaprMachineState *spapr,
|
||||
PowerPCCPU *cpu, Error **errp);
|
||||
void spapr_irq_cpu_intc_reset(SpaprMachineState *spapr, PowerPCCPU *cpu);
|
||||
void spapr_irq_cpu_intc_destroy(SpaprMachineState *spapr, PowerPCCPU *cpu);
|
||||
void spapr_irq_print_info(SpaprMachineState *spapr, Monitor *mon);
|
||||
void spapr_irq_dt(SpaprMachineState *spapr, uint32_t nr_servers,
|
||||
void *fdt, uint32_t phandle);
|
||||
|
@ -181,6 +181,7 @@ void icp_resend(ICPState *ss);
|
||||
|
||||
Object *icp_create(Object *cpu, const char *type, XICSFabric *xi,
|
||||
Error **errp);
|
||||
void icp_destroy(ICPState *icp);
|
||||
|
||||
/* KVM */
|
||||
void icp_get_kvm_state(ICPState *icp);
|
||||
|
@ -416,6 +416,7 @@ uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, unsigned size);
|
||||
void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon);
|
||||
Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp);
|
||||
void xive_tctx_reset(XiveTCTX *tctx);
|
||||
void xive_tctx_destroy(XiveTCTX *tctx);
|
||||
|
||||
static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx)
|
||||
{
|
||||
|
@ -100,7 +100,7 @@ static bool kvmppc_is_pr(KVMState *ks)
|
||||
return kvm_vm_check_extension(ks, KVM_CAP_PPC_GET_PVINFO) != 0;
|
||||
}
|
||||
|
||||
static int kvm_ppc_register_host_cpu_type(MachineState *ms);
|
||||
static int kvm_ppc_register_host_cpu_type(void);
|
||||
static void kvmppc_get_cpu_characteristics(KVMState *s);
|
||||
static int kvmppc_get_dec_bits(void);
|
||||
|
||||
@ -147,7 +147,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
kvm_ppc_register_host_cpu_type(ms);
|
||||
kvm_ppc_register_host_cpu_type();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2534,13 +2534,19 @@ PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void)
|
||||
return pvr_pcc;
|
||||
}
|
||||
|
||||
static int kvm_ppc_register_host_cpu_type(MachineState *ms)
|
||||
static void pseries_machine_class_fixup(ObjectClass *oc, void *opaque)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
|
||||
mc->default_cpu_type = TYPE_HOST_POWERPC_CPU;
|
||||
}
|
||||
|
||||
static int kvm_ppc_register_host_cpu_type(void)
|
||||
{
|
||||
TypeInfo type_info = {
|
||||
.name = TYPE_HOST_POWERPC_CPU,
|
||||
.class_init = kvmppc_host_cpu_class_init,
|
||||
};
|
||||
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||||
PowerPCCPUClass *pvr_pcc;
|
||||
ObjectClass *oc;
|
||||
DeviceClass *dc;
|
||||
@ -2552,10 +2558,9 @@ static int kvm_ppc_register_host_cpu_type(MachineState *ms)
|
||||
}
|
||||
type_info.parent = object_class_get_name(OBJECT_CLASS(pvr_pcc));
|
||||
type_register(&type_info);
|
||||
if (object_dynamic_cast(OBJECT(ms), TYPE_SPAPR_MACHINE)) {
|
||||
/* override TCG default cpu type with 'host' cpu model */
|
||||
mc->default_cpu_type = TYPE_HOST_POWERPC_CPU;
|
||||
}
|
||||
/* override TCG default cpu type with 'host' cpu model */
|
||||
object_class_foreach(pseries_machine_class_fixup, TYPE_SPAPR_MACHINE,
|
||||
false, NULL);
|
||||
|
||||
oc = object_class_by_name(type_info.name);
|
||||
g_assert(oc);
|
||||
|
Loading…
Reference in New Issue
Block a user