David Hendricks | 2004b93 | 2018-03-09 13:58:27 -0800 | [diff] [blame] | 1 | /***********************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 Hendricks | 7d48ac5 | 2018-03-09 14:30:38 -0800 | [diff] [blame] | 40 | #include <libbdk-hal/bdk-utils.h> |
David Hendricks | 2004b93 | 2018-03-09 13:58:27 -0800 | [diff] [blame] | 41 | |
| 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 | */ |
| 57 | int __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 Garber | 4926e98 | 2019-07-26 11:45:43 -0600 | [diff] [blame] | 63 | void *ptr = bdk_phys_to_ptr(area); |
David Hendricks | 2004b93 | 2018-03-09 13:58:27 -0800 | [diff] [blame] | 64 | 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 | |