From patchwork Fri Jan 17 12:25:04 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hanjun Guo X-Patchwork-Id: 3504071 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id D18129F2E9 for ; Fri, 17 Jan 2014 12:44:41 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E34F920114 for ; Fri, 17 Jan 2014 12:44:40 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id DACEA2010F for ; Fri, 17 Jan 2014 12:44:39 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1W48mq-0005s5-7q; Fri, 17 Jan 2014 12:44:36 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1W48mn-0007hy-Tr; Fri, 17 Jan 2014 12:44:33 +0000 Received: from mail-pa0-f52.google.com ([209.85.220.52]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1W48mk-0007h5-P5 for linux-arm-kernel@lists.infradead.org; Fri, 17 Jan 2014 12:44:31 +0000 Received: by mail-pa0-f52.google.com with SMTP id bj1so2583337pad.39 for ; Fri, 17 Jan 2014 04:44:08 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=3iXielpc5qnm09C6oGV1WAp9HwEE75dk7F9K/B3RyIM=; b=c8xynSEnxbMjtW3GfuSoEpDUVCJFi9pfhCC4n3izVCz0alt/fnEw76ygecIIEbVg4M ac/fPSbBXSvmiEsKlIAxNddE0euxebKeuDkCQF5bhcqptqh3NTeZB2nTkiHJUwoKMUC/ TJDAyXd6FqBTX50Duds2ttOHZzykLVxuVzEvupRHi4cxrQR9H4SECHwFQgeRWWh5LEY+ GNNFhEbY2PIFYKh28wC5rt0iJY3cbNbyT595hpCOJZniQQ2eh1DOAuQh/znWMwMYvCWW p66JjXPdHLpNDagSZw44wxTwz/ji38m6T+gWLTbxVov7alIim7KtGpajB3AJMinCUtv6 9UKg== X-Gm-Message-State: ALoCoQl3p9eRLnglpho8KiSQr9jJBWqLzpvzt/ES4eP0xDIgjjuFdbJ2u1htfoYH4aan3ILMWybc X-Received: by 10.68.254.230 with SMTP id al6mr1861100pbd.3.1389962648191; Fri, 17 Jan 2014 04:44:08 -0800 (PST) Received: from localhost ([218.17.215.175]) by mx.google.com with ESMTPSA id un5sm30364438pab.3.2014.01.17.04.43.39 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 17 Jan 2014 04:44:07 -0800 (PST) From: Hanjun Guo To: "Rafael J. Wysocki" , Catalin Marinas , Will Deacon , Russell King - ARM Linux Subject: [PATCH 10/20] ARM64 / ACPI: Enumerate possible/present CPU set and map logical cpu id to APIC id Date: Fri, 17 Jan 2014 20:25:04 +0800 Message-Id: <1389961514-13562-11-git-send-email-hanjun.guo@linaro.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1389961514-13562-1-git-send-email-hanjun.guo@linaro.org> References: <1389961514-13562-1-git-send-email-hanjun.guo@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140117_074430_967700_3A590E61 X-CRM114-Status: GOOD ( 26.15 ) X-Spam-Score: -1.8 (-) Cc: Mark Rutland , Matthew Garrett , linaro-kernel@lists.linaro.org, Arnd Bergmann , Rob Herring , Linus Walleij , Olof Johansson , linux-kernel@vger.kernel.org, linaro-acpi@lists.linaro.org, linux-acpi@vger.kernel.org, Hanjun Guo , patches@linaro.org, Grant Likely , Bjorn Helgaas , linux-arm-kernel@lists.infradead.org, Charles.Garcia-Tobin@arm.com X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-3.7 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RCVD_IN_SORBS_WEB, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When boot the kernel with MADT, the cpu possible and present sets should be enumerated for later smp initialization. The logic cpu id maps to APIC id (GIC id) is also implemented, it is needed for acpi processor drivers. Signed-off-by: Hanjun Guo --- arch/arm64/include/asm/acpi.h | 7 ++-- drivers/acpi/plat/arm-core.c | 83 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 3 deletions(-) diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h index c335c6d..7edd39e 100644 --- a/arch/arm64/include/asm/acpi.h +++ b/arch/arm64/include/asm/acpi.h @@ -76,9 +76,6 @@ static inline void acpi_disable_pci(void) /* FIXME: this function should be moved to topology.h when it's ready */ void arch_fix_phys_package_id(int num, u32 slot); -/* temperally define -1 to make acpi core compilerable */ -#define cpu_physical_id(cpu) -1 - /* Low-level suspend routine. */ extern int (*acpi_suspend_lowlevel)(void); #define acpi_wakeup_address (0) @@ -86,6 +83,10 @@ extern int (*acpi_suspend_lowlevel)(void); #define MAX_GIC_CPU_INTERFACE 256 #define MAX_GIC_DISTRIBUTOR 1 /* should be the same as MAX_GIC_NR */ +/* map logic cpu id to physical GIC id */ +extern int arm_cpu_to_apicid[NR_CPUS]; +#define cpu_physical_id(cpu) arm_cpu_to_apicid[cpu] + #else /* !CONFIG_ACPI */ #define acpi_disabled 1 /* ACPI sometimes enabled on ARM */ #define acpi_noirq 1 /* ACPI sometimes enabled on ARM */ diff --git a/drivers/acpi/plat/arm-core.c b/drivers/acpi/plat/arm-core.c index 8ba3e6f..1d9b789 100644 --- a/drivers/acpi/plat/arm-core.c +++ b/drivers/acpi/plat/arm-core.c @@ -31,6 +31,7 @@ #include #include +#include /* * We never plan to use RSDT on arm/arm64 as its deprecated in spec but this @@ -52,6 +53,13 @@ EXPORT_SYMBOL(acpi_pci_disabled); */ static u64 acpi_lapic_addr __initdata; +/* available_cpus here means enabled cpu in MADT */ +static int available_cpus; + +/* Map logic cpu id to physical GIC id (physical CPU id). */ +int arm_cpu_to_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = -1 }; +static int boot_cpu_apic_id = -1; + #define BAD_MADT_ENTRY(entry, end) ( \ (!entry) || (unsigned long)entry + sizeof(*entry) > end || \ ((struct acpi_subtable_header *)entry)->length < sizeof(*entry)) @@ -132,6 +140,55 @@ static int __init acpi_parse_madt(struct acpi_table_header *table) * Please refer to chapter5.2.12.14/15 of ACPI 5.0 */ +/** + * acpi_register_gic_cpu_interface - register a gic cpu interface and + * generates a logic cpu number + * @id: gic cpu interface id to register + * @enabled: this cpu is enabled or not + * + * Returns the logic cpu number which maps to the gic cpu interface + */ +static int acpi_register_gic_cpu_interface(int id, u8 enabled) +{ + int cpu; + + if (id >= MAX_GIC_CPU_INTERFACE) { + pr_info(PREFIX "skipped apicid that is too big\n"); + return -EINVAL; + } + + total_cpus++; + if (!enabled) + return -EINVAL; + + if (available_cpus >= NR_CPUS) { + pr_warn(PREFIX "NR_CPUS limit of %d reached," + " Processor %d/0x%x ignored.\n", NR_CPUS, total_cpus, id); + return -EINVAL; + } + + available_cpus++; + + /* allocate a logic cpu id for the new comer */ + if (boot_cpu_apic_id == id) { + /* + * boot_cpu_init() already hold bit 0 in cpu_present_mask + * for BSP, no need to allocte again. + */ + cpu = 0; + } else { + cpu = cpumask_next_zero(-1, cpu_present_mask); + } + + /* map the logic cpu id to APIC id */ + arm_cpu_to_apicid[cpu] = id; + + set_cpu_present(cpu, true); + set_cpu_possible(cpu, true); + + return cpu; +} + static int __init acpi_parse_gic(struct acpi_subtable_header *header, const unsigned long end) { @@ -144,6 +201,16 @@ acpi_parse_gic(struct acpi_subtable_header *header, const unsigned long end) acpi_table_print_madt_entry(header); + /* + * We need to register disabled CPU as well to permit + * counting disabled CPUs. This allows us to size + * cpus_possible_map more accurately, to permit + * to not preallocating memory for all NR_CPUS + * when we use CPU hotplug. + */ + acpi_register_gic_cpu_interface(processor->gic_id, + processor->flags & ACPI_MADT_ENABLED); + return 0; } @@ -186,6 +253,19 @@ static int __init acpi_parse_madt_gic_entries(void) return count; } +#ifdef CONFIG_SMP + if (available_cpus == 0) { + pr_info(PREFIX "Found 0 CPUs; assuming 1\n"); + arm_cpu_to_apicid[available_cpus] = + read_cpuid_mpidr() & MPIDR_HWID_BITMASK; + available_cpus = 1; /* We've got at least one of these */ + } +#endif + + /* Make boot-up look pretty */ + pr_info("%d CPUs available, %d CPUs total\n", available_cpus, + total_cpus); + return 0; } @@ -321,6 +401,9 @@ int __init early_acpi_boot_init(void) if (acpi_disabled) return -ENODEV; + /* Get the boot CPU's GIC cpu interface id before MADT parsing */ + boot_cpu_apic_id = read_cpuid_mpidr() & MPIDR_HWID_BITMASK; + /* * Process the Multiple APIC Description Table (MADT), if present */