blob: afa1ed28af1e2d399c36c1e3cea43164b19d355f [file] [log] [blame]
David Hendricks2004b932018-03-09 13:58:27 -08001/***********************license start***********************************
2* Copyright (c) 2003-2017 Cavium Inc. (support@cavium.com). All rights
3* reserved.
4*
5*
6* Redistribution and use in source and binary forms, with or without
7* modification, are permitted provided that the following conditions are
8* met:
9*
10* * Redistributions of source code must retain the above copyright
11* notice, this list of conditions and the following disclaimer.
12*
13* * Redistributions in binary form must reproduce the above
14* copyright notice, this list of conditions and the following
15* disclaimer in the documentation and/or other materials provided
16* with the distribution.
17*
18* * Neither the name of Cavium Inc. nor the names of
19* its contributors may be used to endorse or promote products
20* derived from this software without specific prior written
21* permission.
22*
23* This Software, including technical data, may be subject to U.S. export
24* control laws, including the U.S. Export Administration Act and its
25* associated regulations, and may be subject to export or import
26* regulations in other countries.
27*
28* TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29* AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
30* WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT
31* TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
32* REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
33* DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
34* OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
35* PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT,
36* QUIET POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK
37* ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
38***********************license end**************************************/
39#include "bdk.h"
David Hendricks7d48ac52018-03-09 14:30:38 -080040#include <libbdk-hal/bdk-utils.h>
David Hendricks2004b932018-03-09 13:58:27 -080041
42/* Used for all memory reads/writes related to the test */
43#define READ64(address) __bdk_dram_read64(address)
44#define WRITE64(address, data) __bdk_dram_write64(address, data)
45
46/**
47 * Address bus test. This test writes a single value to each power of two in the
48 * area, looking for false aliases that would be created by address lines being
49 * shorted or tied together.
50 *
51 * @param area
52 * @param max_address
53 * @param bursts
54 *
55 * @return
56 */
57int __bdk_dram_test_mem_address_bus(uint64_t area, uint64_t max_address, int bursts)
58{
59 int failures = 0;
60
61 /* Clear our work area. Checking for aliases later could get false
62 positives if it matched stale data */
Jacob Garber4926e982019-07-26 11:45:43 -060063 void *ptr = bdk_phys_to_ptr(area);
David Hendricks2004b932018-03-09 13:58:27 -080064 bdk_zero_memory(ptr, max_address - area);
65 __bdk_dram_flush_to_mem_range(area, max_address);
66
67 /* Each time we write, we'll write this pattern xored the address it is
68 written too */
69 uint64_t pattern = 0x0fedcba987654321;
70
71 /* Walk through the region incrementing our offset by a power of two. The
72 first few writes will be to the same cache line (offset 0x8, 0x10, 0x20,
73 and 0x40. Offset 0x80 and beyond will be to different cache lines */
74 uint64_t offset = 0x8;
75 while (area + offset < max_address)
76 {
77 uint64_t address = area + offset;
78 /* Write one location with pattern xor address */
79 uint64_t p = pattern ^ address;
80 WRITE64(address, p);
81 __bdk_dram_flush_to_mem(address);
82 offset <<= 1;
83 }
84
85 /* Read all of the area to make sure no other locations were written */
86 uint64_t a = area;
87 offset = 0x8;
88 uint64_t next_write = area + offset;
89 while (a < max_address)
90 {
91 if (a + 256 < max_address)
92 BDK_PREFETCH(a + 256, 0);
93 for (int i=0; i<16; i++)
94 {
95 uint64_t data = READ64(a);
96 uint64_t correct;
97 if (a == next_write)
98 {
99 correct = pattern ^ next_write;
100 offset <<= 1;
101 next_write = area + offset;
102 }
103 else
104 correct = 0;
105 if (bdk_unlikely(data != correct))
106 {
107 failures++;
108 __bdk_dram_report_error(a, data, correct, 0, -1);
109 }
110 a += 8;
111 }
112 }
113
114 return failures;
115}
116