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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Peter Maydell
						Peter Maydell