Re: [Qemu-devel] [RFC PATCH v1 06/13] spapr: CPU hotplug support
On Fri, Jan 23, 2015 at 01:41:38PM +0100, Igor Mammedov wrote: On Thu, 8 Jan 2015 11:40:13 +0530 Bharata B Rao bhar...@linux.vnet.ibm.com wrote: Support CPU hotplug via device-add command. Use the exising EPOW event infrastructure to send CPU hotplug notification to the guest. Signed-off-by: Bharata B Rao bhar...@linux.vnet.ibm.com --- hw/ppc/spapr.c | 205 +++- hw/ppc/spapr_events.c | 8 +- target-ppc/translate_init.c | 6 ++ 3 files changed, 215 insertions(+), 4 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 515d770..a293a59 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -330,6 +330,8 @@ static void add_str(GString *s, const gchar *s1) g_string_append_len(s, s1, strlen(s1) + 1); } +uint32_t cpus_per_socket; static ??? Sure. + +static void spapr_cpu_plug(HotplugHandler *hotplug_dev, DeviceState *dev, +Error **errp) +{ +Error *local_err = NULL; +CPUState *cs = CPU(dev); +PowerPCCPU *cpu = POWERPC_CPU(cs); +sPAPRDRConnector *drc = +spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, cpu-cpu_dt_id); just rant: does this have any relation to hotplug_dev, the point here is to get these data from hotplug_dev object/some child of it rather then via direct adhoc call. I see how hotplug_dev is being used to pass on the plug request to ACPI, but have to check how hotplug_dev can be used more meaningfully here. + +/* TODO: Check if DR is enabled ? */ +g_assert(drc); + +spapr_cpu_reset(POWERPC_CPU(CPU(dev))); reset probably should be don at realize time, see x86_cpu_realizefn() for example. Yes, can be done. +spapr_cpu_hotplug_add(dev, cs); +spapr_hotplug_req_add_event(drc); +error_propagate(errp, local_err); +return; +} + +static void spapr_machine_device_plug(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ +if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { +if (dev-hotplugged) { +spapr_cpu_plug(hotplug_dev, dev, errp); Would be nicer if this could do cold-plugged CPUs wiring too. Yes, will check and see how intrusive change that would be. diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 9c642a5..cf9d8d3 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -32,6 +32,7 @@ #include hw/qdev-properties.h #include hw/ppc/spapr.h #include hw/ppc/ppc.h +#include sysemu/sysemu.h //#define PPC_DUMP_CPU //#define PPC_DEBUG_SPR @@ -8909,6 +8910,11 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) return; } +if (cs-cpu_index = max_cpus) { pls note that cpu_index is monotonically increases, so when you do unplug and then plug it will go above max_cpus or the same will happen if one device_add fails in the middle, the next CPU add will fail because of cs-cpu_index goes overboard. I'd suggest not to rely/use cpu_index for any purposes and use other means to identify where cpu is plugged in. On x68 we slowly getting rid of this dependency in favor of apic_id (topology information), eventually it could become: -device cpu_foo,socket=X,core=Y[,thread=Z][,node=N] you probably could do the same. It doesn't have to be in this series, just be aware of potential issues. I see your point and this needs to be fixed as I see this causing problems with CPU removal (from the middle) and subsequent addition (which makes use of vcpu fd parking and reuse mechanism). Thanks for your review. Regards, Bharata.
Re: [Qemu-devel] [RFC PATCH v1 06/13] spapr: CPU hotplug support
On Thu, Jan 08, 2015 at 11:40:13AM +0530, Bharata B Rao wrote: Support CPU hotplug via device-add command. Use the exising EPOW event infrastructure to send CPU hotplug notification to the guest. Signed-off-by: Bharata B Rao bhar...@linux.vnet.ibm.com --- hw/ppc/spapr.c | 205 +++- hw/ppc/spapr_events.c | 8 +- target-ppc/translate_init.c | 6 ++ 3 files changed, 215 insertions(+), 4 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 515d770..a293a59 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -330,6 +330,8 @@ static void add_str(GString *s, const gchar *s1) g_string_append_len(s, s1, strlen(s1) + 1); } +uint32_t cpus_per_socket; + static void *spapr_create_fdt_skel(hwaddr initrd_base, hwaddr initrd_size, hwaddr kernel_size, @@ -350,9 +352,9 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base, unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80}; QemuOpts *opts = qemu_opts_find(qemu_find_opts(smp-opts), NULL); unsigned sockets = opts ? qemu_opt_get_number(opts, sockets, 0) : 0; -uint32_t cpus_per_socket = sockets ? (smp_cpus / sockets) : 1; char *buf; +cpus_per_socket = sockets ? (smp_cpus / sockets) : 1; add_str(hypertas, hcall-pft); add_str(hypertas, hcall-term); add_str(hypertas, hcall-dabr); @@ -1744,12 +1746,209 @@ static void spapr_nmi(NMIState *n, int cpu_index, Error **errp) } } +/* TODO: Duplicates code from spapr_create_fdt_skel(), Fix this */ Uh, yeah, you should fix this. I think you probably want to move the filling out of the cpu dt information from create_fdt_skel() to finalize_fdt(), then you should be able to use a common helper function. +static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset, +int drc_index) +{ +PowerPCCPU *cpu = POWERPC_CPU(cs); +CPUPPCState *env = cpu-env; +PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs); +int index = ppc_get_vcpu_dt_id(cpu); +uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40), + 0x, 0x}; +uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TIMEBASE_FREQ; +uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 10; +uint32_t page_sizes_prop[64]; +size_t page_sizes_prop_size; +int smpt = ppc_get_compat_smt_threads(cpu); +uint32_t servers_prop[smpt]; +uint32_t gservers_prop[smpt * 2]; +int i; +uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr-htab_shift)}; +uint32_t associativity[] = {cpu_to_be32(0x5), +cpu_to_be32(0x0), +cpu_to_be32(0x0), +cpu_to_be32(0x0), +cpu_to_be32(cs-numa_node), +cpu_to_be32(index)}; + +_FDT((fdt_setprop_cell(fdt, offset, reg, index))); +_FDT((fdt_setprop_string(fdt, offset, device_type, cpu))); + +_FDT((fdt_setprop_cell(fdt, offset, cpu-version, env-spr[SPR_PVR]))); +_FDT((fdt_setprop_cell(fdt, offset, d-cache-block-size, +env-dcache_line_size))); +_FDT((fdt_setprop_cell(fdt, offset, d-cache-line-size, +env-dcache_line_size))); +_FDT((fdt_setprop_cell(fdt, offset, i-cache-block-size, +env-icache_line_size))); +_FDT((fdt_setprop_cell(fdt, offset, i-cache-line-size, +env-icache_line_size))); + +if (pcc-l1_dcache_size) { +_FDT((fdt_setprop_cell(fdt, offset, d-cache-size, +pcc-l1_dcache_size))); +} else { +fprintf(stderr, Warning: Unknown L1 dcache size for cpu\n); +} +if (pcc-l1_icache_size) { +_FDT((fdt_setprop_cell(fdt, offset, i-cache-size, +pcc-l1_icache_size))); +} else { +fprintf(stderr, Warning: Unknown L1 icache size for cpu\n); +} + +_FDT((fdt_setprop_cell(fdt, offset, timebase-frequency, tbfreq))); +_FDT((fdt_setprop_cell(fdt, offset, clock-frequency, cpufreq))); +_FDT((fdt_setprop_cell(fdt, offset, ibm,slb-size, env-slb_nr))); +_FDT((fdt_setprop_string(fdt, offset, status, okay))); +_FDT((fdt_setprop(fdt, offset, 64-bit, NULL, 0))); + +if (env-spr_cb[SPR_PURR].oea_read) { +_FDT((fdt_setprop(fdt, offset, ibm,purr, NULL, 0))); +} + +if (env-mmu_model POWERPC_MMU_1TSEG) { +_FDT((fdt_setprop(fdt, offset, ibm,processor-segment-sizes, + segs, sizeof(segs; +} + +/* Advertise VMX/VSX (vector extensions) if available + * 0 / no property == no vector extensions + * 1 == VMX / Altivec available + * 2 == VSX available */ +if (env-insns_flags PPC_ALTIVEC) { +
Re: [Qemu-devel] [RFC PATCH v1 06/13] spapr: CPU hotplug support
On Thu, Jan 22, 2015 at 04:16:01PM -0600, Michael Roth wrote: Quoting Bharata B Rao (2015-01-08 00:10:13) +static void spapr_machine_device_plug(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ +if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { +if (dev-hotplugged) { Maybe just if (dev-hotplugged spapr-dr_cpu_enabled) { ... Would do it This is a common -plug() handler and would be used for memory too. Hence there is a need to identify the type of object (CPU or memory) and handle it differently. Regards, Bharata.
Re: [Qemu-devel] [RFC PATCH v1 06/13] spapr: CPU hotplug support
Quoting Bharata B Rao (2015-01-27 22:19:56) On Thu, Jan 22, 2015 at 04:16:01PM -0600, Michael Roth wrote: Quoting Bharata B Rao (2015-01-08 00:10:13) +static void spapr_machine_device_plug(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ +if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { +if (dev-hotplugged) { Maybe just if (dev-hotplugged spapr-dr_cpu_enabled) { ... Would do it This is a common -plug() handler and would be used for memory too. Hence there is a need to identify the type of object (CPU or memory) and handle it differently. I mean in terms of the /* TODO: Check if DR is enabled ? */. Adding this check here, as well as during spapr_dr_connector_new(), should cover all the cases where the value needs to be checked AFAICT. Regards, Bharata.
Re: [Qemu-devel] [RFC PATCH v1 06/13] spapr: CPU hotplug support
On Thu, 8 Jan 2015 11:40:13 +0530 Bharata B Rao bhar...@linux.vnet.ibm.com wrote: Support CPU hotplug via device-add command. Use the exising EPOW event infrastructure to send CPU hotplug notification to the guest. Signed-off-by: Bharata B Rao bhar...@linux.vnet.ibm.com --- hw/ppc/spapr.c | 205 +++- hw/ppc/spapr_events.c | 8 +- target-ppc/translate_init.c | 6 ++ 3 files changed, 215 insertions(+), 4 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 515d770..a293a59 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -330,6 +330,8 @@ static void add_str(GString *s, const gchar *s1) g_string_append_len(s, s1, strlen(s1) + 1); } +uint32_t cpus_per_socket; static ??? + static void *spapr_create_fdt_skel(hwaddr initrd_base, hwaddr initrd_size, hwaddr kernel_size, @@ -350,9 +352,9 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base, unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80}; QemuOpts *opts = qemu_opts_find(qemu_find_opts(smp-opts), NULL); unsigned sockets = opts ? qemu_opt_get_number(opts, sockets, 0) : 0; -uint32_t cpus_per_socket = sockets ? (smp_cpus / sockets) : 1; char *buf; +cpus_per_socket = sockets ? (smp_cpus / sockets) : 1; add_str(hypertas, hcall-pft); add_str(hypertas, hcall-term); add_str(hypertas, hcall-dabr); @@ -1744,12 +1746,209 @@ static void spapr_nmi(NMIState *n, int cpu_index, Error **errp) } } +/* TODO: Duplicates code from spapr_create_fdt_skel(), Fix this */ +static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset, +int drc_index) +{ +PowerPCCPU *cpu = POWERPC_CPU(cs); +CPUPPCState *env = cpu-env; +PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs); +int index = ppc_get_vcpu_dt_id(cpu); +uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40), + 0x, 0x}; +uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TIMEBASE_FREQ; +uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 10; +uint32_t page_sizes_prop[64]; +size_t page_sizes_prop_size; +int smpt = ppc_get_compat_smt_threads(cpu); +uint32_t servers_prop[smpt]; +uint32_t gservers_prop[smpt * 2]; +int i; +uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr-htab_shift)}; +uint32_t associativity[] = {cpu_to_be32(0x5), +cpu_to_be32(0x0), +cpu_to_be32(0x0), +cpu_to_be32(0x0), +cpu_to_be32(cs-numa_node), +cpu_to_be32(index)}; + +_FDT((fdt_setprop_cell(fdt, offset, reg, index))); +_FDT((fdt_setprop_string(fdt, offset, device_type, cpu))); + +_FDT((fdt_setprop_cell(fdt, offset, cpu-version, env-spr[SPR_PVR]))); +_FDT((fdt_setprop_cell(fdt, offset, d-cache-block-size, +env-dcache_line_size))); +_FDT((fdt_setprop_cell(fdt, offset, d-cache-line-size, +env-dcache_line_size))); +_FDT((fdt_setprop_cell(fdt, offset, i-cache-block-size, +env-icache_line_size))); +_FDT((fdt_setprop_cell(fdt, offset, i-cache-line-size, +env-icache_line_size))); + +if (pcc-l1_dcache_size) { +_FDT((fdt_setprop_cell(fdt, offset, d-cache-size, +pcc-l1_dcache_size))); +} else { +fprintf(stderr, Warning: Unknown L1 dcache size for cpu\n); +} +if (pcc-l1_icache_size) { +_FDT((fdt_setprop_cell(fdt, offset, i-cache-size, +pcc-l1_icache_size))); +} else { +fprintf(stderr, Warning: Unknown L1 icache size for cpu\n); +} + +_FDT((fdt_setprop_cell(fdt, offset, timebase-frequency, tbfreq))); +_FDT((fdt_setprop_cell(fdt, offset, clock-frequency, cpufreq))); +_FDT((fdt_setprop_cell(fdt, offset, ibm,slb-size, env-slb_nr))); +_FDT((fdt_setprop_string(fdt, offset, status, okay))); +_FDT((fdt_setprop(fdt, offset, 64-bit, NULL, 0))); + +if (env-spr_cb[SPR_PURR].oea_read) { +_FDT((fdt_setprop(fdt, offset, ibm,purr, NULL, 0))); +} + +if (env-mmu_model POWERPC_MMU_1TSEG) { +_FDT((fdt_setprop(fdt, offset, ibm,processor-segment-sizes, + segs, sizeof(segs; +} + +/* Advertise VMX/VSX (vector extensions) if available + * 0 / no property == no vector extensions + * 1 == VMX / Altivec available + * 2 == VSX available */ +if (env-insns_flags PPC_ALTIVEC) { +uint32_t vmx = (env-insns_flags2 PPC2_VSX) ? 2 : 1; + +_FDT((fdt_setprop_cell(fdt, offset, ibm,vmx, vmx))); +} + +/* Advertise DFP (Decimal
Re: [Qemu-devel] [RFC PATCH v1 06/13] spapr: CPU hotplug support
Quoting Bharata B Rao (2015-01-08 00:10:13) Support CPU hotplug via device-add command. Use the exising EPOW event infrastructure to send CPU hotplug notification to the guest. Signed-off-by: Bharata B Rao bhar...@linux.vnet.ibm.com --- hw/ppc/spapr.c | 205 +++- hw/ppc/spapr_events.c | 8 +- target-ppc/translate_init.c | 6 ++ 3 files changed, 215 insertions(+), 4 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 515d770..a293a59 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -330,6 +330,8 @@ static void add_str(GString *s, const gchar *s1) g_string_append_len(s, s1, strlen(s1) + 1); } +uint32_t cpus_per_socket; + static void *spapr_create_fdt_skel(hwaddr initrd_base, hwaddr initrd_size, hwaddr kernel_size, @@ -350,9 +352,9 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base, unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80}; QemuOpts *opts = qemu_opts_find(qemu_find_opts(smp-opts), NULL); unsigned sockets = opts ? qemu_opt_get_number(opts, sockets, 0) : 0; -uint32_t cpus_per_socket = sockets ? (smp_cpus / sockets) : 1; char *buf; +cpus_per_socket = sockets ? (smp_cpus / sockets) : 1; add_str(hypertas, hcall-pft); add_str(hypertas, hcall-term); add_str(hypertas, hcall-dabr); @@ -1744,12 +1746,209 @@ static void spapr_nmi(NMIState *n, int cpu_index, Error **errp) } } +/* TODO: Duplicates code from spapr_create_fdt_skel(), Fix this */ +static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset, +int drc_index) +{ +PowerPCCPU *cpu = POWERPC_CPU(cs); +CPUPPCState *env = cpu-env; +PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs); +int index = ppc_get_vcpu_dt_id(cpu); +uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40), + 0x, 0x}; +uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TIMEBASE_FREQ; +uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 10; +uint32_t page_sizes_prop[64]; +size_t page_sizes_prop_size; +int smpt = ppc_get_compat_smt_threads(cpu); +uint32_t servers_prop[smpt]; +uint32_t gservers_prop[smpt * 2]; +int i; +uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr-htab_shift)}; +uint32_t associativity[] = {cpu_to_be32(0x5), +cpu_to_be32(0x0), +cpu_to_be32(0x0), +cpu_to_be32(0x0), +cpu_to_be32(cs-numa_node), +cpu_to_be32(index)}; + +_FDT((fdt_setprop_cell(fdt, offset, reg, index))); +_FDT((fdt_setprop_string(fdt, offset, device_type, cpu))); + +_FDT((fdt_setprop_cell(fdt, offset, cpu-version, env-spr[SPR_PVR]))); +_FDT((fdt_setprop_cell(fdt, offset, d-cache-block-size, +env-dcache_line_size))); +_FDT((fdt_setprop_cell(fdt, offset, d-cache-line-size, +env-dcache_line_size))); +_FDT((fdt_setprop_cell(fdt, offset, i-cache-block-size, +env-icache_line_size))); +_FDT((fdt_setprop_cell(fdt, offset, i-cache-line-size, +env-icache_line_size))); + +if (pcc-l1_dcache_size) { +_FDT((fdt_setprop_cell(fdt, offset, d-cache-size, +pcc-l1_dcache_size))); +} else { +fprintf(stderr, Warning: Unknown L1 dcache size for cpu\n); +} +if (pcc-l1_icache_size) { +_FDT((fdt_setprop_cell(fdt, offset, i-cache-size, +pcc-l1_icache_size))); +} else { +fprintf(stderr, Warning: Unknown L1 icache size for cpu\n); +} + +_FDT((fdt_setprop_cell(fdt, offset, timebase-frequency, tbfreq))); +_FDT((fdt_setprop_cell(fdt, offset, clock-frequency, cpufreq))); +_FDT((fdt_setprop_cell(fdt, offset, ibm,slb-size, env-slb_nr))); +_FDT((fdt_setprop_string(fdt, offset, status, okay))); +_FDT((fdt_setprop(fdt, offset, 64-bit, NULL, 0))); + +if (env-spr_cb[SPR_PURR].oea_read) { +_FDT((fdt_setprop(fdt, offset, ibm,purr, NULL, 0))); +} + +if (env-mmu_model POWERPC_MMU_1TSEG) { +_FDT((fdt_setprop(fdt, offset, ibm,processor-segment-sizes, + segs, sizeof(segs; +} + +/* Advertise VMX/VSX (vector extensions) if available + * 0 / no property == no vector extensions + * 1 == VMX / Altivec available + * 2 == VSX available */ +if (env-insns_flags PPC_ALTIVEC) { +uint32_t vmx = (env-insns_flags2 PPC2_VSX) ? 2 : 1; + +_FDT((fdt_setprop_cell(fdt, offset, ibm,vmx, vmx))); +} + +/* Advertise DFP (Decimal Floating Point) if available + * 0 / no property == no
[Qemu-devel] [RFC PATCH v1 06/13] spapr: CPU hotplug support
Support CPU hotplug via device-add command. Use the exising EPOW event infrastructure to send CPU hotplug notification to the guest. Signed-off-by: Bharata B Rao bhar...@linux.vnet.ibm.com --- hw/ppc/spapr.c | 205 +++- hw/ppc/spapr_events.c | 8 +- target-ppc/translate_init.c | 6 ++ 3 files changed, 215 insertions(+), 4 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 515d770..a293a59 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -330,6 +330,8 @@ static void add_str(GString *s, const gchar *s1) g_string_append_len(s, s1, strlen(s1) + 1); } +uint32_t cpus_per_socket; + static void *spapr_create_fdt_skel(hwaddr initrd_base, hwaddr initrd_size, hwaddr kernel_size, @@ -350,9 +352,9 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base, unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80}; QemuOpts *opts = qemu_opts_find(qemu_find_opts(smp-opts), NULL); unsigned sockets = opts ? qemu_opt_get_number(opts, sockets, 0) : 0; -uint32_t cpus_per_socket = sockets ? (smp_cpus / sockets) : 1; char *buf; +cpus_per_socket = sockets ? (smp_cpus / sockets) : 1; add_str(hypertas, hcall-pft); add_str(hypertas, hcall-term); add_str(hypertas, hcall-dabr); @@ -1744,12 +1746,209 @@ static void spapr_nmi(NMIState *n, int cpu_index, Error **errp) } } +/* TODO: Duplicates code from spapr_create_fdt_skel(), Fix this */ +static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset, +int drc_index) +{ +PowerPCCPU *cpu = POWERPC_CPU(cs); +CPUPPCState *env = cpu-env; +PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs); +int index = ppc_get_vcpu_dt_id(cpu); +uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40), + 0x, 0x}; +uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TIMEBASE_FREQ; +uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 10; +uint32_t page_sizes_prop[64]; +size_t page_sizes_prop_size; +int smpt = ppc_get_compat_smt_threads(cpu); +uint32_t servers_prop[smpt]; +uint32_t gservers_prop[smpt * 2]; +int i; +uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr-htab_shift)}; +uint32_t associativity[] = {cpu_to_be32(0x5), +cpu_to_be32(0x0), +cpu_to_be32(0x0), +cpu_to_be32(0x0), +cpu_to_be32(cs-numa_node), +cpu_to_be32(index)}; + +_FDT((fdt_setprop_cell(fdt, offset, reg, index))); +_FDT((fdt_setprop_string(fdt, offset, device_type, cpu))); + +_FDT((fdt_setprop_cell(fdt, offset, cpu-version, env-spr[SPR_PVR]))); +_FDT((fdt_setprop_cell(fdt, offset, d-cache-block-size, +env-dcache_line_size))); +_FDT((fdt_setprop_cell(fdt, offset, d-cache-line-size, +env-dcache_line_size))); +_FDT((fdt_setprop_cell(fdt, offset, i-cache-block-size, +env-icache_line_size))); +_FDT((fdt_setprop_cell(fdt, offset, i-cache-line-size, +env-icache_line_size))); + +if (pcc-l1_dcache_size) { +_FDT((fdt_setprop_cell(fdt, offset, d-cache-size, +pcc-l1_dcache_size))); +} else { +fprintf(stderr, Warning: Unknown L1 dcache size for cpu\n); +} +if (pcc-l1_icache_size) { +_FDT((fdt_setprop_cell(fdt, offset, i-cache-size, +pcc-l1_icache_size))); +} else { +fprintf(stderr, Warning: Unknown L1 icache size for cpu\n); +} + +_FDT((fdt_setprop_cell(fdt, offset, timebase-frequency, tbfreq))); +_FDT((fdt_setprop_cell(fdt, offset, clock-frequency, cpufreq))); +_FDT((fdt_setprop_cell(fdt, offset, ibm,slb-size, env-slb_nr))); +_FDT((fdt_setprop_string(fdt, offset, status, okay))); +_FDT((fdt_setprop(fdt, offset, 64-bit, NULL, 0))); + +if (env-spr_cb[SPR_PURR].oea_read) { +_FDT((fdt_setprop(fdt, offset, ibm,purr, NULL, 0))); +} + +if (env-mmu_model POWERPC_MMU_1TSEG) { +_FDT((fdt_setprop(fdt, offset, ibm,processor-segment-sizes, + segs, sizeof(segs; +} + +/* Advertise VMX/VSX (vector extensions) if available + * 0 / no property == no vector extensions + * 1 == VMX / Altivec available + * 2 == VSX available */ +if (env-insns_flags PPC_ALTIVEC) { +uint32_t vmx = (env-insns_flags2 PPC2_VSX) ? 2 : 1; + +_FDT((fdt_setprop_cell(fdt, offset, ibm,vmx, vmx))); +} + +/* Advertise DFP (Decimal Floating Point) if available + * 0 / no property == no DFP + * 1 == DFP available */ +if (env-insns_flags2 PPC2_DFP) { +_FDT((fdt_setprop_cell(fdt, offset, ibm,dfp, 1))); +} + +