post1.S 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742
  1. /*
  2. * (C) Copyright 2001
  3. * Bill Hunter, Wave 7 Optics, william.hunter@mediaone.net
  4. * and
  5. * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com
  6. *
  7. * See file CREDITS for list of people who contributed to this
  8. * project.
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License as
  12. * published by the Free Software Foundation; either version 2 of
  13. * the License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  23. * MA 02111-1307 USA
  24. */
  25. /*
  26. * Description:
  27. * Routine to exercise memory for the bringing up of our boards.
  28. */
  29. #include <config.h>
  30. #include <ppc4xx.h>
  31. #define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
  32. #include <ppc_asm.tmpl>
  33. #include <ppc_defs.h>
  34. #include <asm/cache.h>
  35. #include <asm/mmu.h>
  36. #include <watchdog.h>
  37. #include "errors.h"
  38. #define _ASMLANGUAGE
  39. .globl test_sdram
  40. .globl test_led
  41. .globl log_stat
  42. .globl log_warn
  43. .globl log_err
  44. .globl temp_uart_init
  45. .globl post_puts
  46. .globl disp_hex
  47. /*****************************************************
  48. ******* Text Strings for low level printing ******
  49. ******* In section got2 *******
  50. *****************************************************/
  51. /*
  52. * Define the text strings for errors and warnings.
  53. * Switch to .data section.
  54. */
  55. .section ".data"
  56. err_str: .asciz "*** POST ERROR = "
  57. warn_str: .asciz "*** POST WARNING = "
  58. end_str: .asciz "\r\n"
  59. /*
  60. * Enter the labels in Global Entry Table (GOT).
  61. * Switch to .got2 section.
  62. */
  63. START_GOT
  64. GOT_ENTRY(err_str)
  65. GOT_ENTRY(warn_str)
  66. GOT_ENTRY(end_str)
  67. END_GOT
  68. /*
  69. * Switch back to .text section.
  70. */
  71. .text
  72. /****************************************
  73. ****************************************
  74. ******** LED register test ********
  75. ****************************************
  76. ***************************************/
  77. test_led:
  78. /* save the return info on stack */
  79. mflr r0 /* Get link register */
  80. stwu r1, -12(r1) /* Save back chain and move SP */
  81. stw r0, +16(r1) /* Save link register */
  82. stw r4, +8(r1) /* save R4 */
  83. WATCHDOG_RESET /* Reset the watchdog */
  84. addi r3, 0, ERR_FF /* first test value is ffff */
  85. addi r4, r3, 0 /* save copy of pattern */
  86. bl set_led /* store first test value */
  87. bl get_led /* read it back */
  88. xor. r4, r4, r3 /* compare to original */
  89. #if defined(CONFIG_W7OLMC)
  90. andi. r4, r4, 0x00ff /* lmc has 8 bits */
  91. #else
  92. andi. r4, r4, 0xffff /* lmg has 16 bits */
  93. #endif
  94. beq LED2 /* next test */
  95. addi r3, 0, ERR_LED /* error code = 1 */
  96. bl log_err /* display error and halt */
  97. LED2: addi r3, 0, ERR_00 /* 2nd test value is 0000 */
  98. addi r4, r3, 0 /* save copy of pattern */
  99. bl set_led /* store first test value */
  100. bl get_led /* read it back */
  101. xor. r4, r4, r3 /* compare to original */
  102. #if defined(CONFIG_W7OLMC)
  103. andi. r4, r4, 0x00ff /* lmc has 8 bits */
  104. #else
  105. andi. r4, r4, 0xffff /* lmg has 16 bits */
  106. #endif
  107. beq LED3 /* next test */
  108. addi r3, 0, ERR_LED /* error code = 1 */
  109. bl log_err /* display error and halt */
  110. LED3: /* restore stack and return */
  111. lwz r0, +16(r1) /* Get saved link register */
  112. mtlr r0 /* Restore link register */
  113. lwz r4, +8(r1) /* restore r4 */
  114. addi r1, r1, +12 /* Remove frame from stack */
  115. blr /* Return to calling function */
  116. /****************************************
  117. ****************************************
  118. ******** SDRAM TESTS ********
  119. ****************************************
  120. ***************************************/
  121. test_sdram:
  122. /* called with mem size in r3 */
  123. /* save the return info on stack */
  124. mflr r0 /* Get link register */
  125. stwu r1, -16(r1) /* Save back chain and move SP */
  126. stw r0, +20(r1) /* Save link register */
  127. stmw r30, +8(r1) /* save R30,R31 */
  128. /* r30 is log2(mem size) */
  129. /* r31 is mem size */
  130. /* take log2 of total mem size */
  131. addi r31, r3, 0 /* save total mem size */
  132. addi r30, 0, 0 /* clear r30 */
  133. l2_loop:
  134. srwi. r31, r31, 1 /* shift right 1 */
  135. addi r30, r30, 1 /* count shifts */
  136. bne l2_loop /* loop till done */
  137. addi r30, r30, -1 /* correct for over count */
  138. addi r31, r3, 0 /* save original size */
  139. /* now kick the dog and test the mem */
  140. WATCHDOG_RESET /* Reset the watchdog */
  141. bl Data_Buster /* test crossed/shorted data lines */
  142. addi r3, r30, 0 /* get log2(memsize) */
  143. addi r4, r31, 0 /* get memsize */
  144. bl Ghost_Buster /* test crossed/shorted addr lines */
  145. addi r3, r31, 0 /* get mem size */
  146. bl Bit_Buster /* check for bad internal bits */
  147. /* restore stack and return */
  148. lmw r30, +8(r1) /* Restore r30, r31 */
  149. lwz r0, +20(r1) /* Get saved link register */
  150. mtlr r0 /* Restore link register */
  151. addi r1, r1, +16 /* Remove frame from stack */
  152. blr /* Return to calling function */
  153. /****************************************
  154. ******** sdram data bus test ********
  155. ***************************************/
  156. Data_Buster:
  157. /* save the return info on stack */
  158. mflr r0 /* Get link register */
  159. stwu r1, -24(r1) /* Save back chain and move SP */
  160. stw r0, +28(r1) /* Save link register */
  161. stmw r28, 8(r1) /* save r28 - r31 on stack */
  162. /* r31 i/o register */
  163. /* r30 sdram base address */
  164. /* r29 5555 syndrom */
  165. /* r28 aaaa syndrom */
  166. /* set up led register for this test */
  167. addi r3, 0, ERR_RAMG /* set led code to 1 */
  168. bl log_stat /* store test value */
  169. /* now test the dram data bus */
  170. xor r30, r30, r30 /* load r30 with base addr of sdram */
  171. addis r31, 0, 0x5555 /* load r31 with test value */
  172. ori r31, r31, 0x5555
  173. stw r31,0(r30) /* sto the value */
  174. lwz r29,0(r30) /* read it back */
  175. xor r29,r31,r29 /* compare it to original */
  176. addis r31, 0, 0xaaaa /* load r31 with test value */
  177. ori r31, r31, 0xaaaa
  178. stw r31,0(r30) /* sto the value */
  179. lwz r28,0(r30) /* read it back */
  180. xor r28,r31,r28 /* compare it to original */
  181. or r3,r28,r29 /* or together both error terms */
  182. /*
  183. * Now that we have the error bits,
  184. * we have to decide which part they are in.
  185. */
  186. bl get_idx /* r5 is now index to error */
  187. addi r3, r3, ERR_RAMG
  188. cmpwi r3, ERR_RAMG /* check for errors */
  189. beq db_done /* skip if no errors */
  190. bl log_err /* log the error */
  191. db_done:
  192. lmw r28, 8(r1) /* restore r28 - r31 from stack */
  193. lwz r0, +28(r1) /* Get saved link register */
  194. addi r1, r1, +24 /* Remove frame from stack */
  195. mtlr r0 /* Restore link register */
  196. blr /* Return to calling function */
  197. /****************************************************
  198. ******** test for address ghosting in dram ********
  199. ***************************************************/
  200. Ghost_Buster:
  201. /* save the return info on stack */
  202. mflr r0 /* Get link register */
  203. stwu r1, -36(r1) /* Save back chain and move SP */
  204. stw r0, +40(r1) /* Save link register */
  205. stmw r25, 8(r1) /* save r25 - r31 on stack */
  206. /* r31 = scratch register */
  207. /* r30 is main referance loop counter,
  208. 0 to 23 */
  209. /* r29 is ghost loop count, 0 to 22 */
  210. /* r28 is referance address */
  211. /* r27 is ghost address */
  212. /* r26 is log2 (mem size) =
  213. number of byte addr bits */
  214. /* r25 is mem size */
  215. /* save the log2(mem size) and mem size */
  216. addi r26, r3, 0 /* r26 is number of byte addr bits */
  217. addi r25, r4, 0 /* r25 is mem size in bytes */
  218. /* set the leds for address ghost test */
  219. addi r3, 0, ERR_ADDG
  220. bl set_led
  221. /* first fill memory with zeros */
  222. srwi r31, r25, 2 /* convert bytes to longs */
  223. mtctr r31 /* setup byte counter */
  224. addi r28, 0, 0 /* start at address at 0 */
  225. addi r31, 0, 0 /* data value = 0 */
  226. clr_loop:
  227. stw r31, 0(r28) /* Store zero value */
  228. addi r28, r28, 4 /* Increment to next word */
  229. andi. r27, r28, 0xffff /* check for 2^16 loops */
  230. bne clr_skip /* if not there, then skip */
  231. WATCHDOG_RESET /* kick the dog every now and then */
  232. clr_skip:
  233. bdnz clr_loop /* Round and round... */
  234. /* now do main test */
  235. addi r30, 0, 0 /* start referance counter at 0 */
  236. outside:
  237. /*
  238. * Calculate the referance address
  239. * the referance address is calculated by setting the (r30-1)
  240. * bit of the base address
  241. * when r30=0, the referance address is the base address.
  242. * thus the sequence 0,1,2,4,8,..,2^(n-1)
  243. * setting the bit is done with the following shift functions.
  244. */
  245. WATCHDOG_RESET /* Reset the watchdog */
  246. addi r31, 0, 1 /* r31 = 1 */
  247. slw r28, r31, r30 /* set bit coresponding to loop cnt */
  248. srwi r28, r28, 1 /* then shift it right one so */
  249. /* we start at location 0 */
  250. /* fill referance address with Fs */
  251. addi r31, 0, 0x00ff /* r31 = one byte of set bits */
  252. stb r31,0(r28) /* save ff in referance address */
  253. /* ghost (inner) loop, now check all posible ghosted addresses */
  254. addi r29, 0, 0 /* start ghosted loop counter at 0 */
  255. inside:
  256. /*
  257. * Calculate the ghost address by flipping one
  258. * bit of referance address. This gives the
  259. * sequence 1,2,4,8,...,2^(n-1)
  260. */
  261. addi r31, 0, 1 /* r31 = 1 */
  262. slw r27, r31, r29 /* set bit coresponding to loop cnt */
  263. xor r27, r28, r27 /* ghost address = ref addr with
  264. bit flipped*/
  265. /* now check for ghosting */
  266. lbz r31,0(r27) /* get content of ghost addr */
  267. cmpwi r31, 0 /* compare read value to 0 */
  268. bne Casper /* we found a ghost! */
  269. /* now close ghost ( inner ) loop */
  270. addi r29, r29, 1 /* increment inner loop counter */
  271. cmpw r29, r26 /* check for last inner loop */
  272. blt inside /* do more inner loops */
  273. /* now close referance ( outer ) loop */
  274. addi r31, 0, 0 /* r31 = zero */
  275. stb r31, 0(28) /* zero out the altered address loc. */
  276. /*
  277. * Increment and check for end, count is zero based.
  278. * With the ble, this gives us one more loops than
  279. * address bits for sequence 0,1,2,4,8,...2^(n-1)
  280. */
  281. addi r30, r30, 1 /* increment outer loop counter */
  282. cmpw r30, r26 /* check for last inner loop */
  283. ble outside /* do more outer loops */
  284. /* were done, lets go home */
  285. b gb_done
  286. Casper: /* we found a ghost !! */
  287. addi r3, 0, ERR_ADDF /* get indexed error message */
  288. bl log_err /* log error led error code */
  289. gb_done: /* pack your bags, and go home */
  290. lmw r25, 8(r1) /* restore r25 - r31 from stack */
  291. lwz r0, +40(r1) /* Get saved link register */
  292. addi r1, r1, +36 /* Remove frame from stack */
  293. mtlr r0 /* Restore link register */
  294. blr /* Return to calling function */
  295. /****************************************************
  296. ******** SDRAM data fill tests **********
  297. ***************************************************/
  298. Bit_Buster:
  299. /* called with mem size in r3 */
  300. /* save the return info on stack */
  301. mflr r0 /* Get link register */
  302. stwu r1, -16(r1) /* Save back chain and move SP */
  303. stw r0, +20(r1) /* Save link register */
  304. stw r4, +8(r1) /* save R4 */
  305. stw r5, +12(r1) /* save r5 */
  306. addis r5, r3, 0 /* save mem size */
  307. /* Test 55555555 */
  308. addi r3, 0, ERR_R55G /* set up error code in case we fail */
  309. bl log_stat /* store test value */
  310. addis r4, 0, 0x5555
  311. ori r4, r4, 0x5555
  312. bl fill_test
  313. /* Test aaaaaaaa */
  314. addi r3, 0, ERR_RAAG /* set up error code in case we fail */
  315. bl log_stat /* store test value */
  316. addis r4, 0, 0xAAAA
  317. ori r4, r4, 0xAAAA
  318. bl fill_test
  319. /* Test 00000000 */
  320. addi r3, 0, ERR_R00G /* set up error code in case we fail */
  321. bl log_stat /* store test value */
  322. addis r4, 0, 0
  323. ori r4, r4, 0
  324. bl fill_test
  325. /* restore stack and return */
  326. lwz r5, +12(r1) /* restore r4 */
  327. lwz r4, +8(r1) /* restore r4 */
  328. lwz r0, +20(r1) /* Get saved link register */
  329. addi r1, r1, +16 /* Remove frame from stack */
  330. mtlr r0 /* Restore link register */
  331. blr /* Return to calling function */
  332. /****************************************************
  333. ******** fill test ********
  334. ***************************************************/
  335. /* tests memory by filling with value, and reading back */
  336. /* r5 = Size of memory in bytes */
  337. /* r4 = Value to write */
  338. /* r3 = Error code */
  339. fill_test:
  340. mflr r0 /* Get link register */
  341. stwu r1, -32(r1) /* Save back chain and move SP */
  342. stw r0, +36(r1) /* Save link register */
  343. stmw r27, 8(r1) /* save r27 - r31 on stack */
  344. /* r31 - scratch register */
  345. /* r30 - memory address */
  346. mr r27, r3
  347. mr r28, r4
  348. mr r29, r5
  349. WATCHDOG_RESET /* Reset the watchdog */
  350. /* first fill memory with Value */
  351. srawi r31, r29, 2 /* convert bytes to longs */
  352. mtctr r31 /* setup counter */
  353. addi r30, 0, 0 /* Make r30 = addr 0 */
  354. ft_0: stw r28, 0(r30) /* Store value */
  355. addi r30, r30, 4 /* Increment to next word */
  356. andi. r31, r30, 0xffff /* check for 2^16 loops */
  357. bne ft_0a /* if not there, then skip */
  358. WATCHDOG_RESET /* kick the dog every now and then */
  359. ft_0a: bdnz ft_0 /* Round and round... */
  360. WATCHDOG_RESET /* Reset the watchdog */
  361. /* Now confirm Value is in memory */
  362. srawi r31, r29, 2 /* convert bytes to longs */
  363. mtctr r31 /* setup counter */
  364. addi r30, 0, 0 /* Make r30 = addr 0 */
  365. ft_1: lwz r31, 0(r30) /* get value from memory */
  366. xor. r31, r31, r28 /* Writen = Read ? */
  367. bne ft_err /* If bad, than halt */
  368. addi r30, r30, 4 /* Increment to next word */
  369. andi. r31, r30, 0xffff /* check for 2^16 loops*/
  370. bne ft_1a /* if not there, then skip */
  371. WATCHDOG_RESET /* kick the dog every now and then */
  372. ft_1a: bdnz ft_1 /* Round and round... */
  373. WATCHDOG_RESET /* Reset the watchdog */
  374. b fill_done /* restore and return */
  375. ft_err: addi r29, r27, 0 /* save current led code */
  376. addi r27, r31, 0 /* get pattern in r27 */
  377. bl get_idx /* get index from r27 */
  378. add r27, r27, r29 /* add index to old led code */
  379. bl log_err /* output led err code, halt CPU */
  380. fill_done:
  381. lmw r27, 8(r1) /* restore r27 - r31 from stack */
  382. lwz r0, +36(r1) /* Get saved link register */
  383. addi r1, r1, +32 /* Remove frame from stack */
  384. mtlr r0 /* Restore link register */
  385. blr /* Return to calling function */
  386. /****************************************************
  387. ******* get error index from r3 pattern ********
  388. ***************************************************/
  389. get_idx: /* r3 = (MSW(r3) !=0)*2 +
  390. (LSW(r3) !=0) */
  391. /* save the return info on stack */
  392. mflr r0 /* Get link register */
  393. stwu r1, -12(r1) /* Save back chain and move SP */
  394. stw r0, +16(r1) /* Save link register */
  395. stw r4, +8(r1) /* save R4 */
  396. andi. r4, r3, 0xffff /* check for lower bits */
  397. beq gi2 /* skip if no bits set */
  398. andis. r4, r3, 0xffff /* check for upper bits */
  399. beq gi3 /* skip if no bits set */
  400. addi r3, 0, 3 /* both upper and lower bits set */
  401. b gi_done
  402. gi2: andis. r4, r3, 0xffff /* check for upper bits*/
  403. beq gi4 /* skip if no bits set */
  404. addi r3, 0, 2 /* only upper bits set */
  405. b gi_done
  406. gi3: addi r3, 0, 1 /* only lower bits set */
  407. b gi_done
  408. gi4: addi r3, 0, 0 /* no bits set */
  409. gi_done:
  410. /* restore stack and return */
  411. lwz r0, +16(r1) /* Get saved link register */
  412. mtlr r0 /* Restore link register */
  413. lwz r4, +8(r1) /* restore r4 */
  414. addi r1, r1, +12 /* Remove frame from stack */
  415. blr /* Return to calling function */
  416. /****************************************************
  417. ******** set LED to R5 and hang ********
  418. ***************************************************/
  419. log_stat: /* output a led code and continue */
  420. set_led:
  421. /* save the return info on stack */
  422. mflr r0 /* Get link register */
  423. stwu r1, -12(r1) /* Save back chain and move SP */
  424. stw r0, +16(r1) /* Save link register */
  425. stw r4, +8(r1) /* save R4 */
  426. addis r4, 0, 0xfe00 /* LED buffer is at 0xfe000000 */
  427. #if defined(CONFIG_W7OLMG) /* only on gateway, invert outputs */
  428. xori r3,r3, 0xffff /* complement led code, active low */
  429. sth r3, 0(r4) /* store first test value */
  430. xori r3,r3, 0xffff /* complement led code, active low */
  431. #else /* if not gateway, then don't invert */
  432. sth r3, 0(r4) /* store first test value */
  433. #endif
  434. /* restore stack and return */
  435. lwz r0, +16(r1) /* Get saved link register */
  436. mtlr r0 /* Restore link register */
  437. lwz r4, +8(r1) /* restore r4 */
  438. addi r1, r1, +12 /* Remove frame from stack */
  439. blr /* Return to calling function */
  440. get_led:
  441. /* save the return info on stack */
  442. mflr r0 /* Get link register */
  443. stwu r1, -12(r1) /* Save back chain and move SP */
  444. stw r0, +16(r1) /* Save link register */
  445. stw r4, +8(r1) /* save R4 */
  446. addis r4, 0, 0xfe00 /* LED buffer is at 0xfe000000 */
  447. lhz r3, 0(r4) /* store first test value */
  448. #if defined(CONFIG_W7OLMG) /* only on gateway, invert inputs */
  449. xori r3,r3, 0xffff /* complement led code, active low */
  450. #endif
  451. /* restore stack and return */
  452. lwz r0, +16(r1) /* Get saved link register */
  453. mtlr r0 /* Restore link register */
  454. lwz r4, +8(r1) /* restore r4 */
  455. addi r1, r1, +12 /* Remove frame from stack */
  456. blr /* Return to calling function */
  457. log_err: /* output the error and hang the board ( for now ) */
  458. /* save the return info on stack */
  459. mflr r0 /* Get link register */
  460. stwu r1, -12(r1) /* Save back chain and move SP */
  461. stw r0, +16(r1) /* Save link register */
  462. stw r3, +8(r1) /* save a copy of error code */
  463. bl set_led /* set the led pattern */
  464. GET_GOT /* get GOT address in r14 */
  465. lwz r3,GOT(err_str) /* get address of string */
  466. bl post_puts /* output the warning string */
  467. lwz r3, +8(r1) /* get error code */
  468. addi r4, 0, 2 /* set disp length to 2 nibbles */
  469. bl disp_hex /* output the error code */
  470. lwz r3,GOT(end_str) /* get address of string */
  471. bl post_puts /* output the warning string */
  472. halt:
  473. b halt /* hang */
  474. /* restore stack and return */
  475. lwz r0, +16(r1) /* Get saved link register */
  476. mtlr r0 /* Restore link register */
  477. addi r1, r1, +12 /* Remove frame from stack */
  478. blr /* Return to calling function */
  479. log_warn: /* output a warning, then continue with operations */
  480. /* save the return info on stack */
  481. mflr r0 /* Get link register */
  482. stwu r1, -16(r1) /* Save back chain and move SP */
  483. stw r0, +20(r1) /* Save link register */
  484. stw r3, +8(r1) /* save a copy of error code */
  485. stw r14, +12(r1) /* save a copy of r14 (used by GOT) */
  486. bl set_led /* set the led pattern */
  487. GET_GOT /* get GOT address in r14 */
  488. lwz r3,GOT(warn_str) /* get address of string */
  489. bl post_puts /* output the warning string */
  490. lwz r3, +8(r1) /* get error code */
  491. addi r4, 0, 2 /* set disp length to 2 nibbles */
  492. bl disp_hex /* output the error code */
  493. lwz r3,GOT(end_str) /* get address of string */
  494. bl post_puts /* output the warning string */
  495. addis r3, 0, 64 /* has a long delay */
  496. mtctr r3
  497. log_2:
  498. WATCHDOG_RESET /* this keeps dog from barking, */
  499. /* and takes time */
  500. bdnz log_2 /* loop till time expires */
  501. /* restore stack and return */
  502. lwz r0, +20(r1) /* Get saved link register */
  503. lwz r14, +12(r1) /* restore r14 */
  504. mtlr r0 /* Restore link register */
  505. addi r1, r1, +16 /* Remove frame from stack */
  506. blr /* Return to calling function */
  507. /*******************************************************************
  508. * temp_uart_init
  509. * Temporary UART initialization routine
  510. * Sets up UART0 to run at 9600N81 off of the internal clock.
  511. * R3-R4 are used.
  512. ******************************************************************/
  513. temp_uart_init:
  514. /* save the return info on stack */
  515. mflr r0 /* Get link register */
  516. stwu r1, -8(r1) /* Save back chain and move SP */
  517. stw r0, +12(r1) /* Save link register */
  518. addis r3, 0, 0xef60
  519. ori r3, r3, 0x0303 /* r3 = UART0_LCR */
  520. addi r4, 0, 0x83 /* n81 format, divisor regs enabled */
  521. stb r4, 0(r3)
  522. /* set baud rate to use internal clock,
  523. baud = (200e6/16)/31/42 = 9600 */
  524. addis r3, 0, 0xef60 /* Address of baud divisor reg */
  525. ori r3, r3, 0x0300 /* UART0_DLM */
  526. addi r4, 0, +42 /* uart baud divisor LSB = 93 */
  527. stb r4, 0(r3) /* baud = (200 /16)/14/93 */
  528. addi r3, r3, 0x0001 /* uart baud divisor addr */
  529. addi r4, 0, 0
  530. stb r4, 0(r3) /* Divisor Latch MSB = 0 */
  531. addis r3, 0, 0xef60
  532. ori r3, r3, 0x0303 /* r3 = UART0_LCR */
  533. addi r4, 0, 0x03 /* n81 format, tx/rx regs enabled */
  534. stb r4, 0(r3)
  535. /* output a few line feeds */
  536. addi r3, 0, '\n' /* load line feed */
  537. bl post_putc /* output the char */
  538. addi r3, 0, '\n' /* load line feed */
  539. bl post_putc /* output the char */
  540. /* restore stack and return */
  541. lwz r0, +12(r1) /* Get saved link register */
  542. mtlr r0 /* Restore link register */
  543. addi r1, r1, +8 /* Remove frame from stack */
  544. blr /* Return to calling function */
  545. /**********************************************************************
  546. ** post_putc
  547. ** outputs charactor in R3
  548. ** r3 returns the error code ( -1 if there is an error )
  549. *********************************************************************/
  550. post_putc:
  551. /* save the return info on stack */
  552. mflr r0 /* Get link register */
  553. stwu r1, -20(r1) /* Save back chain and move SP */
  554. stw r0, +24(r1) /* Save link register */
  555. stmw r29, 8(r1) /* save r29 - r31 on stack
  556. r31 - uart base address
  557. r30 - delay counter
  558. r29 - scratch reg */
  559. addis r31, 0, 0xef60 /* Point to uart base */
  560. ori r31, r31, 0x0300
  561. addis r30, 0, 152 /* Load about 10,000,000 ticks. */
  562. pputc_lp:
  563. lbz r29, 5(r31) /* Read Line Status Register */
  564. andi. r29, r29, 0x20 /* Check THRE status */
  565. bne thre_set /* Branch if FIFO empty */
  566. addic. r30, r30, -1 /* Decrement and check if empty. */
  567. bne pputc_lp /* Try, try again */
  568. addi r3, 0, -1 /* Load error code for timeout */
  569. b pputc_done /* Bail out with error code set */
  570. thre_set:
  571. stb r3, 0(r31) /* Store character to UART */
  572. addi r3, 0, 0 /* clear error code */
  573. pputc_done:
  574. lmw r29, 8(r1) /*restore r29 - r31 from stack */
  575. lwz r0, +24(r1) /* Get saved link register */
  576. addi r1, r1, +20 /* Remove frame from stack */
  577. mtlr r0 /* Restore link register */
  578. blr /* Return to calling function */
  579. /****************************************************************
  580. post_puts
  581. Accepts a null-terminated string pointed to by R3
  582. Outputs to the serial port until 0x00 is found.
  583. r3 returns the error code ( -1 if there is an error )
  584. *****************************************************************/
  585. post_puts:
  586. /* save the return info on stack */
  587. mflr r0 /* Get link register */
  588. stwu r1, -12(r1) /* Save back chain and move SP */
  589. stw r0, +16(r1) /* Save link register */
  590. stw r31, 8(r1) /* save r31 - char pointer */
  591. addi r31, r3, 0 /* move pointer to R31 */
  592. pputs_nxt:
  593. lbz r3, 0(r31) /* Get next character */
  594. addic. r3, r3, 0 /* Check for zero */
  595. beq pputs_term /* bail out if zero */
  596. bl post_putc /* output the char */
  597. addic. r3, r3, 0 /* check for error */
  598. bne pputs_err
  599. addi r31, r31, 1 /* point to next char */
  600. b pputs_nxt /* loop till term */
  601. pputs_err:
  602. addi r3, 0, -1 /* set error code */
  603. b pputs_end /* were outa here */
  604. pputs_term:
  605. addi r3, 0, 1 /* set success code */
  606. /* restore stack and return */
  607. pputs_end:
  608. lwz r31, 8(r1) /* restore r27 - r31 from stack */
  609. lwz r0, +16(r1) /* Get saved link register */
  610. addi r1, r1, +12 /* Remove frame from stack */
  611. mtlr r0 /* Restore link register */
  612. blr /* Return to calling function */
  613. /********************************************************************
  614. ***** disp_hex
  615. ***** Routine to display a hex value from a register.
  616. ***** R3 is value to display
  617. ***** R4 is number of nibbles to display ie 2 for byte 8 for (long)word
  618. ***** Returns -1 in R3 if there is an error ( ie serial port hangs )
  619. ***** Returns 0 in R3 if no error
  620. *******************************************************************/
  621. disp_hex:
  622. /* save the return info on stack */
  623. mflr r0 /* Get link register */
  624. stwu r1, -16(r1) /* Save back chain and move SP */
  625. stw r0, +20(r1) /* Save link register */
  626. stmw r30, 8(r1) /* save r30 - r31 on stack */
  627. /* r31 output char */
  628. /* r30 uart base address */
  629. addi r30, 0, 8 /* Go through 8 nibbles. */
  630. addi r31, r3, 0
  631. pputh_nxt:
  632. rlwinm r31, r31, 4, 0, 31 /* Rotate next nibble into position */
  633. andi. r3, r31, 0x0f /* Get nibble. */
  634. addi r3, r3, 0x30 /* Add zero's ASCII code. */
  635. cmpwi r3, 0x03a
  636. blt pputh_out
  637. addi r3, r3, 0x07 /* 0x27 for lower case. */
  638. pputh_out:
  639. cmpw r30, r4
  640. bgt pputh_skip
  641. bl post_putc
  642. addic. r3, r3, 0 /* check for error */
  643. bne pputh_err
  644. pputh_skip:
  645. addic. r30, r30, -1
  646. bne pputh_nxt
  647. xor r3, r3, r3 /* Clear error code */
  648. b pputh_done
  649. pputh_err:
  650. addi r3, 0, -1 /* set error code */
  651. pputh_done:
  652. /* restore stack and return */
  653. lmw r30, 8(r1) /* restore r30 - r31 from stack */
  654. lwz r0, +20(r1) /* Get saved link register */
  655. addi r1, r1, +16 /* Remove frame from stack */
  656. mtlr r0 /* Restore link register */
  657. blr /* Return to calling function */