From patchwork Thu Sep 26 11:09:40 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 20590 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qa0-f72.google.com (mail-qa0-f72.google.com [209.85.216.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 2F64E24687 for ; Thu, 26 Sep 2013 11:10:29 +0000 (UTC) Received: by mail-qa0-f72.google.com with SMTP id j7sf983165qaq.3 for ; Thu, 26 Sep 2013 04:10:29 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=Do+ImgsnPH7tX19yajApf1s9Ik5e8qemgA7tLb5R6w4=; b=NMjMZel5/Ct2CuUOzb8TFNprymX4geEnxzatWgajlj3iiT/AMWtMDheT3jYbFQsYth 5IfDV65G1PRa3rV4nukB3gPIJ9dvR+IsfuDEFWmrEijlL3/Qs5pqq1erRzZpwzmwrqVS +vnE9SZb228j2QsbxPvbpHfIF04wMziWR+H316AKGaLdaHwt/+TrnM+MQLdCcP387Xet JhHtdHMMYWDoLVQAN/QsC3BBv7IH0AcZx71p+cVI8AVy5+AfMV6tFVsVKH4lVDI1dQmw c6ymKfkRmSadDRstvxrgnkPUOYqhSxsjdxK+8nrYtvdEpw3lxsGKMGr3HUi/gmot9x8U qaXQ== X-Gm-Message-State: ALoCoQk670pMavvheWyDCAuygNUsqcml+1i+lHqSOBAQLD+oCLz8DVjCisT+kh5eXHWL4gQbZMjR X-Received: by 10.236.4.69 with SMTP id 45mr66209yhi.20.1380193829056; Thu, 26 Sep 2013 04:10:29 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.81.230 with SMTP id d6ls955139qey.93.gmail; Thu, 26 Sep 2013 04:10:28 -0700 (PDT) X-Received: by 10.52.164.16 with SMTP id ym16mr97504vdb.39.1380193828948; Thu, 26 Sep 2013 04:10:28 -0700 (PDT) Received: from mail-vc0-f177.google.com (mail-vc0-f177.google.com [209.85.220.177]) by mx.google.com with ESMTPS id sc5si259000vdc.22.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 26 Sep 2013 04:10:28 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.220.177 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.177; Received: by mail-vc0-f177.google.com with SMTP id hv10so701883vcb.22 for ; Thu, 26 Sep 2013 04:09:58 -0700 (PDT) X-Received: by 10.220.183.2 with SMTP id ce2mr150371vcb.58.1380193798820; Thu, 26 Sep 2013 04:09:58 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.174.196 with SMTP id u4csp359572vcz; Thu, 26 Sep 2013 04:09:58 -0700 (PDT) X-Received: by 10.180.188.202 with SMTP id gc10mr299849wic.3.1380193797749; Thu, 26 Sep 2013 04:09:57 -0700 (PDT) Received: from mail-wg0-f43.google.com (mail-wg0-f43.google.com [74.125.82.43]) by mx.google.com with ESMTPS id lr10si412174wic.35.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 26 Sep 2013 04:09:57 -0700 (PDT) Received-SPF: neutral (google.com: 74.125.82.43 is neither permitted nor denied by best guess record for domain of julien.grall@linaro.org) client-ip=74.125.82.43; Received: by mail-wg0-f43.google.com with SMTP id z12so982843wgg.10 for ; Thu, 26 Sep 2013 04:09:57 -0700 (PDT) X-Received: by 10.180.12.4 with SMTP id u4mr27153597wib.29.1380193797294; Thu, 26 Sep 2013 04:09:57 -0700 (PDT) Received: from belegaer.uk.xensource.com. ([185.25.64.249]) by mx.google.com with ESMTPSA id q5sm2409641wiz.3.1969.12.31.16.00.00 (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 26 Sep 2013 04:09:56 -0700 (PDT) From: Julien Grall To: xen-devel@lists.xen.org Cc: stefano.stabellini@eu.citrix.com, ian.campbell@citrix.com, patches@linaro.org, Julien Grall Subject: [PATCH v5 6/7] xen/arm: Dissociate logical and hardware CPU ID Date: Thu, 26 Sep 2013 12:09:40 +0100 Message-Id: <1380193781-17474-7-git-send-email-julien.grall@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1380193781-17474-1-git-send-email-julien.grall@linaro.org> References: <1380193781-17474-1-git-send-email-julien.grall@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: julien.grall@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.177 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Introduce cpu_logical_map to associate a logical CPU ID to an hardware CPU ID. This map will be filled during Xen boot via the device tree. Each CPU node contains a "reg" property which contains the hardware ID (ie MPIDR[0:23]). Also move /cpus parsing later so we can use the dt_* API. Signed-off-by: Julien Grall Acked-by: Ian Campbell --- Changes in v3: - re-add the mask (lost v2) for the mpidr. Changes in v2: - for_each_child was renamed to dt_for_each_child - move init_cpus_maps later to take advantage of boot_cpu_data - move to initdata tmp_map --- xen/arch/arm/setup.c | 112 ++++++++++++++++++++++++++++++++++++++- xen/arch/arm/smpboot.c | 4 ++ xen/common/device_tree.c | 48 ----------------- xen/include/asm-arm/processor.h | 4 ++ 4 files changed, 119 insertions(+), 49 deletions(-) diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index 62147b2..1d0b5e9 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -498,6 +498,114 @@ void __init setup_cache(void) cacheline_bytes = 1U << (4 + (ccsid & 0x7)); } +/* Parse the device tree and build the logical map array containing + * MPIDR values related to logical cpus + * Code base on Linux arch/arm/kernel/devtree.c + */ +static void __init init_cpus_maps(void) +{ + register_t mpidr; + struct dt_device_node *cpus = dt_find_node_by_path("/cpus"); + struct dt_device_node *cpu; + unsigned int i, j; + unsigned int cpuidx = 1; + static u32 tmp_map[NR_CPUS] __initdata = + { + [0 ... NR_CPUS - 1] = MPIDR_INVALID + }; + bool_t bootcpu_valid = 0; + + mpidr = boot_cpu_data.mpidr.bits & MPIDR_HWID_MASK; + + if ( !cpus ) + { + printk(XENLOG_WARNING "WARNING: Can't find /cpus in the device tree.\n" + "Using only 1 CPU\n"); + return; + } + + dt_for_each_child_node( cpus, cpu ) + { + u32 hwid; + + if ( !dt_device_type_is_equal(cpu, "cpu") ) + continue; + + if ( !dt_property_read_u32(cpu, "reg", &hwid) ) + { + printk(XENLOG_WARNING "cpu node `%s`: missing reg property\n", + dt_node_full_name(cpu)); + continue; + } + + /* + * 8 MSBs must be set to 0 in the DT since the reg property + * defines the MPIDR[23:0] + */ + if ( hwid & ~MPIDR_HWID_MASK ) + { + printk(XENLOG_WARNING "cpu node `%s`: invalid hwid value (0x%x)\n", + dt_node_full_name(cpu), hwid); + continue; + } + + /* + * Duplicate MPIDRs are a recipe for disaster. Scan all initialized + * entries and check for duplicates. If any found just skip the node. + * temp values values are initialized to MPIDR_INVALID to avoid + * matching valid MPIDR[23:0] values. + */ + for ( j = 0; j < cpuidx; j++ ) + { + if ( tmp_map[j] == hwid ) + { + printk(XENLOG_WARNING "cpu node `%s`: duplicate /cpu reg properties in the DT\n", + dt_node_full_name(cpu)); + continue; + } + } + + /* + * Build a stashed array of MPIDR values. Numbering scheme requires + * that if detected the boot CPU must be assigned logical id 0. Other + * CPUs get sequential indexes starting from 1. If a CPU node + * with a reg property matching the boot CPU MPIDR is detected, + * this is recorded and so that the logical map build from DT is + * validated and can be used to set the map. + */ + if ( hwid == mpidr ) + { + i = 0; + bootcpu_valid = 1; + } + else + i = cpuidx++; + + if ( cpuidx > NR_CPUS ) + { + printk(XENLOG_WARNING "DT /cpu %u node greater than max cores %u, capping them\n", + cpuidx, NR_CPUS); + cpuidx = NR_CPUS; + break; + } + + tmp_map[i] = hwid; + } + + if ( !bootcpu_valid ) + { + printk(XENLOG_WARNING "DT missing boot CPU MPIDR[23:0]\n" + "Using only 1 CPU\n"); + return; + } + + for ( i = 0; i < cpuidx; i++ ) + { + cpumask_set_cpu(i, &cpu_possible_map); + cpu_logical_map(i) = tmp_map[i]; + } +} + /* C entry point for boot CPU */ void __init start_xen(unsigned long boot_phys_offset, unsigned long fdt_paddr, @@ -517,7 +625,6 @@ void __init start_xen(unsigned long boot_phys_offset, + (fdt_paddr & ((1 << SECOND_SHIFT) - 1)); fdt_size = device_tree_early_init(device_tree_flattened); - cpus = smp_get_max_cpus(); cmdline_parse(device_tree_bootargs(device_tree_flattened)); setup_pagetables(boot_phys_offset, get_xen_paddr()); @@ -534,6 +641,9 @@ void __init start_xen(unsigned long boot_phys_offset, processor_id(); + init_cpus_maps(); + cpus = smp_get_max_cpus(); + platform_init(); init_xen_time(); diff --git a/xen/arch/arm/smpboot.c b/xen/arch/arm/smpboot.c index 945f473..8ea4750 100644 --- a/xen/arch/arm/smpboot.c +++ b/xen/arch/arm/smpboot.c @@ -39,6 +39,9 @@ EXPORT_SYMBOL(cpu_possible_map); struct cpuinfo_arm cpu_data[NR_CPUS]; +/* CPU logical map: map xen cpuid to an MPIDR */ +u32 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = MPIDR_INVALID }; + /* Fake one node for now. See also include/asm-arm/numa.h */ nodemask_t __read_mostly node_online_map = { { [0] = 1UL } }; @@ -85,6 +88,7 @@ smp_clear_cpu_maps (void) cpumask_clear(&cpu_online_map); cpumask_set_cpu(0, &cpu_online_map); cpumask_set_cpu(0, &cpu_possible_map); + cpu_logical_map(0) = READ_SYSREG(MPIDR_EL1) & MPIDR_HWID_MASK; } int __init diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c index 0ece249..9a16650 100644 --- a/xen/common/device_tree.c +++ b/xen/common/device_tree.c @@ -118,18 +118,6 @@ static bool_t __init device_tree_node_matches(const void *fdt, int node, && (name[match_len] == '@' || name[match_len] == '\0'); } -static bool_t __init device_tree_type_matches(const void *fdt, int node, - const char *match) -{ - const void *prop; - - prop = fdt_getprop(fdt, node, "device_type", NULL); - if ( prop == NULL ) - return 0; - - return !dt_node_cmp(prop, match); -} - static bool_t __init device_tree_node_compatible(const void *fdt, int node, const char *match) { @@ -348,40 +336,6 @@ static void __init process_memory_node(const void *fdt, int node, } } -static void __init process_cpu_node(const void *fdt, int node, - const char *name, - u32 address_cells, u32 size_cells) -{ - const struct fdt_property *prop; - u32 cpuid; - int len; - - prop = fdt_get_property(fdt, node, "reg", &len); - if ( !prop ) - { - early_printk("fdt: node `%s': missing `reg' property\n", name); - return; - } - - if ( len < sizeof (cpuid) ) - { - dt_printk("fdt: node `%s': `reg` property length is too short\n", - name); - return; - } - - cpuid = dt_read_number((const __be32 *)prop->data, 1); - - /* TODO: handle non-contiguous CPU ID */ - if ( cpuid >= NR_CPUS ) - { - dt_printk("fdt: node `%s': reg(0x%x) >= NR_CPUS(%d)\n", - name, cpuid, NR_CPUS); - return; - } - cpumask_set_cpu(cpuid, &cpu_possible_map); -} - static void __init process_multiboot_node(const void *fdt, int node, const char *name, u32 address_cells, u32 size_cells) @@ -435,8 +389,6 @@ static int __init early_scan_node(const void *fdt, { if ( device_tree_node_matches(fdt, node, "memory") ) process_memory_node(fdt, node, name, address_cells, size_cells); - else if ( device_tree_type_matches(fdt, node, "cpu") ) - process_cpu_node(fdt, node, name, address_cells, size_cells); else if ( device_tree_node_compatible(fdt, node, "xen,multiboot-module" ) ) process_multiboot_node(fdt, node, name, address_cells, size_cells); diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h index 808567e..0646422 100644 --- a/xen/include/asm-arm/processor.h +++ b/xen/include/asm-arm/processor.h @@ -13,6 +13,7 @@ #define MPIDR_AFF0_SHIFT (0) #define MPIDR_AFF0_MASK (0xff << MPIDR_AFF0_SHIFT) #define MPIDR_HWID_MASK 0xffffff +#define MPIDR_INVALID (~MPIDR_HWID_MASK) /* TTBCR Translation Table Base Control Register */ #define TTBCR_EAE 0x80000000 @@ -230,6 +231,9 @@ extern void identify_cpu(struct cpuinfo_arm *); extern struct cpuinfo_arm cpu_data[]; #define current_cpu_data cpu_data[smp_processor_id()] +extern u32 __cpu_logical_map[]; +#define cpu_logical_map(cpu) __cpu_logical_map[cpu] + union hsr { uint32_t bits; struct {