Commit bf08dcac authored by Benoit Rat's avatar Benoit Rat

g45memtest: correct ddr and boot bug & improve the test

parent b997eee6
No preview for this file type
From f87ac48aaf4ec7726391b87577fceede1b561228 Mon Sep 17 00:00:00 2001
From 6c56f4f07d953d33a90584dd15360f8d572483a4 Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Thu, 15 Sep 2011 23:41:14 +0200
Subject: [PATCH 1/6] board 9g45ek: fix ddr config for WRS-V3
Subject: [PATCH 01/19] board 9g45ek: fix ddr config for WRS-V3
---
board/at91sam9g45ek/at91sam9g45ek.c | 2 +-
......@@ -81,5 +81,5 @@ index 550aea4..a4a168f 100644
#define AT91C_DDRC2_NR_12 (0x1 << 2) // (HDDRSDRC2) 12 Bits
#define AT91C_DDRC2_NR_13 (0x2 << 2) // (HDDRSDRC2) 13 Bits
--
1.7.7.2
1.7.9.5
From c27eea873f4a7dd9bea3da51b8e4aba27b9e52fc Mon Sep 17 00:00:00 2001
From b257bbfacdfa9475ca0a812a64d6ab59de9ea440 Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Tue, 6 Mar 2012 10:18:59 +0100
Subject: [PATCH 2/6] printf: added files from pptp, unchanged
Subject: [PATCH 02/19] printf: added files from pptp, unchanged
---
lib/diag-printf.c | 34 ++++++++++++++++++++++++++
lib/printf-mini.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 103 insertions(+), 0 deletions(-)
2 files changed, 103 insertions(+)
create mode 100644 lib/diag-printf.c
create mode 100644 lib/printf-mini.c
......@@ -126,5 +126,5 @@ index 0000000..d68c848
+ return str - buf;
+}
--
1.7.7.2
1.7.9.5
From 3ebc7c415750ffcd7cf4241010027773609e6919 Mon Sep 17 00:00:00 2001
From dc2e9ac1fcca99e6c4924714f26cf85a87e3259c Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Tue, 6 Mar 2012 10:37:27 +0100
Subject: [PATCH 3/6] printf: fixes and addition to makefile
Subject: [PATCH 03/19] printf: fixes and addition to makefile
---
include/pp_printf.h | 9 +++++++++
......@@ -78,5 +78,5 @@ index 2a46204..8810324 100644
#include "main.h"
#include "dbgu.h"
--
1.7.7.2
1.7.9.5
From 391890df3ca410003b51bf45a4b17a5a8e22a588 Mon Sep 17 00:00:00 2001
From: Benoit Rat <benoit@sevensols.com>
Date: Fri, 23 Mar 2012 13:42:57 +0100
Subject: [PATCH 04/19] version: add tmpconfig to ignore list
---
.gitignore | 1 +
1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore
index d78652e..a973a59 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,4 @@ binaries
*.o
tags
*.swp
+.tmpconfig*
--
1.7.9.5
From c28fc11363fb86c25b447817a6554874ad65f09a Mon Sep 17 00:00:00 2001
From: Benoit Rat <benoit@sevensols.com>
Date: Wed, 28 Mar 2012 18:54:06 +0200
Subject: [PATCH 05/19] version: Improve tracking bin versions adding git
version in Makefile
---
.gitignore | 1 +
Makefile | 25 ++++++++++++++++++++++++-
main.c | 6 ++++++
3 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
index a973a59..8b91fe5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,4 @@ binaries
tags
*.swp
.tmpconfig*
+version.c
diff --git a/Makefile b/Makefile
index 6216632..c61ee3e 100644
--- a/Makefile
+++ b/Makefile
@@ -220,7 +220,7 @@ include driver/driver.mk
SRCS := $(COBJS-y:.o=.c)
-OBJS := $(SOBJS-y) $(COBJS-y)
+OBJS := $(SOBJS-y) $(COBJS-y) version.o
INCL=board/$(BOARD)
@@ -273,6 +273,29 @@ PHONY:=all gen_bin
all: PrintFlags gen_bin ChkFileSize
+## If not git is found
+ifeq ($(shell git status -s | grep -v "fatal*"),)
+version.c: $(SOBJS-y) $(COBJS-y)
+ @echo "/**" > $@
+ @echo " * File automatically generated by Makefile (DO NOT MODIFIED)\n *\n * To use this you in a c code just add the following lines:\n * " >> $@
+ @echo "\textern const char build_time[];\n\textern const char git_user[];\n\textren const char git_revision[];\n * " >> $@
+ @echo "**/" >> $@
+ @echo 'const char build_time[] = __DATE__ " @ " __TIME__ ;' >> $@
+ @echo "const char git_user[] = \"$(shell id -nu)\";" >> $@
+ @echo "const char git_revision[] = \"\";" >> $@
+ @echo "" >> $@
+else
+version.c: $(SOBJS-y) $(COBJS-y) .git/HEAD .git/index
+ @echo "/**" > $@
+ @echo " * File automatically generated by Makefile (DO NOT MODIFIED)\n *\n * To use this you in a c code just add the following lines:\n * " >> $@
+ @echo "\textern const char build_time[];\n\textern const char git_user[];\n\textren const char git_revision[];\n * " >> $@
+ @echo "**/" >> $@
+ @echo 'const char build_time[] = __DATE__ " @ " __TIME__ ;' >> $@
+ @echo "const char git_user[] = \"$(shell git config --get user.name)\";" >> $@
+ @echo "const char git_revision[] = \"$(shell git rev-parse HEAD)$(shell if git status -s > /dev/null; then echo '+'; fi;)\";" >> $@
+ @echo "" >> $@
+endif
+
PrintFlags:
@echo as FLAGS
@echo ========
diff --git a/main.c b/main.c
index 8810324..0ea1716 100644
--- a/main.c
+++ b/main.c
@@ -83,6 +83,10 @@ void Wait(unsigned int count)
/*------------------------------------------------------------------------------*/
int main(void)
{
+ extern const char build_time[];
+ extern const char git_user[];
+ extern const char git_revision[];
+
/*
* ================== 1st step: Hardware Initialization =================
*
@@ -92,6 +96,8 @@ int main(void)
hw_init();
#endif
+ pp_printf("Compiled by %s (%s)\r\ngit rev:%s\r\n\r\n",git_user,build_time,git_revision);
+
#ifdef CONFIG_USER_HW_INIT
user_hw_init();
#endif
--
1.7.9.5
From 4a94ffdd4e78d50d24669f2646b3648bc93a51c4 Mon Sep 17 00:00:00 2001
From: Benoit Rat <benoit@sevensols.com>
Date: Wed, 28 Mar 2012 19:19:46 +0200
Subject: [PATCH 06/19] leds: Correct FPGA LED problems, and add CPU LED
during booting
---
board/at91sam9g45ek/at91sam9g45ek.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/board/at91sam9g45ek/at91sam9g45ek.c b/board/at91sam9g45ek/at91sam9g45ek.c
index 8569231..83c2c29 100644
--- a/board/at91sam9g45ek/at91sam9g45ek.c
+++ b/board/at91sam9g45ek/at91sam9g45ek.c
@@ -80,6 +80,17 @@ void hw_init(void)
};
/*
+ * Configure LED GPIOs
+ */
+ const struct pio_desc led_gpio[] = {
+ {"D11", AT91C_PIN_PA(0), 0, PIO_OPENDRAIN, PIO_OUTPUT}, //Switch on D11 when booting start.
+ {"D12", AT91C_PIN_PA(1), 1, PIO_OPENDRAIN, PIO_OUTPUT}, //Setup D12 such to use when the programs end loading.
+ {"DDone", AT91C_PIN_PA(2), 0, PIO_DEFAULT, PIO_INPUT}, //Setup FPGA LED Done in read mode
+ {"DInit", AT91C_PIN_PA(3), 0, PIO_DEFAULT, PIO_INPUT} //Setup FPGA LED Init in read mode
+ };
+ pio_setup(led_gpio);
+
+ /*
* Disable watchdog
*/
writel(AT91C_WDTC_WDDIS, AT91C_BASE_WDTC + WDTC_WDMR);
--
1.7.9.5
From e5b1d890e842647f0a70af8381d5114a7ca8635d Mon Sep 17 00:00:00 2001
From: Benoit Rat <benoit@sevensols.com>
Date: Mon, 19 Mar 2012 17:49:43 +0100
Subject: [PATCH 07/19] ddr: Fix ba offset bug and improve configuration
---
board/at91sam9g45ek/at91sam9g45ek.c | 34 ++++++++++++++++++----------------
driver/ddramc.c | 20 +++++++++++++-------
include/AT91SAM9G45_inc.h | 5 ++++-
include/DDR2_MT47H_inc.h | 35 +++++++++++++++++++++++++++++++++++
include/ddramc.h | 2 +-
5 files changed, 71 insertions(+), 25 deletions(-)
create mode 100644 include/DDR2_MT47H_inc.h
diff --git a/board/at91sam9g45ek/at91sam9g45ek.c b/board/at91sam9g45ek/at91sam9g45ek.c
index 83c2c29..e6b8f9c 100644
--- a/board/at91sam9g45ek/at91sam9g45ek.c
+++ b/board/at91sam9g45ek/at91sam9g45ek.c
@@ -151,7 +151,7 @@ void hw_init(void)
/*
* Configure DDRAM Controller
*/
- ddramc_hw_init();
+ ddramc_hw_init();
#endif /* CONFIG_DDR2 */
}
#endif /* CONFIG_HW_INIT */
@@ -163,36 +163,38 @@ static SDdramConfig ddram_config;
/* \fn ddramc_hw_init */
/* \brief This function performs DDRAMC HW initialization */
/*------------------------------------------------------------------------------*/
-void ddramc_hw_init(void)
+
+
+void ddramc_hw_init()
{
ddram_config.ddramc_mdr =
(AT91C_DDRC2_DBW_16_BITS | AT91C_DDRC2_MD_DDR2_SDRAM);
- ddram_config.ddramc_cr = (AT91C_DDRC2_NC_DDR10_SDR9 | // 10 column bits (1K)
- AT91C_DDRC2_NR_13 | // 13 row bits (8K)
+ ddram_config.ddramc_cr = (AT91C_DDRC2_NC_XX | // see include/DDR2_MT47H_inc.h
+ AT91C_DDRC2_NR_XX | // see include/DDR2_MT47H_inc.h
AT91C_DDRC2_CAS_3 | // CAS Latency 3
AT91C_DDRC2_DLL_RESET_DISABLED); // DLL not reset
ddram_config.ddramc_rtr = 0x24B;
- ddram_config.ddramc_t0pr = (AT91C_DDRC2_TRAS_6 | // 6 * 7.5 = 45 ns
- AT91C_DDRC2_TRCD_2 | // 2 * 7.5 = 22.5 ns
- AT91C_DDRC2_TWR_2 | // 2 * 7.5 = 15 ns
- AT91C_DDRC2_TRC_8 | // 8 * 7.5 = 75 ns
- AT91C_DDRC2_TRP_2 | // 2 * 7.5 = 22.5 ns
- AT91C_DDRC2_TRRD_1 | // 1 * 7.5 = 7.5 ns
- AT91C_DDRC2_TWTR_1 | // 1 clock cycle
- AT91C_DDRC2_TMRD_2); // 2 clock cycles
+ ddram_config.ddramc_t0pr = (AT91C_DDRC2_TRAS_6 | // 6 * 7.5 = 45 ns
+ AT91C_DDRC2_TRCD_2 | // 2 * 7.5 = 15 ns
+ AT91C_DDRC2_TWR_2 | // 2 * 7.5 = 15 ns
+ AT91C_DDRC2_TRC_8 | // 8 * 7.5 = 75 ns
+ AT91C_DDRC2_TRP_2 | // 2 * 7.5 = 22.5 ns
+ AT91C_DDRC2_TRRD_XX | // see include/DDR2_MT47H_inc.h
+ AT91C_DDRC2_TWTR_1 | // 1 clock cycle
+ AT91C_DDRC2_TMRD_2); // 2 clock cycles
ddram_config.ddramc_t1pr = (AT91C_DDRC2_TXP_2 | // 2 * 7.5 = 15 ns
200 << 16 | // 200 clock cycles, TXSRD: Exit self refresh delay to Read command
16 << 8 | // 16 * 7.5 = 120 ns TXSNR: Exit self refresh delay to non read command
AT91C_DDRC2_TRFC_14 << 0); // 14 * 7.5 = 142 ns (must be 140 ns for 1Gb DDR)
- ddram_config.ddramc_t2pr = (AT91C_DDRC2_TRTP_1 | // 1 * 7.5 = 7.5 ns
- AT91C_DDRC2_TRPA_0 | // 0 * 7.5 = 0 ns
- AT91C_DDRC2_TXARDS_7 | // 7 clock cycles
- AT91C_DDRC2_TXARD_2); // 2 clock cycles
+ ddram_config.ddramc_t2pr = (AT91C_DDRC2_TRTP_1 | // 1 * 7.5 = 7.5 ns
+ AT91C_DDRC2_TRPA_XX | // see include/DDR2_MT47H_inc.h
+ AT91C_DDRC2_TXARDS_XX | // see include/DDR2_MT47H_inc.h
+ AT91C_DDRC2_TXARD_2); // 2 clock cycles
// ENABLE DDR2 clock
writel(AT91C_PMC_DDR, AT91C_BASE_PMC + PMC_SCER);
diff --git a/driver/ddramc.c b/driver/ddramc.c
index e2824ff..f6fdfe8 100644
--- a/driver/ddramc.c
+++ b/driver/ddramc.c
@@ -75,10 +75,16 @@ int ddram_init(unsigned int ddram_controller_address,
ba_offset = (ddram_config->ddramc_cr & AT91C_DDRC2_NC) + 9; // number of column bits for DDR
if (ddram_decod_seq(ddram_config->ddramc_cr))
ba_offset += ((ddram_config->ddramc_cr & AT91C_DDRC2_NR) >> 2) + 11; // number of row bits
- ba_offset += (ddram_config->ddramc_mdr & AT91C_DDRC2_DBW) ? 1 : 2; // bus width
-
- dbg_log(3, " ba_offset = %x ... ", ba_offset);
-
+ ba_offset += (ddram_config->ddramc_mdr & AT91C_DDRC2_DBW) ? 1 : 2; // bus width
+
+ dbg_log(1,"DDR2 Config: %x (NC=%d, NR=%d, CAS=%d, ba_offset = %x)\n\r",
+ ddram_config->ddramc_cr ,
+ (ddram_config->ddramc_cr & AT91C_DDRC2_NC) + 9,
+ ((ddram_config->ddramc_cr & AT91C_DDRC2_NR) >> 2) + 11,
+ (ddram_config->ddramc_cr & AT91C_DDRC2_CAS) >> 4,
+ ba_offset
+ );
+
// Step 1: Program the memory device type
write_ddramc(ddram_controller_address, HDDRSDRC2_MDR,
ddram_config->ddramc_mdr);
@@ -126,7 +132,7 @@ int ddram_init(unsigned int ddram_controller_address,
write_ddramc(ddram_controller_address, HDDRSDRC2_MR,
AT91C_DDRC2_MODE_EXT_LMR_CMD);
/* Perform a write access to DDR address so that BA[1] is set to 1 and BA[0] is set to 0. */
- *((unsigned int *)(ddram_address + 0x4000000 /* (0x2 << ba_offset) */)) = 0;
+ *((unsigned int *)(ddram_address + (0x2 << ba_offset))) = 0;
// wait 2 cycles min (of tCK) = 15 ns min
Wait(2);
@@ -135,7 +141,7 @@ int ddram_init(unsigned int ddram_controller_address,
/* Perform a write access to DDR address so that BA[1] is set to 1 and BA[0] is set to 1. */
write_ddramc(ddram_controller_address, HDDRSDRC2_MR,
AT91C_DDRC2_MODE_EXT_LMR_CMD);
- *((unsigned int *)(ddram_address + 0x6000000 /* (0x3 << ba_offset) */)) = 0;
+ *((unsigned int *)(ddram_address + (0x3 << ba_offset))) = 0;
// wait 2 cycles min (of tCK) = 15 ns min
Wait(2);
@@ -144,7 +150,7 @@ int ddram_init(unsigned int ddram_controller_address,
/* Perform a write access to DDR address so that BA[1] is set to 0 and BA[0] is set to 1. */
write_ddramc(ddram_controller_address, HDDRSDRC2_MR,
AT91C_DDRC2_MODE_EXT_LMR_CMD);
- *((unsigned int *)(ddram_address + 0x2000000 /* (0x1 << ba_offset) */)) = 0;
+ *((unsigned int *)(ddram_address + (0x1 << ba_offset))) = 0;
// wait 200 cycles min (of tCK) = 1500 ns min
Wait(100);
diff --git a/include/AT91SAM9G45_inc.h b/include/AT91SAM9G45_inc.h
index a4a168f..a73fcd3 100644
--- a/include/AT91SAM9G45_inc.h
+++ b/include/AT91SAM9G45_inc.h
@@ -267,7 +267,7 @@
#define AT91C_DDRC2_NC_DDR10_SDR9 (0x1) // (HDDRSDRC2) DDR 10 Bits | SDR 9 Bits
#define AT91C_DDRC2_NC_DDR11_SDR10 (0x2) // (HDDRSDRC2) DDR 11 Bits | SDR 10 Bits
#define AT91C_DDRC2_NC_DDR12_SDR11 (0x3) // (HDDRSDRC2) DDR 12 Bits | SDR 11 Bits
-#define AT91C_DDRC2_NR AT91C_DDRC2_NR_13 // (HDDRSDRC2) Number of Row Bits
+#define AT91C_DDRC2_NR (0x3 << 2) // (HDDRSDRC2) Number of Row Bits (MASK)
#define AT91C_DDRC2_NR_11 (0x0 << 2) // (HDDRSDRC2) 11 Bits
#define AT91C_DDRC2_NR_12 (0x1 << 2) // (HDDRSDRC2) 12 Bits
#define AT91C_DDRC2_NR_13 (0x2 << 2) // (HDDRSDRC2) 13 Bits
@@ -6350,3 +6350,6 @@
#define BOARD_SD_MCI_ID_USE 0
#define CHIP_SRAM0_BASEADDR 0x300000
+
+//Hacks to include our DDR without modifying the whole board
+#include "DDR2_MT47H_inc.h"
\ No newline at end of file
diff --git a/include/DDR2_MT47H_inc.h b/include/DDR2_MT47H_inc.h
new file mode 100644
index 0000000..75b3af3
--- /dev/null
+++ b/include/DDR2_MT47H_inc.h
@@ -0,0 +1,35 @@
+/**
+* Small hacks to make the at91bootstrap works with our DDR memories
+*
+* Author: Benoit RAT
+*
+**/
+#ifndef WRS318V3
+#define WRS318V3 1 //Version 3.1
+
+#define MT47H32M16HR 0x025E
+#ifdef MT47H32M16HR
+ //Then define new value
+ #define AT91C_DDRC2_NC_XX AT91C_DDRC2_NC_DDR10_SDR9 // 10 column bits (1K)
+ #define AT91C_DDRC2_NR_XX AT91C_DDRC2_NR_13 // 13 row bits (8K)
+ #define AT91C_DDRC2_TRRD_XX AT91C_DDRC2_TRRD_2 // 2 * 7.5 > 10 ns
+
+ #if MT47H32M16HR == 0x025E //for -25E
+ #define AT91C_DDRC2_TRPA_XX AT91C_DDRC2_TRPA_2 // 2 * 7.5 = 15 ns
+ #define AT91C_DDRC2_TXARDS_XX AT91C_DDRC2_TXARDS_8 //
+ #endif
+
+ #if MT47H32M16HR == 0x0030 //for -3
+ #define AT91C_DDRC2_TRPA_XX AT91C_DDRC2_TRPA_3 // 3 * 7.5 = 22.5 ns
+ #define AT91C_DDRC2_TXARDS_XX AT91C_DDRC2_TXARDS_7 //
+ #endif
+#else //Original values for AT
+ #define AT91C_DDRC2_NC_XX AT91C_DDRC2_NC_DDR10_SDR9 // 10 column bits (1K)
+ #define AT91C_DDRC2_NR_XX AT91C_DDRC2_NR_13
+ #define AT91C_DDRC2_TRPA_XX AT91C_DDRC2_TRPA_0
+ #define AT91C_DDRC2_TXARDS_XX AT91C_DDRC2_TXARDS_7
+ #define AT91C_DDRC2_TRRD_XX AT91C_DDRC2_TRRD_1
+#endif
+
+
+#endif
\ No newline at end of file
diff --git a/include/ddramc.h b/include/ddramc.h
index 3e7a30a..527436f 100644
--- a/include/ddramc.h
+++ b/include/ddramc.h
@@ -45,6 +45,6 @@ typedef struct SDdramConfig {
extern int ddram_init(unsigned int ddram_controller_address,
unsigned int ddram_address,
struct SDdramConfig *ddram_config);
-extern void ddramc_hw_init(void);
+extern void ddramc_hw_init();
#endif /*SDRAMC_H_ */
--
1.7.9.5
From 3c96273023f759800c3cb3309ac1ef8a83fe7f04 Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Tue, 10 Apr 2012 13:00:22 +0200
Subject: [PATCH 08/19] boot: disable watchdog asap
---
crt0_gnu.S | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/crt0_gnu.S b/crt0_gnu.S
index c00b717..0a9079b 100644
--- a/crt0_gnu.S
+++ b/crt0_gnu.S
@@ -105,6 +105,11 @@ _relocate_to_sram:
ldr pc, =_setup_clocks
#endif /* CONFIG_FLASH */
+ /* disable watchdog */
+ ldr r1, =0xFFFFFD44
+ mov r2, #0x00008000
+ str r2, [r1]
+
ldr r4, = lowlevel_clock_init
mov lr, pc
bx r4
--
1.7.9.5
From a6f38ea81c99fca8ad2c67b0b03d97c16fe97d94 Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Tue, 10 Apr 2012 13:04:09 +0200
Subject: [PATCH 09/19] boot: added flip_leds(count) in assembler
---
crt0_gnu.S | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/crt0_gnu.S b/crt0_gnu.S
index 0a9079b..784c9ce 100644
--- a/crt0_gnu.S
+++ b/crt0_gnu.S
@@ -74,6 +74,35 @@ irq_vector:
b irq_vector
fiq_vector:
b fiq_vector
+
+/*
+ * First of all, write a procedure, that can be called from C or asm,
+ * to flip leds a number of times, after a small delay
+ */
+
+flip_leds: /* input: r0 is the count of flips */
+
+ /* a delay */
+ ldr r1, =200
+1: subs r1, r1, #1
+ bne 1b
+
+ ldr r1, =0xfffff200 /* PIOA */
+ mov r2, #3 /* bit 0 and 1: both leds */
+
+ str r2, [r1] /* enable */
+ str r2, [r1, #0x10] /* output enable */
+ cmp r0, #0
+ beq 2f
+0: str r2, [r1, #0x34] /* output clear (led on) */
+ str r2, [r1, #0x30] /* output set (led off) */
+ subs r0, r0, #1
+ bne 0b
+
+2: bx lr
+
+.ltorg
+
reset_vector:
/* Init the stack */
--
1.7.9.5
From b24256ae1eab66b12e361dc0e7873d081275ac24 Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Tue, 10 Apr 2012 13:40:59 +0200
Subject: [PATCH 10/19] boot: Run a test pattern between clock configuration
---
crt0_gnu.S | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/crt0_gnu.S b/crt0_gnu.S
index 784c9ce..bc54989 100644
--- a/crt0_gnu.S
+++ b/crt0_gnu.S
@@ -79,7 +79,6 @@ fiq_vector:
* First of all, write a procedure, that can be called from C or asm,
* to flip leds a number of times, after a small delay
*/
-
flip_leds: /* input: r0 is the count of flips */
/* a delay */
@@ -139,10 +138,20 @@ _relocate_to_sram:
mov r2, #0x00008000
str r2, [r1]
+ /* test 4x the flip_leds procedure */
+ mov r0, #0x4
+ bl flip_leds
+
+ /* Call the lowlevel clock init function in ./driver/pmc.c */
ldr r4, = lowlevel_clock_init
mov lr, pc
bx r4
+ /* test 8x the flip_leds procedure */
+ mov r0, #0x8
+ bl flip_leds
+
+
#if 0
_setup_clocks:
/* Test if main oscillator is enabled */
--
1.7.9.5
From 00b15b66a2bde319a0e4ba592a26f921d542cfca Mon Sep 17 00:00:00 2001
From: Benoit Rat <benoit@sevensols.com>
Date: Wed, 11 Apr 2012 17:25:28 +0200
Subject: [PATCH 11/19] boot: Correct crash due to an Atmel bug during boot
when PLL clock is already used as master clock
---
driver/pmc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/driver/pmc.c b/driver/pmc.c
index 1a09b9c..189d1c9 100644
--- a/driver/pmc.c
+++ b/driver/pmc.c
@@ -96,7 +96,7 @@ void lowlevel_clock_init()
/*
* After stablization, switch to 12MHz Main Oscillator
*/
- if ((read_pmc(PMC_MCKR) & AT91C_PMC_CSS) != AT91C_PMC_CSS_SLOW_CLK) {
+ if ((read_pmc(PMC_MCKR) & AT91C_PMC_CSS) == AT91C_PMC_CSS_SLOW_CLK) {
write_pmc(PMC_MCKR, AT91C_PMC_CSS_MAIN_CLK | AT91C_PMC_PRES_CLK);
while (!(read_pmc(PMC_SR) & AT91C_PMC_MCKRDY))
;
--
1.7.9.5
From 8083ba2049c07ce9f939819ce3016912d256019f Mon Sep 17 00:00:00 2001
From: Benoit Rat <benoit@sevensols.com>
Date: Wed, 11 Apr 2012 17:25:28 +0200
Subject: [PATCH 12/19] Improve makefile to only take the gitversion of
current directory
---
Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index c61ee3e..fd7f16e 100644
--- a/Makefile
+++ b/Makefile
@@ -292,7 +292,7 @@ version.c: $(SOBJS-y) $(COBJS-y) .git/HEAD .git/index
@echo "**/" >> $@
@echo 'const char build_time[] = __DATE__ " @ " __TIME__ ;' >> $@
@echo "const char git_user[] = \"$(shell git config --get user.name)\";" >> $@
- @echo "const char git_revision[] = \"$(shell git rev-parse HEAD)$(shell if git status -s > /dev/null; then echo '+'; fi;)\";" >> $@
+ @echo "const char git_revision[] = \"$(shell git log --abbrev-commit --pretty=oneline -1 . | cut -d" " -f1)$(shell if git status -s > /dev/null; then echo '+'; fi;)\";" >> $@
@echo "" >> $@
endif
--
1.7.9.5
From eaa9bd4511b69b6097726b68957fa7da5a44323f Mon Sep 17 00:00:00 2001
From: Benoit Rat <benoit@sevensols.com>
Date: Fri, 11 May 2012 12:36:25 +0200
Subject: [PATCH 13/19] add simple script to compile for DF and NF
---
build.sh | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100755 build.sh
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000..a9711d9
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+showhelp()
+{
+ echo "Usage: $0 [options]"
+ echo "options:"
+ echo " --help: show this little help"
+ echo " --df: compile only for dataflash"
+ echo " --nf: compile only for nandflash"
+}
+
+
+
+case "$1" in
+ --help) showhelp;;
+ --nf) yes "" | make at91sam9g45nf_defconfig > /dev/null; make;;
+ --df) yes "" | make at91sam9g45df_defconfig > /dev/null; make;;
+ *) yes "" | make at91sam9g45df_defconfig > /dev/null; make; yes "" | make at91sam9g45nf_defconfig > /dev/null; make;;
+esac
+
+
--
1.7.9.5
From 5006567aeb801664a861ffe05337943c89dcae60 Mon Sep 17 00:00:00 2001
From: Benoit Rat <benoit@sevensols.com>
Date: Fri, 11 May 2012 12:48:13 +0200
Subject: [PATCH 14/19] Correct a bug in makefile
---
Makefile | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
index fd7f16e..88dfffc 100644
--- a/Makefile
+++ b/Makefile
@@ -285,14 +285,14 @@ version.c: $(SOBJS-y) $(COBJS-y)
@echo "const char git_revision[] = \"\";" >> $@
@echo "" >> $@
else
-version.c: $(SOBJS-y) $(COBJS-y) .git/HEAD .git/index
+version.c: $(SOBJS-y) $(COBJS-y) .git/HEAD .git/index Makefile
@echo "/**" > $@
@echo " * File automatically generated by Makefile (DO NOT MODIFIED)\n *\n * To use this you in a c code just add the following lines:\n * " >> $@
@echo "\textern const char build_time[];\n\textern const char git_user[];\n\textren const char git_revision[];\n * " >> $@
@echo "**/" >> $@
@echo 'const char build_time[] = __DATE__ " @ " __TIME__ ;' >> $@
@echo "const char git_user[] = \"$(shell git config --get user.name)\";" >> $@
- @echo "const char git_revision[] = \"$(shell git log --abbrev-commit --pretty=oneline -1 . | cut -d" " -f1)$(shell if git status -s > /dev/null; then echo '+'; fi;)\";" >> $@
+ @echo "const char git_revision[] = \"$(shell git log --abbrev-commit --pretty=oneline -1 . | cut -d" " -f1)$(shell if git status -s > /dev/null; then echo '+'; else echo ''; fi;)\";" >> $@
@echo "" >> $@
endif
--
1.7.9.5
From 425ef2fa1550b9e480167f8b125adb897f281798 Mon Sep 17 00:00:00 2001
From 80b81d783772a87000356f126cb47dc429a95f3d Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Tue, 6 Mar 2012 10:42:17 +0100
Subject: [PATCH 4/6] memtest.c: copied from barebox (our version)
Subject: [PATCH 15/19] memtest: copied from barebox (our version)
---
lib/memtest.c | 355 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 355 insertions(+), 0 deletions(-)
1 file changed, 355 insertions(+)
create mode 100644 lib/memtest.c
diff --git a/lib/memtest.c b/lib/memtest.c
......@@ -370,5 +370,5 @@ index 0000000..d9c8b3d
+BAREBOX_CMD_END
+
--
1.7.7.2
1.7.9.5
From 74e27efd703fbafab08c28c7f7d0eb1aaae7db8e Mon Sep 17 00:00:00 2001
From fa3b681d37c9787473f4ed8fc33205471696db8d Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Tue, 6 Mar 2012 11:38:53 +0100
Subject: [PATCH 5/6] memtest: fix it and add to makefile
Subject: [PATCH 16/19] memtest: fix it and add to makefile
---
lib/libc.mk | 1 +
lib/memtest.c | 85 +++++++++++++++++++++++---------------------------------
lib/memtest.c | 85 ++++++++++++++++++++++++---------------------------------
2 files changed, 36 insertions(+), 50 deletions(-)
diff --git a/lib/libc.mk b/lib/libc.mk
......@@ -191,5 +191,5 @@ index d9c8b3d..52542c9 100644
-BAREBOX_CMD_END
-
--
1.7.7.2
1.7.9.5
From cf60a3a806e75315e39610d40607d76efcc5816c Mon Sep 17 00:00:00 2001
From 5f895df9f30230375cbbf2320a7c8af00d852fc2 Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Tue, 6 Mar 2012 11:39:13 +0100
Subject: [PATCH 6/6] main: call memtest
Subject: [PATCH 17/19] main: call memtest
---
main.c | 92 +++-------------------------------------------------------------
1 files changed, 4 insertions(+), 88 deletions(-)
main.c | 93 ++++------------------------------------------------------------
1 file changed, 5 insertions(+), 88 deletions(-)
diff --git a/main.c b/main.c
index 8810324..e4a6956 100644
index 0ea1716..60f3fe7 100644
--- a/main.c
+++ b/main.c
@@ -83,6 +83,7 @@ void Wait(unsigned int count)
/*------------------------------------------------------------------------------*/
int main(void)
{
+ extern void mem_test(unsigned long ini, unsigned long end);
@@ -86,6 +86,8 @@ int main(void)
extern const char build_time[];
extern const char git_user[];
extern const char git_revision[];
+
+ extern void mem_test(unsigned long ini, unsigned long end);
/*
* ================== 1st step: Hardware Initialization =================
*
@@ -101,92 +102,7 @@ int main(void)
@@ -107,92 +109,7 @@ int main(void)
load_1wire_info();
#endif
......@@ -116,5 +117,5 @@ index 8810324..e4a6956 100644
+ return 0; /* not reached */
}
--
1.7.7.2
1.7.9.5
From 65c1e3949e8a8c6dfc82bcdb778ff1eb7bf82a14 Mon Sep 17 00:00:00 2001
From: Benoit Rat <benoit@sevensols.com>
Date: Mon, 2 Apr 2012 14:10:36 +0200
Subject: [PATCH 18/19] memtest: Improve DDR check with basic dataline,
adressline and integrity tests
---
lib/memtest.c | 523 +++++++++++++++++++++++++++++++++------------------------
1 file changed, 304 insertions(+), 219 deletions(-)
diff --git a/lib/memtest.c b/lib/memtest.c
index 52542c9..4366171 100644
--- a/lib/memtest.c
+++ b/lib/memtest.c
@@ -25,6 +25,8 @@
#include <pp_printf.h>
#include <dbgu.h>
+#include <debug.h>
+//#include <stdlib.h>
/* BEGIN HACKS - to compile barebox code out of barebox */
typedef unsigned char uchar;
@@ -39,16 +41,106 @@ typedef volatile unsigned char vu_char;
#define printf pp_printf
#define puts dbgu_print
+#ifdef DEBUG
+#define pr_debug(fmt, arg...) printf(fmt, ##arg)
+#else
+#define pr_debug(fmt, arg...) do {} while(0)
+#endif
+#define debug(fmt, arg...) pr_debug(fmt, ##arg)
+
static inline int ctrlc(void) {return 0;}
static inline void __putc(int c) {printf("%c", c);}
+#define CONFIG_CMD_MTEST_ALTERNATIVE
+
/* END HACKS - to compile barebox code out of barebox */
+
+/**
+* Check integrity of the memory with various patterns
+**/
+int mem_test_integrity(ulong _start, ulong _end, ulong pattern)
+{
+ vu_long *addr;
+ vu_long *start = (vu_long *)_start;
+ vu_long *end = (vu_long *)_end;
+ ulong val;
+ ulong readback;
+ ulong incr;
+ ulong iter;
+ ulong pattern_next;
+ ulong val_next;
+ int rcode;
+
+ incr = 1;
+ iter=1;
+
+ for (addr=start,val=pattern; addr<end; addr++) {
+ *addr = val;
+ val += incr;
+ }
+
+
+ for (;;) {
+ if (ctrlc()) {
+ putchar('\n');
+ return 1;
+ }
+
+
+ /*
+ * Flip the pattern each time to make lots of zeros and
+ * then, the next time, lots of ones. We decrement
+ * the "negative" patterns and increment the "positive"
+ * patterns to preserve this feature.
+ */
+ if(pattern & 0x80000000) {
+ pattern_next = -pattern; /* complement & increment */
+ }
+ else {
+ pattern_next = ~pattern;
+ }
+
+
+
+ printf ("#0x%08lx: Pattern 0x%08lX ...",iter,pattern);
+
+ for (addr=start,val=pattern, val_next=pattern_next; addr<end; addr++) {
+ readback = *addr;
+ if (readback != val) {
+ printf ("\r\nMem error @ 0x%08X: "
+ "found 0x%08lX, expected 0x%08lX\r\n",
+ (uint)addr, readback, val);
+ rcode = 1;
+ }
+
+ //Write the the next value to read
+ *addr=val_next;
+
+ //Increment actual read value and decrement write value.
+ val += incr;
+ val_next -= incr;
+ }
+
+ printf("\tOK\r\n");
+ iter++;
+ pattern=pattern_next;
+ incr = -incr;
+
+ }
+ return rcode;
+}
+
+
+
+
/*
* Perform a memory test. A more complete alternative test can be
* configured using CONFIG_CMD_MTEST_ALTERNATIVE. The complete test
* loops until interrupted by ctrl-c or by a failure of one of the
* sub-tests.
+ *
+ * ref: http://www.barrgroup.com/Embedded-Systems/How-To/Memory-Test-Suite-C
*/
#ifdef CONFIG_CMD_MTEST_ALTERNATIVE
int mem_test(ulong _start, ulong _end, ulong pattern_unused)
@@ -57,6 +149,7 @@ int mem_test(ulong _start, ulong _end, ulong pattern_unused)
vu_long *end = (vu_long *)_end;
vu_long *addr;
ulong val;
+ ulong nErr;
ulong readback;
vu_long addr_mask;
vu_long offset;
@@ -71,7 +164,7 @@ int mem_test(ulong _start, ulong _end, ulong pattern_unused)
vu_long *dummy = start;
#endif
int j;
- int iterations = 1;
+
static const ulong bitpattern[] = {
0x00000001, /* single bit */
@@ -84,257 +177,249 @@ int mem_test(ulong _start, ulong _end, ulong pattern_unused)
0xaaaaaaaa, /* alternating 1/0 */
};
+
+ printf ("\rTesting DDR: 0x%08lX"
+ " > 0x%08lX\n\r",
+ _start, _end);
+
+
/* XXX: enforce alignment of start and end? */
- for (;;) {
- if (ctrlc()) {
- putchar ('\n');
- return 1;
- }
+ if (ctrlc()) {
+ putchar ('\n');
+ return 1;
+ }
- printf("Iteration: %6d\r", iterations);
- iterations++;
- /*
- * Data line test: write a pattern to the first
- * location, write the 1's complement to a 'parking'
- * address (changes the state of the data bus so a
- * floating bus doen't give a false OK), and then
- * read the value back. Note that we read it back
- * into a variable because the next time we read it,
- * it might be right (been there, tough to explain to
- * the quality guys why it prints a failure when the
- * "is" and "should be" are obviously the same in the
- * error message).
- *
- * Rather than exhaustively testing, we test some
- * patterns by shifting '1' bits through a field of
- * '0's and '0' bits through a field of '1's (i.e.
- * pattern and ~pattern).
- */
- addr = start;
- /* XXX */
- if (addr == dummy) ++addr;
- for (j = 0; j < sizeof(bitpattern)/sizeof(bitpattern[0]); j++) {
- val = bitpattern[j];
- for(; val != 0; val <<= 1) {
+ printf ("Testing Data line...\n\r");
+
+
+ /*
+ * Data line test: write a pattern to the first
+ * location, write the 1's complement to a 'parking'
+ * address (changes the state of the data bus so a
+ * floating bus doen't give a false OK), and then
+ * read the value back. Note that we read it back
+ * into a variable because the next time we read it,
+ * it might be right (been there, tough to explain to
+ * the quality guys why it prints a failure when the
+ * "is" and "should be" are obviously the same in the
+ * error message).
+ *
+ * Rather than exhaustively testing, we test some
+ * patterns by shifting '1' bits through a field of
+ * '0's and '0' bits through a field of '1's (i.e.
+ * pattern and ~pattern).
+ */
+ addr = start;
+ nErr=0;
+ /* XXX */
+ if (addr == dummy) ++addr;
+ for (j = 0; j < sizeof(bitpattern)/sizeof(bitpattern[0]); j++) {
+ val = bitpattern[j];
+ for(; val != 0; val <<= 1) {
*addr = val;
*dummy = ~val; /* clear the test data off of the bus */
readback = *addr;
if(readback != val) {
- printf ("FAILURE (data line): "
- "expected 0x%08lx, actual 0x%08lx at address 0x%p\r\n",
- val, readback, addr);
+ nErr++;
+ printf ("FAILURE (data line) : "
+ "expected 0x%08x, actual 0x%08x @ 0x%08x\n\r",
+ val, readback, addr);
}
+ else nErr--;
+
*addr = ~val;
*dummy = val;
readback = *addr;
if(readback != ~val) {
- printf ("FAILURE (data line): "
- "Is 0x%08lx, should be 0x%08lx at address 0x%p\r\n",
- readback, ~val, addr);
+ printf ("FAILURE (data line)~ : "
+ "expected 0x%08x, actual 0x%08x @ 0x%08x\n\r",
+ ~val, readback, addr);
+ nErr++;
}
- }
+ else nErr--;
}
+ if(nErr>64) break;
+ }
+
+ printf ("\tOK: data line\n\r");
- /*
- * Based on code whose Original Author and Copyright
- * information follows: Copyright (c) 1998 by Michael
- * Barr. This software is placed into the public
- * domain and may be used for any purpose. However,
- * this notice must not be changed or removed and no
- * warranty is either expressed or implied by its
- * publication or distribution.
- */
- /*
- * Address line test
- *
- * Description: Test the address bus wiring in a
- * memory region by performing a walking
- * 1's test on the relevant bits of the
- * address and checking for aliasing.
- * This test will find single-bit
- * address failures such as stuck -high,
- * stuck-low, and shorted pins. The base
- * address and size of the region are
- * selected by the caller.
- *
- * Notes: For best results, the selected base
- * address should have enough LSB 0's to
- * guarantee single address bit changes.
- * For example, to test a 64-Kbyte
- * region, select a base address on a
- * 64-Kbyte boundary. Also, select the
- * region size as a power-of-two if at
- * all possible.
- *
- * Returns: 0 if the test succeeds, 1 if the test fails.
- *
- * ## NOTE ## Be sure to specify start and end
- * addresses such that addr_mask has
- * lots of bits set. For example an
- * address range of 01000000 02000000 is
- * bad while a range of 01000000
- * 01ffffff is perfect.
- */
- addr_mask = ((ulong)end - (ulong)start)/sizeof(vu_long);
- pattern = (vu_long) 0xaaaaaaaa;
- anti_pattern = (vu_long) 0x55555555;
+ /*
+ * Based on code whose Original Author and Copyright
+ * information follows: Copyright (c) 1998 by Michael
+ * Barr. This software is placed into the public
+ * domain and may be used for any purpose. However,
+ * this notice must not be changed or removed and no
+ * warranty is either expressed or implied by its
+ * publication or distribution.
+ */
- debug("%s:%d: addr mask = 0x%.8lx\r\n",
- __FUNCTION__, __LINE__,
- addr_mask);
- /*
- * Write the default pattern at each of the
- * power-of-two offsets.
- */
- for (offset = 1; (offset & addr_mask) != 0; offset <<= 1)
- start[offset] = pattern;
+ /*
+ * Address line test
+ *
+ * Description: Test the address bus wiring in a
+ * memory region by performing a walking
+ * 1's test on the relevant bits of the
+ * address and checking for aliasing.
+ * This test will find single-bit
+ * address failures such as stuck -high,
+ * stuck-low, and shorted pins. The base
+ * address and size of the region are
+ * selected by the caller.
+ *
+ * Notes: For best results, the selected base
+ * address should have enough LSB 0's to
+ * guarantee single address bit changes.
+ * For example, to test a 64-Kbyte
+ * region, select a base address on a
+ * 64-Kbyte boundary. Also, select the
+ * region size as a power-of-two if at
+ * all possible.
+ *
+ * Returns: 0 if the test succeeds, 1 if the test fails.
+ *
+ * ## NOTE ## Be sure to specify start and end
+ * addresses such that addr_mask has
+ * lots of bits set. For example an
+ * address range of 01000000 02000000 is
+ * bad while a range of 01000000
+ * 01ffffff is perfect.
+ */
- /*
- * Check for address bits stuck high.
- */
- test_offset = 0;
- start[test_offset] = anti_pattern;
-
- for (offset = 1; (offset & addr_mask) != 0; offset <<= 1) {
- temp = start[offset];
- if (temp != pattern) {
- printf ("FAILURE: Address bit stuck high @ 0x%.8lx:"
- " expected 0x%.8lx, actual 0x%.8lx\r\n",
- (ulong)&start[offset], pattern, temp);
- return 1;
- }
- }
- start[test_offset] = pattern;
+ printf ("Testing addressline (addr mask = 0x%.8lx) ... \n\r",addr_mask);
- /*
- * Check for addr bits stuck low or shorted.
- */
- for (test_offset = 1; (test_offset & addr_mask) != 0; test_offset <<= 1) {
- start[test_offset] = anti_pattern;
-
- for (offset = 1; (offset & addr_mask) != 0; offset <<= 1) {
- temp = start[offset];
- if ((temp != pattern) && (offset != test_offset)) {
- printf ("FAILURE: Address bit stuck low or shorted @"
- " 0x%.8lx: expected 0x%.8lx, actual 0x%.8lx\r\n",
- (ulong)&start[offset], pattern, temp);
- return 1;
- }
- }
- start[test_offset] = pattern;
- }
+ addr_mask = ((ulong)end - (ulong)start)/sizeof(vu_long);
+ pattern = (vu_long) 0xaaaaaaaa;
+ anti_pattern = (vu_long) 0x55555555;
- /*
- * Description: Test the integrity of a physical
- * memory device by performing an
- * increment/decrement test over the
- * entire region. In the process every
- * storage bit in the device is tested
- * as a zero and a one. The base address
- * and the size of the region are
- * selected by the caller.
- *
- * Returns: 0 if the test succeeds, 1 if the test fails.
- */
- num_words = ((ulong)end - (ulong)start)/sizeof(vu_long) + 1;
+ debug("%s:%d: addr mask = 0x%.8lx\r\n",
+ __FUNCTION__, __LINE__,
+ addr_mask);
+ /*
+ * Write the default pattern at each of the
+ * power-of-two offsets.
+ */
+ for (offset = 1; (offset & addr_mask) != 0; offset <<= 1)
+ start[offset] = pattern;
- /*
- * Fill memory with a known pattern.
- */
- for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
- start[offset] = pattern;
- }
+ /*
+ * Check for address bits stuck high.
+ */
+ test_offset = 0;
+ start[test_offset] = anti_pattern;
- /*
- * Check each location and invert it for the second pass.
- */
- for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
- temp = start[offset];
- if (temp != pattern) {
- printf ("FAILURE (read/write) @ 0x%.8lx:"
- " expected 0x%.8lx, actual 0x%.8lx)\r\n",
- (ulong)&start[offset], pattern, temp);
- return 1;
- }
+ for (offset = 1; (offset & addr_mask) != 0; offset <<= 1) {
+ temp = start[offset];
+ if (temp != pattern) {
+ printf ("FAILURE: Address bit stuck high @ 0x%.8lx:"
+ " expected 0x%.8lx, actual 0x%.8lx\r\n",
+ (ulong)&start[offset], pattern, temp);
+ return 1;
+ }
+ }
+ start[test_offset] = pattern;
- anti_pattern = ~pattern;
- start[offset] = anti_pattern;
- }
+ /*
+ * Check for addr bits stuck low or shorted.
+ */
+ for (test_offset = 1; (test_offset & addr_mask) != 0; test_offset <<= 1) {
+ start[test_offset] = anti_pattern;
- /*
- * Check each location for the inverted pattern and zero it.
- */
- for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
- anti_pattern = ~pattern;
- temp = start[offset];
- if (temp != anti_pattern) {
- printf ("FAILURE (read/write): @ 0x%.8lx:"
- " expected 0x%.8lx, actual 0x%.8lx)\r\n",
- (ulong)&start[offset], anti_pattern, temp);
- return 1;
- }
- start[offset] = 0;
+ for (offset = 1; (offset & addr_mask) != 0; offset <<= 1) {
+ temp = start[offset];
+ if ((temp != pattern) && (offset != test_offset)) {
+ printf ("FAILURE: Address bit stuck low or shorted @"
+ " 0x%.8lx: expected 0x%.8lx, actual 0x%.8lx\r\n",
+ (ulong)&start[offset], pattern, temp);
+ return 1;
}
+ }
+ start[test_offset] = pattern;
}
-}
-#else
-int mem_test(ulong _start, ulong _end, ulong pattern)
-{
- vu_long *addr;
- vu_long *start = (vu_long *)_start;
- vu_long *end = (vu_long *)_end;
- ulong val;
- ulong readback;
- ulong incr;
- int rcode;
+ printf ("OK: address line\n\r");
- incr = 1;
- for (;;) {
- if (ctrlc()) {
- putchar('\n');
- return 1;
- }
- printf ("\rPattern 0x%08lX Writing..."
- "%12s"
- "\b\b\b\b\b\b\b\b\b\b",
- pattern, "");
+ /*
+ * Description: Test the integrity of a physical
+ * memory device by performing an
+ * increment/decrement test over the
+ * entire region. In the process every
+ * storage bit in the device is tested
+ * as a zero and a one. The base address
+ * and the size of the region are
+ * selected by the caller.
+ *
+ * Returns: 0 if the test succeeds, 1 if the test fails.
+ */
+ num_words = ((ulong)end - (ulong)start)/sizeof(vu_long);
- for (addr=start,val=pattern; addr<end; addr++) {
- *addr = val;
- val += incr;
- }
+ printf ("Testing memory integrity: hold a counter ... \n\r");
+ /*
+ * Fill memory with a known pattern.
+ */
+ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
+ start[offset] = pattern;
+ }
- puts ("Reading...");
+ /*
+ * Check each location and invert it for the second pass.
+ */
+ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
+ temp = start[offset];
+ if (temp != pattern) {
+ printf ("FAILURE (read/write) @ 0x%.8lx:"
+ " expected 0x%.8lx, actual 0x%.8lx)\r\n",
+ (ulong)&start[offset], pattern, temp);
+ return 1;
+ }
- for (addr=start,val=pattern; addr<end; addr++) {
- readback = *addr;
- if (readback != val) {
- printf ("\r\nMem error @ 0x%08X: "
- "found 0x%08lX, expected 0x%08lX\r\n",
- (uint)addr, readback, val);
- rcode = 1;
- }
- val += incr;
- }
+ anti_pattern = ~pattern;
+ start[offset] = anti_pattern;
+ }
- /*
- * Flip the pattern each time to make lots of zeros and
- * then, the next time, lots of ones. We decrement
- * the "negative" patterns and increment the "positive"
- * patterns to preserve this feature.
- */
- if(pattern & 0x80000000) {
- pattern = -pattern; /* complement & increment */
- }
- else {
- pattern = ~pattern;
- }
- incr = -incr;
+ printf ("OK: memory integrity (counter)\n\r");
+ printf ("Testing memory integrity: hold an anti-counter\n\r");
+
+ /*
+ * Check each location for the inverted pattern and zero it.
+ */
+ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) {
+ anti_pattern = ~pattern;
+ temp = start[offset];
+ if (temp != anti_pattern) {
+ printf ("FAILURE (read/write): @ 0x%.8lx:"
+ " expected 0x%.8lx, actual 0x%.8lx)\r\n",
+ (ulong)&start[offset], anti_pattern, temp);
+ return 1;
+ }
+ start[offset] = 0;
}
- return rcode;
+
+ printf ("OK: memory integrity (anti-counter)\n\r");
+ printf ("OK: bus line, address line and integrity are OK\n\r\n\r");
+ printf ("Now it will continue to check integrity with various patterns. (Ctrl+C to exit)...\n\r");
+
+ return mem_test_integrity(_start,_end,pattern_unused);
+
+}
+#else
+/**
+* Small test that check different patterns on the whole range of memory
+* only check integrity (holding some values), not shortcut address!
+**/
+int mem_test(ulong _start, ulong _end, ulong pattern)
+{
+
+ printf ("\rTesting Range: 0x%08lX"
+ " > 0x%08lX\n\r",
+ _start, _end);
+
+ return mem_test_integrity(_start,_end,pattern);
+
}
#endif
+
+
+
--
1.7.9.5
From 78f344309e4fa491efd1240f481d15c00f6d47b2 Mon Sep 17 00:00:00 2001
From: Benoit Rat <benoit@sevensols.com>
Date: Mon, 2 Apr 2012 15:43:17 +0200
Subject: [PATCH 19/19] memtest: Add CPU LED switching to memtest
---
lib/memtest.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/lib/memtest.c b/lib/memtest.c
index 4366171..20c5e45 100644
--- a/lib/memtest.c
+++ b/lib/memtest.c
@@ -26,6 +26,7 @@
#include <pp_printf.h>
#include <dbgu.h>
#include <debug.h>
+#include <gpio.h>
//#include <stdlib.h>
/* BEGIN HACKS - to compile barebox code out of barebox */
@@ -120,6 +121,8 @@ int mem_test_integrity(ulong _start, ulong _end, ulong pattern)
//Increment actual read value and decrement write value.
val += incr;
val_next -= incr;
+
+ if((*addr % (1024*100)) == 0) pio_set_value(AT91C_PIN_PA(0),*addr % (2048*100)); //Blinking light while testing
}
printf("\tOK\r\n");
@@ -401,6 +404,10 @@ int mem_test(ulong _start, ulong _end, ulong pattern_unused)
printf ("OK: bus line, address line and integrity are OK\n\r\n\r");
printf ("Now it will continue to check integrity with various patterns. (Ctrl+C to exit)...\n\r");
+ pio_set_value(AT91C_PIN_PA(0),1);
+ pio_set_value(AT91C_PIN_PA(1),0);
+
+
return mem_test_integrity(_start,_end,pattern_unused);
}
--
1.7.9.5
G45 memtest
============
The test is inspired from the one in barebox
It has been improved[^1] and now check:
* Data lines
* Address lines
* Memory integrity
* holding counters
* holding anti-counters
* Random patterns
You can find the source on my github: https://github.com/neub/wrs-sw-at91bootstrap/tree/memtest
[^1]: http://www.barrgroup.com/Embedded-Systems/How-To/Memory-Test-Suite-C
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment