sc520_asm.S 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  1. /*
  2. * (C) Copyright 2002
  3. * Daniel Engström, Omicron Ceti AB <daniel@omicron.se>.
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. /* This file is largely based on code obtned from AMD. AMD's original
  24. * copyright is included below
  25. */
  26. /* TITLE SIZER - Aspen DRAM Sizing Routine.
  27. * =============================================================================
  28. *
  29. * Copyright 1999 Advanced Micro Devices, Inc.
  30. * You may redistribute this program and/or modify this program under the terms
  31. * of the GNU General Public License as published by the Free Software Foundation;
  32. * either version 2 of the License, or (at your option) any later version.
  33. *
  34. * This program is distributed WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED
  35. * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  36. * General Public License for more details.
  37. *
  38. * You should have received a copy of the GNU General Public License along with
  39. * this program; if not, write to the Free Software Foundation, Inc.,
  40. * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  41. *
  42. * THE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY
  43. * OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT OF
  44. * THIRD-PARTY INTELLECTUAL PROPERTY, OR FITNESS FOR ANY PARTICULAR PURPOSE.
  45. * IN NO EVENT SHALL AMD OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER
  46. * (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS
  47. * INTERRUPTION, LOSS OF INFORMATION) ARISING OUT OF THE USE OF OR INABILITY
  48. * TO USE THE MATERIALS, EVEN IF AMD HAS BEEN ADVISED OF THE POSSIBILITY OF
  49. * SUCH DAMAGES. BECAUSE SOME JURSIDICTIONS PROHIBIT THE EXCLUSION OR
  50. * LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE
  51. * LIMITATION MAY NOT APPLY TO YOU.
  52. *
  53. * AMD does not assume any responsibility for any errors that may appear in
  54. * the Materials nor any responsibility to support or update the Materials.
  55. * AMD retains the right to make changes to its test specifications at any
  56. * time, without notice.
  57. * ==============================================================================
  58. */
  59. /*
  60. ******************************************************************************
  61. *
  62. * FILE : sizer.asm - SDRAM DIMM Sizing Algorithm
  63. *
  64. *
  65. *
  66. * FUNCTIONS : sizemem() - jumped to, not called. To be executed after
  67. * reset to determine the size of the SDRAM DIMMs. Initializes
  68. * the memory subsystem.
  69. *
  70. *
  71. * AUTHOR : Buddy Fey - Original.
  72. *
  73. *
  74. * DESCRIPTION : Performs sizing on SDRAM DIMMs on ASPEN processor.
  75. * NOTE: This is a small memory model version
  76. *
  77. *
  78. * INPUTS : BP contains return address offset
  79. * CACHE is assumed to be disabled.
  80. * The FS segment limit has already been set to big real mode
  81. * (full 32-bit addressing capability)
  82. *
  83. *
  84. * OUTPUTS : None
  85. *
  86. *
  87. * REG USE : ax,bx,cx,dx,di,si,bp, fs
  88. *
  89. *
  90. * REVISION : See PVCS info below
  91. *
  92. *
  93. * TEST PLAN CROSS REFERENCE:
  94. *
  95. *
  96. * $Workfile: $
  97. * $Revision: 1.2 $
  98. * $Date: 1999/09/22 12:49:33 $
  99. * $Author: chipf $
  100. * $Log: sizer.asm $
  101. * Revision 1.2 1999/09/22 12:49:33 chipf
  102. * Add legal header
  103. *
  104. *******************************************************************************
  105. */
  106. /*******************************************************************************
  107. * FUNCTIONAL DESCRIPTION:
  108. * This routine is called to autodetect the geometry of the DRAM.
  109. *
  110. * This routine is called to determine the number of column bits for the DRAM
  111. * devices in this external bank. This routine assumes that the external bank
  112. * has been configured for an 11-bit column and for 4 internal banks. This gives
  113. * us the maximum address reach in memory. By writing a test value to the max
  114. * address and locating where it aliases to, we can determine the number of valid
  115. * column bits.
  116. *
  117. * This routine is called to determine the number of internal banks each DRAM
  118. * device has. The external bank (under test) is configured for maximum reach
  119. * with 11-bit columns and 4 internal banks. This routine will write to a max
  120. * address (BA1 and BA0 = 1) and then read from an address with BA1=0 to see if
  121. * that column is a "don't care". If BA1 does not affect write/read of data,
  122. * then this device has only 2 internal banks.
  123. *
  124. * This routine is called to determine the ending address for this external
  125. * bank of SDRAM. We write to a max address with a data value and then disable
  126. * row address bits looking for "don't care" locations. Each "don't care" bit
  127. * represents a dividing of the maximum density (128M) by 2. By dividing the
  128. * maximum of 32 4M chunks in an external bank down by all the "don't care" bits
  129. * determined during sizing, we set the proper density.
  130. *
  131. * WARNINGS.
  132. * bp must be preserved because it is used for return linkage.
  133. *
  134. * EXIT
  135. * nothing returned - but the memory subsystem is enabled
  136. *******************************************************************************
  137. */
  138. #include <config.h>
  139. .section .text
  140. .equ DRCCTL, 0x0fffef010 /* DRAM control register */
  141. .equ DRCTMCTL, 0x0fffef012 /* DRAM timing control register */
  142. .equ DRCCFG, 0x0fffef014 /* DRAM bank configuration register */
  143. .equ DRCBENDADR, 0x0fffef018 /* DRAM bank ending address register */
  144. .equ ECCCTL, 0x0fffef020 /* DRAM ECC control register */
  145. .equ ECCINT, 0x0fffefd18 /* DRAM ECC nmi-INT mapping */
  146. .equ DBCTL, 0x0fffef040 /* DRAM buffer control register */
  147. .equ CACHELINESZ, 0x00000010 /* size of our cache line (read buffer) */
  148. .equ COL11_ADR, 0x0e001e00 /* 11 col addrs */
  149. .equ COL10_ADR, 0x0e000e00 /* 10 col addrs */
  150. .equ COL09_ADR, 0x0e000600 /* 9 col addrs */
  151. .equ COL08_ADR, 0x0e000200 /* 8 col addrs */
  152. .equ ROW14_ADR, 0x0f000000 /* 14 row addrs */
  153. .equ ROW13_ADR, 0x07000000 /* 13 row addrs */
  154. .equ ROW12_ADR, 0x03000000 /* 12 row addrs */
  155. .equ ROW11_ADR, 0x01000000 /* 11 row addrs/also bank switch */
  156. .equ ROW10_ADR, 0x00000000 /* 10 row addrs/also bank switch */
  157. .equ COL11_DATA, 0x0b0b0b0b /* 11 col addrs */
  158. .equ COL10_DATA, 0x0a0a0a0a /* 10 col data */
  159. .equ COL09_DATA, 0x09090909 /* 9 col data */
  160. .equ COL08_DATA, 0x08080808 /* 8 col data */
  161. .equ ROW14_DATA, 0x3f3f3f3f /* 14 row data (MASK) */
  162. .equ ROW13_DATA, 0x1f1f1f1f /* 13 row data (MASK) */
  163. .equ ROW12_DATA, 0x0f0f0f0f /* 12 row data (MASK) */
  164. .equ ROW11_DATA, 0x07070707 /* 11 row data/also bank switch (MASK) */
  165. .equ ROW10_DATA, 0xaaaaaaaa /* 10 row data/also bank switch (MASK) */
  166. /*
  167. * initialize dram controller registers
  168. */
  169. .globl mem_init
  170. mem_init:
  171. xorw %ax,%ax
  172. movl $DBCTL, %edi
  173. movb %al, (%edi) /* disable write buffer */
  174. movl $ECCCTL, %edi
  175. movb %al, (%edi) /* disable ECC */
  176. movl $DRCTMCTL, %edi
  177. movb $0x1E,%al /* Set SDRAM timing for slowest */
  178. movb %al, (%edi)
  179. /*
  180. * setup loop to do 4 external banks starting with bank 3
  181. */
  182. movl $0xff000000,%eax /* enable last bank and setup */
  183. movl $DRCBENDADR, %edi /* ending address register */
  184. movl %eax, (%edi)
  185. movl $DRCCFG, %edi /* setup */
  186. movw $0xbbbb,%ax /* dram config register for */
  187. movw %ax, (%edi)
  188. /*
  189. * issue a NOP to all DRAMs
  190. */
  191. movl $DRCCTL, %edi /* setup DRAM control register with */
  192. movb $0x1,%al /* Disable refresh,disable write buffer */
  193. movb %al, (%edi)
  194. movl $CACHELINESZ, %esi /* just a dummy address to write for */
  195. movw %ax, (%esi)
  196. /*
  197. * delay for 100 usec? 200?
  198. * ******this is a cludge for now *************
  199. */
  200. movw $100,%cx
  201. sizdelay:
  202. loop sizdelay /* we need 100 usec here */
  203. /***********************************************/
  204. /*
  205. * issue all banks precharge
  206. */
  207. movb $0x2,%al /* All banks precharge */
  208. movb %al, (%edi)
  209. movw %ax, (%esi)
  210. /*
  211. * issue 2 auto refreshes to all banks
  212. */
  213. movb $0x4,%al /* Auto refresh cmd */
  214. movb %al, (%edi)
  215. movw $2,%cx
  216. refresh1:
  217. movw %ax, (%esi)
  218. loop refresh1
  219. /*
  220. * issue LOAD MODE REGISTER command
  221. */
  222. movb $0x3,%al /* Load mode register cmd */
  223. movb %al, (%edi)
  224. movw %ax, (%esi)
  225. /*
  226. * issue 8 more auto refreshes to all banks
  227. */
  228. movb $0x4,%al /* Auto refresh cmd */
  229. movb %al, (%edi)
  230. movw $8,%cx
  231. refresh2:
  232. movw %ax, (%esi)
  233. loop refresh2
  234. /*
  235. * set control register to NORMAL mode
  236. */
  237. movb $0x0,%al /* Normal mode value */
  238. movb %al, (%edi)
  239. /*
  240. * size dram starting with external bank 3 moving to external bank 0
  241. */
  242. movl $0x3,%ecx /* start with external bank 3 */
  243. nextbank:
  244. /*
  245. * write col 11 wrap adr
  246. */
  247. movl $COL11_ADR, %esi /* set address to max col (11) wrap addr */
  248. movl $COL11_DATA, %eax /* pattern for max supported columns(11) */
  249. movl %eax, (%esi) /* write max col pattern at max col adr */
  250. movl (%esi), %ebx /* optional read */
  251. cmpl %ebx,%eax /* to verify write */
  252. jnz bad_ram /* this ram is bad */
  253. /*
  254. * write col 10 wrap adr
  255. */
  256. movl $COL10_ADR, %esi /* set address to 10 col wrap address */
  257. movl $COL10_DATA, %eax /* pattern for 10 col wrap */
  258. movl %eax, (%esi) /* write 10 col pattern @ 10 col wrap adr */
  259. movl (%esi), %ebx /* optional read */
  260. cmpl %ebx,%eax /* to verify write */
  261. jnz bad_ram /* this ram is bad */
  262. /*
  263. * write col 9 wrap adr
  264. */
  265. movl $COL09_ADR, %esi /* set address to 9 col wrap address */
  266. movl $COL09_DATA, %eax /* pattern for 9 col wrap */
  267. movl %eax, (%esi) /* write 9 col pattern @ 9 col wrap adr */
  268. movl (%esi), %ebx /* optional read */
  269. cmpl %ebx,%eax /* to verify write */
  270. jnz bad_ram /* this ram is bad */
  271. /*
  272. * write col 8 wrap adr
  273. */
  274. movl $COL08_ADR, %esi /* set address to min(8) col wrap address */
  275. movl $COL08_DATA, %eax /* pattern for min (8) col wrap */
  276. movl %eax, (%esi) /* write min col pattern @ min col adr */
  277. movl (%esi), %ebx /* optional read */
  278. cmpl %ebx,%eax /* to verify write */
  279. jnz bad_ram /* this ram is bad */
  280. /*
  281. * write row 14 wrap adr
  282. */
  283. movl $ROW14_ADR, %esi /* set address to max row (14) wrap addr */
  284. movl $ROW14_DATA, %eax /* pattern for max supported rows(14) */
  285. movl %eax, (%esi) /* write max row pattern at max row adr */
  286. movl (%esi), %ebx /* optional read */
  287. cmpl %ebx,%eax /* to verify write */
  288. jnz bad_ram /* this ram is bad */
  289. /*
  290. * write row 13 wrap adr
  291. */
  292. movl $ROW13_ADR, %esi /* set address to 13 row wrap address */
  293. movl $ROW13_DATA, %eax /* pattern for 13 row wrap */
  294. movl %eax, (%esi) /* write 13 row pattern @ 13 row wrap adr */
  295. movl (%esi), %ebx /* optional read */
  296. cmpl %ebx,%eax /* to verify write */
  297. jnz bad_ram /* this ram is bad */
  298. /*
  299. * write row 12 wrap adr
  300. */
  301. movl $ROW12_ADR, %esi /* set address to 12 row wrap address */
  302. movl $ROW12_DATA, %eax /* pattern for 12 row wrap */
  303. movl %eax, (%esi) /* write 12 row pattern @ 12 row wrap adr */
  304. movl (%esi), %ebx /* optional read */
  305. cmpl %ebx,%eax /* to verify write */
  306. jnz bad_ram /* this ram is bad */
  307. /*
  308. * write row 11 wrap adr
  309. */
  310. movl $ROW11_ADR, %edi /* set address to 11 row wrap address */
  311. movl $ROW11_DATA, %eax /* pattern for 11 row wrap */
  312. movl %eax, (%edi) /* write 11 row pattern @ 11 row wrap adr */
  313. movl (%edi), %ebx /* optional read */
  314. cmpl %ebx,%eax /* to verify write */
  315. jnz bad_ram /* this ram is bad */
  316. /*
  317. * write row 10 wrap adr --- this write is really to determine number of banks
  318. */
  319. movl $ROW10_ADR, %edi /* set address to 10 row wrap address */
  320. movl $ROW10_DATA, %eax /* pattern for 10 row wrap (AA) */
  321. movl %eax, (%edi) /* write 10 row pattern @ 10 row wrap adr */
  322. movl (%edi), %ebx /* optional read */
  323. cmpl %ebx,%eax /* to verify write */
  324. jnz bad_ram /* this ram is bad */
  325. /*
  326. * read data @ row 12 wrap adr to determine * banks,
  327. * and read data @ row 14 wrap adr to determine * rows.
  328. * if data @ row 12 wrap adr is not AA, 11 or 12 we have bad RAM.
  329. * if data @ row 12 wrap == AA, we only have 2 banks, NOT 4
  330. * if data @ row 12 wrap == 11 or 12, we have 4 banks,
  331. */
  332. xorw %di,%di /* value for 2 banks in DI */
  333. movl (%esi), %ebx /* read from 12 row wrap to check banks
  334. * (esi is setup from the write to row 12 wrap) */
  335. cmpl %ebx,%eax /* check for AA pattern (eax holds the aa pattern) */
  336. jz only2 /* if pattern == AA, we only have 2 banks */
  337. /* 4 banks */
  338. movw $8,%di /* value for 4 banks in DI (BNK_CNT bit) */
  339. cmpl $ROW11_DATA, %ebx /* only other legitimate values are 11 */
  340. jz only2
  341. cmpl $ROW12_DATA, %ebx /* and 12 */
  342. jnz bad_ram /* its bad if not 11 or 12! */
  343. /* fall through */
  344. only2:
  345. /*
  346. * validate row mask
  347. */
  348. movl $ROW14_ADR, %esi /* set address back to max row wrap addr */
  349. movl (%esi), %eax /* read actual number of rows @ row14 adr */
  350. cmpl $ROW11_DATA, %eax /* row must be greater than 11 pattern */
  351. jb bad_ram
  352. cmpl $ROW14_DATA, %eax /* and row must be less than 14 pattern */
  353. ja bad_ram
  354. cmpb %ah,%al /* verify all 4 bytes of dword same */
  355. jnz bad_ram
  356. movl %eax,%ebx
  357. shrl $16,%ebx
  358. cmpw %bx,%ax
  359. jnz bad_ram
  360. /*
  361. * read col 11 wrap adr for real column data value
  362. */
  363. movl $COL11_ADR, %esi /* set address to max col (11) wrap addr */
  364. movl (%esi), %eax /* read real col number at max col adr */
  365. /*
  366. * validate column data
  367. */
  368. cmpl $COL08_DATA, %eax /* col must be greater than 8 pattern */
  369. jb bad_ram
  370. cmpl $COL11_DATA, %eax /* and row must be less than 11 pattern */
  371. ja bad_ram
  372. subl $COL08_DATA, %eax /* normalize column data to zero */
  373. jc bad_ram
  374. cmpb %ah,%al /* verify all 4 bytes of dword equal */
  375. jnz bad_ram
  376. movl %eax,%edx
  377. shrl $16,%edx
  378. cmpw %dx,%ax
  379. jnz bad_ram
  380. /*
  381. * merge bank and col data together
  382. */
  383. addw %di,%dx /* merge of bank and col info in dl */
  384. /*
  385. * fix ending addr mask based upon col info
  386. */
  387. movb $3,%al
  388. subb %dh,%al /* dh contains the overflow from the bank/col merge */
  389. movb %bl,%dh /* bl contains the row mask (aa, 07, 0f, 1f or 3f) */
  390. xchgw %cx,%ax /* cx = ax = 3 or 2 depending on 2 or 4 bank device */
  391. shrb %cl,%dh /* */
  392. incb %dh /* ending addr is 1 greater than real end */
  393. xchgw %cx,%ax /* cx is bank number again */
  394. /*
  395. * issue all banks precharge
  396. */
  397. bad_reint:
  398. movl $DRCCTL, %esi /* setup DRAM control register with */
  399. movb $0x2,%al /* All banks precharge */
  400. movb %al, (%esi)
  401. movl $CACHELINESZ, %esi /* address to init read buffer */
  402. movw %ax, (%esi)
  403. /*
  404. * update ENDING ADDRESS REGISTER
  405. */
  406. movl $DRCBENDADR, %edi /* DRAM ending address register */
  407. movl %ecx,%ebx
  408. addl %ebx, %edi
  409. movb %dh, (%edi)
  410. /*
  411. * update CONFIG REGISTER
  412. */
  413. xorb %dh,%dh
  414. movw $0x00f,%bx
  415. movw %cx,%ax
  416. shlw $2,%ax
  417. xchgw %cx,%ax
  418. shlw %cl,%dx
  419. shlw %cl,%bx
  420. notw %bx
  421. xchgw %cx,%ax
  422. movl $DRCCFG, %edi
  423. mov (%edi), %ax
  424. andw %bx,%ax
  425. orw %dx,%ax
  426. movw %ax, (%edi)
  427. jcxz cleanup
  428. decw %cx
  429. movl %ecx,%ebx
  430. movl $DRCBENDADR, %edi /* DRAM ending address register */
  431. movb $0xff,%al
  432. addl %ebx, %edi
  433. movb %al, (%edi)
  434. /*
  435. * set control register to NORMAL mode
  436. */
  437. movl $DRCCTL, %esi /* setup DRAM control register with */
  438. movb $0x0,%al /* Normal mode value */
  439. movb %al, (%esi)
  440. movl $CACHELINESZ, %esi /* address to init read buffer */
  441. movw %ax, (%esi)
  442. jmp nextbank
  443. cleanup:
  444. movl $DRCBENDADR, %edi /* DRAM ending address register */
  445. movw $4,%cx
  446. xorw %ax,%ax
  447. cleanuplp:
  448. movb (%edi), %al
  449. orb %al,%al
  450. jz emptybank
  451. addb %ah,%al
  452. jns nottoomuch
  453. movb $0x7f,%al
  454. nottoomuch:
  455. movb %al,%ah
  456. orb $0x80,%al
  457. movb %al, (%edi)
  458. emptybank:
  459. incl %edi
  460. loop cleanuplp
  461. #if defined CONFIG_SYS_SDRAM_DRCTMCTL
  462. /* just have your hardware desinger _GIVE_ you what you need here! */
  463. movl $DRCTMCTL, %edi
  464. movb $CONFIG_SYS_SDRAM_DRCTMCTL,%al
  465. movb %al, (%edi)
  466. #else
  467. #if defined(CONFIG_SYS_SDRAM_CAS_LATENCY_2T) || defined(CONFIG_SYS_SDRAM_CAS_LATENCY_3T)
  468. /* set the CAS latency now since it is hard to do
  469. * when we run from the RAM */
  470. movl $DRCTMCTL, %edi /* DRAM timing register */
  471. movb (%edi), %al
  472. #ifdef CONFIG_SYS_SDRAM_CAS_LATENCY_2T
  473. andb $0xef, %al
  474. #endif
  475. #ifdef CONFIG_SYS_SDRAM_CAS_LATENCY_3T
  476. orb $0x10, %al
  477. #endif
  478. movb %al, (%edi)
  479. #endif
  480. #endif
  481. movl $DRCCTL, %edi /* DRAM Control register */
  482. movb $0x3,%al /* Load mode register cmd */
  483. movb %al, (%edi)
  484. movw %ax, (%esi)
  485. movl $DRCCTL, %edi /* DRAM Control register */
  486. movb $0x18,%al /* Enable refresh and NORMAL mode */
  487. movb %al, (%edi)
  488. jmp dram_done
  489. bad_ram:
  490. xorl %edx,%edx
  491. xorl %edi,%edi
  492. jmp bad_reint
  493. dram_done:
  494. #if CONFIG_SYS_SDRAM_ECC_ENABLE
  495. /*
  496. * We are in the middle of an existing 'call' - Need to store the
  497. * existing return address before making another 'call'
  498. */
  499. movl %ebp, %ebx
  500. /* Get the memory size */
  501. movl $init_ecc, %ebp
  502. jmpl get_mem_size
  503. init_ecc:
  504. /* Restore the orignal return address */
  505. movl %ebx, %ebp
  506. /* A nominal memory test: just a byte at each address line */
  507. movl %eax, %ecx
  508. shrl $0x1, %ecx
  509. movl $0x1, %edi
  510. memtest0:
  511. movb $0xa5, (%edi)
  512. cmpb $0xa5, (%edi)
  513. jne out
  514. shrl $1, %ecx
  515. andl %ecx,%ecx
  516. jz set_ecc
  517. shll $1, %edi
  518. jmp memtest0
  519. set_ecc:
  520. /* clear all ram with a memset */
  521. movl %eax, %ecx
  522. xorl %esi, %esi
  523. xorl %edi, %edi
  524. xorl %eax, %eax
  525. shrl $2, %ecx
  526. cld
  527. rep stosl
  528. /* enable read, write buffers */
  529. movb $0x11, %al
  530. movl $DBCTL, %edi
  531. movb %al, (%edi)
  532. /* enable NMI mapping for ECC */
  533. movl $ECCINT, %edi
  534. mov $0x10, %al
  535. movb %al, (%edi)
  536. /* Turn on ECC */
  537. movl $ECCCTL, %edi
  538. mov $0x05, %al
  539. movb %al, (%edi)
  540. #endif
  541. out:
  542. jmp *%ebp
  543. /*
  544. * Read and decode the sc520 DRCBENDADR MMCR and return the number of
  545. * available ram bytes in %eax
  546. */
  547. .globl get_mem_size
  548. get_mem_size:
  549. movl $DRCBENDADR, %edi /* DRAM ending address register */
  550. bank0: movl (%edi), %eax
  551. movl %eax, %ecx
  552. andl $0x00000080, %ecx
  553. jz bank1
  554. andl $0x0000007f, %eax
  555. shll $22, %eax
  556. movl %eax, %ebx
  557. bank1: movl (%edi), %eax
  558. movl %eax, %ecx
  559. andl $0x00008000, %ecx
  560. jz bank2
  561. andl $0x00007f00, %eax
  562. shll $14, %eax
  563. movl %eax, %ebx
  564. bank2: movl (%edi), %eax
  565. movl %eax, %ecx
  566. andl $0x00800000, %ecx
  567. jz bank3
  568. andl $0x007f0000, %eax
  569. shll $6, %eax
  570. movl %eax, %ebx
  571. bank3: movl (%edi), %eax
  572. movl %eax, %ecx
  573. andl $0x80000000, %ecx
  574. jz done
  575. andl $0x7f000000, %eax
  576. shrl $2, %eax
  577. movl %eax, %ebx
  578. done:
  579. movl %ebx, %eax
  580. jmp *%ebp