From patchwork Fri Jun 21 23:48:22 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Santosh Shilimkar X-Patchwork-Id: 2765151 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 697879F756 for ; Sat, 22 Jun 2013 00:34:20 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 52B2B201B7 for ; Sat, 22 Jun 2013 00:34:19 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 218B8201B3 for ; Sat, 22 Jun 2013 00:34:18 +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 1UqB6x-0001EK-6F; Fri, 21 Jun 2013 23:51:25 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UqB5x-000069-4U; Fri, 21 Jun 2013 23:50:21 +0000 Received: from bear.ext.ti.com ([192.94.94.41]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UqB4r-0008RE-Lz for linux-arm-kernel@lists.infradead.org; Fri, 21 Jun 2013 23:49:19 +0000 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id r5LNmn1N026874; Fri, 21 Jun 2013 18:48:49 -0500 Received: from DFLE73.ent.ti.com (dfle73.ent.ti.com [128.247.5.110]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id r5LNmnas005082; Fri, 21 Jun 2013 18:48:49 -0500 Received: from dlelxv22.itg.ti.com (172.17.1.197) by DFLE73.ent.ti.com (128.247.5.110) with Microsoft SMTP Server id 14.2.342.3; Fri, 21 Jun 2013 18:48:48 -0500 Received: from ula0393909.am.dhcp.ti.com (ula0393909.am.dhcp.ti.com [158.218.103.117]) by dlelxv22.itg.ti.com (8.13.8/8.13.8) with ESMTP id r5LNmPJK025428; Fri, 21 Jun 2013 18:48:48 -0500 From: Santosh Shilimkar To: Subject: [PATCH 8/8] ARM: keystone: Switch over to high physical address range Date: Fri, 21 Jun 2013 19:48:22 -0400 Message-ID: <1371858502-10083-9-git-send-email-santosh.shilimkar@ti.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1371858502-10083-1-git-send-email-santosh.shilimkar@ti.com> References: <1371858502-10083-1-git-send-email-santosh.shilimkar@ti.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130621_194913_889319_C8932BF7 X-CRM114-Status: GOOD ( 20.46 ) X-Spam-Score: -8.4 (--------) Cc: nicolas.pitre@linaro.org, linux@arm.linux.org.uk, catalin.marinas@arm.com, will.deacon@arm.com, r.sricharan@ti.com, Santosh Shilimkar 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: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-5.7 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, 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 Keystone platforms have their physical memory mapped at an address outside the 32-bit physical range. A Keystone machine with 16G of RAM would find its memory at 0x0800000000 - 0x0bffffffff. For boot purposes, the interconnect supports a limited alias of some of this memory within the 32-bit addressable space (0x80000000 - 0xffffffff). This aliasing is implemented in hardware, and is not intended to be used much beyond boot. For instance, DMA coherence does not work when running out of this aliased address space. Therefore, a two pahsed boot approach is implemented. 1) Boot out of the low physical address range 2) Switch over to the high range once we're safely inside machine initialization. This patch implements this switch over mechanism, which involves rewiring the TTBRs and page tables to point to the new physical address space. Based on earlier patch version from Cyril. Signed-off-by: Santosh Shilimkar --- arch/arm/mach-keystone/keystone.c | 49 +++++++++++++++++++++++++++++++++++++ arch/arm/mach-keystone/memory.h | 24 ++++++++++++++++++ arch/arm/mach-keystone/platsmp.c | 16 +++++++++++- 3 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-keystone/memory.h diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c index fe4d9ff..90442bb 100644 --- a/arch/arm/mach-keystone/keystone.c +++ b/arch/arm/mach-keystone/keystone.c @@ -20,6 +20,9 @@ #include #include #include +#include + +#include "memory.h" #include "keystone.h" @@ -44,6 +47,51 @@ static void __init keystone_init(void) of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } +static phys_addr_t keystone_virt_to_idmap(unsigned long x) +{ + return (phys_addr_t)(x) - CONFIG_PAGE_OFFSET + KEYSTONE_LOW_PHYS_START; +} + +static void __init keystone_init_meminfo(void) +{ + bool lpae = IS_ENABLED(CONFIG_ARM_LPAE); + bool pvpatch = IS_ENABLED(CONFIG_ARM_PATCH_PHYS_VIRT); + phys_addr_t offset = PHYS_OFFSET - KEYSTONE_LOW_PHYS_START; + phys_addr_t mem_start, mem_end; + + BUG_ON(meminfo.nr_banks < 1); + mem_start = meminfo.bank[0].start; + mem_end = mem_start + meminfo.bank[0].size - 1; + + /* nothing to do if we are running out of the <32-bit space */ + if (mem_start >= KEYSTONE_LOW_PHYS_START && + mem_end <= KEYSTONE_LOW_PHYS_END) + return; + + if (!lpae || !pvpatch) { + pr_crit("Enable %s%s%s to run outside 32-bit space\n", + !lpae ? __stringify(CONFIG_ARM_LPAE) : "", + (!lpae && !pvpatch) ? " and " : "", + !pvpatch ? __stringify(CONFIG_ARM_PATCH_PHYS_VIRT) : ""); + } + + if (mem_start < KEYSTONE_HIGH_PHYS_START || + mem_end > KEYSTONE_HIGH_PHYS_END) { + pr_crit("Invalid address space for memory (%08llx-%08llx)\n", + (u64)mem_start, (u64)mem_end); + } + + offset += KEYSTONE_HIGH_PHYS_START; + __pv_phys_offset = offset; + __pv_offset = (offset - PAGE_OFFSET); + __pv_offset >>= PV_LOW_SHIFT; + + /* Populate the arch idmap hook */ + arch_virt_to_idmap = keystone_virt_to_idmap; + + pr_info("Switching to high address space at 0x%llx\n", (u64)offset); +} + static const char *keystone_match[] __initconst = { "ti,keystone-evm", NULL, @@ -72,4 +120,5 @@ DT_MACHINE_START(KEYSTONE, "Keystone") .init_machine = keystone_init, .dt_compat = keystone_match, .restart = keystone_restart, + .init_meminfo = keystone_init_meminfo, MACHINE_END diff --git a/arch/arm/mach-keystone/memory.h b/arch/arm/mach-keystone/memory.h new file mode 100644 index 0000000..83fc5a9 --- /dev/null +++ b/arch/arm/mach-keystone/memory.h @@ -0,0 +1,24 @@ +/* + * Copyright 2013 Texas Instruments, Inc. + * Santosh Shilimkar + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ +#ifndef __MACH_MEMORY_H +#define __MACH_MEMORY_H + +#define MAX_PHYSMEM_BITS 36 +#define SECTION_SIZE_BITS 34 + +#define KEYSTONE_LOW_PHYS_START 0x80000000ULL +#define KEYSTONE_LOW_PHYS_SIZE 0x80000000ULL /* 2G */ +#define KEYSTONE_LOW_PHYS_END (KEYSTONE_LOW_PHYS_START + \ + KEYSTONE_LOW_PHYS_SIZE - 1) + +#define KEYSTONE_HIGH_PHYS_START 0x800000000ULL +#define KEYSTONE_HIGH_PHYS_SIZE 0x400000000ULL /* 16G */ +#define KEYSTONE_HIGH_PHYS_END (KEYSTONE_HIGH_PHYS_START + \ + KEYSTONE_HIGH_PHYS_SIZE - 1) +#endif /* _MACH_MEMORY_H */ diff --git a/arch/arm/mach-keystone/platsmp.c b/arch/arm/mach-keystone/platsmp.c index 1d4181e..4be8ea2 100644 --- a/arch/arm/mach-keystone/platsmp.c +++ b/arch/arm/mach-keystone/platsmp.c @@ -18,13 +18,15 @@ #include #include +#include +#include #include "keystone.h" static int __cpuinit keystone_smp_boot_secondary(unsigned int cpu, struct task_struct *idle) { - unsigned long start = virt_to_phys(&secondary_startup); + unsigned long start = virt_to_idmap(&secondary_startup); int error; pr_debug("keystone-smp: booting cpu %d, vector %08lx\n", @@ -37,7 +39,19 @@ static int __cpuinit keystone_smp_boot_secondary(unsigned int cpu, return error; } +static void __cpuinit keystone_smp_secondary_initmem(unsigned int cpu) +{ + bool lpae = IS_ENABLED(CONFIG_ARM_LPAE); + + if (lpae) { + pgd_t *pgd0 = pgd_offset_k(0); + cpu_set_ttbr(1, __pa(pgd0) + TTBR1_OFFSET); + local_flush_tlb_all(); + } +} + struct smp_operations keystone_smp_ops __initdata = { .smp_init_cpus = arm_dt_init_cpu_maps, .smp_boot_secondary = keystone_smp_boot_secondary, + .smp_secondary_init = keystone_smp_secondary_initmem, };