sc520_asm.S 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  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. .globl mem_init
  167. mem_init:
  168. /* Preserve Boot Flags */
  169. movl %ebx, %ebp
  170. /* initialize dram controller registers */
  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. /* setup loop to do 4 external banks starting with bank 3 */
  180. movl $0xff000000, %eax /* enable last bank and setup */
  181. movl $DRCBENDADR, %edi /* ending address register */
  182. movl %eax, (%edi)
  183. movl $DRCCFG, %edi /* setup */
  184. movw $0xbbbb, %ax /* dram config register for */
  185. movw %ax, (%edi)
  186. /* issue a NOP to all DRAMs */
  187. movl $DRCCTL, %edi /* setup DRAM control register with */
  188. movb $0x01, %al /* Disable refresh,disable write buffer */
  189. movb %al, (%edi)
  190. movl $CACHELINESZ, %esi /* just a dummy address to write for */
  191. movw %ax, (%esi)
  192. /* delay for 100 usec? */
  193. movw $100, %cx
  194. sizdelay:
  195. loop sizdelay
  196. /* issue all banks precharge */
  197. movb $0x02, %al
  198. movb %al, (%edi)
  199. movw %ax, (%esi)
  200. /* issue 2 auto refreshes to all banks */
  201. movb $0x04, %al /* Auto refresh cmd */
  202. movb %al, (%edi)
  203. movw $0x02, %cx
  204. refresh1:
  205. movw %ax, (%esi)
  206. loop refresh1
  207. /* issue LOAD MODE REGISTER command */
  208. movb $0x03, %al /* Load mode register cmd */
  209. movb %al, (%edi)
  210. movw %ax, (%esi)
  211. /* issue 8 more auto refreshes to all banks */
  212. movb $0x04, %al /* Auto refresh cmd */
  213. movb %al, (%edi)
  214. movw $0x0008, %cx
  215. refresh2:
  216. movw %ax, (%esi)
  217. loop refresh2
  218. /* set control register to NORMAL mode */
  219. movb $0x00, %al /* Normal mode value */
  220. movb %al, (%edi)
  221. /*
  222. * size dram starting with external bank 3
  223. * moving to external bank 0
  224. */
  225. movl $0x3, %ecx /* start with external bank 3 */
  226. nextbank:
  227. /* write col 11 wrap adr */
  228. movl $COL11_ADR, %esi /* set address to max col (11) wrap addr */
  229. movl $COL11_DATA, %eax /* pattern for max supported columns(11) */
  230. movl %eax, (%esi) /* write max col pattern at max col adr */
  231. movl (%esi), %ebx /* optional read */
  232. cmpl %ebx, %eax /* to verify write */
  233. jnz bad_ram /* this ram is bad */
  234. /* write col 10 wrap adr */
  235. movl $COL10_ADR, %esi /* set address to 10 col wrap address */
  236. movl $COL10_DATA, %eax /* pattern for 10 col wrap */
  237. movl %eax, (%esi) /* write 10 col pattern @ 10 col wrap adr */
  238. movl (%esi), %ebx /* optional read */
  239. cmpl %ebx, %eax /* to verify write */
  240. jnz bad_ram /* this ram is bad */
  241. /* write col 9 wrap adr */
  242. movl $COL09_ADR, %esi /* set address to 9 col wrap address */
  243. movl $COL09_DATA, %eax /* pattern for 9 col wrap */
  244. movl %eax, (%esi) /* write 9 col pattern @ 9 col wrap adr */
  245. movl (%esi), %ebx /* optional read */
  246. cmpl %ebx, %eax /* to verify write */
  247. jnz bad_ram /* this ram is bad */
  248. /* write col 8 wrap adr */
  249. movl $COL08_ADR, %esi /* set address to min(8) col wrap address */
  250. movl $COL08_DATA, %eax /* pattern for min (8) col wrap */
  251. movl %eax, (%esi) /* write min col pattern @ min col adr */
  252. movl (%esi), %ebx /* optional read */
  253. cmpl %ebx, %eax /* to verify write */
  254. jnz bad_ram /* this ram is bad */
  255. /* write row 14 wrap adr */
  256. movl $ROW14_ADR, %esi /* set address to max row (14) wrap addr */
  257. movl $ROW14_DATA, %eax /* pattern for max supported rows(14) */
  258. movl %eax, (%esi) /* write max row pattern at max row adr */
  259. movl (%esi), %ebx /* optional read */
  260. cmpl %ebx, %eax /* to verify write */
  261. jnz bad_ram /* this ram is bad */
  262. /* write row 13 wrap adr */
  263. movl $ROW13_ADR, %esi /* set address to 13 row wrap address */
  264. movl $ROW13_DATA, %eax /* pattern for 13 row wrap */
  265. movl %eax, (%esi) /* write 13 row pattern @ 13 row wrap adr */
  266. movl (%esi), %ebx /* optional read */
  267. cmpl %ebx, %eax /* to verify write */
  268. jnz bad_ram /* this ram is bad */
  269. /* write row 12 wrap adr */
  270. movl $ROW12_ADR, %esi /* set address to 12 row wrap address */
  271. movl $ROW12_DATA, %eax /* pattern for 12 row wrap */
  272. movl %eax, (%esi) /* write 12 row pattern @ 12 row wrap adr */
  273. movl (%esi), %ebx /* optional read */
  274. cmpl %ebx, %eax /* to verify write */
  275. jnz bad_ram /* this ram is bad */
  276. /* write row 11 wrap adr */
  277. movl $ROW11_ADR, %edi /* set address to 11 row wrap address */
  278. movl $ROW11_DATA, %eax /* pattern for 11 row wrap */
  279. movl %eax, (%edi) /* write 11 row pattern @ 11 row wrap adr */
  280. movl (%edi), %ebx /* optional read */
  281. cmpl %ebx, %eax /* to verify write */
  282. jnz bad_ram /* this ram is bad */
  283. /*
  284. * write row 10 wrap adr --- this write is really to determine
  285. * number of banks
  286. */
  287. movl $ROW10_ADR, %edi /* set address to 10 row wrap address */
  288. movl $ROW10_DATA, %eax /* pattern for 10 row wrap (AA) */
  289. movl %eax, (%edi) /* write 10 row pattern @ 10 row wrap adr */
  290. movl (%edi), %ebx /* optional read */
  291. cmpl %ebx, %eax /* to verify write */
  292. jnz bad_ram /* this ram is bad */
  293. /*
  294. * read data @ row 12 wrap adr to determine * banks,
  295. * and read data @ row 14 wrap adr to determine * rows.
  296. * if data @ row 12 wrap adr is not AA, 11 or 12 we have bad RAM.
  297. * if data @ row 12 wrap == AA, we only have 2 banks, NOT 4
  298. * if data @ row 12 wrap == 11 or 12, we have 4 banks,
  299. */
  300. xorw %di, %di /* value for 2 banks in DI */
  301. movl (%esi), %ebx /* read from 12 row wrap to check banks */
  302. /* (esi is setup from the write to row 12 wrap) */
  303. cmpl %ebx, %eax /* check for AA pattern (eax holds the aa pattern) */
  304. jz only2 /* if pattern == AA, we only have 2 banks */
  305. /* 4 banks */
  306. movw $0x008, %di /* value for 4 banks in DI (BNK_CNT bit) */
  307. cmpl $ROW11_DATA, %ebx /* only other legitimate values are 11 */
  308. jz only2
  309. cmpl $ROW12_DATA, %ebx /* and 12 */
  310. jnz bad_ram /* its bad if not 11 or 12! */
  311. /* fall through */
  312. only2:
  313. /*
  314. * validate row mask
  315. */
  316. movl $ROW14_ADR, %esi /* set address back to max row wrap addr */
  317. movl (%esi), %eax /* read actual number of rows @ row14 adr */
  318. cmpl $ROW11_DATA, %eax /* row must be greater than 11 pattern */
  319. jb bad_ram
  320. cmpl $ROW14_DATA, %eax /* and row must be less than 14 pattern */
  321. ja bad_ram
  322. cmpb %ah, %al /* verify all 4 bytes of dword same */
  323. jnz bad_ram
  324. movl %eax, %ebx
  325. shrl $16, %ebx
  326. cmpw %bx, %ax
  327. jnz bad_ram
  328. /*
  329. * read col 11 wrap adr for real column data value
  330. */
  331. movl $COL11_ADR, %esi /* set address to max col (11) wrap addr */
  332. movl (%esi), %eax /* read real col number at max col adr */
  333. /*
  334. * validate column data
  335. */
  336. cmpl $COL08_DATA, %eax /* col must be greater than 8 pattern */
  337. jb bad_ram
  338. cmpl $COL11_DATA, %eax /* and row must be less than 11 pattern */
  339. ja bad_ram
  340. subl $COL08_DATA, %eax /* normalize column data to zero */
  341. jc bad_ram
  342. cmpb %ah, %al /* verify all 4 bytes of dword equal */
  343. jnz bad_ram
  344. movl %eax, %edx
  345. shrl $16, %edx
  346. cmpw %dx, %ax
  347. jnz bad_ram
  348. /*
  349. * merge bank and col data together
  350. */
  351. addw %di, %dx /* merge of bank and col info in dl */
  352. /*
  353. * fix ending addr mask based upon col info
  354. */
  355. movb $0x03, %al
  356. subb %dh, %al /* dh contains the overflow from the bank/col merge */
  357. movb %bl, %dh /* bl contains the row mask (aa, 07, 0f, 1f or 3f) */
  358. xchgw %cx, %ax /* cx = ax = 3 or 2 depending on 2 or 4 bank device */
  359. shrb %cl, %dh
  360. incb %dh /* ending addr is 1 greater than real end */
  361. xchgw %cx, %ax /* cx is bank number again */
  362. bad_reint:
  363. /*
  364. * issue all banks precharge
  365. */
  366. movl $DRCCTL, %esi /* setup DRAM control register with */
  367. movb $0x02, %al /* All banks precharge */
  368. movb %al, (%esi)
  369. movl $CACHELINESZ, %esi /* address to init read buffer */
  370. movw %ax, (%esi)
  371. /*
  372. * update ENDING ADDRESS REGISTER
  373. */
  374. movl $DRCBENDADR, %edi /* DRAM ending address register */
  375. movl %ecx, %ebx
  376. addl %ebx, %edi
  377. movb %dh, (%edi)
  378. /*
  379. * update CONFIG REGISTER
  380. */
  381. xorb %dh, %dh
  382. movw $0x000f, %bx
  383. movw %cx, %ax
  384. shlw $2, %ax
  385. xchgw %cx, %ax
  386. shlw %cl, %dx
  387. shlw %cl, %bx
  388. notw %bx
  389. xchgw %cx, %ax
  390. movl $DRCCFG, %edi
  391. movw (%edi), %ax
  392. andw %bx, %ax
  393. orw %dx, %ax
  394. movw %ax, (%edi)
  395. jcxz cleanup
  396. decw %cx
  397. movl %ecx, %ebx
  398. movl $DRCBENDADR, %edi /* DRAM ending address register */
  399. movb $0xff, %al
  400. addl %ebx, %edi
  401. movb %al, (%edi)
  402. /*
  403. * set control register to NORMAL mode
  404. */
  405. movl $DRCCTL, %esi /* setup DRAM control register with */
  406. movb $0x00, %al /* Normal mode value */
  407. movb %al, (%esi)
  408. movl $CACHELINESZ, %esi /* address to init read buffer */
  409. movw %ax, (%esi)
  410. jmp nextbank
  411. cleanup:
  412. movl $DRCBENDADR, %edi /* DRAM ending address register */
  413. movw $0x04, %cx
  414. xorw %ax, %ax
  415. cleanuplp:
  416. movb (%edi), %al
  417. orb %al, %al
  418. jz emptybank
  419. addb %ah, %al
  420. jns nottoomuch
  421. movb $0x7f, %al
  422. nottoomuch:
  423. movb %al, %ah
  424. orb $0x80, %al
  425. movb %al, (%edi)
  426. emptybank:
  427. incl %edi
  428. loop cleanuplp
  429. #if defined CONFIG_SYS_SDRAM_DRCTMCTL
  430. /* just have your hardware desinger _GIVE_ you what you need here! */
  431. movl $DRCTMCTL, %edi
  432. movb $CONFIG_SYS_SDRAM_DRCTMCTL, %al
  433. movb %al, (%edi)
  434. #else
  435. #if defined(CONFIG_SYS_SDRAM_CAS_LATENCY_2T) || defined(CONFIG_SYS_SDRAM_CAS_LATENCY_3T)
  436. /*
  437. * Set the CAS latency now since it is hard to do
  438. * when we run from the RAM
  439. */
  440. movl $DRCTMCTL, %edi /* DRAM timing register */
  441. movb (%edi), %al
  442. #ifdef CONFIG_SYS_SDRAM_CAS_LATENCY_2T
  443. andb $0xef, %al
  444. #endif
  445. #ifdef CONFIG_SYS_SDRAM_CAS_LATENCY_3T
  446. orb $0x10, %al
  447. #endif
  448. movb %al, (%edi)
  449. #endif
  450. #endif
  451. movl $DRCCTL, %edi /* DRAM Control register */
  452. movb $0x03, %al /* Load mode register cmd */
  453. movb %al, (%edi)
  454. movw %ax, (%esi)
  455. movl $DRCCTL, %edi /* DRAM Control register */
  456. movb $0x18, %al /* Enable refresh and NORMAL mode */
  457. movb %al, (%edi)
  458. jmp dram_done
  459. bad_ram:
  460. xorl %edx, %edx
  461. xorl %edi, %edi
  462. jmp bad_reint
  463. dram_done:
  464. /* Restore Boot Flags */
  465. movl %ebx, %ebp
  466. jmp mem_init_ret
  467. #if CONFIG_SYS_SDRAM_ECC_ENABLE
  468. .globl init_ecc
  469. init_ecc:
  470. /* A nominal memory test: just a byte at each address line */
  471. movl %eax, %ecx
  472. shrl $0x1, %ecx
  473. movl $0x1, %edi
  474. memtest0:
  475. movb $0xa5, (%edi)
  476. cmpb $0xa5, (%edi)
  477. jne out
  478. shrl $0x1, %ecx
  479. andl %ecx, %ecx
  480. jz set_ecc
  481. shll $0x1, %edi
  482. jmp memtest0
  483. set_ecc:
  484. /* clear all ram with a memset */
  485. movl %eax, %ecx
  486. xorl %esi, %esi
  487. xorl %edi, %edi
  488. xorl %eax, %eax
  489. shrl $0x2, %ecx
  490. cld
  491. rep stosl
  492. /* enable read, write buffers */
  493. movb $0x11, %al
  494. movl $DBCTL, %edi
  495. movb %al, (%edi)
  496. /* enable NMI mapping for ECC */
  497. movl $ECCINT, %edi
  498. movb $0x10, %al
  499. movb %al, (%edi)
  500. /* Turn on ECC */
  501. movl $ECCCTL, %edi
  502. movb $0x05, %al
  503. movb %al,(%edi)
  504. out:
  505. jmp init_ecc_ret
  506. #endif
  507. /*
  508. * Read and decode the sc520 DRCBENDADR MMCR and return the number of
  509. * available ram bytes in %eax
  510. */
  511. .globl get_mem_size
  512. get_mem_size:
  513. movl $DRCBENDADR, %edi /* DRAM ending address register */
  514. bank0: movl (%edi), %eax
  515. movl %eax, %ecx
  516. andl $0x00000080, %ecx
  517. jz bank1
  518. andl $0x0000007f, %eax
  519. shll $22, %eax
  520. movl %eax, %edx
  521. bank1: movl (%edi), %eax
  522. movl %eax, %ecx
  523. andl $0x00008000, %ecx
  524. jz bank2
  525. andl $0x00007f00, %eax
  526. shll $14, %eax
  527. movl %eax, %edx
  528. bank2: movl (%edi), %eax
  529. movl %eax, %ecx
  530. andl $0x00800000, %ecx
  531. jz bank3
  532. andl $0x007f0000, %eax
  533. shll $6, %eax
  534. movl %eax, %edx
  535. bank3: movl (%edi), %eax
  536. movl %eax, %ecx
  537. andl $0x80000000, %ecx
  538. jz done
  539. andl $0x7f000000, %eax
  540. shrl $2, %eax
  541. movl %eax, %edx
  542. done:
  543. movl %edx, %eax
  544. jmp get_mem_size_ret