llsc4.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:24k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* 
  2.  *
  3.  * This file is subject to the terms and conditions of the GNU General Public
  4.  * License.  See the file "COPYING" in the main directory of this archive
  5.  * for more details.
  6.  *
  7.  * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
  8.  */
  9. #include <linux/config.h>
  10. #include <linux/kernel.h>
  11. #include <linux/sched.h>
  12. #include <linux/init.h>
  13. #include <linux/interrupt.h>
  14. #include <linux/smp.h>
  15. #include <linux/kernel_stat.h>
  16. #include <linux/mm.h>
  17. #include <linux/delay.h>
  18. #include <linux/string.h>
  19. #include <linux/efi.h>
  20. #include <asm/page.h>
  21. #include <linux/threads.h>
  22. #include <asm/sn/simulator.h>
  23. #include <asm/sn/leds.h>
  24. #include "llsc4.h"
  25. #ifdef STANDALONE
  26. #include "lock.h"
  27. #endif
  28. #ifdef INTTEST
  29. static int inttest=0;
  30. #endif
  31. #ifdef IA64_SEMFIX_INSN
  32. #undef IA64_SEMFIX_INSN
  33. #endif
  34. #ifdef IA64_SEMFIX
  35. #undef IA64_SEMFIX
  36. #endif
  37. # define IA64_SEMFIX_INSN
  38. # define IA64_SEMFIX    ""
  39. #define NOLOCK 0xdead
  40. #define BGUARD(linei) (0xbbbb0000 | (linei));
  41. #define EGUARD(linei) (0xeeee0000 | (linei));
  42. #define GUARDLINE(v) ((v)&0xffff)
  43. /*
  44.  * Test parameter table for AUTOTEST
  45.  */
  46. typedef struct {
  47. int passes;
  48. int linecount;
  49. int linepad;
  50. } autotest_table_t;
  51. autotest_table_t autotest_table[] = {
  52. {50000000, 2, 0x2b4 },
  53. {50000000, 16, 0, },
  54. {50000000, 16, 4, },
  55. {50000000, 128, 0x44 },
  56. {50000000, 128, 0x84 },
  57. {50000000, 128, 0x200 },
  58. {50000000, 128, 0x204 },
  59. {50000000, 128, 0x2b4 },
  60. {50000000, 2, 8*MB+0x2b4 },
  61. {50000000, 16, 8*MB+0 },
  62. {50000000, 16, 8*MB+4 },
  63. {50000000, 128, 8*MB+0x44 },
  64. {50000000, 128, 8*MB+0x84 },
  65. {50000000, 128, 8*MB+0x200 },
  66. {50000000, 128, 8*MB+0x204 },
  67. {50000000, 128, 8*MB+0x2b4 },
  68. {0}};
  69. /*
  70.  * Array of virtual addresses available for test purposes.
  71.  */
  72. typedef struct {
  73. long vstart;
  74. long vend;
  75. long nextaddr;
  76. long nextinit;
  77. int wrapcount;
  78. } memmap_t;
  79. #define MAPCHUNKS 128
  80. memmap_t  memmap[MAPCHUNKS];
  81. int memmapx=0;
  82. typedef struct {
  83. void *addr;
  84. long data[16];
  85. long data_fc[16];
  86. } capture_line_t;
  87. typedef struct {
  88. int size;
  89. void *blockaddr;
  90. void *shadaddr;
  91. long blockdata[48];
  92. long shaddata[48];
  93. long blockdata_fc[48];
  94. long shaddata_fc[48];
  95. long synerr;
  96. } capture_t;
  97. /*
  98.  * PORTING NOTE: revisit this statement. On hardware we put mbase at 0 and
  99.  * the rest of the tables have to start at 1MB to skip PROM tables.
  100.  */
  101. #define THREADPRIVATESZ() ((sizeof(threadprivate_t)+511)/512*512)
  102. #define THREADPRIVATE(t) ((threadprivate_t*)(((long)mbase)+4096+t*THREADPRIVATESZ()))
  103. #define k_capture mbase->sk_capture
  104. #define k_go mbase->sk_go
  105. #define k_linecount mbase->sk_linecount
  106. #define k_passes mbase->sk_passes
  107. #define k_napticks mbase->sk_napticks
  108. #define k_stop_on_error mbase->sk_stop_on_error
  109. #define k_verbose mbase->sk_verbose
  110. #define k_threadprivate mbase->sk_threadprivate
  111. #define k_blocks mbase->sk_blocks
  112. #define k_iter_msg mbase->sk_iter_msg
  113. #define k_vv mbase->sk_vv
  114. #define k_linepad mbase->sk_linepad
  115. #define k_options mbase->sk_options
  116. #define k_testnumber mbase->sk_testnumber
  117. #define k_currentpass mbase->sk_currentpass
  118. static long blocks[MAX_LINECOUNT]; /* addresses of data blocks */
  119. static control_t *mbase;
  120. static vint initialized=0;
  121. static unsigned int ran_conf_llsc(int);
  122. static int  rerr(capture_t *, char *, void *, void *, int, int, int, int, int, int);
  123. static void dumpline(void *, char *, char *, void *, void *, int);
  124. static int  checkstop(int, int, uint);
  125. static void spin(int);
  126. static void capturedata(capture_t *, uint, void *, void *, int);
  127. static int  randn(uint max, uint *seed);
  128. static uint zrandom (uint *zranseed);
  129. static int  set_lock(uint *, uint);
  130. static int  clr_lock(uint *, uint);
  131. static void Speedo(void);
  132. int autotest_enabled=0;
  133. static int llsctest_number=-1;
  134. static int errstop_enabled=0;
  135. static int fail_enabled=0;
  136. static int l4_opt=0;
  137. static int selective_trigger=0;
  138. static int dump_block_addrs_opt=0;
  139. static lock_t errlock=NOLOCK;
  140. static private_t init_private[LLSC_MAXCPUS];
  141. static int __init autotest_enable(char *str)
  142. {
  143.         autotest_enabled = 1;
  144. return 1;
  145. }
  146. static int __init set_llscblkadr(char *str)
  147. {
  148. dump_block_addrs_opt = 1;
  149. return 1;
  150. }
  151. static int __init set_llscselt(char *str)
  152. {
  153. selective_trigger = 1;
  154. return 1;
  155. }
  156. static int __init set_llsctest(char *str)
  157. {
  158.         llsctest_number = simple_strtol(str, &str, 10);
  159. if (llsctest_number < 0 || llsctest_number > 15)
  160. llsctest_number = -1;
  161. return 1;
  162. }
  163. static int __init set_llscerrstop(char *str)
  164. {
  165.         errstop_enabled = 1;
  166. return 1;
  167. }
  168. static int __init set_llscfail(char *str)
  169. {
  170.         fail_enabled = 8;
  171. return 1;
  172. }
  173. static int __init set_llscl4(char *str)
  174. {
  175.         l4_opt = 1;
  176. return 1;
  177. }
  178. static void print_params(void)
  179. {
  180. printk ("********* Enter AUTOTEST facility on master cpu *************n");
  181. printk ("  Test options:n");
  182. printk ("     llsctest=<n>t%dtTest number to run (all = -1)n", llsctest_number);
  183. printk ("     llscerrstop t%stStop on errorn", errstop_enabled ? "on" : "off");
  184. printk ("     llscfail    t%stForce a failure to test the trigger & error messagesn", fail_enabled ? "on" : "off");
  185. printk ("     llscselt    t%stSelective triger on failuresn", selective_trigger ? "on" : "off");
  186. printk ("     llscblkadr  t%stDump data block addressesn", dump_block_addrs_opt ? "on" : "off");
  187. printk ("     llscl4      t%stRun only tests that evict from L4n", l4_opt ? "on" : "off");
  188. printk ("  SEMFIX: %sn", IA64_SEMFIX);
  189. printk ("n");
  190. }
  191. __setup("autotest", autotest_enable);
  192. __setup("llsctest=", set_llsctest);
  193. __setup("llscerrstop", set_llscerrstop);
  194. __setup("llscfail", set_llscfail);
  195. __setup("llscselt", set_llscselt);
  196. __setup("llscblkadr", set_llscblkadr);
  197. __setup("llscl4", set_llscl4);
  198. static inline int
  199. set_lock(uint *lock, uint id)
  200. {
  201. uint old;
  202. old = cmpxchg_acq(lock, NOLOCK, id);
  203. return (old == NOLOCK);
  204. }
  205. static inline int
  206. clr_lock(uint *lock, uint id)
  207. {
  208. uint old;
  209. old = cmpxchg_rel(lock, id, NOLOCK);
  210. return (old == id);
  211. }
  212. static inline void
  213. init_lock(uint *lock)
  214. {
  215. *lock = NOLOCK;
  216. }
  217. /*------------------------------------------------------------------------+
  218. | Routine  :  ran_conf_llsc - ll/sc shared data test                      |
  219. | Description: This test checks the coherency of shared data              |
  220. +------------------------------------------------------------------------*/
  221. static unsigned int
  222. ran_conf_llsc(int thread)
  223. {
  224. private_t pval;
  225. share_t sval, sval2;
  226. uint vv, linei, slinei, sharei, pass;
  227. long t;
  228. lock_t lockpat;
  229. share_t *sharecopy;
  230. long verbose, napticks, passes, linecount, lcount;
  231. dataline_t *linep, *slinep;
  232. int s, seed;
  233. threadprivate_t *tp;
  234. uint iter_msg, iter_msg_i=0;
  235. int vv_mask;
  236. int correct_errors;
  237. int errs=0;
  238. int stillbad;
  239. capture_t capdata;
  240. private_t *privp;
  241. share_t *sharep;
  242. linecount = k_linecount;
  243. napticks = k_napticks;
  244. verbose = k_verbose;
  245. passes = k_passes;
  246. iter_msg = k_iter_msg;
  247. seed = (thread + 1) * 647;
  248. tp = THREADPRIVATE(thread);
  249. vv_mask = (k_vv>>((thread%16)*4)) & 0xf;
  250. correct_errors = k_options&0xff;
  251. memset (&capdata, 0, sizeof(capdata));
  252. for (linei=0; linei<linecount; linei++)
  253. tp->private[linei] = thread;
  254. for (pass = 1; passes == 0 || pass < passes; pass++) {
  255. lockpat = (pass & 0x0fffffff) + (thread <<28);
  256. if (lockpat == NOLOCK)
  257. continue;
  258. tp->threadpasses = pass;
  259. if (checkstop(thread, pass, lockpat))
  260. return 0;
  261. iter_msg_i++;
  262. if (iter_msg && iter_msg_i > iter_msg) {
  263. printk("Thread %d, Pass %dn", thread, pass);
  264. iter_msg_i = 0;
  265. }
  266. lcount = 0;
  267. /*
  268.  * Select line to perform operations on.
  269.  */
  270. linei = randn(linecount, &seed);
  271. sharei = randn(2, &seed);
  272. slinei = (linei + (linecount/2))%linecount; /* I dont like this - fix later */
  273. linep = (dataline_t *)blocks[linei];
  274. slinep = (dataline_t *)blocks[slinei];
  275. if (sharei == 0)
  276. sharecopy = &slinep->share0;
  277. else
  278. sharecopy = &slinep->share1;
  279. vv = randn(4, &seed);
  280. if ((vv_mask & (1<<vv)) == 0)
  281. continue;
  282. if (napticks) {
  283. t = randn(napticks, &seed);
  284. udelay(t);
  285. }
  286. privp = &linep->private[thread];
  287. sharep = &linep->share[sharei];
  288. switch(vv) {
  289. case 0:
  290. /* Read and verify private count on line. */
  291. pval = *privp;
  292. if (verbose)
  293. printk("Line:%3d, Thread:%d:%d. Val: %xn", linei, thread, vv, tp->private[linei]);
  294. if (pval != tp->private[linei]) {
  295. capturedata(&capdata, pass, privp, NULL, sizeof(*privp));
  296. stillbad = (*privp != tp->private[linei]);
  297. if (rerr(&capdata, "Private count", linep, slinep, thread, pass, linei, tp->private[linei], pval, stillbad)) {
  298. return 1;
  299. }
  300. if (correct_errors) {
  301. tp->private[linei] = *privp;
  302. }
  303. errs++;
  304. }
  305. break;
  306. case 1:
  307. /* Read, verify, and increment private count on line. */
  308. pval = *privp;
  309. if (verbose)
  310. printk("Line:%3d, Thread:%d:%d. Val: %xn", linei, thread, vv, tp->private[linei]);
  311. if (pval != tp->private[linei]) {
  312. capturedata(&capdata, pass, privp, NULL, sizeof(*privp));
  313. stillbad = (*privp != tp->private[linei]);
  314. if (rerr(&capdata, "Private count & inc", linep, slinep, thread, pass, linei, tp->private[linei], pval, stillbad)) {
  315. return 1;
  316. }
  317. errs++;
  318. }
  319. pval = (pval==255) ? 0 : pval+1;
  320. *privp = pval;
  321. tp->private[linei] = pval;
  322. break;
  323. case 2:
  324. /* Lock line, read and verify shared data. */
  325. if (verbose)
  326. printk("Line:%3d, Thread:%d:%d. Val: %xn", linei, thread, vv, *sharecopy);
  327. lcount = 0;
  328. while (LOCK(sharei) != 1) {
  329. if (checkstop(thread, pass, lockpat))
  330. return 0;
  331. if (lcount++>1000000) {
  332. capturedata(&capdata, pass, LOCKADDR(sharei), NULL, sizeof(lock_t));
  333. stillbad = (GETLOCK(sharei) != 0);
  334. rerr(&capdata, "Shared data lock", linep, slinep, thread, pass, linei, 0, GETLOCK(sharei), stillbad);
  335. return 1;
  336. }
  337. if ((lcount&0x3fff) == 0)
  338. udelay(1000);
  339. }
  340. sval = *sharep;
  341. sval2 = *sharecopy;
  342. if (pass > 12 && thread == 0 && fail_enabled == 1)
  343. sval++;
  344. if (sval != sval2) {
  345. capturedata(&capdata, pass, sharep, sharecopy, sizeof(*sharecopy));
  346. stillbad = (*sharep != *sharecopy);
  347. if (!stillbad && *sharep != sval && *sharecopy == sval2)
  348. stillbad = 2;
  349. if (rerr(&capdata, "Shared data", linep, slinep, thread, pass, linei, sval2, sval, stillbad)) {
  350. return 1;
  351. }
  352. if (correct_errors)
  353. *sharep = *sharecopy;
  354. errs++;
  355. }
  356. if ( (s=UNLOCK(sharei)) != 1) {
  357. capturedata(&capdata, pass, LOCKADDR(sharei), NULL, 4);
  358. stillbad = (GETLOCK(sharei) != lockpat);
  359. if (rerr(&capdata, "Shared data unlock", linep, slinep, thread, pass, linei, lockpat, GETLOCK(sharei), stillbad))
  360. return 1;
  361. if (correct_errors)
  362. ZEROLOCK(sharei);
  363. errs++;
  364. }
  365. break;
  366. case 3:
  367. /* Lock line, read and verify shared data, modify shared data. */
  368. if (verbose)
  369. printk("Line:%3d, Thread:%d:%d. Val: %xn", linei, thread, vv, *sharecopy);
  370. lcount = 0;
  371. while (LOCK(sharei) != 1) {
  372. if (checkstop(thread, pass, lockpat))
  373. return 0;
  374. if (lcount++>1000000) {
  375. capturedata(&capdata, pass, LOCKADDR(sharei), NULL, sizeof(lock_t));
  376. stillbad = (GETLOCK(sharei) != 0);
  377. rerr(&capdata, "Shared data lock & inc", linep, slinep, thread, pass, linei, 0, GETLOCK(sharei), stillbad);
  378. return 1;
  379. }
  380. if ((lcount&0x3fff) == 0)
  381. udelay(1000);
  382. }
  383. sval = *sharep;
  384. sval2 = *sharecopy;
  385. if (sval != sval2) {
  386. capturedata(&capdata, pass, sharep, sharecopy, sizeof(*sharecopy));
  387. stillbad = (*sharep != *sharecopy);
  388. if (!stillbad && *sharep != sval && *sharecopy == sval2)
  389. stillbad = 2;
  390. if (rerr(&capdata, "Shared data & inc", linep, slinep, thread, pass, linei, sval2, sval, stillbad)) {
  391. return 1;
  392. }
  393. errs++;
  394. }
  395. *sharep = lockpat;
  396. *sharecopy = lockpat;
  397. if ( (s=UNLOCK(sharei)) != 1) {
  398. capturedata(&capdata, pass, LOCKADDR(sharei), NULL, 4);
  399. stillbad = (GETLOCK(sharei) != lockpat);
  400. if (rerr(&capdata, "Shared data & inc unlock", linep, slinep, thread, pass, linei, thread, GETLOCK(sharei), stillbad))
  401. return 1;
  402. if (correct_errors)
  403. ZEROLOCK(sharei);
  404. errs++;
  405. }
  406. break;
  407. }
  408. }
  409. return (errs > 0);
  410. }
  411. static void
  412. trigger_la(long val)
  413. {
  414. long *p;
  415. p = (long*)0xc0000a0001000020L; /* PI_CPU_NUM */
  416. *p = val;
  417. }
  418. static long
  419. getsynerr(void)
  420. {
  421. long err, *errp;
  422. errp = (long*)0xc0000e0000000340L; /* SYN_ERR */
  423. err = *errp;
  424. if (err)
  425. *errp = -1L;
  426. return (err & ~0x60);
  427. }
  428. static int
  429. rerr(capture_t *cap, char *msg, void *lp, void *slp, int thread, int pass, int badlinei, int exp, int found, int stillbad)
  430. {
  431. int cpu, i, linei;
  432. long  synerr;
  433. int selt;
  434. selt = selective_trigger && stillbad > 1 && 
  435. memcmp(cap->blockdata, cap->blockdata_fc, 128) != 0 &&
  436. memcmp(cap->shaddata, cap->shaddata_fc, 128) == 0;
  437. if (selt) {
  438. trigger_la(pass);
  439. } else if (selective_trigger) {
  440. k_go = ST_STOP;
  441. return k_stop_on_error;;
  442. }
  443. spin(1);
  444. i = 100;
  445. while (i && set_lock(&errlock, 1) != 1) {
  446. spin(1);
  447. i--;
  448. }
  449. printk ("nDataError!: %-20s, test %ld, thread %d, line:%d, pass %d (0x%x), time %ld expected:%x, found:%xn",
  450.     msg, k_testnumber, thread, badlinei, pass, pass, jiffies, exp, found);
  451. dumpline (lp, "Corrupted data", "D ", cap->blockaddr, cap->blockdata, cap->size);
  452. #ifdef ZZZ
  453. if (memcmp(cap->blockdata, cap->blockdata_fc, 128))
  454. dumpline (lp, "Corrupted data", "DF", cap->blockaddr, cap->blockdata_fc, cap->size);
  455. #endif
  456. if (cap->shadaddr) {
  457. dumpline (slp, "Shadow    data", "S ", cap->shadaddr, cap->shaddata, cap->size);
  458. #ifdef ZZZ
  459. if (memcmp(cap->shaddata, cap->shaddata_fc, 128))
  460. dumpline (slp, "Shadow    data", "SF", cap->shadaddr, cap->shaddata_fc, cap->size);
  461. #endif
  462. }
  463. printk("Threadpasses: ");
  464. for (cpu=0,i=0; cpu<LLSC_MAXCPUS; cpu++)
  465. if (k_threadprivate[cpu]->threadpasses) {
  466. if (i && (i%8) == 0)
  467. printk("n            : ");
  468. printk("  %d:0x%x", cpu, k_threadprivate[cpu]->threadpasses);
  469. i++;
  470. }
  471. printk("n");
  472. for (linei=0; linei<k_linecount; linei++) {
  473. int slinei, g1linei, g2linei, g1err, g2err, sh0err, sh1err;
  474. dataline_t *linep, *slinep;
  475. slinei = (linei + (k_linecount/2))%k_linecount;
  476. linep = (dataline_t *)blocks[linei];
  477. slinep = (dataline_t *)blocks[slinei];
  478. g1linei = GUARDLINE(linep->guard1);
  479. g2linei = GUARDLINE(linep->guard2);
  480. g1err = (g1linei != linei);
  481. g2err = (g2linei != linei);
  482. sh0err = (linep->share[0] != slinep->share0);
  483. sh1err = (linep->share[1] != slinep->share1);
  484. if (g1err || g2err || sh0err || sh1err) {
  485. printk("Line 0x%lx (%03d), %sG1 0x%lx (%03d), %sG2 0x%lx (%03d), %sSH0 %08x (%08x), %sSH1 %08x (%08x)n",
  486. blocks[linei], linei, 
  487. g1err ? "*" : " ", blocks[g1linei], g1linei,
  488. g2err ? "*" : " ", blocks[g2linei], g2linei,
  489. sh0err ? "*" : " ", linep->share[0], slinep->share0,
  490. sh1err ? "*" : " ", linep->share[1], slinep->share1);
  491. }
  492. }
  493. printk("nData was %sfixed by flushcachen", (stillbad == 1 ? "**** NOT **** " : " "));
  494. synerr = getsynerr();
  495. if (synerr)
  496. printk("SYNERR: Thread %d, Synerr: 0x%lxn", thread, synerr);
  497. spin(2);
  498. printk("nn");
  499. clr_lock(&errlock, 1);
  500. if (errstop_enabled) {
  501. local_irq_disable();
  502. while(1);
  503. }
  504. return k_stop_on_error;
  505. }
  506. static void
  507. dumpline(void *lp, char *str1, char *str2, void *addr, void *data, int size)
  508. {
  509. long *p;
  510. int i, off;
  511. printk("%s at 0x%lx, size %d, block starts at 0x%lxn", str1, (long)addr, size, (long)lp);
  512. p = (long*) data;
  513. for (i=0; i<48; i++, p++) {
  514. if (i%8 == 0) printk("%2s", i==16 ? str2 : "  ");
  515. printk(" %016lx", *p);
  516. if ((i&7)==7) printk("n");
  517. }
  518. printk("   ");
  519. off = (((long)addr) ^ size) & 63L;
  520. for (i=0; i<off+size; i++) {
  521. printk("%s", (i>=off) ? "--" : "  ");
  522. if ((i%8) == 7)
  523. printk(" ");
  524. }
  525. off = ((long)addr) & 127;
  526. printk(" (line %d)n", 2+off/64+1);
  527. }
  528. static int
  529. randn(uint max, uint *seedp)
  530. {
  531. if (max == 1)
  532. return(0);
  533. else
  534. return((int)(zrandom(seedp)>>10) % max);
  535. }
  536. static int
  537. checkstop(int thread, int pass, uint lockpat)
  538. {
  539. long synerr;
  540. if (k_go == ST_RUN)
  541. return 0;
  542. if (k_go == ST_STOP)
  543. return 1;
  544. if (errstop_enabled) {
  545. local_irq_disable();
  546. while(1);
  547. }
  548. synerr = getsynerr();
  549. spin(2);
  550. if (k_go == ST_STOP)
  551. return 1;
  552. if (synerr)
  553. printk("SYNERR: Thread %d, Synerr: 0x%lxn", thread, synerr);
  554. return 1;
  555. }
  556. static void
  557. spin(int j)
  558. {
  559. udelay(j * 500000);
  560. }
  561. static void
  562. capturedata(capture_t *cap, uint pass, void *blockaddr, void *shadaddr, int size)
  563. {
  564. if (!selective_trigger)
  565. trigger_la (pass);
  566. memcpy (cap->blockdata, CACHEALIGN(blockaddr)-128, 3*128);
  567. if (shadaddr) 
  568. memcpy (cap->shaddata, CACHEALIGN(shadaddr)-128, 3*128);
  569. if (k_stop_on_error) {
  570. k_go = ST_ERRSTOP;
  571. }
  572.   cap->size = size;
  573. cap->blockaddr = blockaddr;
  574. cap->shadaddr = shadaddr;
  575. asm volatile ("fc %0" :: "r"(blockaddr) : "memory");
  576. ia64_sync_i();
  577. ia64_srlz_d();
  578. memcpy (cap->blockdata_fc, CACHEALIGN(blockaddr)-128, 3*128);
  579. if (shadaddr) {
  580. asm volatile ("fc %0" :: "r"(shadaddr) : "memory");
  581. ia64_sync_i();
  582. ia64_srlz_d();
  583. memcpy (cap->shaddata_fc, CACHEALIGN(shadaddr)-128, 3*128);
  584. }
  585. }
  586. int             zranmult = 0x48c27395;
  587. static uint  
  588. zrandom (uint *seedp)
  589. {
  590.         *seedp = (*seedp * zranmult) & 0x7fffffff;
  591.         return (*seedp);
  592. }
  593. void
  594. set_autotest_params(void)
  595. {
  596. static int testnumber=-1;
  597. if (llsctest_number >= 0) {
  598. testnumber = llsctest_number;
  599. } else {
  600. testnumber++;
  601. if (autotest_table[testnumber].passes == 0) {
  602. testnumber = 0;
  603. dump_block_addrs_opt = 0;
  604. }
  605. }
  606. if (testnumber == 0 && l4_opt) testnumber = 9;
  607. k_passes = autotest_table[testnumber].passes;
  608. k_linepad = autotest_table[testnumber].linepad;
  609. k_linecount = autotest_table[testnumber].linecount;
  610. k_testnumber = testnumber;
  611. if (IS_RUNNING_ON_SIMULATOR()) {
  612. printk ("llsc start test %ldn", k_testnumber);
  613. k_passes = 1000;
  614. }
  615. }
  616. static void
  617. set_leds(int errs)
  618. {
  619. unsigned char leds=0;
  620. /*
  621.  * Leds are:
  622.  *  ppppeee-  
  623.  *   where
  624.  *      pppp = test number
  625.  *       eee = error count but top bit is stick
  626.  */
  627. leds =  ((errs&7)<<1) | ((k_testnumber&15)<<4) | (errs ? 0x08 : 0);
  628. set_led_bits(leds, LED_MASK_AUTOTEST);
  629. }
  630. static void
  631. setup_block_addresses(void)
  632. {
  633. int i, stride, memmapi;
  634. dataline_t *dp;
  635. long *ip, *ipe;
  636. stride = k_linepad + sizeof(dataline_t);
  637. memmapi = 0;
  638. for (i=0; i<memmapx; i++) {
  639. memmap[i].nextaddr = memmap[i].vstart;
  640. memmap[i].nextinit = memmap[i].vstart;
  641. memmap[i].wrapcount = 0;
  642. }
  643. for (i=0; i<k_linecount; i++) {
  644. blocks[i] = memmap[memmapi].nextaddr;
  645. dp = (dataline_t*)blocks[i];
  646. memmap[memmapi].nextaddr += (stride & 0xffff);
  647. if (memmap[memmapi].nextaddr + sizeof(dataline_t) >= memmap[memmapi].vend) {
  648. memmap[memmapi].wrapcount++;
  649. memmap[memmapi].nextaddr = memmap[memmapi].vstart + 
  650. memmap[memmapi].wrapcount * sizeof(dataline_t);
  651. }
  652. ip = (long*)((memmap[memmapi].nextinit+7)&~7);
  653. ipe = (long*)(memmap[memmapi].nextaddr+2*sizeof(dataline_t)+8);
  654. while(ip <= ipe && ip < ((long*)memmap[memmapi].vend-8))
  655. *ip++ = (long)ip;
  656. memmap[memmapi].nextinit = (long) ipe;
  657. dp->guard1 = BGUARD(i);
  658. dp->guard2 = EGUARD(i);
  659. dp->lock[0] = dp->lock[1] = NOLOCK;
  660. dp->share[0] = dp->share0 = 0x1111;
  661. dp->share[1] = dp->share1 = 0x2222;
  662. memcpy(dp->private, init_private, LLSC_MAXCPUS*sizeof(private_t));
  663. if (stride > 16384) {
  664. memmapi++;
  665. if (memmapi == memmapx)
  666. memmapi = 0;
  667. }
  668. }
  669. }
  670. static void
  671. dump_block_addrs(void)
  672. {
  673. int i;
  674. printk("LLSC TestNumber %ldn", k_testnumber);
  675. for (i=0; i<k_linecount; i++) {
  676. printk("  %lx", blocks[i]);
  677. if (i%4 == 3)
  678. printk("n");
  679. }
  680. printk("n");
  681. }
  682. static void
  683. set_thread_state(int cpuid, int state)
  684. {
  685. if (k_threadprivate[cpuid]->threadstate == TS_KILLED) {
  686. set_led_bits(LED_MASK_AUTOTEST, LED_MASK_AUTOTEST);
  687. while(1);
  688. }
  689. k_threadprivate[cpuid]->threadstate = state;
  690. }
  691. #define MINBLK (16*1024*1024)
  692. static int
  693. build_mem_map(unsigned long start, unsigned long end, void *arg)
  694. {
  695. long lstart, lend;
  696. long align = 8*MB;
  697. printk ("LLSC memmap: start 0x%lx, end 0x%lx, (0x%lx - 0x%lx)n", 
  698. start, end, (long) virt_to_page(start), (long) virt_to_page(end-PAGE_SIZE));
  699. if (memmapx >= MAPCHUNKS || (end-start) < MINBLK)
  700. return 0;
  701. /*
  702.  * Start in the middle of the range & find the first non-free page in both directions
  703.  * from the midpoint. This is likely to be the bigest free block.
  704.  */
  705. lend = lstart = start + (end-start)/2;
  706. while (lend < end && !PageReserved(virt_to_page(lend)) && virt_to_page(lend)->count.counter == 0)
  707. lend += PAGE_SIZE;
  708. lend -= PAGE_SIZE;
  709. while (lstart >= start && !PageReserved(virt_to_page(lstart)) && virt_to_page(lstart)->count.counter == 0)
  710. lstart -= PAGE_SIZE;
  711. lstart += PAGE_SIZE;
  712. lstart = (lstart + align -1) /align * align;
  713. end = end / align * align;
  714. if (lstart >= end)
  715. return 0;
  716. printk ("     memmap: start 0x%lx, end 0x%lxn", lstart, end);
  717. memmap[memmapx].vstart = lstart;
  718. memmap[memmapx].vend = end;
  719. memmapx++;
  720. return 0;
  721. }
  722. void int_test(void);
  723. int
  724. llsc_main (int cpuid)
  725. {
  726. int i, cpu, is_master, repeatcnt=0;
  727. unsigned int preverr=0, errs=0, pass=0;
  728. int automode=0;
  729. #ifdef INTTEST
  730. if (inttest)
  731. int_test();
  732. #endif
  733. if (!autotest_enabled)
  734. return 0;
  735. #ifdef CONFIG_SMP
  736. is_master = !smp_processor_id();
  737. #else
  738. is_master = 1;
  739. #endif
  740. if (is_master) {
  741. mbase = (control_t*) __get_free_pages(GFP_KERNEL, get_order(4096+THREADPRIVATESZ()*LLSC_MAXCPUS));
  742. printk("LLSC: mbase 0x%lxn", (long)mbase);
  743. print_params();
  744. if(!IS_RUNNING_ON_SIMULATOR())
  745. spin(10);
  746. k_currentpass = 0;
  747. k_go = ST_IDLE;
  748. k_passes = DEF_PASSES;
  749. k_napticks = DEF_NAPTICKS;
  750. k_stop_on_error = DEF_STOP_ON_ERROR;
  751. k_verbose = DEF_VERBOSE;
  752. k_linecount = DEF_LINECOUNT;
  753. k_iter_msg = DEF_ITER_MSG;
  754. k_vv = DEF_VV;
  755. k_linepad = DEF_LINEPAD;
  756. k_blocks = (void*)blocks;
  757. efi_memmap_walk(build_mem_map, 0);
  758. #ifdef CONFIG_IA64_SGI_AUTOTEST
  759. automode = 1;
  760. #endif
  761. for (i=0; i<LLSC_MAXCPUS; i++) {
  762. k_threadprivate[i] = THREADPRIVATE(i);
  763. memset(k_threadprivate[i], 0, sizeof(*k_threadprivate[i]));
  764. init_private[i] = i;
  765. }
  766. mb();
  767. initialized = 1;
  768. } else {
  769. while (initialized == 0)
  770. udelay(100);
  771. }
  772. loop:
  773. if (is_master) {
  774. if (automode) {
  775. if (!preverr || repeatcnt++ > 5) {
  776. set_autotest_params();
  777. repeatcnt = 0;
  778. }
  779. } else {
  780. while (k_go == ST_IDLE);
  781. }
  782. k_go = ST_INIT;
  783. if (k_linecount > MAX_LINECOUNT) k_linecount = MAX_LINECOUNT;
  784. k_linecount = k_linecount & ~1;
  785. setup_block_addresses();
  786. if (!preverr && dump_block_addrs_opt)
  787. dump_block_addrs();
  788. k_currentpass = pass++;
  789. k_go = ST_RUN;
  790. if (fail_enabled)
  791. fail_enabled--;
  792. } else {
  793. while (k_go != ST_RUN || k_currentpass != pass);
  794. pass++;
  795. }
  796. set_leds(errs);
  797. set_thread_state(cpuid, TS_RUNNING);
  798. errs += ran_conf_llsc(cpuid);
  799. preverr = (k_go == ST_ERRSTOP);
  800. set_leds(errs);
  801. set_thread_state(cpuid, TS_STOPPED);
  802. if (is_master) {
  803. Speedo();
  804. for (i=0, cpu=0; cpu<LLSC_MAXCPUS; cpu++) {
  805. while (k_threadprivate[cpu]->threadstate == TS_RUNNING) {
  806. i++;
  807. if (i == 10000) { 
  808. k_go = ST_STOP;
  809. printk ("  llsc master stopping test number %ldn", k_testnumber);
  810. }
  811. if (i > 100000) {
  812. k_threadprivate[cpu]->threadstate = TS_KILLED;
  813. printk ("  llsc: master killing cpuid %d, running test number %ldn", 
  814. cpu, k_testnumber);
  815. }
  816. udelay(1000);
  817. }
  818. }
  819. }
  820. goto loop;
  821. }
  822. static void
  823. Speedo(void)
  824. {
  825. static int i = 0;
  826. switch (++i%4) {
  827. case 0:
  828. printk("|b");
  829. break;
  830. case 1:
  831. printk("\b");
  832. break;
  833. case 2:
  834. printk("-b");
  835. break;
  836. case 3:
  837. printk("/b");
  838. break;
  839. }
  840. }
  841. #ifdef INTTEST
  842. /* ======================================================================================================== 
  843.  *
  844.  * Some test code to verify that interrupts work
  845.  *
  846.  * Add the following to the arch/ia64/kernel/smp.c after the comment "Reschedule callback"
  847.  *  if (zzzprint_resched) printk("  cpu %d got interruptn", smp_processor_id());
  848.  *
  849.  * Enable the code in arch/ia64/sn/sn1/smp.c to print sending IPIs.
  850.  *
  851.  */
  852. static int __init set_inttest(char *str)
  853. {
  854.         inttest = 1;
  855. autotest_enabled = 1;
  856. return 1;
  857. }
  858. __setup("inttest=", set_inttest);
  859. int zzzprint_resched=0;
  860. void
  861. int_test() {
  862. int mycpu, cpu;
  863. static volatile int control_cpu=0;
  864. mycpu = smp_processor_id();
  865. zzzprint_resched = 2;
  866. printk("Testing cross interruptsn");
  867. while (control_cpu != smp_num_cpus) {
  868. if (mycpu == cpu_logical_map(control_cpu)) {
  869. for (cpu=0; cpu<smp_num_cpus; cpu++) {
  870. printk("Sending interrupt from %d to %dn", mycpu, cpu_logical_map(cpu));
  871. udelay(IS_RUNNING_ON_SIMULATOR ? 10000 : 400000);
  872. smp_send_reschedule(cpu_logical_map(cpu));
  873. udelay(IS_RUNNING_ON_SIMULATOR ? 10000 : 400000);
  874. smp_send_reschedule(cpu_logical_map(cpu));
  875. udelay(IS_RUNNING_ON_SIMULATOR ? 10000 : 400000);
  876. }
  877. control_cpu++;
  878. }
  879. }
  880. zzzprint_resched = 1;
  881. if (mycpu == cpu_logical_map(smp_num_cpus-1)) {
  882. printk("nTight loop of cpu %d sending ints to cpu 0 (every 100 us)n", mycpu);
  883. udelay(IS_RUNNING_ON_SIMULATOR ? 1000 : 1000000);
  884. __cli();
  885. while (1) {
  886. smp_send_reschedule(0);
  887. udelay(100);
  888. }
  889. }
  890. while(1);
  891. }
  892. #endif