Skip to contentSkip to conversation

avr32: simple paging support

PATCH New Haavard Skinnemoen 5 participants 16 messages Aug 12, 2010 – Sep 3, 2010 Arm/Microchip (AT91) SoC support

lore
Share & tools
lore
#0 lore raw

v2 cover avr32: simple paging support

This series fixes 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.

This is the second version of this series. The following changes have been made since v1:
- Rebased onto testing/arm-reloc-and-cache-support
- Dropped asm/unaligned.h fix because a similar patch has already been applied to mainline.
- Fixed SDRAM initialization issue noticed on certain boards

Haavard Skinnemoen (3):
avr32: Print unrelocated PC on exception
avr32: Use uncached() macro to get an address for SDRAM init
avr32: Add simple paging support

 arch/avr32/cpu/at32ap700x/Makefile                 |    2 +-
 arch/avr32/cpu/at32ap700x/mmu.c                    |   78 ++++++++++++++++++++
 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/lib/board.c                             |    4 +
 board/atmel/atngw100/atngw100.c                    |   19 ++++-
 board/atmel/atstk1000/atstk1000.c                  |   19 ++++-
 board/earthlcd/favr-32-ezkit/favr-32-ezkit.c       |   19 ++++-
 board/mimc/mimc200/mimc200.c                       |   24 +++++-
 board/miromico/hammerhead/hammerhead.c             |   19 ++++-
 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 +
 20 files changed, 274 insertions(+), 27 deletions(-)
 create mode 100644 arch/avr32/cpu/at32ap700x/mmu.c
 create mode 100644 arch/avr32/include/asm/arch-at32ap700x/mmu.h
#1 lore raw

PATCH v2 1/3 avr32: Print unrelocated PC on exception

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.

---
 arch/avr32/cpu/exception.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
arch/avr32/cpu/exception.c +2 -1
index dc9c300..b21ef1f 100644
@@ -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:
Signature · 1 line
1.7.0.4
#2 lore raw

PATCH v2 1/3 avr32: Print unrelocated PC on exception

Hello Andreas,

did/can you test that one as well?
Then I can take all 3 of the series in.

Thanks,
Reinhard

Quoted 23 lines

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.

---
 arch/avr32/cpu/exception.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
arch/avr32/cpu/exception.c +2 -1
index dc9c300..b21ef1f 100644
@@ -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:
#3 lore raw

PATCH v2 1/3 avr32: Print unrelocated PC on exception

Dear Reinhard Meyer,

Am 03.09.2010 13:51, schrieb Reinhard Meyer:

Quoted 4 lines

Hello Andreas,

did/can you test that one as well?
Then I can take all 3 of the series in.

Well I have applied this patch but have never tested this till now. Yes it works and shows correct information.

Quoted 5 lines
Quoted 5 lines

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.

regards

Andreas Bie?mann

#4 lore raw

PATCH v2 1/3 avr32: Print unrelocated PC on exception

In reply to Haavard Skinnemoen
Quoted 8 lines · Haavard Skinnemoen

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.

---
 arch/avr32/cpu/exception.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

Applied to u-boot-atmel/avr32
Thanks,
Reinhard
-------------- next part --------------
A non-text attachment was scrubbed...
Name: reinhard_meyer.vcf
Type: text/x-vcard
Size: 370 bytes
Desc: not available
Url : http://lists.denx.de/pipermail/u-boot/attachments/20100903/c949bab8/attachment.vcf

#5 lore raw

PATCH v2 2/3 avr32: Use uncached() macro to get an address for SDRAM init

In reply to Haavard Skinnemoen

The paging system which is required to set up caching properties has not yet been initialized when the SDRAM is initialized. So when the map_physmem() function is converted to return the physical address unchanged, the SDRAM initialization will break on some boards.

The avr32-specific uncached() macro will return an address which will always cause uncached accessed to be made. Since this happens in the board code, using avr32-specific features should be ok, and will allow the SDRAM initialization to keep working.

---
 board/atmel/atngw100/atngw100.c              |    4 +---
 board/atmel/atstk1000/atstk1000.c            |    4 +---
 board/earthlcd/favr-32-ezkit/favr-32-ezkit.c |    4 +---
 board/mimc/mimc200/mimc200.c                 |    4 +---
 board/miromico/hammerhead/hammerhead.c       |    4 +---
 5 files changed, 5 insertions(+), 15 deletions(-)
board/atmel/atngw100/atngw100.c +1 -3
index 004d8da..4580f55 100644
@@ -75,13 +75,11 @@ phys_size_t initdram(int board_type)
 	unsigned long actual_size;
 	void *sdram_base;
 
-	sdram_base = map_physmem(EBI_SDRAM_BASE, EBI_SDRAM_SIZE, MAP_NOCACHE);
+	sdram_base = uncached(EBI_SDRAM_BASE);
 
 	expected_size = sdram_init(sdram_base, &sdram_config);
 	actual_size = get_ram_size(sdram_base, expected_size);
 
-	unmap_physmem(sdram_base, EBI_SDRAM_SIZE);
-
 	if (expected_size != actual_size)
 		printf("Warning: Only %lu of %lu MiB SDRAM is working\n",
 				actual_size >> 20, expected_size >> 20);
board/atmel/atstk1000/atstk1000.c +1 -3
index c36cb57..d91d594 100644
@@ -97,13 +97,11 @@ phys_size_t initdram(int board_type)
 	unsigned long actual_size;
 	void *sdram_base;
 
-	sdram_base = map_physmem(EBI_SDRAM_BASE, EBI_SDRAM_SIZE, MAP_NOCACHE);
+	sdram_base = uncached(EBI_SDRAM_BASE);
 
 	expected_size = sdram_init(sdram_base, &sdram_config);
 	actual_size = get_ram_size(sdram_base, expected_size);
 
-	unmap_physmem(sdram_base, EBI_SDRAM_SIZE);
-
 	if (expected_size != actual_size)
 		printf("Warning: Only %lu of %lu MiB SDRAM is working\n",
 				actual_size >> 20, expected_size >> 20);
board/earthlcd/favr-32-ezkit/favr-32-ezkit.c +1 -3
index 8af680f..d2843c9 100644
@@ -68,13 +68,11 @@ phys_size_t initdram(int board_type)
 	unsigned long actual_size;
 	void *sdram_base;
 
-	sdram_base = map_physmem(EBI_SDRAM_BASE, EBI_SDRAM_SIZE, MAP_NOCACHE);
+	sdram_base = uncached(EBI_SDRAM_BASE);
 
 	expected_size = sdram_init(sdram_base, &sdram_config);
 	actual_size = get_ram_size(sdram_base, expected_size);
 
-	unmap_physmem(sdram_base, EBI_SDRAM_SIZE);
-
 	if (expected_size != actual_size)
 		printf("Warning: Only %lu of %lu MiB SDRAM is working\n",
 				actual_size >> 20, expected_size >> 20);
board/mimc/mimc200/mimc200.c +1 -3
index cc0f137..9940669 100644
@@ -153,13 +153,11 @@ phys_size_t initdram(int board_type)
 	unsigned long actual_size;
 	void *sdram_base;
 
-	sdram_base = map_physmem(EBI_SDRAM_BASE, EBI_SDRAM_SIZE, MAP_NOCACHE);
+	sdram_base = uncached(EBI_SDRAM_BASE);
 
 	expected_size = sdram_init(sdram_base, &sdram_config);
 	actual_size = get_ram_size(sdram_base, expected_size);
 
-	unmap_physmem(sdram_base, EBI_SDRAM_SIZE);
-
 	if (expected_size != actual_size)
 		printf("Warning: Only %lu of %lu MiB SDRAM is working\n",
 				actual_size >> 20, expected_size >> 20);
board/miromico/hammerhead/hammerhead.c +1 -3
index 8b3e22c..5ab999e 100644
@@ -80,13 +80,11 @@ phys_size_t initdram(int board_type)
 	unsigned long actual_size;
 	void *sdram_base;
 
-	sdram_base = map_physmem(EBI_SDRAM_BASE, EBI_SDRAM_SIZE, MAP_NOCACHE);
+	sdram_base = uncached(EBI_SDRAM_BASE);
 
 	expected_size = sdram_init(sdram_base, &sdram_config);
 	actual_size = get_ram_size(sdram_base, expected_size);
 
-	unmap_physmem(sdram_base, EBI_SDRAM_SIZE);
-
 	if (expected_size != actual_size)
 		printf("Warning: Only %lu of %lu MiB SDRAM is working\n",
 		       actual_size >> 20, expected_size >> 20);
Signature · 1 line
1.7.0.4
#6 lore raw

PATCH v2 2/3 avr32: Use uncached() macro to get an address for SDRAM init

Hi Haavard,

Quoted 25 lines

The paging system which is required to set up caching properties has not yet been initialized when the SDRAM is initialized. So when the map_physmem() function is converted to return the physical address unchanged, the SDRAM initialization will break on some boards.

The avr32-specific uncached() macro will return an address which will always cause uncached accessed to be made. Since this happens in the board code, using avr32-specific features should be ok, and will allow the SDRAM initialization to keep working.

---
 board/atmel/atngw100/atngw100.c              |    4 +---
 board/atmel/atstk1000/atstk1000.c            |    4 +---
 board/earthlcd/favr-32-ezkit/favr-32-ezkit.c |    4 +---
 board/mimc/mimc200/mimc200.c                 |    4 +---
 board/miromico/hammerhead/hammerhead.c       |    4 +---
 5 files changed, 5 insertions(+), 15 deletions(-)
board/atmel/atngw100/atngw100.c +0 -0
index 004d8da..4580f55 100644
@@ -75,13 +75,11 @@ phys_size_t initdram(int board_type)
 	unsigned long actual_size;

board/atmel/atngw100/atngw100.c phys_size_t initdram(int board_type) · line 84

Quoted 10 lines
board/atmel/atngw100/atngw100.c +1 -3
 	void *sdram_base;
 
-	sdram_base = map_physmem(EBI_SDRAM_BASE, EBI_SDRAM_SIZE, MAP_NOCACHE);
+	sdram_base = uncached(EBI_SDRAM_BASE);
 
 	expected_size = sdram_init(sdram_base, &sdram_config);
 	actual_size = get_ram_size(sdram_base, expected_size);
 
-	unmap_physmem(sdram_base, EBI_SDRAM_SIZE);
-

So this patch replaces a construct which seems to be valid over all architectures by a construct which is only used in avr32, right? It also deletes the explicit statement that such a mapping is not needed any further.

Isn't this a step backward? Can't you put the functionality inside the map function and leave the unmap a noop?

Cheers
Detlev

Signature · 7 lines
Man against god... God against Man... Man against nature... Nature against
man...   God against nature...   Nature against god...  a very, very funny
religion.             -- Zen Master D.T. Suzuki commenting on Christianity
--
DENX Software Engineering GmbH,      MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich,  Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-40 Fax: (+49)-8142-66989-80 Email: dzu at denx.de
#7 lore raw

PATCH v2 2/3 avr32: Use uncached() macro to get an address for SDRAM init

Quoted 4 lines · Detlev Zundel

So this patch replaces a construct which seems to be valid over all architectures by a construct which is only used in avr32, right? It also deletes the explicit statement that such a mapping is not needed any further.

Problem is that in order to make the CFI driver work on avr32, we need to change the map_physmem() macro to return the physical address unchanged.

Quoted 2 lines

Isn't this a step backward? Can't you put the functionality inside the map function and leave the unmap a noop?

I agree it's a step backward, but since the previous flamewar didn't get us anywhere, I decided to go for a compromise this time. At least this small architecture-specific kludge is localized to architecture-specific code.

The map_physmem() macro currently does exactly the same thing as the uncached() macro, and the unmap is a noop, but the next patch changes it in order to fix the CFI driver. If the next patch is applied without this patch being applied first, the SDRAM driver will do cached accesses during initialization, and that may cause the initialization to fail.

Haavard

#8 lore raw

PATCH v2 2/3 avr32: Use uncached() macro to get an address for SDRAM init

Hi Haavard,

Quoted 9 lines
Quoted 4 lines · Detlev Zundel

So this patch replaces a construct which seems to be valid over all architectures by a construct which is only used in avr32, right? It also deletes the explicit statement that such a mapping is not needed any further.

Problem is that in order to make the CFI driver work on avr32, we need to change the map_physmem() macro to return the physical address unchanged.

I see. And I presume you cannot tell the situation apart inside map_physmem?

Quoted 8 lines
Quoted 2 lines

Isn't this a step backward? Can't you put the functionality inside the map function and leave the unmap a noop?

I agree it's a step backward, but since the previous flamewar didn't get us anywhere, I decided to go for a compromise this time. At least this small architecture-specific kludge is localized to architecture-specific code.

Quoted 6 lines

The map_physmem() macro currently does exactly the same thing as the uncached() macro, and the unmap is a noop, but the next patch changes it in order to fix the CFI driver. If the next patch is applied without this patch being applied first, the SDRAM driver will do cached accesses during initialization, and that may cause the initialization to fail.

Why not include a note to this extent into the git commit message? This would be a great help for other people to later understand why this change has been done the "backward way" that it was.

Cheers
Detlev

Signature · 5 lines
vi vi vi - the roman numeral of the beast.
--
DENX Software Engineering GmbH,      MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich,  Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-40 Fax: (+49)-8142-66989-80 Email: dzu at denx.de
#9 lore raw

PATCH v2 2/3 avr32: Use uncached() macro to get an address for SDRAM init

Quoted 6 lines · Detlev Zundel
Quoted 3 lines

Problem is that in order to make the CFI driver work on avr32, we need to change the map_physmem() macro to return the physical address unchanged.

I see. And I presume you cannot tell the situation apart inside map_physmem?

I don't think so. How do you propose we do that?

Quoted 10 lines
Quoted 6 lines

The map_physmem() macro currently does exactly the same thing as the uncached() macro, and the unmap is a noop, but the next patch changes it in order to fix the CFI driver. If the next patch is applied without this patch being applied first, the SDRAM driver will do cached accesses during initialization, and that may cause the initialization to fail.

Why not include a note to this extent into the git commit message? This would be a great help for other people to later understand why this change has been done the "backward way" that it was.

The commit message already contains this:

The paging system which is required to set up caching properties has not yet been initialized when the SDRAM is initialized. So when the map_physmem() function is converted to return the physical address unchanged, the SDRAM initialization will break on some boards.

which is essentially the same thing, isn't it?

Haavard

#10 lore raw

PATCH v2 2/3 avr32: Use uncached() macro to get an address for SDRAM init

Hi Haavard,

Quoted 9 lines
Quoted 6 lines · Detlev Zundel
Quoted 3 lines

Problem is that in order to make the CFI driver work on avr32, we need to change the map_physmem() macro to return the physical address unchanged.

I see. And I presume you cannot tell the situation apart inside map_physmem?

I don't think so. How do you propose we do that?

I don't know, that's why I'm asking.

Let's take a step back and please excuse my ignorant question - why exactly does the CFI driver need the physical address unchanged? Isn't the real constraint that the address requested by CFI is uncached? Why can't this be done by map_physmem()?

Quoted 11 lines
Quoted 10 lines
Quoted 6 lines

The map_physmem() macro currently does exactly the same thing as the uncached() macro, and the unmap is a noop, but the next patch changes it in order to fix the CFI driver. If the next patch is applied without this patch being applied first, the SDRAM driver will do cached accesses during initialization, and that may cause the initialization to fail.

Why not include a note to this extent into the git commit message? This would be a great help for other people to later understand why this change has been done the "backward way" that it was.

Quoted 8 lines

The commit message already contains this:

The paging system which is required to set up caching properties has not yet been initialized when the SDRAM is initialized. So when the map_physmem() function is converted to return the physical address unchanged, the SDRAM initialization will break on some boards.

which is essentially the same thing, isn't it?

For me this is not the same - it does not include a word why the change which you agree "looks backward" is something that we want to do. For me something like this would give me more information:

Unfortunately we cannot make "map_physmem()/unmap_physmem()" on the AVR32 platform work with the CFI driver as it works on other platforms. [I don't understand why this is the case, so your explanation would go here ;) ] To still fix the issue we deliberately replace these generic routines by AVR32 specific routines. If someone can fix this using the generic patterns, patches are welcome.

I believe that good docmumentation should include such pro- and con reasoning so that code changes can be comprehended even after the fact.

Cheers
Detlev

Signature · 7 lines
Emacs seems a more likely candidate  to contain a mail system than the
mail system to contain an Emacs, so this is the way it was done.
                                            -- Bernard S. Greenberg
--
DENX Software Engineering GmbH,      MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich,  Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-40 Fax: (+49)-8142-66989-80 Email: dzu at denx.de
#11 lore raw

PATCH v2 2/3 avr32: Use uncached() macro to get an address for SDRAM init

In reply to Haavard Skinnemoen

Dear Haavard Skinnemoen,

Am 12.08.2010 08:52, schrieb Haavard Skinnemoen:

Quoted 11 lines

The paging system which is required to set up caching properties has not yet been initialized when the SDRAM is initialized. So when the map_physmem() function is converted to return the physical address unchanged, the SDRAM initialization will break on some boards.

The avr32-specific uncached() macro will return an address which will always cause uncached accessed to be made. Since this happens in the board code, using avr32-specific features should be ok, and will allow the SDRAM initialization to keep working.

one colleague reported similar problems initialising SDRAM on our own board. I could not reproduce this issue here, however this patch fixed the problem. Thanks for that, it came the right time.

This patch should be applied too.

regards

Andreas Bie?mann

#12 lore raw

PATCH v2 2/3 avr32: Use uncached() macro to get an address for SDRAM init

In reply to Haavard Skinnemoen
Quoted 10 lines · Haavard Skinnemoen

The paging system which is required to set up caching properties has not yet been initialized when the SDRAM is initialized. So when the map_physmem() function is converted to return the physical address unchanged, the SDRAM initialization will break on some boards.

The avr32-specific uncached() macro will return an address which will always cause uncached accessed to be made. Since this happens in the board code, using avr32-specific features should be ok, and will allow the SDRAM initialization to keep working.

Quoted 8 lines
---
 board/atmel/atngw100/atngw100.c              |    4 +---
 board/atmel/atstk1000/atstk1000.c            |    4 +---
 board/earthlcd/favr-32-ezkit/favr-32-ezkit.c |    4 +---
 board/mimc/mimc200/mimc200.c                 |    4 +---
 board/miromico/hammerhead/hammerhead.c       |    4 +---
 5 files changed, 5 insertions(+), 15 deletions(-)

Applied to u-boot-atmel/avr32
Thanks,
Reinhard

#13 lore raw

PATCH v2 3/3 avr32: Add simple paging support

In reply to 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.

---
 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
arch/avr32/cpu/at32ap700x/Makefile +1 -1
index 46e6ef6..30ea925 100644
@@ -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))
 
arch/avr32/cpu/at32ap700x/mmu.c new file +78 -0

78 lines not on this page · raw message

arch/avr32/cpu/start.S +13 -6
index 99c9e06..06bf4c6 100644
@@ -82,12 +82,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
 
arch/avr32/include/asm/arch-at32ap700x/addrspace.h +1 -4
index 409eee3..4edc1bd 100644
@@ -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 */
arch/avr32/include/asm/arch-at32ap700x/mmu.h new file +66 -0

66 lines not on this page · raw message

arch/avr32/lib/board.c +4 -0
index b2def97..e6b81cc 100644
@@ -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 ""
@@ -265,6 +266,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;
board/atmel/atngw100/atngw100.c +15 -0
index 4580f55..49bc03e 100644
@@ -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,
board/atmel/atstk1000/atstk1000.c +15 -0
index d91d594..8b1e1b5 100644
@@ -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 */
board/earthlcd/favr-32-ezkit/favr-32-ezkit.c +15 -0
index d2843c9..b0eca93 100644
@@ -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,
board/mimc/mimc200/mimc200.c +20 -0
index 9940669..470adba 100644
@@ -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 = {
board/miromico/hammerhead/hammerhead.c +15 -0
index 5ab999e..78f4fd4 100644
@@ -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,
include/configs/atngw100.h +3 -0
index 4ed5514..83056b6 100644
@@ -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>
include/configs/atstk1002.h +3 -0
index b258f2d..6416d17 100644
@@ -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>
include/configs/atstk1003.h +3 -0
index 2ef2552..a4d9b0b 100644
@@ -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>
include/configs/atstk1004.h +3 -0
index 195be82..06bb5da 100644
@@ -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>
include/configs/atstk1006.h +3 -0
index f93118e..d3cbee6 100644
@@ -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>
include/configs/favr-32-ezkit.h +3 -0
index 739ff0d..1c381c7 100644
@@ -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>
include/configs/hammerhead.h +3 -0
index 0c70af5..8ca04ea 100644
@@ -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>
include/configs/mimc200.h +3 -0
index 36488b3..6ed9e75 100644
@@ -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>
Signature · 1 line
1.7.0.4
#14 lore raw

PATCH v2 3/3 avr32: Add simple paging support

Dear Haavard Skinnemnoen,

Am 12.08.2010 08:52, schrieb Haavard Skinnemoen:

Quoted 11 lines

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.

Quoted 4 lines

This makes the 'saveenv' command work again on ATNGW100 and other boards using the CFI driver, hopefully without breaking any rules.

there were no changes to this patch since last submission. Applying this should be done soon.

regards

Andreas Bie?mann

#15 lore raw

PATCH v2 3/3 avr32: Add simple paging support

In reply to Haavard Skinnemoen
Quoted 30 lines · 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.

---
 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 +
Quoted 8 lines
 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

Applied to u-boot-atmel/avr32
Thanks,
Reinhard