uboot/examples/standalone/test_burst.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2005
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 *
   7 * The test exercises SDRAM accesses in burst mode
   8 */
   9
  10#include <common.h>
  11#include <exports.h>
  12
  13#include <commproc.h>
  14#include <asm/mmu.h>
  15#include <asm/processor.h>
  16
  17#include <serial.h>
  18#include <watchdog.h>
  19
  20#include "test_burst.h"
  21
  22/* 8 MB test region of physical RAM */
  23#define TEST_PADDR      0x00800000
  24/* The uncached virtual region */
  25#define TEST_VADDR_NC   0x00800000
  26/* The cached virtual region */
  27#define TEST_VADDR_C    0x01000000
  28/* When an error is detected, the address where the error has been found,
  29   and also the current and the expected data will be written to
  30   the following flash address
  31*/
  32#define TEST_FLASH_ADDR 0x40100000
  33
  34static void test_prepare (void);
  35static int test_burst_start (unsigned long size, unsigned long pattern);
  36static void test_map_8M (unsigned long paddr, unsigned long vaddr, int cached);
  37static int test_mmu_is_on(void);
  38static void test_desc(unsigned long size);
  39static void test_error(char * step, volatile void * addr, unsigned long val, unsigned long pattern);
  40static void signal_init(void);
  41static void signal_start(void);
  42static void signal_error(void);
  43static void test_usage(void);
  44
  45static unsigned long test_pattern [] = {
  46        0x00000000,
  47        0xffffffff,
  48        0x55555555,
  49        0xaaaaaaaa,
  50};
  51
  52
  53int test_burst (int argc, char * const argv[])
  54{
  55        unsigned long size = CACHE_LINE_SIZE;
  56        unsigned int pass = 0;
  57        int res = 0;
  58        int i, j;
  59
  60        if (argc == 3) {
  61                char * d;
  62                for (size = 0, d = argv[1]; *d >= '0' && *d <= '9'; d++) {
  63                        size *= 10;
  64                        size += *d - '0';
  65                }
  66                if (size == 0 || *d) {
  67                        test_usage();
  68                        return 1;
  69                }
  70                for (d = argv[2]; *d >= '0' && *d <= '9'; d++) {
  71                        pass *= 10;
  72                        pass += *d - '0';
  73                }
  74                if (*d) {
  75                        test_usage();
  76                        return 1;
  77                }
  78        } else if (argc > 3) {
  79                test_usage();
  80                return 1;
  81        }
  82
  83        size +=  (CACHE_LINE_SIZE - 1);
  84        size &= ~(CACHE_LINE_SIZE - 1);
  85
  86        if (!test_mmu_is_on()) {
  87                test_prepare();
  88        }
  89
  90        test_desc(size);
  91
  92        for (j = 0; !pass || j < pass; j++) {
  93                for (i = 0; i < sizeof(test_pattern) / sizeof(test_pattern[0]);
  94                     i++) {
  95                        res = test_burst_start(size, test_pattern[i]);
  96                        if (res != 0) {
  97                                goto Done;
  98                        }
  99                }
 100
 101                printf ("Iteration #%d passed\n", j + 1);
 102
 103                if (tstc() && 0x03 == getc())
 104                        break;
 105        }
 106Done:
 107        return res;
 108}
 109
 110static void test_prepare (void)
 111{
 112        printf ("\n");
 113
 114        caches_init();
 115        disable_interrupts();
 116        mmu_init();
 117
 118        printf ("Interrupts are disabled\n");
 119        printf ("I-Cache is ON\n");
 120        printf ("D-Cache is ON\n");
 121        printf ("MMU is ON\n");
 122
 123        printf ("\n");
 124
 125        test_map_8M (TEST_PADDR, TEST_VADDR_NC, 0);
 126        test_map_8M (TEST_PADDR, TEST_VADDR_C,  1);
 127
 128        test_map_8M (TEST_FLASH_ADDR & 0xFF800000, TEST_FLASH_ADDR & 0xFF800000, 0);
 129
 130        /* Configure GPIO ports */
 131        signal_init();
 132}
 133
 134static int test_burst_start (unsigned long size, unsigned long pattern)
 135{
 136        volatile unsigned long * vaddr_c = (unsigned long *)TEST_VADDR_C;
 137        volatile unsigned long * vaddr_nc = (unsigned long *)TEST_VADDR_NC;
 138        int i, n;
 139        int res = 1;
 140
 141        printf ("Test pattern %08lx ...", pattern);
 142
 143        n = size / 4;
 144
 145        for (i = 0; i < n; i ++) {
 146                vaddr_c [i] = pattern;
 147        }
 148        signal_start();
 149        flush_dcache_range((unsigned long)vaddr_c, (unsigned long)(vaddr_c + n) - 1);
 150
 151        for (i = 0; i < n; i ++) {
 152                register unsigned long tmp = vaddr_nc [i];
 153                if (tmp != pattern) {
 154                        test_error("2a", vaddr_nc + i, tmp, pattern);
 155                        goto Done;
 156                }
 157        }
 158
 159        for (i = 0; i < n; i ++) {
 160                register unsigned long tmp = vaddr_c [i];
 161                if (tmp != pattern) {
 162                        test_error("2b", vaddr_c + i, tmp, pattern);
 163                        goto Done;
 164                }
 165        }
 166
 167        for (i = 0; i < n; i ++) {
 168                vaddr_nc [i] = pattern;
 169        }
 170
 171        for (i = 0; i < n; i ++) {
 172                register unsigned long tmp = vaddr_nc [i];
 173                if (tmp != pattern) {
 174                        test_error("3a", vaddr_nc + i, tmp, pattern);
 175                        goto Done;
 176                }
 177        }
 178
 179        signal_start();
 180        for (i = 0; i < n; i ++) {
 181                register unsigned long tmp = vaddr_c [i];
 182                if (tmp != pattern) {
 183                        test_error("3b", vaddr_c + i, tmp, pattern);
 184                        goto Done;
 185                }
 186        }
 187
 188        res = 0;
 189Done:
 190        printf(" %s\n", res == 0 ? "OK" : "");
 191
 192        return res;
 193}
 194
 195static void test_map_8M (unsigned long paddr, unsigned long vaddr, int cached)
 196{
 197        mtspr (MD_EPN, (vaddr & 0xFFFFFC00) | MI_EVALID);
 198        mtspr (MD_TWC, MI_PS8MEG | MI_SVALID);
 199        mtspr (MD_RPN, (paddr & 0xFFFFF000) | MI_BOOTINIT | (cached ? 0 : 2));
 200        mtspr (MD_AP, MI_Kp);
 201}
 202
 203static int test_mmu_is_on(void)
 204{
 205        unsigned long msr;
 206
 207        asm volatile("mfmsr %0" : "=r" (msr) :);
 208
 209        return msr & MSR_DR;
 210}
 211
 212static void test_desc(unsigned long size)
 213{
 214        printf(
 215        "The following tests will be conducted:\n"
 216        "1)  Map %ld-byte region of physical RAM at 0x%08x\n"
 217        "    into two virtual regions:\n"
 218        "    one cached at 0x%08x and\n"
 219        "    the the other uncached at 0x%08x.\n",
 220        size, TEST_PADDR, TEST_VADDR_NC, TEST_VADDR_C);
 221
 222        puts(
 223        "2)  Fill the cached region with a pattern, and flush the cache\n"
 224        "2a) Check the uncached region to match the pattern\n"
 225        "2b) Check the cached region to match the pattern\n"
 226        "3)  Fill the uncached region with a pattern\n"
 227        "3a) Check the cached region to match the pattern\n"
 228        "3b) Check the uncached region to match the pattern\n"
 229        "2b) Change the patterns and go to step 2\n"
 230        "\n"
 231        );
 232}
 233
 234static void test_error(
 235        char * step, volatile void * addr, unsigned long val, unsigned long pattern)
 236{
 237        volatile unsigned long * p = (void *)TEST_FLASH_ADDR;
 238
 239        signal_error();
 240
 241        p[0] = (unsigned long)addr;
 242        p[1] = val;
 243        p[2] = pattern;
 244
 245        printf ("\nError at step %s, addr %08lx: read %08lx, pattern %08lx",
 246                step, (unsigned long)addr, val, pattern);
 247}
 248
 249static void signal_init(void)
 250{
 251#if defined(GPIO1_INIT)
 252        GPIO1_INIT;
 253#endif
 254#if defined(GPIO2_INIT)
 255        GPIO2_INIT;
 256#endif
 257}
 258
 259static void signal_start(void)
 260{
 261#if defined(GPIO1_INIT)
 262        if (GPIO1_DAT & GPIO1_BIT) {
 263                GPIO1_DAT &= ~GPIO1_BIT;
 264        } else {
 265                GPIO1_DAT |= GPIO1_BIT;
 266        }
 267#endif
 268}
 269
 270static void signal_error(void)
 271{
 272#if defined(GPIO2_INIT)
 273        if (GPIO2_DAT & GPIO2_BIT) {
 274                GPIO2_DAT &= ~GPIO2_BIT;
 275        } else {
 276                GPIO2_DAT |= GPIO2_BIT;
 277        }
 278#endif
 279}
 280
 281static void test_usage(void)
 282{
 283        printf("Usage: go 0x40004 [size] [count]\n");
 284}
 285