📄 mem285.s
字号:
* r2 - scratch offset * r1 - base address of 64M block in consideration * r0 - base address of control register sets */ mov r8, #SA110_SDRAM_ADDRESS_SIZE_ARRAY_0_o mov r1, #0 ldr r5, =0x12345678 mvn r4, r5 20: str r5, [r1] // Offset 0 should work regardless str r4, [r1, #4] // put something else on the data bus ldr r3, [r1] // read back original cmps r3, r5 // If we didn't read pattern, then no memory present movne r3, #0 strne r3, [r0, r8] // write to addr/size register bne 49f // straight to next loop /* * This bank is populated, so try to determine mux mode. * All banks are currently set for mux mode 2. */ // A21 having no effect distinguishes the need for mux mode 0. str r5, [r1] mov r2, #(1 << 21) str r4, [r1, r2] // Store bad value at A21 mirror address // expect to trash value at r1 if mode 0 ldr r3, [r1] cmps r3, r5 // If we don't read back pattern, then its mux mode 0 // Force to 32M size to include A18 when sizing: movne r3, #(SA110_SDRAM_SIZE_32MB | SA110_SDRAM_MUX_MODE0) bne 2f // A23 having effect distinguishes the need for mux mode 2. str r5, [r1] mov r2, #(1 << 23) str r4, [r1, r2] // Store bad value at A23 mirror address // expect to preserve value at r1 if mode 2 ldr r3, [r1] cmps r3, r5 // if pattern still there, then mode 2 moveq r3, #(SA110_SDRAM_SIZE_64MB | SA110_SDRAM_MUX_MODE2) beq 2f // A22 having effect distinguishes the need for mux mode 4. str r5, [r1] mov r2, #(1 << 22) str r4, [r1, r2] // Store bad value at A22 mirror address // expect to preserve value at r1 if mode 4 ldr r3, [r1] cmps r3, r5 // if pattern A still there, then mode 4 moveq r3, #(SA110_SDRAM_SIZE_64MB | SA110_SDRAM_MUX_MODE4) beq 2f /* * At this point it is either mode 1 or 3. There is no clear cut * test to differentiate the two, so make a best guess now, then * correct later (if necessary) while sizing the bank. */ // NB the bank is still in mux mode 2, so A24 is fed to the wire for // A22 (mode 1) or no-connection (mode 3); so: // A24 having effect distinguishes the need for mux mode 1 // A24 having no effect distinguishes the need for mux mode 3 str r5, [r1] mov r2, #(1 << 24) str r4, [r1, r2] ldr r3, [r1] cmps r3, r5 // If pattern, try mode 1 moveq r3, #(SA110_SDRAM_SIZE_64MB | SA110_SDRAM_MUX_MODE1) // otherwise, try mode 3 movne r3, #(SA110_SDRAM_SIZE_64MB | SA110_SDRAM_MUX_MODE3) bne 2f 2: orr r3, r3, r1 // add in base address str r3, [r0, r8] // write to addr/size register /* * Now that mux mode for this array is (hopefully) setup, we can try * to size this SDRAM array. * * Register usage: * r8 - offset to current size/mode register * r1 - offset to current base (in 64M blocks) * r0 - base address of control register sets */ mov r4, #(63 << 20) // 63Mb to start with 1: str r4, [r1, r4] subs r4, r4, #(1 << 20) // go down in increments of 1Mb bpl 1b str r4, [r1, #4] // change pattern on data bus // search for first unexpected data in ascending order mov r4, #0 1: ldr r5, [r1, r4] cmps r5, r4 bne 23f // different so end of array add r4, r4, #(1 << 20) // go up in increments of 1Mb cmps r4, #(64 << 20) blt 1b // fall-through assumes it is a 64Mb device 23: movs r4, r4, lsr #20 // get a plain number of Mb // if this gave a zero, maybe we were mistaken about the RAM // working earlier: disable this bank. streq r4, [r0, r8] // write to addr/size register beq 49f // straight to next loop // apparently, mode 3 devices *must* be 8Mb; if we got a different // answer, set it to mode 1 and go back to try again: cmps r4, #8 beq 4f // skip if 8Mb; we are happy ldr r3, [r0, r8] // read in the mode we set and r3, r3, #SA110_SDRAM_MUX_MODE_MASK cmp r3, #SA110_SDRAM_MUX_MODE3 // Must be misconfigured mux mode. Set to mode 1 and retry moveq r3, #(SA110_SDRAM_SIZE_64MB | SA110_SDRAM_MUX_MODE1) beq 2b // not mux mode 3; drop though OK 4: // convert MB size to register size val mov r5, #0 mov r3, r4 5: movs r3, r3, lsr #1 add r5, r5, #1 bcc 5b // Double check that the size was a power of 2 mov r6, #1 mov r6, r6, lsl r5 // should get Mb count back doubled cmps r6, r4, lsl #1 // compare with doubled movne r5, #0 // disable this bank ldr r3, [r0, r8] // Load current setting bic r3, r3, #7 orr r3, r3, r5 // insert the correct size code str r3, [r0, r8] // into the control register 49: add r8, r8, #4 // next addr/size register add r1, r1, #(64<<20) // next array cmps r1, #(256<<20) // top address + 1 bank blt 20b // END of main loop to size all 4 DRAM banks /* * At this point, the size values are all in the control registers. * * We want to set memory up to be contiguous. Since the * banks' base address needs to be naturally aligned, we * need to sort the bank sizes from large to small. * * Register usage: * r0 - base address of control register sets * r1 - bitmap of which slots we have covered in toto * r2 - cumulative base address of mapped SDRAM * r3 - biggest size code this pass * r4 - bit index of current slot * r5 - bit index of biggest slot found this pass * r6 - scratch control reg contents * r7 - scratch size code * r8 - address of current slot's control register * r9 - address of biggest slot found's control register */ mov r1, #0 // bitmap of which we have covered mov r2, #0 // cumulative base address // do... until there are no more slots to deal with 70: mov r3, #0 // biggest this pass mov r4, #1 // bit index of current slot mov r5, #0 // bit index of biggest slot found mov r8, #SA110_SDRAM_ADDRESS_SIZE_ARRAY_0_o mov r9, #0 // address of biggest slot found // Foreach slot we have not yet dealt with 75: tst r4, r1 bne 88f ldr r6, [r0, r8] and r7, r6, #7 cmps r7, r3 movgt r3, r7 // save biggest's size movgt r5, r4 // save biggest's index movgt r9, r8 // save biggest's reg address 88: mov r4, r4, asl #1 add r8, r8, #4 cmps r4, #0x10 blt 75b // next slot // Did we find a largest slot? cmps r5, #0 beq 95f // No! Finished orr r1, r1, r5 // can forget r4 and r5 now ldr r6, [r0, r9] // get the control register bic r6, r6, #0x0ff00000 // clear base address bits orr r6, r6, r2 // insert base address to use str r6, [r0, r9] // store the new control register mov r6, #1 mov r6, r6, asl r3 mov r6, r6, asl #19 // 1 << (size-code + 19) is size add r2, r2, r6 // increment the cumulating address b 70b // go look for the next one 95: // all done! // at this point, r2 contains the top of memory. // (r11 is the value from last time or zero if first time) cmps r11, r2 // Same answer as last time? movne r11, r2 // if not, save memsize bne 12b // ...and try again. mov r0, r2 mov pc, lr #endif // ! defined CYG_HAL_STARTUP_RAM//FUNC_END __mem285_init/* EOF mem285.S */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -