mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: Barebox List <barebox@lists.infradead.org>
Subject: [PATCH 4/4] ARM: Rework vector table setup
Date: Fri,  1 Apr 2016 14:05:19 +0200	[thread overview]
Message-ID: <1459512319-32073-5-git-send-email-s.hauer@pengutronix.de> (raw)
In-Reply-To: <1459512319-32073-1-git-send-email-s.hauer@pengutronix.de>

The current vector table setup has some shortcomings. First of all
currently the case when the high vectors are inside SDRAM (that is,
SDRAM reaches the end of the address space) is not supported. In this
case we create a secondary page table for the section containing the
vectors which gets overwritten by the general SDRAM secondary page
table entries creation afterwards. On ARMv7 and later the exception
table setup can be improved: Here the vector table address is configurable
in the VBAR register. We can use this register to skip remapping the
vector table.

With this patch we first try to use the VBAR register before doing
something else. Also, when we have to use the high vectors we first
try a request_sdram_region to test if the vector table memory is already
mapped. While at it sprinkle some comments into the code.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/cpu/mmu.c         | 164 +++++++++++++++++++++++++++++++++++----------
 arch/arm/lib/barebox.lds.S |   1 +
 2 files changed, 128 insertions(+), 37 deletions(-)

diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c
index bc5325f..a31bce4 100644
--- a/arch/arm/cpu/mmu.c
+++ b/arch/arm/cpu/mmu.c
@@ -272,59 +272,149 @@ static int arm_mmu_remap_sdram(struct memory_bank *bank)
  */
 #define ARM_VECTORS_SIZE	(sizeof(u32) * 8 * 2)
 
-/*
- * Map vectors and zero page
+#define ARM_HIGH_VECTORS	0xffff0000
+#define ARM_LOW_VECTORS		0x0
+
+/**
+ * create_vector_table - create a vector table at given address
+ * @adr - The address where the vector table should be created
+ *
+ * After executing this function the vector table is found at the
+ * virtual address @adr.
  */
-static void vectors_init(void)
+static void create_vector_table(unsigned long adr)
 {
-	u32 *exc, *zero = NULL;
+	struct resource *vectors_sdram;
 	void *vectors;
-	u32 cr;
+	u32 *exc;
+	int idx;
 
-	cr = get_cr();
-	cr |= CR_V;
-	set_cr(cr);
-	cr = get_cr();
-
-	if (cr & CR_V) {
+	vectors_sdram = request_sdram_region("vector table", adr, SZ_4K);
+	if (vectors_sdram) {
 		/*
-		 * If we can use high vectors, create the second level
-		 * page table for the high vectors and zero page
+		 * The vector table address is inside the SDRAM physical
+		 * address space. Use the existing identity mapping for
+		 * the vector table.
 		 */
-		exc = arm_create_pte(0xfff00000);
-		zero = arm_create_pte(0x0);
-
-		/* Set the zero page to faulting */
-		zero[0] = 0;
+		pr_debug("Creating vector table, virt = phys = 0x%08lx\n", adr);
+		vectors = (void *)vectors_sdram->start;
 	} else {
 		/*
-		 * Otherwise map the vectors to the zero page. We have to
-		 * live without being able to catch NULL pointer dereferences
+		 * The vector table address is outside of SDRAM. Create
+		 * a secondary page table for the section and map
+		 * allocated memory to the vector address.
 		 */
-		exc = arm_create_pte(0x0);
-
-		if (cpu_architecture() >= CPU_ARCH_ARMv7) {
-			/*
-			 * ARMv7 CPUs allow to remap low vectors from
-			 * 0x0 to an arbitrary address using VBAR
-			 * register, so let's make sure we have it
-			 * pointing to the correct address
-			 */
-			set_vbar(0x0);
-		}
+		vectors = xmemalign(PAGE_SIZE, PAGE_SIZE);
+		pr_debug("Creating vector table, virt = 0x%p, phys = 0x%08lx\n",
+			 vectors, adr);
+		exc = arm_create_pte(adr);
+		idx = (adr & (SZ_1M - 1)) >> PAGE_SHIFT;
+		exc[idx] = (u32)vectors | PTE_TYPE_SMALL | pte_flags_cached;
 	}
 
 	arm_fixup_vectors();
 
-	vectors = xmemalign(PAGE_SIZE, PAGE_SIZE);
 	memset(vectors, 0, PAGE_SIZE);
 	memcpy(vectors, __exceptions_start, __exceptions_stop - __exceptions_start);
+}
 
-	if (cr & CR_V)
-		exc[256 - 16] = (u32)vectors | PTE_TYPE_SMALL |
-			pte_flags_cached;
-	else
-		exc[0] = (u32)vectors | PTE_TYPE_SMALL | pte_flags_cached;
+/**
+ * set_vector_table - let CPU use the vector table at given address
+ * @adr - The address of the vector table
+ *
+ * Depending on the CPU the possibilities differ. ARMv7 and later allow
+ * to map the vector table to arbitrary addresses. Other CPUs only allow
+ * vectors at 0xffff0000 or at 0x0.
+ */
+static int set_vector_table(unsigned long adr)
+{
+	u32 cr;
+
+	if (cpu_architecture() >= CPU_ARCH_ARMv7) {
+		pr_debug("Vectors are at 0x%08lx\n", adr);
+		set_vbar(adr);
+		return 0;
+	}
+
+	if (adr == ARM_HIGH_VECTORS) {
+		cr = get_cr();
+		cr |= CR_V;
+		set_cr(cr);
+		cr = get_cr();
+		if (cr & CR_V) {
+			pr_debug("Vectors are at 0x%08lx\n", adr);
+			return 0;
+		} else {
+			return -EINVAL;
+		}
+	}
+
+	if (adr == ARM_LOW_VECTORS) {
+		cr = get_cr();
+		cr &= ~CR_V;
+		set_cr(cr);
+		cr = get_cr();
+		if (cr & CR_V) {
+			return -EINVAL;
+		} else {
+			pr_debug("Vectors are at 0x%08lx\n", adr);
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static void create_zero_page(void)
+{
+	struct resource *zero_sdram;
+	u32 *zero;
+
+	zero_sdram = request_sdram_region("zero page", 0x0, SZ_4K);
+	if (zero_sdram) {
+		/*
+		 * Here we would need to set the second level page table
+		 * entry to faulting. This is not yet implemented.
+		 */
+		pr_debug("zero page is in SDRAM area, currently not supported\n");
+	} else {
+		zero = arm_create_pte(0x0);
+		zero[0] = 0;
+		pr_debug("Created zero page\n");
+	}
+}
+
+/*
+ * Map vectors and zero page
+ */
+static void vectors_init(void)
+{
+	/*
+	 * First try to use the vectors where they actually are, works
+	 * on ARMv7 and later.
+	 */
+	if (!set_vector_table((unsigned long)__exceptions_start)) {
+		arm_fixup_vectors();
+		create_zero_page();
+		return;
+	}
+
+	/*
+	 * Next try high vectors at 0xffff0000.
+	 */
+	if (!set_vector_table(ARM_HIGH_VECTORS)) {
+		create_zero_page();
+		create_vector_table(ARM_HIGH_VECTORS);
+		return;
+	}
+
+	/*
+	 * As a last resort use low vectors at 0x0. With this we can't
+	 * set the zero page to faulting and can't catch NULL pointer
+	 * exceptions.
+	 */
+	set_vector_table(ARM_LOW_VECTORS);
+	create_vector_table(ARM_LOW_VECTORS);
 }
 
 /*
diff --git a/arch/arm/lib/barebox.lds.S b/arch/arm/lib/barebox.lds.S
index 5344557..6dc8bd2 100644
--- a/arch/arm/lib/barebox.lds.S
+++ b/arch/arm/lib/barebox.lds.S
@@ -43,6 +43,7 @@ SECTIONS
 		__bare_init_start = .;
 		*(.text_bare_init*)
 		__bare_init_end = .;
+		. = ALIGN(4);
 		__exceptions_start = .;
 		KEEP(*(.text_exceptions*))
 		__exceptions_stop = .;
-- 
2.7.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

      parent reply	other threads:[~2016-04-01 12:05 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-01 12:05 [PATCH] ARM: Fix memory at end of address space Sascha Hauer
2016-04-01 12:05 ` [PATCH 1/4] ARM: pbl-multi: Fix SDRAM " Sascha Hauer
2016-04-01 12:05 ` [PATCH 2/4] ARM: start: Fix wrong format specifier Sascha Hauer
2016-04-01 12:05 ` [PATCH 3/4] ARM: Do not use last 64KiB of address space for barebox Sascha Hauer
2016-04-01 12:05 ` Sascha Hauer [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1459512319-32073-5-git-send-email-s.hauer@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox