uboot/examples/standalone/test_burst.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2005
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 *
  23 * The test exercises SDRAM accesses in burst mode
  24 */
  25
  26#include <common.h>
  27#include <exports.h>
  28
  29#include <commproc.h>
  30#include <asm/mmu.h>
  31#include <asm/processor.h>
  32
  33#include <serial.h>
  34#include <watchdog.h>
  35
  36#include "test_burst.h"
  37
  38/* 8 MB test region of physical RAM */
  39#define TEST_PADDR      0x00800000
  40/* The uncached virtual region */
  41#define TEST_VADDR_NC   0x00800000
  42/* The cached virtual region */
  43#define TEST_VADDR_C    0x01000000
  44/* When an error is detected, the address where the error has been found,
  45   and also the current and the expected data will be written to
  46   the following flash address
  47*/
  48#define TEST_FLASH_ADDR 0x40100000
  49
  50/* Define GPIO ports to signal start of burst transfers and errors */
  51#ifdef CONFIG_LWMON
  52/* Use PD.8 to signal start of burst transfers */
  53#define GPIO1_DAT       (((volatile immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pddat)
  54#define GPIO1_BIT       0x0080
  55/* Configure PD.8 as general purpose output */
  56#define GPIO1_INIT \
  57        ((volatile immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pdpar &= ~GPIO1_BIT; \
  58        ((volatile immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pddir |=  GPIO1_BIT;
  59/* Use PD.9 to signal error */
  60#define GPIO2_DAT       (((volatile immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pddat)
  61#define GPIO2_BIT       0x0040
  62/* Configure PD.9 as general purpose output */
  63#define GPIO2_INIT \
  64        ((volatile immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pdpar &= ~GPIO2_BIT; \
  65        ((volatile immap_t *)CONFIG_SYS_IMMR)->im_ioport.iop_pddir |=  GPIO2_BIT;
  66#endif /* CONFIG_LWMON */
  67
  68
  69static void test_prepare (void);
  70static int test_burst_start (unsigned long size, unsigned long pattern);
  71static void test_map_8M (unsigned long paddr, unsigned long vaddr, int cached);
  72static int test_mmu_is_on(void);
  73static void test_desc(unsigned long size);
  74static void test_error(char * step, volatile void * addr, unsigned long val, unsigned long pattern);
  75static void signal_init(void);
  76static void signal_start(void);
  77static void signal_error(void);
  78static void test_usage(void);
  79
  80static unsigned long test_pattern [] = {
  81        0x00000000,
  82        0xffffffff,
  83        0x55555555,
  84        0xaaaaaaaa,
  85};
  86
  87
  88int test_burst (int argc, char * const argv[])
  89{
  90        unsigned long size = CACHE_LINE_SIZE;
  91        unsigned int pass = 0;
  92        int res = 0;
  93        int i, j;
  94
  95        if (argc == 3) {
  96                char * d;
  97                for (size = 0, d = argv[1]; *d >= '0' && *d <= '9'; d++) {
  98                        size *= 10;
  99                        size += *d - '0';
 100                }
 101                if (size == 0 || *d) {
 102                        test_usage();
 103                        return 1;
 104                }
 105                for (d = argv[2]; *d >= '0' && *d <= '9'; d++) {
 106                        pass *= 10;
 107                        pass += *d - '0';
 108                }
 109                if (*d) {
 110                        test_usage();
 111                        return 1;
 112                }
 113        } else if (argc > 3) {
 114                test_usage();
 115                return 1;
 116        }
 117
 118        size +=  (CACHE_LINE_SIZE - 1);
 119        size &= ~(CACHE_LINE_SIZE - 1);
 120
 121        if (!test_mmu_is_on()) {
 122                test_prepare();
 123        }
 124
 125        test_desc(size);
 126
 127        for (j = 0; !pass || j < pass; j++) {
 128                for (i = 0; i < sizeof(test_pattern) / sizeof(test_pattern[0]);
 129                     i++) {
 130                        res = test_burst_start(size, test_pattern[i]);
 131                        if (res != 0) {
 132                                goto Done;
 133                        }
 134                }
 135
 136                printf ("Iteration #%d passed\n", j + 1);
 137
 138                if (tstc() && 0x03 == getc())
 139                        break;
 140        }
 141Done:
 142        return res;
 143}
 144
 145static void test_prepare (void)
 146{
 147        printf ("\n");
 148
 149        caches_init();
 150        disable_interrupts();
 151        mmu_init();
 152
 153        printf ("Interrupts are disabled\n");
 154        printf ("I-Cache is ON\n");
 155        printf ("D-Cache is ON\n");
 156        printf ("MMU is ON\n");
 157
 158        printf ("\n");
 159
 160        test_map_8M (TEST_PADDR, TEST_VADDR_NC, 0);
 161        test_map_8M (TEST_PADDR, TEST_VADDR_C,  1);
 162
 163        test_map_8M (TEST_FLASH_ADDR & 0xFF800000, TEST_FLASH_ADDR & 0xFF800000, 0);
 164
 165        /* Configure GPIO ports */
 166        signal_init();
 167}
 168
 169static int test_burst_start (unsigned long size, unsigned long pattern)
 170{
 171        volatile unsigned long * vaddr_c = (unsigned long *)TEST_VADDR_C;
 172        volatile unsigned long * vaddr_nc = (unsigned long *)TEST_VADDR_NC;
 173        int i, n;
 174        int res = 1;
 175
 176        printf ("Test pattern %08lx ...", pattern);
 177
 178        n = size / 4;
 179
 180        for (i = 0; i < n; i ++) {
 181                vaddr_c [i] = pattern;
 182        }
 183        signal_start();
 184        flush_dcache_range((unsigned long)vaddr_c, (unsigned long)(vaddr_c + n) - 1);
 185
 186        for (i = 0; i < n; i ++) {
 187                register unsigned long tmp = vaddr_nc [i];
 188                if (tmp != pattern) {
 189                        test_error("2a", vaddr_nc + i, tmp, pattern);
 190                        goto Done;
 191                }
 192        }
 193
 194        for (i = 0; i < n; i ++) {
 195                register unsigned long tmp = vaddr_c [i];
 196                if (tmp != pattern) {
 197                        test_error("2b", vaddr_c + i, tmp, pattern);
 198                        goto Done;
 199                }
 200        }
 201
 202        for (i = 0; i < n; i ++) {
 203                vaddr_nc [i] = pattern;
 204        }
 205
 206        for (i = 0; i < n; i ++) {
 207                register unsigned long tmp = vaddr_nc [i];
 208                if (tmp != pattern) {
 209                        test_error("3a", vaddr_nc + i, tmp, pattern);
 210                        goto Done;
 211                }
 212        }
 213
 214        signal_start();
 215        for (i = 0; i < n; i ++) {
 216                register unsigned long tmp = vaddr_c [i];
 217                if (tmp != pattern) {
 218                        test_error("3b", vaddr_c + i, tmp, pattern);
 219                        goto Done;
 220                }
 221        }
 222
 223        res = 0;
 224Done:
 225        printf(" %s\n", res == 0 ? "OK" : "");
 226
 227        return res;
 228}
 229
 230static void test_map_8M (unsigned long paddr, unsigned long vaddr, int cached)
 231{
 232        mtspr (MD_EPN, (vaddr & 0xFFFFFC00) | MI_EVALID);
 233        mtspr (MD_TWC, MI_PS8MEG | MI_SVALID);
 234        mtspr (MD_RPN, (paddr & 0xFFFFF000) | MI_BOOTINIT | (cached ? 0 : 2));
 235        mtspr (MD_AP, MI_Kp);
 236}
 237
 238static int test_mmu_is_on(void)
 239{
 240        unsigned long msr;
 241
 242        asm volatile("mfmsr %0" : "=r" (msr) :);
 243
 244        return msr & MSR_DR;
 245}
 246
 247static void test_desc(unsigned long size)
 248{
 249        printf(
 250        "The following tests will be conducted:\n"
 251        "1)  Map %ld-byte region of physical RAM at 0x%08x\n"
 252        "    into two virtual regions:\n"
 253        "    one cached at 0x%08x and\n"
 254        "    the the other uncached at 0x%08x.\n",
 255        size, TEST_PADDR, TEST_VADDR_NC, TEST_VADDR_C);
 256
 257        puts(
 258        "2)  Fill the cached region with a pattern, and flush the cache\n"
 259        "2a) Check the uncached region to match the pattern\n"
 260        "2b) Check the cached region to match the pattern\n"
 261        "3)  Fill the uncached region with a pattern\n"
 262        "3a) Check the cached region to match the pattern\n"
 263        "3b) Check the uncached region to match the pattern\n"
 264        "2b) Change the patterns and go to step 2\n"
 265        "\n"
 266        );
 267}
 268
 269static void test_error(
 270        char * step, volatile void * addr, unsigned long val, unsigned long pattern)
 271{
 272        volatile unsigned long * p = (void *)TEST_FLASH_ADDR;
 273
 274        signal_error();
 275
 276        p[0] = (unsigned long)addr;
 277        p[1] = val;
 278        p[2] = pattern;
 279
 280        printf ("\nError at step %s, addr %08lx: read %08lx, pattern %08lx",
 281                step, (unsigned long)addr, val, pattern);
 282}
 283
 284static void signal_init(void)
 285{
 286#if defined(GPIO1_INIT)
 287        GPIO1_INIT;
 288#endif
 289#if defined(GPIO2_INIT)
 290        GPIO2_INIT;
 291#endif
 292}
 293
 294static void signal_start(void)
 295{
 296#if defined(GPIO1_INIT)
 297        if (GPIO1_DAT & GPIO1_BIT) {
 298                GPIO1_DAT &= ~GPIO1_BIT;
 299        } else {
 300                GPIO1_DAT |= GPIO1_BIT;
 301        }
 302#endif
 303}
 304
 305static void signal_error(void)
 306{
 307#if defined(GPIO2_INIT)
 308        if (GPIO2_DAT & GPIO2_BIT) {
 309                GPIO2_DAT &= ~GPIO2_BIT;
 310        } else {
 311                GPIO2_DAT |= GPIO2_BIT;
 312        }
 313#endif
 314}
 315
 316static void test_usage(void)
 317{
 318        printf("Usage: go 0x40004 [size] [count]\n");
 319}
 320