From patchwork Wed Feb 4 14:01:55 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Parth Dixit X-Patchwork-Id: 44348 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f199.google.com (mail-wi0-f199.google.com [209.85.212.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id CDAD02029F for ; Wed, 4 Feb 2015 14:05:21 +0000 (UTC) Received: by mail-wi0-f199.google.com with SMTP id r20sf2478291wiv.2 for ; Wed, 04 Feb 2015 06:05:21 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:cc:subject:precedence:list-id:list-unsubscribe:list-post :list-help:list-subscribe:mime-version:content-type :content-transfer-encoding:sender:errors-to:x-original-sender :x-original-authentication-results:mailing-list:list-archive; bh=hYIL26InJJX7WmB3Gzhpfphih+g+5/341TSM8AiOCa8=; b=FG5UP1d+RsMvA69LABI1+NiXbBGUhMCrsjy+Nq3ZKSuv+v9Z7qF5Ok5X00lS839tNG 6OePjPu8wazsMOn8PUC5bM29sw7BKHSFcEZa2V0m1qApKy48GndEM123eyvMKh6nsV2T ksPNQiFFZcDcu3Vbdml8pANDVSpviqdSXvO+nVr7Cpq+7+btp3L6FbkRk4QN9CWwi9EW zwptxNFQPnQGz52i62kjxrqAYo81yhD07lOXEdbZwq2YYjHR5pk/T8Ssk1TM1dk3UsmK W9xpI4OXbRrh9iMDwxKI+goS//QeYtsvT+VQAnyFVOnv3jjQ+3bJgxqHv5TZelj12fRW Vafg== X-Gm-Message-State: ALoCoQl2iTmGfx8Uy9HjoYDG6xh/DCr5xcBEmvm+2wULmWcyvfDVj3ub3ohcCkdEyQhCXc/MOfU6 X-Received: by 10.112.161.201 with SMTP id xu9mr3941971lbb.11.1423058721011; Wed, 04 Feb 2015 06:05:21 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.234.5 with SMTP id ua5ls31303lac.68.gmail; Wed, 04 Feb 2015 06:05:20 -0800 (PST) X-Received: by 10.152.234.69 with SMTP id uc5mr30402038lac.16.1423058720864; Wed, 04 Feb 2015 06:05:20 -0800 (PST) Received: from mail-la0-f49.google.com (mail-la0-f49.google.com. [209.85.215.49]) by mx.google.com with ESMTPS id xl5si1424777lbb.60.2015.02.04.06.05.20 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 04 Feb 2015 06:05:20 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.49 as permitted sender) client-ip=209.85.215.49; Received: by mail-la0-f49.google.com with SMTP id gf13so1695480lab.8 for ; Wed, 04 Feb 2015 06:05:20 -0800 (PST) X-Received: by 10.112.98.99 with SMTP id eh3mr29969782lbb.32.1423058720755; Wed, 04 Feb 2015 06:05:20 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.35.133 with SMTP id h5csp506918lbj; Wed, 4 Feb 2015 06:05:19 -0800 (PST) X-Received: by 10.52.154.175 with SMTP id vp15mr16026966vdb.97.1423058718434; Wed, 04 Feb 2015 06:05:18 -0800 (PST) Received: from lists.xen.org (lists.xen.org. [50.57.142.19]) by mx.google.com with ESMTPS id yw2si757102vdb.4.2015.02.04.06.05.17 (version=TLSv1 cipher=RC4-SHA bits=128/128); Wed, 04 Feb 2015 06:05:18 -0800 (PST) Received-SPF: none (google.com: xen-devel-bounces@lists.xen.org does not designate permitted sender hosts) client-ip=50.57.142.19; Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1YJ0Yx-0006ys-5f; Wed, 04 Feb 2015 14:04:15 +0000 Received: from mail6.bemta14.messagelabs.com ([193.109.254.103]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1YJ0Yv-0006xp-SZ for xen-devel@lists.xen.org; Wed, 04 Feb 2015 14:04:14 +0000 Received: from [193.109.254.147] by server-5.bemta-14.messagelabs.com id 91/D6-03170-DD622D45; Wed, 04 Feb 2015 14:04:13 +0000 X-Env-Sender: parth.dixit@linaro.org X-Msg-Ref: server-16.tower-27.messagelabs.com!1423058649!7377362!1 X-Originating-IP: [209.85.192.172] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 6.13.4; banners=-,-,- X-VirusChecked: Checked Received: (qmail 17385 invoked from network); 4 Feb 2015 14:04:11 -0000 Received: from mail-pd0-f172.google.com (HELO mail-pd0-f172.google.com) (209.85.192.172) by server-16.tower-27.messagelabs.com with RC4-SHA encrypted SMTP; 4 Feb 2015 14:04:11 -0000 Received: by pdjp10 with SMTP id p10so876137pdj.1 for ; Wed, 04 Feb 2015 06:04:09 -0800 (PST) X-Received: by 10.67.13.12 with SMTP id eu12mr47122535pad.157.1423058648651; Wed, 04 Feb 2015 06:04:08 -0800 (PST) Received: from parthd-ubunutu.qualcomm.com ([202.46.23.62]) by mx.google.com with ESMTPSA id kg12sm2161881pbb.44.2015.02.04.06.04.03 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 04 Feb 2015 06:04:07 -0800 (PST) From: parth.dixit@linaro.org To: xen-devel@lists.xen.org Date: Wed, 4 Feb 2015 19:31:55 +0530 Message-Id: <1423058539-26403-12-git-send-email-parth.dixit@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1423058539-26403-1-git-send-email-parth.dixit@linaro.org> References: <1423058539-26403-1-git-send-email-parth.dixit@linaro.org> Cc: ian.campbell@citrix.com, Naresh Bhat , julien.grall@linaro.org, tim@xen.org, Tomasz Nowicki , stefano.stabellini@citrix.com, Hanjun Guo , jbeulich@suse.com, christoffer.dall@linaro.org Subject: [Xen-devel] [PATCH RFC 11/35] ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get cpu_possible/present_map X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: List-Unsubscribe: , List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: parth.dixit@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.49 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Archive: From: Naresh Bhat MADT contains the information for MPIDR which is essential for SMP initialization, parse the GIC cpu interface structures to get the MPIDR value and map it to cpu_logical_map(), and add enabled cpu with valid MPIDR into cpu_possible_map and cpu_present_map. Signed-off-by: Hanjun Guo Signed-off-by: Tomasz Nowicki Signed-off-by: Naresh Bhat --- xen/arch/arm/arm64/acpi/arm-core.c | 139 +++++++++++++++++++++++++++++++++++++ xen/include/asm-arm/acpi.h | 2 + xen/include/xen/acpi.h | 5 ++ 3 files changed, 146 insertions(+) diff --git a/xen/arch/arm/arm64/acpi/arm-core.c b/xen/arch/arm/arm64/acpi/arm-core.c index 2b7e2ef..84b0032 100644 --- a/xen/arch/arm/arm64/acpi/arm-core.c +++ b/xen/arch/arm/arm64/acpi/arm-core.c @@ -26,7 +26,10 @@ #include #include #include +#include +#include +#include #include /* @@ -49,10 +52,141 @@ int acpi_psci_present; /* 1 to indicate HVC must be used instead of SMC as the PSCI conduit */ int acpi_psci_use_hvc; +/* available_cpus means enabled cpu in MADT */ +static int available_cpus; + enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PLATFORM; struct acpi_arm_root acpi_arm_rsdp_info; /* info about RSDP from FDT */ +/* arch-optional setting to enable display of offline cpus >= nr_cpu_ids */ +unsigned int total_cpus = 0; + +/* + * acpi_register_gic_cpu_interface - register a gic cpu interface and + * generates a logic cpu number + * @mpidr: CPU's hardware id to register, MPIDR represented in MADT + * @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(u64 mpidr, u8 enabled) +{ + int cpu; + + if ( mpidr == INVALID_HWID ) + { + printk("Skip invalid cpu hardware ID\n"); + return -EINVAL; + } + + total_cpus++; + if ( !enabled ) + return -EINVAL; + + if ( available_cpus >= NR_CPUS ) + { + printk("NR_CPUS limit of %d reached, Processor %d/0x%llx ignored.\n", + NR_CPUS, total_cpus, (long long unsigned int)mpidr); + return -EINVAL; + } + + /* If it is the first CPU, no need to check duplicate MPIDRs */ + if ( !available_cpus ) + goto skip_mpidr_check; + + /* + * Duplicate MPIDRs are a recipe for disaster. Scan + * all initialized entries and check for + * duplicates. If any is found just ignore the CPU. + */ + for_each_present_cpu(cpu) + { + if ( cpu_logical_map(cpu) == mpidr ) + { + printk("Firmware bug, duplicate CPU MPIDR: 0x%llx in MADT\n", + (long long unsigned int)mpidr); + return -EINVAL; + } + } + +skip_mpidr_check: + available_cpus++; + + /* allocate a logic cpu id for the new comer */ + if ( cpu_logical_map(0) == mpidr ) + { + /* + * 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_map); + + /* map the logic cpu id to cpu MPIDR */ + cpu_logical_map(cpu) = mpidr; + + set_cpu_possible(cpu, true); + set_cpu_present(cpu, true); + + return cpu; +} + +static int __init +acpi_parse_gic_cpu_interface(struct acpi_subtable_header *header, + const unsigned long end) +{ + struct acpi_madt_generic_interrupt *processor; + + processor = (struct acpi_madt_generic_interrupt *)header; + + if ( BAD_MADT_ENTRY(processor, end) ) + return -EINVAL; + + acpi_table_print_madt_entry(header); + + acpi_register_gic_cpu_interface(processor->mpidr, + processor->flags & ACPI_MADT_ENABLED); + + return 0; +} + +/* + * Parse GIC cpu interface related entries in MADT + * returns 0 on success, < 0 on error + */ +static int __init acpi_parse_madt_gic_cpu_interface_entries(void) +{ + int count; + + /* + * do a partial walk of MADT to determine how many CPUs + * we have including disabled CPUs, and get information + * we need for SMP init + */ + count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT, + acpi_parse_gic_cpu_interface, MAX_GIC_CPU_INTERFACE); + + if ( !count ) + { + printk("No GIC CPU interface entries present\n"); + return -ENODEV; + } + else if ( count < 0 ) + { + printk("Error parsing GIC CPU interface entry\n"); + return count; + } + + /* Make boot-up look pretty */ + printk("%d CPUs available, %d CPUs total\n", available_cpus, + total_cpus); + + return 0; +} + int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) { *irq = -1; @@ -140,6 +274,11 @@ int __init acpi_boot_init(void) if ( err ) printk("Can't find FADT\n"); + /* Get the boot CPU's MPIDR before MADT parsing */ + cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK; + + err = acpi_parse_madt_gic_cpu_interface_entries(); + return err; } #endif diff --git a/xen/include/asm-arm/acpi.h b/xen/include/asm-arm/acpi.h index 03051ef..c2d25db 100644 --- a/xen/include/asm-arm/acpi.h +++ b/xen/include/asm-arm/acpi.h @@ -105,4 +105,6 @@ static inline void acpi_disable_pci(void) #define acpi_strict 1 /* no ACPI spec workarounds on ARM */ #endif +#define MAX_GIC_CPU_INTERFACE 65535 + #endif /*_ASM_ARM_ACPI_H*/ diff --git a/xen/include/xen/acpi.h b/xen/include/xen/acpi.h index ff96336..9387b36 100644 --- a/xen/include/xen/acpi.h +++ b/xen/include/xen/acpi.h @@ -67,6 +67,11 @@ typedef int (*acpi_table_handler) (struct acpi_table_header *table); typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end); unsigned int acpi_get_processor_id (unsigned int cpu); + +#define BAD_MADT_ENTRY(entry, end) ( \ + (!entry) || (unsigned long)entry + sizeof(*entry) > end || \ + ((struct acpi_subtable_header *)entry)->length < sizeof(*entry)) + char * __acpi_map_table (paddr_t phys_addr, unsigned long size); int acpi_boot_init (void); int acpi_boot_table_init (void);