#!/usr/bin/perl -w use strict; use Net::Telnet; # Set this to the IP address of the PEEDI my $PEEDI_IP = "172.19.114.50"; # Set this to the IP address of the tftp server my $TFTPD_IP = "172.19.113.252"; # This is the PEEDI prompt my $PEEDI_PROMPT = "mx31\>"; my $PEEDI_PROMPT_REGEX = "/$PEEDI_PROMPT/"; # Verbose ouptut my $VERBOSE = 0; # Read/write single or burst? my $READ_SINGLE = 0; my $WRITE_SINGLE = 0; # Random data or test pattern my $RANDOM_DATA = 0; # DDR2 script variables my $ESDCDLY5 = 0x00cd9f00; # This must match the memtest.elf output (check with arm-elf-objdump) my $SRAM_SRC = 0x10000800; my $SRAM_DST = 0x10001000; my $MEM_DONE = 0x100000a0; my $DDR2_BASE = 0x80000000; my $LOOPS = 0x0001FFFF; # DO NOT EDIT BELOW THIS LINE # Global variable declarations my $line; my $telnet; my $FEATURES = ($READ_SINGLE << 1) | ($WRITE_SINGLE << 0); my $DATA = ($RANDOM_DATA) ? "rand.bin" : "data.bin"; # Read __DATA__ to @DATA so we can replay it my @DATA = (); while () { chomp; push @DATA, $_; } sub debug { print($_[0]."\n".$_[1]."\n"); } sub inforeg { $telnet->print("info reg"); my $regs = {}; $line = $telnet->getline(); while ($line) { $line =~ /(\w+)\s*:\s*(\w+)/; if ($1) { $regs->{$1} = $2; } $line = $telnet->getline(Timeout => '1', Errmode => 'return'); } $telnet->waitfor($PEEDI_PROMPT_REGEX); return $regs } sub memread { $telnet->print("memory read32 " . $_[0] . " " . $_[1]); my $mem = (); $line = $telnet->getline(); while ($line) { $line =~ /^\s*(\w+)\s*:\s*(.+)$/; push @$mem, $2; $line = $telnet->getline(Timeout => '1', Errmode => 'return'); } $telnet->waitfor($PEEDI_PROMPT_REGEX); return $mem } sub runtest { # Reset core print("reset...\n"); $telnet->print("reset\n"); $telnet->waitfor("/initialized/"); print("...done\n"); # Init DDR2 print("ddr2...\n"); foreach (@DATA) { my $line = $_; $line =~ s/(\$\w+)/$1/gee; $telnet->waitfor($PEEDI_PROMPT_REGEX); $telnet->print($line); } print("...done\n"); # Clear DDR2 $telnet->waitfor($PEEDI_PROMPT_REGEX); $telnet->print("memory write32 $DDR2_BASE 0x0 0x800"); # Clear SRAM $telnet->waitfor($PEEDI_PROMPT_REGEX); $telnet->print("memory write32 $SRAM_DST 0x0 0x800"); # Load test program and data $telnet->waitfor($PEEDI_PROMPT_REGEX); $telnet->print("memory load tftp://$TFTPD_IP/memtest.bin 0x10000000"); $telnet->waitfor("/Successfully loaded/"); $telnet->waitfor($PEEDI_PROMPT_REGEX); $telnet->print("memory load tftp://$TFTPD_IP/$DATA $SRAM_SRC"); $telnet->waitfor("/Successfully loaded/"); # Set breakpoints $telnet->waitfor($PEEDI_PROMPT_REGEX); $telnet->print("breakpoint delete all"); $telnet->waitfor($PEEDI_PROMPT_REGEX); $telnet->print("breakpoint add hard $MEM_DONE"); # Set PC $telnet->waitfor($PEEDI_PROMPT_REGEX); $telnet->print("set pc 0x10000000"); # Run test print("memtest...\n"); $telnet->waitfor($PEEDI_PROMPT_REGEX); $telnet->print("set r12 $FEATURES"); $telnet->waitfor($PEEDI_PROMPT_REGEX); $telnet->print("go"); # Wait until we hit the pass or fail breakpoint $telnet->waitfor($PEEDI_PROMPT_REGEX); $telnet->waitfor(Match => '/stopped by breakpoint/', Timeout => '30', Errmode => 'return'); # Load registers print("...done\n"); my $regs = inforeg(); my $errs = 0; if (hex($regs->{"r11"}) == 0) { print("memtest PASS: loop=" . ($LOOPS-hex($regs->{"r11"})). "\n"); } else { print("memtest FAIL: loop=" . ($LOOPS-hex($regs->{"r11"})). " at 0x" . $regs->{"r0"} ."\n"); my $m1 = memread($SRAM_SRC, 0x800/4); my $m2 = memread($SRAM_DST, 0x800/4); my $addr = $DDR2_BASE; foreach (0 .. $#$m1) { next unless $m1->[$_]; if ($m1->[$_] eq $m2->[$_]) { printf("0x%06x: %s %s\n", $addr, $m1->[$_], $m2->[$_]) if $VERBOSE; } else { printf("0x%06x: %s | %s\n", $addr, $m1->[$_], $m2->[$_]) if $VERBOSE; my $s1 = $m1->[$_]; $s1 =~ s/0x//g; $s1 =~ s/\s+//g; my $s2 = $m2->[$_]; $s2 =~ s/0x//g; $s2 =~ s/\s+//g; for (my $i=0; $i<32; $i+=2) { if (substr($s1, $i, 2) ne substr($s2, $i, 2)) { $errs++; } } } $addr += 16; } print("byte errs=$errs\n"); } return $errs; } # Open connection to PEEDI $telnet = new Net::Telnet(Timeout => 30, Errmode => 'die'); $telnet->input_log("log.txt"); $telnet->open($PEEDI_IP); $telnet->waitfor($PEEDI_PROMPT_REGEX); # Can implement test loops here... # Iterate values for ESDCDLY5 my $DLY_OFFSET_5; my $DLY_ABS_OFFSET_5; open(RESULTS, ">> results.csv") || die "Can't open results"; for ($DLY_ABS_OFFSET_5=0x00; $DLY_ABS_OFFSET_5 <= 0xFF; $DLY_ABS_OFFSET_5 += 0x10) { for ($DLY_OFFSET_5=0x00; $DLY_OFFSET_5 <= 0xFF; $DLY_OFFSET_5 += 0x02) { $ESDCDLY5 = ($DLY_OFFSET_5 << 16) | ($DLY_ABS_OFFSET_5 << 8); print("========\n\n"); printf("ESDCDLY5=0x%08x\n", $ESDCDLY5); my $errs = -1; eval { $errs = runtest() }; print $@ if $@; printf(RESULTS "%d,%d,%d\n", $DLY_OFFSET_5, $DLY_ABS_OFFSET_5, $errs); } } close(RESULTS); # Single shot #eval { runtest() }; print $@ if $@; __DATA__ ; AIPS setup memory write32 0x43f00040 0x00000000 memory write32 0x43f00044 0x00000000 memory write32 0x43f00048 0x00000000 memory write32 0x43f0004C 0x00000000 memory write32 0x43f00050 0x00000000 memory write32 0x43f00000 0x77777777 memory write32 0x43f00004 0x77777777 memory write32 0x53f00040 0x00000000 memory write32 0x53f00044 0x00000000 memory write32 0x53f00048 0x00000000 memory write32 0x53f0004C 0x00000000 memory write32 0x53f00050 0x00000000 memory write32 0x53f00000 0x77777777 memory write32 0x53f00004 0x77777777 ; Clock setup memory write32 0x53F80004 0x00821000 ; first need to set IPU_HND_BYP memory write32 0x53F80004 0x00821000 ; arm clock is 399Mhz and ahb clock is 133Mhz. ; DDR group settings memory write32 0x43fac794 0x1000 ; SDCKE memory write32 0x43fac798 0x1000 ; DQS[3:0] memory write32 0x43fac79c 0x1000 ; SDBA1, SDBA0 memory write32 0x43fac7a0 0x1000 ; SD[31:0] memory write32 0x43fac7a4 0x1000 ; sdclk, DQM ; IOMUXC: ; 0x80 = PULL UP ; ; 0x00 = NOMINAL DRIVE STRENGTH ; 0x02 = HIGH DRIVE STRENGTH ; 0x06 = MAX DRIVE STRENGTH ; IO SW PAD Control registers memory write32 0x43FAC368 0x00000002 ; A0 memory write32 0x43FAC36C 0x00000002 memory write32 0x43FAC370 0x00000002 memory write32 0x43FAC374 0x00000002 memory write32 0x43FAC378 0x00000002 memory write32 0x43FAC37C 0x00000002 memory write32 0x43FAC380 0x00000002 memory write32 0x43FAC384 0x00000002 memory write32 0x43FAC388 0x00000002 memory write32 0x43FAC38C 0x00000002 memory write32 0x43FAC390 0x00000002 memory write32 0x43FAC394 0x00000002 memory write32 0x43FAC398 0x00000002 memory write32 0x43FAC39C 0x00000002 memory write32 0x43FAC3A0 0x00000002 memory write32 0x43FAC3A4 0x00000002 memory write32 0x43FAC3A8 0x00000002 memory write32 0x43FAC3AC 0x00000002 memory write32 0x43FAC3B0 0x00000002 memory write32 0x43FAC3B4 0x00000002 memory write32 0x43FAC3B8 0x00000002 memory write32 0x43FAC3BC 0x00000002 memory write32 0x43FAC3C0 0x00000002 memory write32 0x43FAC3C4 0x00000002 memory write32 0x43FAC3C8 0x00000002 memory write32 0x43FAC3CC 0x00000002 memory write32 0x43FAC3D0 0x00000002 ; A25 memory write32 0x43FAC3D4 0x00000002 ; SDBA1 memory write32 0x43FAC3D8 0x00000002 ; SDBA0 ; DDR data bus SD 0 through 31 memory write32 0x43FAC3DC 0x00000002 ; SD0 memory write32 0x43FAC3E0 0x00000002 memory write32 0x43FAC3E4 0x00000002 memory write32 0x43FAC3E8 0x00000002 memory write32 0x43FAC3EC 0x00000002 memory write32 0x43FAC3F0 0x00000002 memory write32 0x43FAC3F4 0x00000002 memory write32 0x43FAC3F8 0x00000002 memory write32 0x43FAC3FC 0x00000002 memory write32 0x43FAC400 0x00000002 memory write32 0x43FAC404 0x00000002 memory write32 0x43FAC408 0x00000002 memory write32 0x43FAC40C 0x00000002 memory write32 0x43FAC410 0x00000002 memory write32 0x43FAC414 0x00000002 memory write32 0x43FAC418 0x00000002 memory write32 0x43FAC41c 0x00000002 memory write32 0x43FAC420 0x00000002 memory write32 0x43FAC424 0x00000002 memory write32 0x43FAC428 0x00000002 memory write32 0x43FAC42c 0x00000002 memory write32 0x43FAC430 0x00000002 memory write32 0x43FAC434 0x00000002 memory write32 0x43FAC438 0x00000002 memory write32 0x43FAC43c 0x00000002 memory write32 0x43FAC440 0x00000002 memory write32 0x43FAC444 0x00000002 memory write32 0x43FAC448 0x00000002 memory write32 0x43FAC44c 0x00000002 memory write32 0x43FAC450 0x00000002 memory write32 0x43FAC454 0x00000002 memory write32 0x43FAC458 0x00000002 ; SD31 memory write32 0x43FAC45c 0x00000002 ; DQM0 memory write32 0x43FAC460 0x00000002 memory write32 0x43FAC464 0x00000002 memory write32 0x43FAC468 0x00000002 ; DQM3 memory write32 0x43FAC46c 0x00000002 ; EB0 memory write32 0x43FAC470 0x00000002 ; EB1 memory write32 0x43FAC474 0x00000002 ; OE memory write32 0x43FAC478 0x00000002 ; CS0 memory write32 0x43FAC47c 0x00000002 ; CS1 memory write32 0x43FAC480 0x00000002 ; CS2 memory write32 0x43FAC484 0x00000002 ; CS3 memory write32 0x43FAC488 0x00000002 ; CS4 memory write32 0x43FAC48c 0x00000002 ; CS5 memory write32 0x43FAC490 0x00000002 ; NF_CE0 memory write32 0x43FAC494 0x00000002 ; ECB memory write32 0x43FAC498 0x00000002 ; LBA memory write32 0x43FAC49c 0x00000002 ; BCLK memory write32 0x43FAC4A0 0x00000002 ; RW memory write32 0x43FAC4A4 0x00001002 ; RAS memory write32 0x43FAC4A8 0x00001002 ; CAS memory write32 0x43FAC4Ac 0x00001002 ; SDWE memory write32 0x43FAC4B0 0x00000002 ; SDCKE0 memory write32 0x43FAC4B4 0x00000002 ; SDCKE1 memory write32 0x43FAC4B8 0x00001002 ; SDCLK memory write32 0x43FAC4Bc 0x00000002 ; SDQS0 memory write32 0x43FAC4C0 0x00000002 ; SDQS1 memory write32 0x43FAC4C4 0x00000002 ; SDQS2 memory write32 0x43FAC4C8 0x00000002 ; SDQS3 ; ESD_MISC : enable DDR2 memory write32 0xB8001010 0x00000304 ; ESD_ESDCFG0 : set timing paramters memory write32 0xB8001004 0x007ffC2f ; ESD_ESDCTL0 : select Prechare-All mode memory write32 0xB8001000 0x92120000 ; DDR2 : Prechare-All memory write8 0x80000400 0x12345678 ; ESD_ESDCTL0 : select Load-Mode-Register mode memory write32 0xB8001000 0xB2120000 ; DDR2 : Load reg EMR2 memory write8 0x84000000 0xda ; DDR2 : Load reg EMR3 memory write8 0x86000000 0xda ; DDR2 : Load reg EMR1 -- enable DLL memory write8 0x82000402 0xda ; DDR2 : Load reg MR -- reset DLL memory write8 0x80000333 0xda ; ESD_ESDCTL0 : select Prechare-All mode memory write32 0xB8001000 0x92120000 ; DDR2 : Prechare-All memory write8 0x80000400 0x12345678 ; ESD_ESDCTL0 : select Manual-Refresh mode memory write32 0xB8001000 0xA2120000 ; DDR2 : Manual-Refresh 2 times memory write32 0x80000000 0x87654321 memory write32 0x80000000 0x87654321 ; ESD_ESDCTL0 : select Load-Mode-Register mode memory write32 0xB8001000 0xB2120000 ; DDR2 : Load reg MR -- CL3, BL=8, end DLL reset memory write8 0x80000233 0xda ; DDR2 : Load reg EMR1 -- OCD default memory write8 0x82000782 0xda ; DDR2 : Load reg EMR1 -- OCD exit memory write8 0x82000400 0xda ; ODT disabled ; ESD_ESDCTL0 : select normal-operation mode ; DSIZ=32-bit, BL=8, COL=10-bit, ROW=13-bit ; disable PWT & PRCT ; disable Auto-Refresh memory write32 0xB8001000 0x82120080 ; ESD_ESDCTL0 : enable Auto-Refresh memory write32 0xB8001000 0x82126080 memory write32 0xB8001008 0x00002000 ; Adjust the ESDCDLY5 register memory write32 0xB8001020 0x00F48000 ; DQS[0] delay memory write32 0xB8001024 0x00F48000 ; DQS[1] delay memory write32 0xB8001028 0x00F48000 ; DQS[2] delay memory write32 0xB800102c 0x00F48000 ; DQS[3] delay memory write32 0xB8001030 $ESDCDLY5 ; DATA write delay ; make force measure with the dedicated bit (Bit 7 at ESDMISC) memory write32 0xB8001010 0x00000384 wait 10 memory write32 0xB8001010 0x00000304 ; dummy write to DDR memory to set DQS low memory write32 0x80000000 0x00000000