* [PATCH] ARM: Fix memory at end of address space
@ 2016-04-01 12:05 Sascha Hauer
2016-04-01 12:05 ` [PATCH 1/4] ARM: pbl-multi: Fix SDRAM " Sascha Hauer
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Sascha Hauer @ 2016-04-01 12:05 UTC (permalink / raw)
To: Barebox List
When the registered SDRAM reaches the end of the address space the
vector table is not properly initialized. This series fixes this.
Sascha
----------------------------------------------------------------
Sascha Hauer (4):
ARM: pbl-multi: Fix SDRAM at end of address space
ARM: start: Fix wrong format specifier
ARM: Do not use last 64KiB of address space for barebox
ARM: Rework vector table setup
arch/arm/cpu/entry.c | 3 +-
arch/arm/cpu/mmu.c | 164 ++++++++++++++++++++++++++++---------
arch/arm/cpu/start.c | 2 +-
arch/arm/cpu/uncompress.c | 2 +-
arch/arm/include/asm/barebox-arm.h | 2 +-
arch/arm/lib/barebox.lds.S | 1 +
6 files changed, 133 insertions(+), 41 deletions(-)
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/4] ARM: pbl-multi: Fix SDRAM at end of address space
2016-04-01 12:05 [PATCH] ARM: Fix memory at end of address space Sascha Hauer
@ 2016-04-01 12:05 ` Sascha Hauer
2016-04-01 12:05 ` [PATCH 2/4] ARM: start: Fix wrong format specifier Sascha Hauer
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2016-04-01 12:05 UTC (permalink / raw)
To: Barebox List
When SDRAM reaches to the end of the address space the comparison
membase + memsize evaluates to 0, so pc - membase < memsize can never
be true. Fix this by substracting membase on both sides of the
comparison.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/cpu/uncompress.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c
index 5bcce6b..b8e2e9f 100644
--- a/arch/arm/cpu/uncompress.c
+++ b/arch/arm/cpu/uncompress.c
@@ -60,7 +60,7 @@ void __noreturn barebox_multi_pbl_start(unsigned long membase,
* to the current address. Otherwise it may be a readonly location.
* Copy and relocate to the start of the memory in this case.
*/
- if (pc > membase && pc < membase + memsize)
+ if (pc > membase && pc - membase < memsize)
relocate_to_current_adr();
else
relocate_to_adr(membase);
--
2.7.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/4] ARM: start: Fix wrong format specifier
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 ` 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 ` [PATCH 4/4] ARM: Rework vector table setup Sascha Hauer
3 siblings, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2016-04-01 12:05 UTC (permalink / raw)
To: Barebox List
Print a hex number after 0x, not a decimal number.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/cpu/start.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
index d03d1ed..e037d91 100644
--- a/arch/arm/cpu/start.c
+++ b/arch/arm/cpu/start.c
@@ -193,7 +193,7 @@ __noreturn void barebox_non_pbl_start(unsigned long membase,
if (totalsize) {
unsigned long mem = arm_mem_boarddata(membase, endmem,
totalsize);
- pr_debug("found %s in boarddata, copying to 0x%lu\n",
+ pr_debug("found %s in boarddata, copying to 0x%08lx\n",
name, mem);
barebox_boarddata = memcpy((void *)mem, boarddata,
totalsize);
--
2.7.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 3/4] ARM: Do not use last 64KiB of address space for barebox
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 ` Sascha Hauer
2016-04-01 12:05 ` [PATCH 4/4] ARM: Rework vector table setup Sascha Hauer
3 siblings, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2016-04-01 12:05 UTC (permalink / raw)
To: Barebox List
The last 64KiB of address space may be used for the vector table at
0xffff0000, so we cannot use it for barebox. The easiest way to archieve
this is to never use the last 64KiB of memory.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/cpu/entry.c | 3 ++-
arch/arm/include/asm/barebox-arm.h | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/entry.c b/arch/arm/cpu/entry.c
index 3b74c6a..0cdcfec 100644
--- a/arch/arm/cpu/entry.c
+++ b/arch/arm/cpu/entry.c
@@ -1,6 +1,7 @@
#include <types.h>
#include <asm/cache.h>
+#include <asm/barebox-arm.h>
#include "entry.h"
@@ -26,7 +27,7 @@
void __naked __noreturn barebox_arm_entry(unsigned long membase,
unsigned long memsize, void *boarddata)
{
- arm_setup_stack(membase + memsize - 16);
+ arm_setup_stack(arm_mem_stack(membase, membase + memsize) + STACK_SIZE - 16);
arm_early_mmu_cache_invalidate();
if (IS_ENABLED(CONFIG_PBL_MULTI_IMAGES))
diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h
index 6713326..8e7b45c 100644
--- a/arch/arm/include/asm/barebox-arm.h
+++ b/arch/arm/include/asm/barebox-arm.h
@@ -97,7 +97,7 @@ void *barebox_arm_boot_dtb(void);
static inline unsigned long arm_mem_stack(unsigned long membase,
unsigned long endmem)
{
- return endmem - STACK_SIZE;
+ return endmem - SZ_64K - STACK_SIZE;
}
static inline unsigned long arm_mem_ttb(unsigned long membase,
--
2.7.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 4/4] ARM: Rework vector table setup
2016-04-01 12:05 [PATCH] ARM: Fix memory at end of address space Sascha Hauer
` (2 preceding siblings ...)
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
3 siblings, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2016-04-01 12:05 UTC (permalink / raw)
To: Barebox List
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
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2016-04-01 12:05 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH 4/4] ARM: Rework vector table setup Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox