From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33952) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VC6mj-0006Fd-2d for qemu-devel@nongnu.org; Wed, 21 Aug 2013 07:41:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VC6md-0000vV-5X for qemu-devel@nongnu.org; Wed, 21 Aug 2013 07:41:08 -0400 Received: from cantor2.suse.de ([195.135.220.15]:37278 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VC6mc-0000vC-OC for qemu-devel@nongnu.org; Wed, 21 Aug 2013 07:41:03 -0400 Message-ID: <5214A749.7080302@suse.de> Date: Wed, 21 Aug 2013 13:40:57 +0200 From: =?ISO-8859-15?Q?Andreas_F=E4rber?= MIME-Version: 1.0 References: <0577863ea4bc4e0d91675e4fd250c1065ba4ebd9.1377075625.git.hutao@cn.fujitsu.com> In-Reply-To: <0577863ea4bc4e0d91675e4fd250c1065ba4ebd9.1377075625.git.hutao@cn.fujitsu.com> Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PATCH 2/2] q35: add cpu hotplug support List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Hu Tao Cc: Igor Mammedov , qemu-devel@nongnu.org Am 21.08.2013 11:04, schrieb Hu Tao: > Signed-off-by: Hu Tao > --- > hw/acpi/ich9.c | 91 ++++++++++++++++++++++++++++++++++++++++++= ++++++-- > include/hw/acpi/ich9.h | 11 ++++++ > 2 files changed, 100 insertions(+), 2 deletions(-) >=20 > diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c > index 8717c15..146216a 100644 > --- a/hw/acpi/ich9.c > +++ b/hw/acpi/ich9.c > @@ -43,17 +43,22 @@ do { printf("%s "fmt, __func__, ## __VA_ARGS__); } = while (0) > #define ICH9_DEBUG(fmt, ...) do { } while (0) > #endif > =20 > + > +#define ICH9_CPU_HOTPLUG_STATUS 4 > + > static void pm_update_sci(ICH9LPCPMRegs *pm) > { > int sci_level, pm1a_sts; > =20 > pm1a_sts =3D acpi_pm1_evt_get_sts(&pm->acpi_regs); > =20 > - sci_level =3D (((pm1a_sts & pm->acpi_regs.pm1.evt.en) & > + sci_level =3D ((((pm1a_sts & pm->acpi_regs.pm1.evt.en) & > (ACPI_BITMASK_RT_CLOCK_ENABLE | > ACPI_BITMASK_POWER_BUTTON_ENABLE | > ACPI_BITMASK_GLOBAL_LOCK_ENABLE | > - ACPI_BITMASK_TIMER_ENABLE)) !=3D 0); > + ACPI_BITMASK_TIMER_ENABLE)) !=3D 0) || > + (((pm->acpi_regs.gpe.sts[0] & pm->acpi_regs.gpe.en[0]= ) & > + ICH9_CPU_HOTPLUG_STATUS) !=3D 0)); > qemu_set_irq(pm->irq, sci_level); > =20 > /* schedule a timer interruption if needed */ > @@ -93,6 +98,80 @@ static const MemoryRegionOps ich9_gpe_ops =3D { > .endianness =3D DEVICE_LITTLE_ENDIAN, > }; > =20 > +static uint64_t cpu_status_read(void *opaque, hwaddr addr, unsigned in= t size) > +{ > + ICH9LPCPMRegs *pm =3D opaque; > + CPUStatus *cpus =3D &pm->gpe_cpu; > + uint64_t val =3D cpus->sts[addr]; > + > + ICH9_DEBUG("addr: %" HWADDR_PRIx ", val: %" PRIx64 "\n", addr, val= ); > + > + return val; > +} > + > +static void cpu_status_write(void *opaque, hwaddr addr, uint64_t data, > + unsigned int size) > +{ > + /* TODO: implement VCPU removal on guest signal that CPU can be re= moved */ > +} > + > +static const MemoryRegionOps cpu_hotplug_ops =3D { > + .read =3D cpu_status_read, > + .write =3D cpu_status_write, > + .endianness =3D DEVICE_LITTLE_ENDIAN, > + .valid =3D { > + .min_access_size =3D 1, > + .max_access_size =3D 1, > + }, > +}; > + > +typedef enum { > + PLUG, > + UNPLUG, > +} HotplugEventType; > + > +static void ich9_cpu_hotplug_req(ICH9LPCPMRegs *pm, CPUState *cpu, > + HotplugEventType action) > +{ > + CPUStatus *g =3D &pm->gpe_cpu; > + ACPIGPE *gpe =3D &pm->acpi_regs.gpe; > + CPUClass *k =3D CPU_GET_CLASS(cpu); cc please. (c is not a reserved symbol, and other classes such as X86CPUClass could be used in the future.) > + int64_t cpu_id; > + > + assert(pm !=3D NULL); > + > + *gpe->sts =3D *gpe->sts | ICH9_CPU_HOTPLUG_STATUS; > + cpu_id =3D k->get_arch_id(CPU(cpu)); > + if (action =3D=3D PLUG) { > + g->sts[cpu_id / 8] |=3D (1 << (cpu_id % 8)); > + } else { > + g->sts[cpu_id / 8] &=3D ~(1 << (cpu_id % 8)); > + } > + > + ICH9_DEBUG("cpu_id: %"PRIx64", action: %s\n", cpu_id, > + action =3D=3D PLUG ? "PLUG" : "UNPLUG"); > + > + pm_update_sci(pm); > +} > + > +static void ich9_cpu_added_req(Notifier *n, void *opaque) > +{ > + ICH9LPCPMRegs *pm =3D container_of(n, ICH9LPCPMRegs, cpu_added_not= ifier); > + > + ich9_cpu_hotplug_req(pm, CPU(opaque), PLUG); > +} > + > +static void ich9_init_cpu_status(CPUState *cpu, void *data) > +{ > + CPUStatus *g =3D (CPUStatus *)data; > + CPUClass *k =3D CPU_GET_CLASS(cpu); cc > + int64_t id =3D k->get_arch_id(cpu); > + > + g_assert((id / 8) < ICH9_PROC_LEN); > + g->sts[id / 8] |=3D (1 << (id % 8)); > +} > + > + > static uint64_t ich9_smi_readl(void *opaque, hwaddr addr, unsigned wid= th) > { > ICH9LPCPMRegs *pm =3D opaque; > @@ -221,6 +300,12 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMReg= s *pm, > "apci-gpe0", ICH9_PMIO_GPE0_LEN); > memory_region_add_subregion(&pm->io, ICH9_PMIO_GPE0_STS, &pm->io_g= pe); > =20 > + qemu_for_each_cpu(ich9_init_cpu_status, &pm->gpe_cpu); Please don't copy this from i440fx, there are patches on the list dropping qemu_for_each_cpu(). Just use a for loop until they hit master - still waiting for reviews. Regards, Andreas > + memory_region_init_io(&pm->io_cpu, OBJECT(lpc_pci), &cpu_hotplug_o= ps, pm, > + "acpi-cpu-hotplug", ICH9_PROC_LEN); > + memory_region_add_subregion(pci_address_space_io(lpc_pci), ICH9_PR= OC_BASE, > + &pm->io_cpu); > + > memory_region_init_io(&pm->io_smi, OBJECT(lpc_pci), &ich9_smi_ops,= pm, > "apci-smi", 8); > memory_region_add_subregion(&pm->io, ICH9_PMIO_SMI_EN, &pm->io_smi= ); > @@ -229,4 +314,6 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs= *pm, > qemu_register_reset(pm_reset, pm); > pm->powerdown_notifier.notify =3D pm_powerdown_req; > qemu_register_powerdown_notifier(&pm->powerdown_notifier); > + pm->cpu_added_notifier.notify =3D ich9_cpu_added_req; > + qemu_register_cpu_added_notifier(&pm->cpu_added_notifier); > } > diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h > index b1fe71f..bac70c6 100644 > --- a/include/hw/acpi/ich9.h > +++ b/include/hw/acpi/ich9.h > @@ -23,6 +23,13 @@ > =20 > #include "hw/acpi/acpi.h" > =20 > +#define ICH9_PROC_BASE 0xaf00 > +#define ICH9_PROC_LEN 32 > + > +typedef struct CPUStatus { > + uint8_t sts[ICH9_PROC_LEN]; > +} CPUStatus; > + > typedef struct ICH9LPCPMRegs { > /* > * In ich9 spec says that pm1_cnt register is 32bit width and > @@ -31,8 +38,11 @@ typedef struct ICH9LPCPMRegs { > */ > ACPIREGS acpi_regs; > =20 > + CPUStatus gpe_cpu; > + > MemoryRegion io; > MemoryRegion io_gpe; > + MemoryRegion io_cpu; > MemoryRegion io_smi; > =20 > uint32_t smi_en; > @@ -42,6 +52,7 @@ typedef struct ICH9LPCPMRegs { > =20 > uint32_t pm_io_base; > Notifier powerdown_notifier; > + Notifier cpu_added_notifier; > } ICH9LPCPMRegs; > =20 > void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, >=20 --=20 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 N=FCrnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imend=F6rffer; HRB 16746 AG N=FCrnbe= rg