📄 test_burst.c
字号:
/* * (C) Copyright 2005 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * See file CREDITS for list of people who contributed to this * project. * * 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; either version 2 of * the License, or (at your option) any later version. * * 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * The test exercises SDRAM accesses in burst mode */#include <common.h>#include <exports.h>#include <commproc.h>#include <asm/mmu.h>#include <asm/processor.h>#include <serial.h>#include <watchdog.h>#include "test_burst.h"/* 8 MB test region of physical RAM */#define TEST_PADDR 0x00800000/* The uncached virtual region */#define TEST_VADDR_NC 0x00800000/* The cached virtual region */#define TEST_VADDR_C 0x01000000/* When an error is detected, the address where the error has been found, and also the current and the expected data will be written to the following flash address*/#define TEST_FLASH_ADDR 0x40100000/* Define GPIO ports to signal start of burst transfers and errors */#ifdef CONFIG_LWMON/* Use PD.8 to signal start of burst transfers */#define GPIO1_DAT (((volatile immap_t *)CFG_IMMR)->im_ioport.iop_pddat)#define GPIO1_BIT 0x0080/* Configure PD.8 as general purpose output */#define GPIO1_INIT \ ((volatile immap_t *)CFG_IMMR)->im_ioport.iop_pdpar &= ~GPIO1_BIT; \ ((volatile immap_t *)CFG_IMMR)->im_ioport.iop_pddir |= GPIO1_BIT;/* Use PD.9 to signal error */#define GPIO2_DAT (((volatile immap_t *)CFG_IMMR)->im_ioport.iop_pddat)#define GPIO2_BIT 0x0040/* Configure PD.9 as general purpose output */#define GPIO2_INIT \ ((volatile immap_t *)CFG_IMMR)->im_ioport.iop_pdpar &= ~GPIO2_BIT; \ ((volatile immap_t *)CFG_IMMR)->im_ioport.iop_pddir |= GPIO2_BIT;#endif /* CONFIG_LWMON */static void test_prepare (void);static int test_burst_start (unsigned long size, unsigned long pattern);static void test_map_8M (unsigned long paddr, unsigned long vaddr, int cached);static int test_mmu_is_on(void);static void test_desc(unsigned long size);static void test_error(char * step, volatile void * addr, unsigned long val, unsigned long pattern);static void signal_init(void);static void signal_start(void);static void signal_error(void);static void test_usage(void);static unsigned long test_pattern [] = { 0x00000000, 0xffffffff, 0x55555555, 0xaaaaaaaa,};int test_burst (int argc, char *argv[]){ unsigned long size = CACHE_LINE_SIZE; unsigned int pass = 0; int res = 0; int i, j; if (argc == 3) { char * d; for (size = 0, d = argv[1]; *d >= '0' && *d <= '9'; d++) { size *= 10; size += *d - '0'; } if (size == 0 || *d) { test_usage(); return 1; } for (d = argv[2]; *d >= '0' && *d <= '9'; d++) { pass *= 10; pass += *d - '0'; } if (*d) { test_usage(); return 1; } } else if (argc > 3) { test_usage(); return 1; } size += (CACHE_LINE_SIZE - 1); size &= ~(CACHE_LINE_SIZE - 1); if (!test_mmu_is_on()) { test_prepare(); } test_desc(size); for (j = 0; !pass || j < pass; j++) { for (i = 0; i < sizeof(test_pattern) / sizeof(test_pattern[0]); i++) { res = test_burst_start(size, test_pattern[i]); if (res != 0) { goto Done; } } printf ("Iteration #%d passed\n", j + 1); if (tstc() && 0x03 == getc()) break; }Done: return res;}static void test_prepare (void){ printf ("\n"); caches_init(); disable_interrupts(); mmu_init(); printf ("Interrupts are disabled\n"); printf ("I-Cache is ON\n"); printf ("D-Cache is ON\n"); printf ("MMU is ON\n"); printf ("\n"); test_map_8M (TEST_PADDR, TEST_VADDR_NC, 0); test_map_8M (TEST_PADDR, TEST_VADDR_C, 1); test_map_8M (TEST_FLASH_ADDR & 0xFF800000, TEST_FLASH_ADDR & 0xFF800000, 0); /* Configure GPIO ports */ signal_init();}static int test_burst_start (unsigned long size, unsigned long pattern){ volatile unsigned long * vaddr_c = (unsigned long *)TEST_VADDR_C; volatile unsigned long * vaddr_nc = (unsigned long *)TEST_VADDR_NC; int i, n; int res = 1; printf ("Test pattern %08x ...", pattern); n = size / 4; for (i = 0; i < n; i ++) { vaddr_c [i] = pattern; } signal_start(); flush_dcache_range((unsigned long)vaddr_c, (unsigned long)(vaddr_c + n) - 1); for (i = 0; i < n; i ++) { register unsigned long tmp = vaddr_nc [i]; if (tmp != pattern) { test_error("2a", vaddr_nc + i, tmp, pattern); goto Done; } } for (i = 0; i < n; i ++) { register unsigned long tmp = vaddr_c [i]; if (tmp != pattern) { test_error("2b", vaddr_c + i, tmp, pattern); goto Done; } } for (i = 0; i < n; i ++) { vaddr_nc [i] = pattern; } for (i = 0; i < n; i ++) { register unsigned long tmp = vaddr_nc [i]; if (tmp != pattern) { test_error("3a", vaddr_nc + i, tmp, pattern); goto Done; } } signal_start(); for (i = 0; i < n; i ++) { register unsigned long tmp = vaddr_c [i]; if (tmp != pattern) { test_error("3b", vaddr_c + i, tmp, pattern); goto Done; } } res = 0;Done: printf(" %s\n", res == 0 ? "OK" : ""); return res;}static void test_map_8M (unsigned long paddr, unsigned long vaddr, int cached){ mtspr (MD_EPN, (vaddr & 0xFFFFFC00) | MI_EVALID); mtspr (MD_TWC, MI_PS8MEG | MI_SVALID); mtspr (MD_RPN, (paddr & 0xFFFFF000) | MI_BOOTINIT | (cached ? 0 : 2)); mtspr (MD_AP, MI_Kp);}static int test_mmu_is_on(void){ unsigned long msr; asm volatile("mfmsr %0" : "=r" (msr) :); return msr & MSR_DR;}static void test_desc(unsigned long size){ printf( "The following tests will be conducted:\n" "1) Map %d-byte region of physical RAM at 0x%08x\n" " into two virtual regions:\n" " one cached at 0x%08x and\n" " the the other uncached at 0x%08x.\n", size, TEST_PADDR, TEST_VADDR_NC, TEST_VADDR_C); puts( "2) Fill the cached region with a pattern, and flush the cache\n" "2a) Check the uncached region to match the pattern\n" "2b) Check the cached region to match the pattern\n" "3) Fill the uncached region with a pattern\n" "3a) Check the cached region to match the pattern\n" "3b) Check the uncached region to match the pattern\n" "2b) Change the patterns and go to step 2\n" "\n" );}static void test_error( char * step, volatile void * addr, unsigned long val, unsigned long pattern){ volatile unsigned long * p = (void *)TEST_FLASH_ADDR; signal_error(); p[0] = (unsigned long)addr; p[1] = val; p[2] = pattern; printf ("\nError at step %s, addr %08x: read %08x, pattern %08x", step, addr, val, pattern);}static void signal_init(void){#if defined(GPIO1_INIT) GPIO1_INIT;#endif#if defined(GPIO2_INIT) GPIO2_INIT;#endif}static void signal_start(void){#if defined(GPIO1_INIT) if (GPIO1_DAT & GPIO1_BIT) { GPIO1_DAT &= ~GPIO1_BIT; } else { GPIO1_DAT |= GPIO1_BIT; }#endif}static void signal_error(void){#if defined(GPIO2_INIT) if (GPIO2_DAT & GPIO2_BIT) { GPIO2_DAT &= ~GPIO2_BIT; } else { GPIO2_DAT |= GPIO2_BIT; }#endif}static void test_usage(void){ printf("Usage: go 0x40004 [size] [count]\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -