From patchwork Sun Aug 3 02:36:12 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siarhei Siamashka X-Patchwork-Id: 375971 X-Patchwork-Delegate: hdegoede@redhat.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id C25551400AA for ; Sun, 3 Aug 2014 12:36:26 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 797614A05D; Sun, 3 Aug 2014 04:36:25 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id lKdbt9+d2hso; Sun, 3 Aug 2014 04:36:23 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id EB8914A04E; Sun, 3 Aug 2014 04:36:22 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 9159D4A04E for ; Sun, 3 Aug 2014 04:36:18 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 59EZntXKW3OD for ; Sun, 3 Aug 2014 04:36:16 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-lb0-f179.google.com (mail-lb0-f179.google.com [209.85.217.179]) by theia.denx.de (Postfix) with ESMTPS id 7507D4A03C for ; Sun, 3 Aug 2014 04:36:14 +0200 (CEST) Received: by mail-lb0-f179.google.com with SMTP id v6so4303304lbi.10 for ; Sat, 02 Aug 2014 19:36:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=QgJ4g20V947aDgIdmmImeN9eRoVdI/aAcd+x+fA7Xkc=; b=xU3TfrpBrERBm1zBmC5Xt35QGgSXqIOIGXo7wZnZ961zbgmX6OqetqFX59fCuuSqTh sV9k8pEuJhh2DW0HKHuFxPzwpqT4LNF2pm7IY9WZ6kuX+pxYkvJ0JOz1FhMioRliTmLk qbkm9dyIITCipHJEJw0l+L3YB4suy0ylfstUz361ZBxjppx5XUlEv1U4Ljj+amtUDHbj lw2H0bIc8orK2cRsx1oLRQDIEM8Y4cpwiReKvZkXS74ihP/ufM4ldFG4oY++G0zH8w4q hqK2Q1tkflwAcbX1fo36PVTHnA4PqcCjdvEmrH14wqe8zCoqC28j2lw0UjjEUexUpMXZ h00g== X-Received: by 10.112.125.132 with SMTP id mq4mr13797lbb.68.1407033374618; Sat, 02 Aug 2014 19:36:14 -0700 (PDT) Received: from localhost.localdomain ([212.16.98.80]) by mx.google.com with ESMTPSA id x10sm7383108lal.13.2014.08.02.19.36.13 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 02 Aug 2014 19:36:13 -0700 (PDT) From: Siarhei Siamashka To: u-boot@lists.denx.de Date: Sun, 3 Aug 2014 05:36:12 +0300 Message-Id: <1407033372-24765-1-git-send-email-siarhei.siamashka@gmail.com> X-Mailer: git-send-email 1.8.3.2 Cc: Marc Zyngier , linux-sunxi@googlegroups.com Subject: [U-Boot] [PATCH] ARM: HYP/non-sec: Add MIDR check to detect unsupported CPUs X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de Unlike 9d195a546179bc732aba9eacccf0a9a3db591288, which had removed the MIDR check against the "white list" of supported CPUs earlier, now we introduce the "black list" of unsupported CPUs. The current PSCI code is not compatible with the Cortex-A8 CPU used in Allwinner A10/A13 SoCs because of making GIC and virtualization support assumptions. Allwinner A10 and Allwinner A20 (with Cortex-A7 CPU, supported by PSCI) are pin compatible, they can be used as drop-in replacements for each other and share the same PCB design: https://www.olimex.com/Products/OLinuXino/A10/A10-OLinuXino-LIME https://www.olimex.com/Products/OLinuXino/A20/A20-OLinuXino-LIME The same u-boot binary binary can boot on Allwinner A10 and Allwinner A20 with just minor tweaks applied. This patch implements one of such necessary tweaks to allow the PSCI code to be compiled in, but skip it if Cortex-A8 is detected at runtime. The function 'armv7_init_nonsec()' now returns an error in the case if Cortex-A8 is detected. Also an extra error check is added for the 'armv7_init_nonsec()' call. If the board config header file provides CONFIG_ARMV7_ALLOW_SECURE_MODE_FALLBACK define, then the kernel is loaded in secure mode as a fallback. In the case is this define is not provided, the failure to switch to non-secure mode is treated as a fatal error and an appropriate message is displayed. Signed-off-by: Siarhei Siamashka --- arch/arm/cpu/armv7/virt-dt.c | 3 +++ arch/arm/cpu/armv7/virt-v7.c | 20 ++++++++++++++++++++ arch/arm/include/asm/armv7.h | 5 +++++ arch/arm/lib/bootm.c | 16 +++++++++++++--- 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/arch/arm/cpu/armv7/virt-dt.c b/arch/arm/cpu/armv7/virt-dt.c index 0b0d6a7..ab1fae9 100644 --- a/arch/arm/cpu/armv7/virt-dt.c +++ b/arch/arm/cpu/armv7/virt-dt.c @@ -31,6 +31,9 @@ static int fdt_psci(void *fdt) int nodeoff; int tmp; + if (armv7_is_cpu_blacklisted_for_nonsec()) + return 0; + nodeoff = fdt_path_offset(fdt, "/cpus"); if (nodeoff < 0) { printf("couldn't find /cpus\n"); diff --git a/arch/arm/cpu/armv7/virt-v7.c b/arch/arm/cpu/armv7/virt-v7.c index 651ca40..4b3bc54 100644 --- a/arch/arm/cpu/armv7/virt-v7.c +++ b/arch/arm/cpu/armv7/virt-v7.c @@ -71,11 +71,31 @@ void __weak smp_kick_all_cpus(void) kick_secondary_cpus_gic(gic_dist_addr); } +/* + * Check the "black list" of CPUs, which are not supported by this code + */ +int armv7_is_cpu_blacklisted_for_nonsec(void) +{ + unsigned midr; + asm("mrc p15, 0, %0, c0, c0, 0\n" : "=r"(midr)); + + /* Cortex-A8 is not supported yet */ + if ((midr & MIDR_PRIMARY_PART_MASK) == MIDR_CORTEX_A8_PRIMARY_PART) + return 1; + + return 0; +} + int armv7_init_nonsec(void) { unsigned int reg; unsigned itlinesnr, i; + if (armv7_is_cpu_blacklisted_for_nonsec()) { + printf("nonsec: This CPU is not supported.\n"); + return -1; + } + /* check whether the CPU supports the security extensions */ reg = read_id_pfr1(); if ((reg & 0xF0) == 0) { diff --git a/arch/arm/include/asm/armv7.h b/arch/arm/include/asm/armv7.h index 323f282..e22c9c1 100644 --- a/arch/arm/include/asm/armv7.h +++ b/arch/arm/include/asm/armv7.h @@ -8,6 +8,10 @@ #ifndef ARMV7_H #define ARMV7_H +/* Cortex-A8 revisions */ +#define MIDR_CORTEX_A8_PRIMARY_PART 0x410FC080 +#define MIDR_CORTEX_A8_R3P2 0x413FC082 + /* Cortex-A9 revisions */ #define MIDR_CORTEX_A9_R0P1 0x410FC091 #define MIDR_CORTEX_A9_R1P2 0x411FC092 @@ -80,6 +84,7 @@ void v7_outer_cache_inval_range(u32 start, u32 end); int armv7_init_nonsec(void); int armv7_update_dt(void *fdt); +int armv7_is_cpu_blacklisted_for_nonsec(void); /* defined in assembly file */ unsigned int _nonsec_init(void); diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 178e8fb..888a0ba 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -281,9 +281,19 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) if (!fake) { #if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) - armv7_init_nonsec(); - secure_ram_addr(_do_nonsec_entry)(kernel_entry, - 0, machid, r2); + if (armv7_init_nonsec()) { + printf("Switch to non-secure mode has failed - "); +#ifdef CONFIG_ARMV7_ALLOW_SECURE_MODE_FALLBACK + printf("booting the kernel in secure mode ...\n\n"); + kernel_entry(0, machid, r2); +#else + printf("hanging ...\n"); + hang(); +#endif + } else { + secure_ram_addr(_do_nonsec_entry)(kernel_entry, + 0, machid, r2); + } #else kernel_entry(0, machid, r2); #endif