llsc4.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:22k
源码类别:

嵌入式Linux

开发平台:

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