diff options
author | Mike Frysinger <vapier@gentoo.org> | 2010-05-04 00:14:08 -0400 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2010-05-22 14:19:10 -0400 |
commit | c70dcabc8eba18113a4735e7b1bd09f7493e38f0 (patch) | |
tree | 80f2ca9f649b05b2bf0de3027061664db8454748 /arch/blackfin | |
parent | 479ba6035862a9c08ce4351c7fff8926fde4ede5 (diff) |
Blackfin: isram: clean up ITEST_COMMAND macro and improve the selftests
The IADDR2DTEST() macro had some duplicated logic with bit 11 and some
incorrect comments, so scrub all of that.
In order to verify these aren't a problem (and won't be in the future),
extend the self tests to operate on as much L1 SRAM as possible.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin')
-rw-r--r-- | arch/blackfin/mm/isram-driver.c | 94 |
1 files changed, 51 insertions, 43 deletions
diff --git a/arch/blackfin/mm/isram-driver.c b/arch/blackfin/mm/isram-driver.c index 39b058564f62..7e2e674ed444 100644 --- a/arch/blackfin/mm/isram-driver.c +++ b/arch/blackfin/mm/isram-driver.c | |||
@@ -43,13 +43,12 @@ static DEFINE_SPINLOCK(dtest_lock); | |||
43 | /* Takes a void pointer */ | 43 | /* Takes a void pointer */ |
44 | #define IADDR2DTEST(x) \ | 44 | #define IADDR2DTEST(x) \ |
45 | ({ unsigned long __addr = (unsigned long)(x); \ | 45 | ({ unsigned long __addr = (unsigned long)(x); \ |
46 | (__addr & 0x47F8) | /* address bits 14 & 10:3 */ \ | 46 | ((__addr & (1 << 11)) << (26 - 11)) | /* addr bit 11 (Way0/Way1) */ \ |
47 | (__addr & 0x8000) << 23 | /* Bank A/B */ \ | 47 | (1 << 24) | /* instruction access = 1 */ \ |
48 | (__addr & 0x0800) << 15 | /* address bit 11 */ \ | 48 | ((__addr & (1 << 15)) << (23 - 15)) | /* addr bit 15 (Data Bank) */ \ |
49 | (__addr & 0x3000) << 4 | /* address bits 13:12 */ \ | 49 | ((__addr & (3 << 12)) << (16 - 12)) | /* addr bits 13:12 (Subbank) */ \ |
50 | (__addr & 0x8000) << 8 | /* address bit 15 */ \ | 50 | (__addr & 0x47F8) | /* addr bits 14 & 10:3 */ \ |
51 | (0x1000000) | /* instruction access = 1 */ \ | 51 | (1 << 2); /* data array = 1 */ \ |
52 | (0x4); /* data array = 1 */ \ | ||
53 | }) | 52 | }) |
54 | 53 | ||
55 | /* Takes a pointer, and returns the offset (in bits) which things should be shifted */ | 54 | /* Takes a pointer, and returns the offset (in bits) which things should be shifted */ |
@@ -196,7 +195,7 @@ EXPORT_SYMBOL(isram_memcpy); | |||
196 | 195 | ||
197 | #ifdef CONFIG_BFIN_ISRAM_SELF_TEST | 196 | #ifdef CONFIG_BFIN_ISRAM_SELF_TEST |
198 | 197 | ||
199 | #define TEST_LEN 0x100 | 198 | static int test_len = 0x20000; |
200 | 199 | ||
201 | static __init void hex_dump(unsigned char *buf, int len) | 200 | static __init void hex_dump(unsigned char *buf, int len) |
202 | { | 201 | { |
@@ -212,15 +211,15 @@ static __init int isram_read_test(char *sdram, void *l1inst) | |||
212 | pr_info("INFO: running isram_read tests\n"); | 211 | pr_info("INFO: running isram_read tests\n"); |
213 | 212 | ||
214 | /* setup some different data to play with */ | 213 | /* setup some different data to play with */ |
215 | for (i = 0; i < TEST_LEN; ++i) | 214 | for (i = 0; i < test_len; ++i) |
216 | sdram[i] = i; | 215 | sdram[i] = i % 255; |
217 | dma_memcpy(l1inst, sdram, TEST_LEN); | 216 | dma_memcpy(l1inst, sdram, test_len); |
218 | 217 | ||
219 | /* make sure we can read the L1 inst */ | 218 | /* make sure we can read the L1 inst */ |
220 | for (i = 0; i < TEST_LEN; i += sizeof(uint64_t)) { | 219 | for (i = 0; i < test_len; i += sizeof(uint64_t)) { |
221 | data1 = isram_read(l1inst + i); | 220 | data1 = isram_read(l1inst + i); |
222 | memcpy(&data2, sdram + i, sizeof(data2)); | 221 | memcpy(&data2, sdram + i, sizeof(data2)); |
223 | if (memcmp(&data1, &data2, sizeof(uint64_t))) { | 222 | if (data1 != data2) { |
224 | pr_err("FAIL: isram_read(%p) returned %#llx but wanted %#llx\n", | 223 | pr_err("FAIL: isram_read(%p) returned %#llx but wanted %#llx\n", |
225 | l1inst + i, data1, data2); | 224 | l1inst + i, data1, data2); |
226 | ++ret; | 225 | ++ret; |
@@ -238,25 +237,25 @@ static __init int isram_write_test(char *sdram, void *l1inst) | |||
238 | pr_info("INFO: running isram_write tests\n"); | 237 | pr_info("INFO: running isram_write tests\n"); |
239 | 238 | ||
240 | /* setup some different data to play with */ | 239 | /* setup some different data to play with */ |
241 | memset(sdram, 0, TEST_LEN * 2); | 240 | memset(sdram, 0, test_len * 2); |
242 | dma_memcpy(l1inst, sdram, TEST_LEN); | 241 | dma_memcpy(l1inst, sdram, test_len); |
243 | for (i = 0; i < TEST_LEN; ++i) | 242 | for (i = 0; i < test_len; ++i) |
244 | sdram[i] = i; | 243 | sdram[i] = i % 255; |
245 | 244 | ||
246 | /* make sure we can write the L1 inst */ | 245 | /* make sure we can write the L1 inst */ |
247 | for (i = 0; i < TEST_LEN; i += sizeof(uint64_t)) { | 246 | for (i = 0; i < test_len; i += sizeof(uint64_t)) { |
248 | memcpy(&data1, sdram + i, sizeof(data1)); | 247 | memcpy(&data1, sdram + i, sizeof(data1)); |
249 | isram_write(l1inst + i, data1); | 248 | isram_write(l1inst + i, data1); |
250 | data2 = isram_read(l1inst + i); | 249 | data2 = isram_read(l1inst + i); |
251 | if (memcmp(&data1, &data2, sizeof(uint64_t))) { | 250 | if (data1 != data2) { |
252 | pr_err("FAIL: isram_write(%p, %#llx) != %#llx\n", | 251 | pr_err("FAIL: isram_write(%p, %#llx) != %#llx\n", |
253 | l1inst + i, data1, data2); | 252 | l1inst + i, data1, data2); |
254 | ++ret; | 253 | ++ret; |
255 | } | 254 | } |
256 | } | 255 | } |
257 | 256 | ||
258 | dma_memcpy(sdram + TEST_LEN, l1inst, TEST_LEN); | 257 | dma_memcpy(sdram + test_len, l1inst, test_len); |
259 | if (memcmp(sdram, sdram + TEST_LEN, TEST_LEN)) { | 258 | if (memcmp(sdram, sdram + test_len, test_len)) { |
260 | pr_err("FAIL: isram_write() did not work properly\n"); | 259 | pr_err("FAIL: isram_write() did not work properly\n"); |
261 | ++ret; | 260 | ++ret; |
262 | } | 261 | } |
@@ -268,12 +267,12 @@ static __init int | |||
268 | _isram_memcpy_test(char pattern, void *sdram, void *l1inst, const char *smemcpy, | 267 | _isram_memcpy_test(char pattern, void *sdram, void *l1inst, const char *smemcpy, |
269 | void *(*fmemcpy)(void *, const void *, size_t)) | 268 | void *(*fmemcpy)(void *, const void *, size_t)) |
270 | { | 269 | { |
271 | memset(sdram, pattern, TEST_LEN); | 270 | memset(sdram, pattern, test_len); |
272 | fmemcpy(l1inst, sdram, TEST_LEN); | 271 | fmemcpy(l1inst, sdram, test_len); |
273 | fmemcpy(sdram + TEST_LEN, l1inst, TEST_LEN); | 272 | fmemcpy(sdram + test_len, l1inst, test_len); |
274 | if (memcmp(sdram, sdram + TEST_LEN, TEST_LEN)) { | 273 | if (memcmp(sdram, sdram + test_len, test_len)) { |
275 | pr_err("FAIL: %s(%p <=> %p, %#x) failed (data is %#x)\n", | 274 | pr_err("FAIL: %s(%p <=> %p, %#x) failed (data is %#x)\n", |
276 | smemcpy, l1inst, sdram, TEST_LEN, pattern); | 275 | smemcpy, l1inst, sdram, test_len, pattern); |
277 | return 1; | 276 | return 1; |
278 | } | 277 | } |
279 | return 0; | 278 | return 0; |
@@ -292,12 +291,13 @@ static __init int isram_memcpy_test(char *sdram, void *l1inst) | |||
292 | /* check read of small, unaligned, and hardware 64bit limits */ | 291 | /* check read of small, unaligned, and hardware 64bit limits */ |
293 | pr_info("INFO: running isram_memcpy (read) tests\n"); | 292 | pr_info("INFO: running isram_memcpy (read) tests\n"); |
294 | 293 | ||
295 | for (i = 0; i < TEST_LEN; ++i) | 294 | /* setup some different data to play with */ |
296 | sdram[i] = i; | 295 | for (i = 0; i < test_len; ++i) |
297 | dma_memcpy(l1inst, sdram, TEST_LEN); | 296 | sdram[i] = i % 255; |
297 | dma_memcpy(l1inst, sdram, test_len); | ||
298 | 298 | ||
299 | thisret = 0; | 299 | thisret = 0; |
300 | for (i = 0; i < TEST_LEN - 32; ++i) { | 300 | for (i = 0; i < test_len - 32; ++i) { |
301 | unsigned char cmp[32]; | 301 | unsigned char cmp[32]; |
302 | for (j = 1; j <= 32; ++j) { | 302 | for (j = 1; j <= 32; ++j) { |
303 | memset(cmp, 0, sizeof(cmp)); | 303 | memset(cmp, 0, sizeof(cmp)); |
@@ -310,7 +310,7 @@ static __init int isram_memcpy_test(char *sdram, void *l1inst) | |||
310 | pr_cont("\n"); | 310 | pr_cont("\n"); |
311 | if (++thisret > 20) { | 311 | if (++thisret > 20) { |
312 | pr_err("FAIL: skipping remaining series\n"); | 312 | pr_err("FAIL: skipping remaining series\n"); |
313 | i = TEST_LEN; | 313 | i = test_len; |
314 | break; | 314 | break; |
315 | } | 315 | } |
316 | } | 316 | } |
@@ -321,11 +321,11 @@ static __init int isram_memcpy_test(char *sdram, void *l1inst) | |||
321 | /* check write of small, unaligned, and hardware 64bit limits */ | 321 | /* check write of small, unaligned, and hardware 64bit limits */ |
322 | pr_info("INFO: running isram_memcpy (write) tests\n"); | 322 | pr_info("INFO: running isram_memcpy (write) tests\n"); |
323 | 323 | ||
324 | memset(sdram + TEST_LEN, 0, TEST_LEN); | 324 | memset(sdram + test_len, 0, test_len); |
325 | dma_memcpy(l1inst, sdram + TEST_LEN, TEST_LEN); | 325 | dma_memcpy(l1inst, sdram + test_len, test_len); |
326 | 326 | ||
327 | thisret = 0; | 327 | thisret = 0; |
328 | for (i = 0; i < TEST_LEN - 32; ++i) { | 328 | for (i = 0; i < test_len - 32; ++i) { |
329 | unsigned char cmp[32]; | 329 | unsigned char cmp[32]; |
330 | for (j = 1; j <= 32; ++j) { | 330 | for (j = 1; j <= 32; ++j) { |
331 | isram_memcpy(l1inst + i, sdram + i, j); | 331 | isram_memcpy(l1inst + i, sdram + i, j); |
@@ -338,7 +338,7 @@ static __init int isram_memcpy_test(char *sdram, void *l1inst) | |||
338 | pr_cont("\n"); | 338 | pr_cont("\n"); |
339 | if (++thisret > 20) { | 339 | if (++thisret > 20) { |
340 | pr_err("FAIL: skipping remaining series\n"); | 340 | pr_err("FAIL: skipping remaining series\n"); |
341 | i = TEST_LEN; | 341 | i = test_len; |
342 | break; | 342 | break; |
343 | } | 343 | } |
344 | } | 344 | } |
@@ -355,22 +355,30 @@ static __init int isram_test_init(void) | |||
355 | char *sdram; | 355 | char *sdram; |
356 | void *l1inst; | 356 | void *l1inst; |
357 | 357 | ||
358 | sdram = kmalloc(TEST_LEN * 2, GFP_KERNEL); | 358 | /* Try to test as much of L1SRAM as possible */ |
359 | if (!sdram) { | 359 | while (test_len) { |
360 | pr_warning("SKIP: could not allocate sdram\n"); | 360 | test_len >>= 1; |
361 | return 0; | 361 | l1inst = l1_inst_sram_alloc(test_len); |
362 | if (l1inst) | ||
363 | break; | ||
362 | } | 364 | } |
363 | |||
364 | l1inst = l1_inst_sram_alloc(TEST_LEN); | ||
365 | if (!l1inst) { | 365 | if (!l1inst) { |
366 | kfree(sdram); | ||
367 | pr_warning("SKIP: could not allocate L1 inst\n"); | 366 | pr_warning("SKIP: could not allocate L1 inst\n"); |
368 | return 0; | 367 | return 0; |
369 | } | 368 | } |
369 | pr_info("INFO: testing %#x bytes (%p - %p)\n", | ||
370 | test_len, l1inst, l1inst + test_len); | ||
371 | |||
372 | sdram = kmalloc(test_len * 2, GFP_KERNEL); | ||
373 | if (!sdram) { | ||
374 | sram_free(l1inst); | ||
375 | pr_warning("SKIP: could not allocate sdram\n"); | ||
376 | return 0; | ||
377 | } | ||
370 | 378 | ||
371 | /* sanity check initial L1 inst state */ | 379 | /* sanity check initial L1 inst state */ |
372 | ret = 1; | 380 | ret = 1; |
373 | pr_info("INFO: running initial dma_memcpy checks\n"); | 381 | pr_info("INFO: running initial dma_memcpy checks %p\n", sdram); |
374 | if (_isram_memcpy_test(0xa, sdram, l1inst, dma_memcpy)) | 382 | if (_isram_memcpy_test(0xa, sdram, l1inst, dma_memcpy)) |
375 | goto abort; | 383 | goto abort; |
376 | if (_isram_memcpy_test(0x5, sdram, l1inst, dma_memcpy)) | 384 | if (_isram_memcpy_test(0x5, sdram, l1inst, dma_memcpy)) |