bios: automatically enable hardware memory controller and test memory
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Tue, 15 May 2012 17:29:26 +0000 (19:29 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Tue, 15 May 2012 17:29:26 +0000 (19:29 +0200)
software/bios/ddrinit.c
software/bios/ddrinit.h
software/bios/main.c
software/include/hw/mem.h [new file with mode: 0644]
tb/asmicon/asmicon_wb.py

index c4f4173f4affda0add089b421f945df1edf1f63c..84990ac14144d4b7e5d28200ea849d4e3d6a810e 100644 (file)
@@ -19,6 +19,7 @@
 #include <stdlib.h>
 
 #include <hw/dfii.h>
+#include <hw/mem.h>
 
 #include "ddrinit.h"
 
@@ -42,8 +43,6 @@ static void init_sequence(void)
 {
        int i;
        
-       printf("Sending initialization sequence...\n");
-       
        /* Bring CKE high */
        setaddr(0x0000);
        CSR_DFII_BA_P0 = 0;
@@ -172,11 +171,45 @@ void ddrwr(char *startaddr)
        CSR_DFII_COMMAND_P1 = DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS|DFII_COMMAND_WRDATA;
 }
 
+#define TEST_SIZE (4*1024*1024)
+
+int memtest_silent(void)
+{
+       volatile unsigned int *array = (unsigned int *)SDRAM_BASE;
+       int i;
+       unsigned int prv;
+       
+       prv = 0;
+       for(i=0;i<TEST_SIZE/4;i++) {
+               prv = 1664525*prv + 1013904223;
+               array[i] = prv;
+       }
+       
+       prv = 0;
+       for(i=0;i<TEST_SIZE/4;i++) {
+               prv = 1664525*prv + 1013904223;
+               if(array[i] != prv)
+                       return 0;
+       }
+       return 1;
+}
+
+void memtest(void)
+{
+       if(memtest_silent())
+               printf("OK\n");
+       else
+               printf("Failed\n");
+}
+
 int ddrinit(void)
 {
-       printf("Initializing DDR SDRAM...\n");
+       printf("Initializing DDRAM...\n");
        
        init_sequence();
+       CSR_DFII_CONTROL = DFII_CONTROL_SEL|DFII_CONTROL_CKE;
+       if(!memtest_silent())
+               return 0;
        
        return 1;
 }
index cabffd345e4553cd9272b6b31360e51a0409d543..e1085fc44c9121ac2d06bcb1716d912c2e4dcc4c 100644 (file)
 #ifndef __DDRINIT_H
 #define __DDRINIT_H
 
-int ddrinit(void);
 void ddrsw(void);
 void ddrhw(void);
 void ddrrow(char *_row);
 void ddrrd(char *startaddr);
 void ddrwr(char *startaddr);
+int memtest_silent(void);
+void memtest(void);
+int ddrinit(void);
 
 #endif /* __DDRINIT_H */
index 5a72cf16a849a9ab6f49d01f38796347b579197e..7225b35e2478133f0f0cac5a1a26e596971dc8b3 100644 (file)
@@ -352,12 +352,13 @@ static void do_command(char *c)
        else if(strcmp(token, "rcsr") == 0) rcsr(get_token(&c));
        else if(strcmp(token, "wcsr") == 0) wcsr(get_token(&c), get_token(&c));
        
-       else if(strcmp(token, "ddrinit") == 0) ddrinit();
        else if(strcmp(token, "ddrrow") == 0) ddrrow(get_token(&c));
        else if(strcmp(token, "ddrsw") == 0) ddrsw();
        else if(strcmp(token, "ddrhw") == 0) ddrhw();
        else if(strcmp(token, "ddrrd") == 0) ddrrd(get_token(&c));
        else if(strcmp(token, "ddrwr") == 0) ddrwr(get_token(&c));
+       else if(strcmp(token, "memtest") == 0) memtest();
+       else if(strcmp(token, "ddrinit") == 0) ddrinit();
 
        else if(strcmp(token, "") != 0)
                printf("Command not found\n");
@@ -384,10 +385,10 @@ static void crcbios(void)
        length = (unsigned int)&_edata - offset_bios;
        actual_crc = crc32((unsigned char *)offset_bios, length);
        if(expected_crc == actual_crc)
-               printf("I: BIOS CRC passed (%08x)\n", actual_crc);
+               printf("BIOS CRC passed (%08x)\n", actual_crc);
        else {
-               printf("W: BIOS CRC failed (expected %08x, got %08x)\n", expected_crc, actual_crc);
-               printf("W: The system will continue, but expect problems.\n");
+               printf("BIOS CRC failed (expected %08x, got %08x)\n", expected_crc, actual_crc);
+               printf("The system will continue, but expect problems.\n");
        }
 }
 
@@ -395,7 +396,7 @@ static void print_mac(void)
 {
        unsigned char *macadr = (unsigned char *)FLASH_OFFSET_MAC_ADDRESS;
 
-       printf("I: MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", macadr[0], macadr[1], macadr[2], macadr[3], macadr[4], macadr[5]);
+       printf("MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", macadr[0], macadr[1], macadr[2], macadr[3], macadr[4], macadr[5]);
 }
 
 static const char banner[] =
@@ -441,6 +442,7 @@ static void readstr(char *s, int size)
 int main(int i, char **c)
 {
        char buffer[64];
+       int ddr_ok;
 
        rescue = !((unsigned int)main > FLASH_OFFSET_REGULAR_BIOS);
 
@@ -449,11 +451,16 @@ int main(int i, char **c)
        uart_init();
        printf(banner);
        crcbios();
+       if(rescue)
+               printf("Rescue mode\n");
        print_mac();
-       ddrinit();
+       ddr_ok = ddrinit();
+       if(ddr_ok) {
+               printf("Booting...\n");
+       } else {
+               printf("Memory initialization failed\n");
+       }
        
-       if(rescue)
-               printf("I: Booting in rescue mode\n");
        
        while(1) {
                putsnonl("\e[1mBIOS>\e[0m ");
diff --git a/software/include/hw/mem.h b/software/include/hw/mem.h
new file mode 100644 (file)
index 0000000..b440a48
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Milkymist SoC (Software)
+ * Copyright (C) 2012 Sebastien Bourdeauducq
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __HW_MEM_H
+#define __HW_MEM_H
+
+#define SDRAM_BASE             (0x40000000)
+
+#endif /* __HW_MEM_H */
index 28f6dc286d2a738c867c2673a7a4cbacc26e71d7..78aaddf6ca70085cab70a568a3f4a7cab39e1567 100644 (file)
@@ -10,18 +10,18 @@ from common import sdram_phy, sdram_geom, sdram_timing, DFILogger
 l2_size = 8192 # in bytes
 
 def my_generator():
+       #for x in range(20):
+               #t = TWrite(x, x)
+               #yield t
+               #print(str(t) + " delay=" + str(t.latency))
        for x in range(20):
-               t = TWrite(x, x)
-               yield t
-               print(str(t) + " delay=" + str(t.latency))
-       for x in range(20):
-               t = TRead(x)
-               yield t
-               print(str(t) + " delay=" + str(t.latency))
-       for x in range(20):
-               t = TRead(x+l2_size//4)
+               t = TRead(4194304//4 + x)
                yield t
                print(str(t) + " delay=" + str(t.latency))
+       #for x in range(20):
+               #t = TRead(x+l2_size//4)
+               #yield t
+               #print(str(t) + " delay=" + str(t.latency))
 
 def main():
        controller = ASMIcon(sdram_phy, sdram_geom, sdram_timing)