[U-Boot] [PATCH 0/3] avr32 fixes

This series fixes a trivial build issue, as well as a longstanding problem with the 'saveenv' command on ATNGW100.
It also includes a trivial enhancement to the exception reporting which I found very useful during debugging.
Hopefully this will make mainline u-boot useful again on AVR32. Without this fix, v2008.10 is the latest usable release.
The patches are based on v2010.06, but it merges fine with the latest upstream master. The AVR32 master branch currently contains a workaround which I plan to revert if these patches are acceptable.
Haavard Skinnemoen (3): avr32: Add missing asm/unaligned.h header file avr32: Print unrelocated PC on exception avr32: Add simple paging support
arch/avr32/cpu/at32ap700x/Makefile | 2 +- arch/avr32/cpu/at32ap700x/mmu.c | 80 ++++++++++++++++++++ arch/avr32/cpu/exception.c | 3 +- arch/avr32/cpu/start.S | 19 +++-- arch/avr32/include/asm/arch-at32ap700x/addrspace.h | 5 +- arch/avr32/include/asm/arch-at32ap700x/mmu.h | 66 ++++++++++++++++ arch/avr32/include/asm/unaligned.h | 1 + arch/avr32/lib/board.c | 3 + board/atmel/atngw100/atngw100.c | 15 ++++ include/configs/atngw100.h | 3 + 10 files changed, 185 insertions(+), 12 deletions(-) create mode 100644 arch/avr32/cpu/at32ap700x/mmu.c create mode 100644 arch/avr32/include/asm/arch-at32ap700x/mmu.h create mode 100644 arch/avr32/include/asm/unaligned.h

Simply include the generic version. We could optimize this a bit more, as unaligned 32-bit accesses are ok on AP7, but let's make it work first.
Signed-off-by: Haavard Skinnemoen haavard.skinnemoen@atmel.com --- arch/avr32/include/asm/unaligned.h | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 arch/avr32/include/asm/unaligned.h
diff --git a/arch/avr32/include/asm/unaligned.h b/arch/avr32/include/asm/unaligned.h new file mode 100644 index 0000000..6cecbbb --- /dev/null +++ b/arch/avr32/include/asm/unaligned.h @@ -0,0 +1 @@ +#include <asm-generic/unaligned.h>

In addition to the real PC value, also print the value of PC after subtracting the relocation offset. This value will match the address in the ELF file so it's much easier to figure out where things went wrong.
Signed-off-by: Haavard Skinnemoen haavard.skinnemoen@atmel.com --- arch/avr32/cpu/exception.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/arch/avr32/cpu/exception.c b/arch/avr32/cpu/exception.c index dc9c300..b21ef1f 100644 --- a/arch/avr32/cpu/exception.c +++ b/arch/avr32/cpu/exception.c @@ -59,7 +59,8 @@ void do_unknown_exception(unsigned int ecr, struct pt_regs *regs) { unsigned int mode;
- printf("\n *** Unhandled exception %u at PC=0x%08lx\n", ecr, regs->pc); + printf("\n *** Unhandled exception %u at PC=0x%08lx [%08lx]\n", + ecr, regs->pc, regs->pc - gd->reloc_off);
switch (ecr) { case ECR_BUS_ERROR_WRITE:

Use the MMU hardware to set up 1:1 mappings between physical and virtual addresses. This allows us to bypass the cache when accessing the flash without having to do any physical-to-virtual address mapping in the CFI driver.
The virtual memory mappings are defined at compile time through a sorted array of virtual memory range objects. When a TLB miss exception happens, the exception handler does a binary search through the array until it finds a matching entry and loads it into the TLB. The u-boot image itself is covered by a fixed TLB entry which is never replaced.
This makes the 'saveenv' command work again on ATNGW100 and other boards using the CFI driver, hopefully without breaking any rules.
Signed-off-by: Haavard Skinnemoen haavard.skinnemoen@atmel.com --- arch/avr32/cpu/at32ap700x/Makefile | 2 +- arch/avr32/cpu/at32ap700x/mmu.c | 78 ++++++++++++++++++++ arch/avr32/cpu/start.S | 19 +++-- arch/avr32/include/asm/arch-at32ap700x/addrspace.h | 5 +- arch/avr32/include/asm/arch-at32ap700x/mmu.h | 66 +++++++++++++++++ arch/avr32/lib/board.c | 4 + board/atmel/atngw100/atngw100.c | 15 ++++ board/atmel/atstk1000/atstk1000.c | 15 ++++ board/earthlcd/favr-32-ezkit/favr-32-ezkit.c | 15 ++++ board/mimc/mimc200/mimc200.c | 20 +++++ board/miromico/hammerhead/hammerhead.c | 15 ++++ include/configs/atngw100.h | 3 + include/configs/atstk1002.h | 3 + include/configs/atstk1003.h | 3 + include/configs/atstk1004.h | 3 + include/configs/atstk1006.h | 3 + include/configs/favr-32-ezkit.h | 3 + include/configs/hammerhead.h | 3 + include/configs/mimc200.h | 3 + 19 files changed, 267 insertions(+), 11 deletions(-) create mode 100644 arch/avr32/cpu/at32ap700x/mmu.c create mode 100644 arch/avr32/include/asm/arch-at32ap700x/mmu.h
diff --git a/arch/avr32/cpu/at32ap700x/Makefile b/arch/avr32/cpu/at32ap700x/Makefile index 46e6ef6..30ea925 100644 --- a/arch/avr32/cpu/at32ap700x/Makefile +++ b/arch/avr32/cpu/at32ap700x/Makefile @@ -24,7 +24,7 @@ include $(TOPDIR)/config.mk
LIB := $(obj)lib$(SOC).a
-COBJS := portmux.o clk.o +COBJS := portmux.o clk.o mmu.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/arch/avr32/cpu/at32ap700x/mmu.c b/arch/avr32/cpu/at32ap700x/mmu.c new file mode 100644 index 0000000..c3a1b93 --- /dev/null +++ b/arch/avr32/cpu/at32ap700x/mmu.c @@ -0,0 +1,78 @@ +#include <common.h> +#include <asm/arch/mmu.h> +#include <asm/sysreg.h> + +void mmu_init_r(unsigned long dest_addr) +{ + uintptr_t vmr_table_addr; + + /* Round monitor address down to the nearest page boundary */ + dest_addr &= PAGE_ADDR_MASK; + + /* Initialize TLB entry 0 to cover the monitor, and lock it */ + sysreg_write(TLBEHI, dest_addr | SYSREG_BIT(TLBEHI_V)); + sysreg_write(TLBELO, dest_addr | MMU_VMR_CACHE_WRBACK); + sysreg_write(MMUCR, SYSREG_BF(DRP, 0) | SYSREG_BF(DLA, 1) + | SYSREG_BIT(MMUCR_S) | SYSREG_BIT(M)); + __builtin_tlbw(); + + /* + * Calculate the address of the VM range table in a PC-relative + * manner to make sure we hit the SDRAM and not the flash. + */ + vmr_table_addr = (uintptr_t)&mmu_vmr_table; + sysreg_write(PTBR, vmr_table_addr); + printf("VMR table @ 0x%08x\n", vmr_table_addr); + + /* Enable paging */ + sysreg_write(MMUCR, SYSREG_BF(DRP, 1) | SYSREG_BF(DLA, 1) + | SYSREG_BIT(MMUCR_S) | SYSREG_BIT(M) | SYSREG_BIT(E)); +} + +int mmu_handle_tlb_miss(void) +{ + const struct mmu_vm_range *vmr_table; + const struct mmu_vm_range *vmr; + unsigned int fault_pgno; + int first, last; + + fault_pgno = sysreg_read(TLBEAR) >> PAGE_SHIFT; + vmr_table = (const struct mmu_vm_range *)sysreg_read(PTBR); + + /* Do a binary search through the VM ranges */ + first = 0; + last = CONFIG_SYS_NR_VM_REGIONS; + while (first < last) { + unsigned int start; + int middle; + + /* Pick the entry in the middle of the remaining range */ + middle = (first + last) >> 1; + vmr = &vmr_table[middle]; + start = vmr->virt_pgno; + + /* Do the bisection thing */ + if (fault_pgno < start) { + last = middle; + } else if (fault_pgno >= (start + vmr->nr_pages)) { + first = middle + 1; + } else { + /* Got it; let's slam it into the TLB */ + uint32_t tlbelo; + + tlbelo = vmr->phys & ~PAGE_ADDR_MASK; + tlbelo |= fault_pgno << PAGE_SHIFT; + sysreg_write(TLBELO, tlbelo); + __builtin_tlbw(); + + /* Zero means success */ + return 0; + } + } + + /* + * Didn't find any matching entries. Return a nonzero value to + * indicate that this should be treated as a fatal exception. + */ + return -1; +} diff --git a/arch/avr32/cpu/start.S b/arch/avr32/cpu/start.S index d37a46e..c43b684 100644 --- a/arch/avr32/cpu/start.S +++ b/arch/avr32/cpu/start.S @@ -81,12 +81,19 @@ _evba: .org 0x44 rjmp unknown_exception /* DTLB Modified */
- .org 0x50 - rjmp unknown_exception /* ITLB Miss */ - .org 0x60 - rjmp unknown_exception /* DTLB Miss (read) */ - .org 0x70 - rjmp unknown_exception /* DTLB Miss (write) */ + .org 0x50 /* ITLB Miss */ + pushm r8-r12,lr + rjmp 1f + .org 0x60 /* DTLB Miss (read) */ + pushm r8-r12,lr + rjmp 1f + .org 0x70 /* DTLB Miss (write) */ + pushm r8-r12,lr +1: mov r12, sp + rcall mmu_handle_tlb_miss + popm r8-r12,lr + brne unknown_exception + rete
.size _evba, . - _evba
diff --git a/arch/avr32/include/asm/arch-at32ap700x/addrspace.h b/arch/avr32/include/asm/arch-at32ap700x/addrspace.h index 409eee3..4edc1bd 100644 --- a/arch/avr32/include/asm/arch-at32ap700x/addrspace.h +++ b/arch/avr32/include/asm/arch-at32ap700x/addrspace.h @@ -75,10 +75,7 @@ static inline void * phys_to_virt(unsigned long address) static inline void * map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) { - if (flags == MAP_WRBACK) - return (void *)P1SEGADDR(paddr); - else - return (void *)P2SEGADDR(paddr); + return (void *)paddr; }
#endif /* __ASM_AVR32_ADDRSPACE_H */ diff --git a/arch/avr32/include/asm/arch-at32ap700x/mmu.h b/arch/avr32/include/asm/arch-at32ap700x/mmu.h new file mode 100644 index 0000000..fcd9a05 --- /dev/null +++ b/arch/avr32/include/asm/arch-at32ap700x/mmu.h @@ -0,0 +1,66 @@ +/* + * In order to deal with the hardcoded u-boot requirement that virtual + * addresses are always mapped 1:1 with physical addresses, we implement + * a small virtual memory manager so that we can use the MMU hardware in + * order to get the caching properties right. + * + * A few pages (or possibly just one) are locked in the TLB permanently + * in order to avoid recursive TLB misses, but most pages are faulted in + * on demand. + */ +#ifndef __ASM_ARCH_MMU_H +#define __ASM_ARCH_MMU_H + +#include <asm/sysreg.h> + +#define PAGE_SHIFT 20 +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_ADDR_MASK (~(PAGE_SIZE - 1)) + +#define MMU_VMR_CACHE_NONE \ + (SYSREG_BF(AP, 3) | SYSREG_BF(SZ, 3) | SYSREG_BIT(TLBELO_D)) +#define MMU_VMR_CACHE_WBUF \ + (MMU_VMR_CACHE_NONE | SYSREG_BIT(B)) +#define MMU_VMR_CACHE_WRTHRU \ + (MMU_VMR_CACHE_NONE | SYSREG_BIT(TLBELO_C) | SYSREG_BIT(W)) +#define MMU_VMR_CACHE_WRBACK \ + (MMU_VMR_CACHE_WBUF | SYSREG_BIT(TLBELO_C)) + +/* + * This structure is used in our "page table". Instead of the usual + * x86-inspired radix tree, we let each entry cover an arbitrary-sized + * virtual address range and store them in a binary search tree. This is + * somewhat slower, but should use significantly less RAM, and we + * shouldn't get many TLB misses when using 1 MB pages anyway. + * + * With 1 MB pages, we need 12 bits to store the page number. In + * addition, we stick an Invalid bit in the high bit of virt_pgno (if + * set, it cannot possibly match any faulting page), and all the bits + * that need to be written to TLBELO in phys_pgno. + */ +struct mmu_vm_range { + uint16_t virt_pgno; + uint16_t nr_pages; + uint32_t phys; +}; + +/* + * An array of mmu_vm_range objects describing all pageable addresses. + * The array is sorted by virt_pgno so that the TLB miss exception + * handler can do a binary search to find the correct entry. + */ +extern struct mmu_vm_range mmu_vmr_table[]; + +/* + * Initialize the MMU. This will set up a fixed TLB entry for the static + * u-boot image at dest_addr and enable paging. + */ +void mmu_init_r(unsigned long dest_addr); + +/* + * Handle a TLB miss exception. This function is called directly from + * the exception vector table written in assembly. + */ +int mmu_handle_tlb_miss(void); + +#endif /* __ASM_ARCH_MMU_H */ diff --git a/arch/avr32/lib/board.c b/arch/avr32/lib/board.c index 917ed6c..6754732 100644 --- a/arch/avr32/lib/board.c +++ b/arch/avr32/lib/board.c @@ -33,6 +33,7 @@
#include <asm/initcalls.h> #include <asm/sections.h> +#include <asm/arch/mmu.h>
#ifndef CONFIG_IDENT_STRING #define CONFIG_IDENT_STRING "" @@ -264,6 +265,9 @@ void board_init_r(gd_t *new_gd, ulong dest_addr) gd->flags |= GD_FLG_RELOC; gd->reloc_off = dest_addr - CONFIG_SYS_MONITOR_BASE;
+ /* Enable the MMU so that we can keep u-boot simple */ + mmu_init_r(dest_addr); + board_early_init_r();
monitor_flash_len = _edata - _text; diff --git a/board/atmel/atngw100/atngw100.c b/board/atmel/atngw100/atngw100.c index 004d8da..978f0c8 100644 --- a/board/atmel/atngw100/atngw100.c +++ b/board/atmel/atngw100/atngw100.c @@ -26,11 +26,26 @@ #include <asm/arch/clk.h> #include <asm/arch/gpio.h> #include <asm/arch/hmatrix.h> +#include <asm/arch/mmu.h> #include <asm/arch/portmux.h> #include <netdev.h>
DECLARE_GLOBAL_DATA_PTR;
+struct mmu_vm_range mmu_vmr_table[CONFIG_SYS_NR_VM_REGIONS] = { + { + .virt_pgno = CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT, + .nr_pages = CONFIG_SYS_FLASH_SIZE >> PAGE_SHIFT, + .phys = (CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT) + | MMU_VMR_CACHE_NONE, + }, { + .virt_pgno = CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT, + .nr_pages = EBI_SDRAM_SIZE >> PAGE_SHIFT, + .phys = (CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT) + | MMU_VMR_CACHE_WRBACK, + }, +}; + static const struct sdram_config sdram_config = { .data_bits = SDRAM_DATA_16BIT, .row_bits = 13, diff --git a/board/atmel/atstk1000/atstk1000.c b/board/atmel/atstk1000/atstk1000.c index c36cb57..9cda020 100644 --- a/board/atmel/atstk1000/atstk1000.c +++ b/board/atmel/atstk1000/atstk1000.c @@ -25,11 +25,26 @@ #include <asm/sdram.h> #include <asm/arch/clk.h> #include <asm/arch/hmatrix.h> +#include <asm/arch/mmu.h> #include <asm/arch/portmux.h> #include <netdev.h>
DECLARE_GLOBAL_DATA_PTR;
+struct mmu_vm_range mmu_vmr_table[CONFIG_SYS_NR_VM_REGIONS] = { + { + .virt_pgno = CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT, + .nr_pages = CONFIG_SYS_FLASH_SIZE >> PAGE_SHIFT, + .phys = (CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT) + | MMU_VMR_CACHE_NONE, + }, { + .virt_pgno = CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT, + .nr_pages = EBI_SDRAM_SIZE >> PAGE_SHIFT, + .phys = (CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT) + | MMU_VMR_CACHE_WRBACK, + }, +}; + static const struct sdram_config sdram_config = { #if defined(CONFIG_ATSTK1006) /* Dual MT48LC16M16A2-7E (64 MB) on daughterboard */ diff --git a/board/earthlcd/favr-32-ezkit/favr-32-ezkit.c b/board/earthlcd/favr-32-ezkit/favr-32-ezkit.c index 8af680f..e1c5653 100644 --- a/board/earthlcd/favr-32-ezkit/favr-32-ezkit.c +++ b/board/earthlcd/favr-32-ezkit/favr-32-ezkit.c @@ -24,10 +24,25 @@ #include <asm/sdram.h> #include <asm/arch/clk.h> #include <asm/arch/hmatrix.h> +#include <asm/arch/mmu.h> #include <asm/arch/portmux.h>
DECLARE_GLOBAL_DATA_PTR;
+struct mmu_vm_range mmu_vmr_table[CONFIG_SYS_NR_VM_REGIONS] = { + { + .virt_pgno = CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT, + .nr_pages = CONFIG_SYS_FLASH_SIZE >> PAGE_SHIFT, + .phys = (CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT) + | MMU_VMR_CACHE_NONE, + }, { + .virt_pgno = CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT, + .nr_pages = EBI_SDRAM_SIZE >> PAGE_SHIFT, + .phys = (CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT) + | MMU_VMR_CACHE_WRBACK, + }, +}; + static const struct sdram_config sdram_config = { /* MT48LC4M32B2P-6 (16 MB) */ .data_bits = SDRAM_DATA_32BIT, diff --git a/board/mimc/mimc200/mimc200.c b/board/mimc/mimc200/mimc200.c index cc0f137..ca7fc23 100644 --- a/board/mimc/mimc200/mimc200.c +++ b/board/mimc/mimc200/mimc200.c @@ -27,12 +27,32 @@ #include <asm/arch/clk.h> #include <asm/arch/gpio.h> #include <asm/arch/hmatrix.h> +#include <asm/arch/mmu.h> #include <asm/arch/portmux.h> #include <atmel_lcdc.h> #include <lcd.h>
#include "../../../arch/avr32/cpu/hsmc3.h"
+struct mmu_vm_range mmu_vmr_table[CONFIG_SYS_NR_VM_REGIONS] = { + { + .virt_pgno = CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT, + .nr_pages = CONFIG_SYS_FLASH_SIZE >> PAGE_SHIFT, + .phys = (CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT) + | MMU_VMR_CACHE_NONE, + }, { + .virt_pgno = EBI_SRAM_CS2_BASE >> PAGE_SHIFT, + .nr_pages = EBI_SRAM_CS2_SIZE >> PAGE_SHIFT, + .phys = (EBI_SRAM_CS2_BASE >> PAGE_SHIFT) + | MMU_VMR_CACHE_NONE, + }, { + .virt_pgno = CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT, + .nr_pages = EBI_SDRAM_SIZE >> PAGE_SHIFT, + .phys = (CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT) + | MMU_VMR_CACHE_WRBACK, + }, +}; + #if defined(CONFIG_LCD) /* 480x272x16 @ 72 Hz */ vidinfo_t panel_info = { diff --git a/board/miromico/hammerhead/hammerhead.c b/board/miromico/hammerhead/hammerhead.c index 8b3e22c..6a6dc30 100644 --- a/board/miromico/hammerhead/hammerhead.c +++ b/board/miromico/hammerhead/hammerhead.c @@ -30,10 +30,25 @@ #include <asm/arch/clk.h> #include <asm/arch/hmatrix.h> #include <asm/arch/memory-map.h> +#include <asm/arch/mmu.h> #include <asm/arch/portmux.h>
DECLARE_GLOBAL_DATA_PTR;
+struct mmu_vm_range mmu_vmr_table[CONFIG_SYS_NR_VM_REGIONS] = { + { + .virt_pgno = CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT, + .nr_pages = CONFIG_SYS_FLASH_SIZE >> PAGE_SHIFT, + .phys = (CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT) + | MMU_VMR_CACHE_NONE, + }, { + .virt_pgno = CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT, + .nr_pages = EBI_SDRAM_SIZE >> PAGE_SHIFT, + .phys = (CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT) + | MMU_VMR_CACHE_WRBACK, + }, +}; + static const struct sdram_config sdram_config = { .data_bits = SDRAM_DATA_32BIT, .row_bits = 13, diff --git a/include/configs/atngw100.h b/include/configs/atngw100.h index 4ed5514..83056b6 100644 --- a/include/configs/atngw100.h +++ b/include/configs/atngw100.h @@ -49,6 +49,9 @@ #define CONFIG_SYS_CLKDIV_PBA 2 #define CONFIG_SYS_CLKDIV_PBB 1
+/* Reserve VM regions for SDRAM and NOR flash */ +#define CONFIG_SYS_NR_VM_REGIONS 2 + /* * The PLLOPT register controls the PLL like this: * icp = PLLOPT<2> diff --git a/include/configs/atstk1002.h b/include/configs/atstk1002.h index b258f2d..6416d17 100644 --- a/include/configs/atstk1002.h +++ b/include/configs/atstk1002.h @@ -73,6 +73,9 @@ */ #define CONFIG_SYS_CLKDIV_PBB 1
+/* Reserve VM regions for SDRAM and NOR flash */ +#define CONFIG_SYS_NR_VM_REGIONS 2 + /* * The PLLOPT register controls the PLL like this: * icp = PLLOPT<2> diff --git a/include/configs/atstk1003.h b/include/configs/atstk1003.h index 2ef2552..a4d9b0b 100644 --- a/include/configs/atstk1003.h +++ b/include/configs/atstk1003.h @@ -73,6 +73,9 @@ */ #define CONFIG_SYS_CLKDIV_PBB 1
+/* Reserve VM regions for SDRAM and NOR flash */ +#define CONFIG_SYS_NR_VM_REGIONS 2 + /* * The PLLOPT register controls the PLL like this: * icp = PLLOPT<2> diff --git a/include/configs/atstk1004.h b/include/configs/atstk1004.h index 195be82..06bb5da 100644 --- a/include/configs/atstk1004.h +++ b/include/configs/atstk1004.h @@ -73,6 +73,9 @@ */ #define CONFIG_SYS_CLKDIV_PBB 1
+/* Reserve VM regions for SDRAM and NOR flash */ +#define CONFIG_SYS_NR_VM_REGIONS 2 + /* * The PLLOPT register controls the PLL like this: * icp = PLLOPT<2> diff --git a/include/configs/atstk1006.h b/include/configs/atstk1006.h index f93118e..d3cbee6 100644 --- a/include/configs/atstk1006.h +++ b/include/configs/atstk1006.h @@ -73,6 +73,9 @@ */ #define CONFIG_SYS_CLKDIV_PBB 1
+/* Reserve VM regions for SDRAM and NOR flash */ +#define CONFIG_SYS_NR_VM_REGIONS 2 + /* * The PLLOPT register controls the PLL like this: * icp = PLLOPT<2> diff --git a/include/configs/favr-32-ezkit.h b/include/configs/favr-32-ezkit.h index 739ff0d..1c381c7 100644 --- a/include/configs/favr-32-ezkit.h +++ b/include/configs/favr-32-ezkit.h @@ -70,6 +70,9 @@ */ #define CONFIG_SYS_CLKDIV_PBB 1
+/* Reserve VM regions for SDRAM and NOR flash */ +#define CONFIG_SYS_NR_VM_REGIONS 2 + /* * The PLLOPT register controls the PLL like this: * icp = PLLOPT<2> diff --git a/include/configs/hammerhead.h b/include/configs/hammerhead.h index 0c70af5..8ca04ea 100644 --- a/include/configs/hammerhead.h +++ b/include/configs/hammerhead.h @@ -47,6 +47,9 @@ #define CONFIG_SYS_CLKDIV_PBA 2 #define CONFIG_SYS_CLKDIV_PBB 1
+/* Reserve VM regions for SDRAM and NOR flash */ +#define CONFIG_SYS_NR_VM_REGIONS 2 + /* * The PLLOPT register controls the PLL like this: * icp = PLLOPT<2> diff --git a/include/configs/mimc200.h b/include/configs/mimc200.h index 36488b3..6ed9e75 100644 --- a/include/configs/mimc200.h +++ b/include/configs/mimc200.h @@ -51,6 +51,9 @@ #define CONFIG_SYS_CLKDIV_PBA 2 #define CONFIG_SYS_CLKDIV_PBB 1
+/* Reserve VM regions for SDRAM, NOR flash and FRAM */ +#define CONFIG_SYS_NR_VM_REGIONS 3 + /* * The PLLOPT register controls the PLL like this: * icp = PLLOPT<2>

Dear Håvard Skinnemoen,
I have tested the simple TLB implementation on our own hardware and it does work with CFI driver. Thanks a lot for introducing this, we had to wait so long ...
Am 02.08.2010 14:06, schrieb Haavard Skinnemoen:
Use the MMU hardware to set up 1:1 mappings between physical and virtual addresses. This allows us to bypass the cache when accessing the flash without having to do any physical-to-virtual address mapping in the CFI driver.
The virtual memory mappings are defined at compile time through a sorted array of virtual memory range objects. When a TLB miss exception happens, the exception handler does a binary search through the array until it finds a matching entry and loads it into the TLB. The u-boot image itself is covered by a fixed TLB entry which is never replaced.
This makes the 'saveenv' command work again on ATNGW100 and other boards using the CFI driver, hopefully without breaking any rules.
Signed-off-by: Haavard Skinnemoen haavard.skinnemoen@atmel.com
Tested-by: Andreas Bießmann biessmann@corscience.de

Dear Haavard Skinnemoen,
In message 1280750789-10359-4-git-send-email-haavard.skinnemoen@atmel.com you wrote:
Use the MMU hardware to set up 1:1 mappings between physical and virtual addresses. This allows us to bypass the cache when accessing the flash without having to do any physical-to-virtual address mapping in the CFI driver.
The virtual memory mappings are defined at compile time through a sorted array of virtual memory range objects. When a TLB miss exception happens, the exception handler does a binary search through the array until it finds a matching entry and loads it into the TLB. The u-boot image itself is covered by a fixed TLB entry which is never replaced.
This makes the 'saveenv' command work again on ATNGW100 and other boards using the CFI driver, hopefully without breaking any rules.
Can you please try and rebase this code on top of Heiko's ARM rework patches, i. e. with cache and relocation support?
See http://thread.gmane.org/gmane.comp.boot-loaders.u-boot/81825/focus=82142
My intention is that after -rc1 has been released (i. e. when we have a "next" branch again), I will first apply the new environment code patches, and then, probably with a week delay or so, Heiko's ARM rework. Your stuff will then have to fit on top of this.
Thanks.
Best regards,
Wolfgang Denk

Wolfgang Denk wd@denx.de wrote:
Can you please try and rebase this code on top of Heiko's ARM rework patches, i. e. with cache and relocation support?
See http://thread.gmane.org/gmane.comp.boot-loaders.u-boot/81825/focus=82142
My intention is that after -rc1 has been released (i. e. when we have a "next" branch again), I will first apply the new environment code patches, and then, probably with a week delay or so, Heiko's ARM rework. Your stuff will then have to fit on top of this.
Sure. The patches probably needs more testing and a refresh anyway...I just saw some issues with SDRAM initialization on some boards which need to be investigated.
Haavard

On Mon, 2 Aug 2010 14:06:26 +0200, Haavard Skinnemoen haavard.skinnemoen@atmel.com wrote:
This series fixes a trivial build issue, as well as a longstanding problem with the 'saveenv' command on ATNGW100.
Is that the same problem that makes flash erase actions fail with the error that the start or end address does not match a sector boundary?
It also includes a trivial enhancement to the exception reporting which I found very useful during debugging.
Hopefully this will make mainline u-boot useful again on AVR32. Without this fix, v2008.10 is the latest usable release.
I had a problem with this version as well when the environment was empty. It said the flash was 4Gig and kept crashing with some DMA error (NGW100 board).
The patches are based on v2010.06, but it merges fine with the latest upstream master. The AVR32 master branch currently contains a workaround which I plan to revert if these patches are acceptable.
I'm happy to test them on my board. What a coincidence with my (first) mailing list post from earlier today.
Thanks a lot!
Bas.

Bas Mevissen abuse@basmevissen.nl wrote:
On Mon, 2 Aug 2010 14:06:26 +0200, Haavard Skinnemoen haavard.skinnemoen@atmel.com wrote:
This series fixes a trivial build issue, as well as a longstanding problem with the 'saveenv' command on ATNGW100.
Is that the same problem that makes flash erase actions fail with the error that the start or end address does not match a sector boundary?
Yes, that's the one.
Hopefully this will make mainline u-boot useful again on AVR32. Without this fix, v2008.10 is the latest usable release.
I had a problem with this version as well when the environment was empty. It said the flash was 4Gig and kept crashing with some DMA error (NGW100 board).
Ok, I wasn't aware of that problem. I don't think I've ever tried running u-boot with empty environment; in fact, I'm not even sure how you do that since it will fall back to a default environment if it can't find anything in flash.
The patches are based on v2010.06, but it merges fine with the latest upstream master. The AVR32 master branch currently contains a workaround which I plan to revert if these patches are acceptable.
I'm happy to test them on my board. What a coincidence with my (first) mailing list post from earlier today.
That would be awesome. I don't really follow the mailing list very closely these days, so I didn't see your post.
Haavard

On Mon, 2 Aug 2010 14:43:36 +0200, Haavard Skinnemoen haavard.skinnemoen@atmel.com wrote:
I had a problem with this version as well when the environment was
empty.
It said the flash was 4Gig and kept crashing with some DMA error
(NGW100
board).
Ok, I wasn't aware of that problem. I don't think I've ever tried running u-boot with empty environment; in fact, I'm not even sure how you do that since it will fall back to a default environment if it can't find anything in flash.
Yes, the strange thing is that it worked fine a few times. But for some reason, it failed later on. I'll try to reproduce the problem and make a proper report.

On 08/02/2010 05:44 PM, Bas Mevissen wrote:
Ok, I wasn't aware of that problem. I don't think I've ever tried running u-boot with empty environment; in fact, I'm not even sure how you do that since it will fall back to a default environment if it can't find anything in flash.
Yes, the strange thing is that it worked fine a few times. But for some reason, it failed later on. I'll try to reproduce the problem and make a proper report.
Here it is, pasted as quotation to avoid line wrapping:
U-Boot 2008.10 (Aug 1 2010 - 01:34:48)
U-Boot code: 00000000 -> 00012f66 data: 000198e8 -> 0004f4e0 malloc: Using memory from 0x11f70000 to 0x11fb0000 DMA: Using memory from 0x11f6c000 to 0x11f70000 Flash: 3.2 GB at address 0x00000000 DRAM Configuration: Bank #0: 10000000 32 MB WARNING: Cannot allocate space for boot parameters *** Warning - bad CRC, using default environment
*** Unhandled exception 5 at PC=0xffffffff MMU exception at address 0xffffffff pc: ffffffff lr: 11fb7ff0 sp: 11f6bf3c r12: ffffffff r11: 00041a67 r10: 00041a67 r9: 00000002 r8: 00000001 r7: 00041a67 r6: 11fca850 r5: 11f6bfa0 r4: 00000001 r3: 00041a67 r2: 00041a67 r1: 0001a85c r0: 0001a858 Flags: qvNzc Mode bits: hrje....g CPU Mode: Supervisor
Stack: (0x11f6bf3c to 0x11f6bfa0) bf20: 11fb819e bf40: 11f6bfcc 11fca850 11f6bfa0 11fcf2a0 11fb0762 11f6bfcc 11fca850 11f6bfa0 bf60: 11fcf2a0 11f6bfcc 0001a860 0001a85c 0001a858 11fb0182 02000000 11fca850 bf80: 24007fb4 11fcf2a0 68616e64 11fb0000 00000000 11fb0000 00000000 00000000 Unhandled exception
I don't know how u-boot knows the flash layout. Maybe something changed between 1.3.3 and 2008.10 (default partition table?)
I compiled pristine 2008.10 for atngw100 with just LZMA compression enabled and the right command line and boot command for OpenWRT:
--- u-boot-2008.10/include/configs/atngw100.h.orig 2008-10-18 21:30:31.000000000 +0200 +++ u-boot-2008.10/include/configs/atngw100.h 2010-08-01 01:34:00.001061885 +0200 @@ -62,6 +62,7 @@
/* User serviceable stuff */ #define CONFIG_DOS_PARTITION 1 +#define CONFIG_LZMA 1
#define CONFIG_CMDLINE_TAG 1 #define CONFIG_SETUP_MEMORY_TAGS 1 @@ -71,9 +72,9 @@
#define CONFIG_BAUDRATE 115200 #define CONFIG_BOOTARGS \
- "console=ttyS0 root=/dev/mtdblock1 rootfstype=jffs2"
- "console=ttyS0i,115200 root=/dev/mtdblock2 rootfstype=jffs2 init=/etc/preinit"
#define CONFIG_BOOTCOMMAND \
- "fsload; bootm"
- "bootm 0x20000"
/*
- Only interrupt autoboot if <space> is pressed. Otherwise, garbage
(make atngw100_config && make)
This is what 1.3.3 does. I just took the plain image from OpenWRT and not the one padded to 128K bytes as usual with OpenWRT. For 1.3.3, that does not seem to make a difference.
OpenWRT only adds LZMA decompression support to the pristine sources.
U-Boot 1.3.3 (Aug 1 2010 - 03:05:20)
U-Boot code: 00000000 -> 00011600 data: 00017b20 -> 0004e408 SDRAM: 32 MB at address 0x10000000 Testing SDRAM...OK malloc: Using memory from 0x11f71000 to 0x11fb1000 DMA: Using memory from 0x11f6d000 to 0x11f71000 Flash: 8 MB at address 0x00000000 DRAM Configuration: Bank #0: 10000000 32 MB *** Warning - bad CRC, using default environment
In: serial Out: serial Err: serial Net: macb0, macb1 Press SPACE to abort autoboot in 1 seconds Wrong Image Format for bootm command ERROR: can't get kernel image! Uboot>
You notice that the flash size is correctly recognized. I fully erased the flash between both attempts and there was no power cycle in between. Actually, I'm not even physically touching the board.
participants (4)
-
Andreas Bießmann
-
Bas Mevissen
-
Haavard Skinnemoen
-
Wolfgang Denk