I am trying to write so code to find the amount of memory available in a device. It can either have 2,4,8, or 16 meg's. The memory starts at 0x00000000. What is the best way to find how much is their. Here is what I am trying now but is their a better (prettier) way. #define DRAM_BASE 0x00000000 #define DRAM_END_2MB 0x001FFFFF #define DRAM_END_4MB 0x003FFFFF #define DRAM_END_8MB 0x007FFFFF #define DRAM_END_16MB 0x00FFFFFF unsigned int probe_dram(void){ char tmp; volatile unsigned char *dram; dram = (volatile unsigned char *) DRAM_BASE; tmp = dram[0]; printk("0mb\n"); dram = (volatile unsigned char *) DRAM_END_2MB; tmp = dram[0]; printk("2mb\n"); dram = (volatile unsigned char *) DRAM_END_4MB; tmp = dram[0]; printk("4mb\n"); dram = (volatile unsigned char *) DRAM_END_8MB; tmp = dram[0]; printk("8mb\n"); dram = (volatile unsigned char *) DRAM_END_16MB; tmp = dram[0]; printk("16mb\n"); return 0; } -kyle
Probing Memory to find size
Started by ●February 9, 2006
Reply by ●February 9, 20062006-02-09
On 9 Feb 2006 18:05:57 -0800, kyle.tk@gmail.com wrote:>I am trying to write so code to find the amount of memory available in >a device. It can either have 2,4,8, or 16 meg's. The memory starts at >0x00000000. What is the best way to find how much is their. Here is >what I am trying now but is their a better (prettier) way.Why does your function always return 0? I see you are reading a memory location, here and there. But how are you planning to detect the presence or absence of memory at those locations? Do you imagine that simply performing a memory reference is sufficient? If so, how does your code detect a failure? Beyond that, you might start out attempting 16M first, fall back to a test for 4M second, if that fails. If 4M succeeds, try 8M. If 4M fails, verify the 2M. Jon
Reply by ●February 9, 20062006-02-09
kyle.tk@gmail.com wrote:> I am trying to write so code to find the amount of memory available in > a device. It can either have 2,4,8, or 16 meg's. The memory starts at > 0x00000000. What is the best way to find how much is their. Here is > what I am trying now but is their a better (prettier) way. > > #define DRAM_BASE 0x00000000 > #define DRAM_END_2MB 0x001FFFFF > #define DRAM_END_4MB 0x003FFFFF > #define DRAM_END_8MB 0x007FFFFF > #define DRAM_END_16MB 0x00FFFFFF > unsigned int probe_dram(void){ > char tmp; > volatile unsigned char *dram; > > dram = (volatile unsigned char *) DRAM_BASE; > tmp = dram[0]; > printk("0mb\n"); > dram = (volatile unsigned char *) DRAM_END_2MB; > tmp = dram[0]; > printk("2mb\n"); > dram = (volatile unsigned char *) DRAM_END_4MB; > tmp = dram[0]; > printk("4mb\n"); > dram = (volatile unsigned char *) DRAM_END_8MB; > tmp = dram[0]; > printk("8mb\n"); > dram = (volatile unsigned char *) DRAM_END_16MB; > tmp = dram[0]; > printk("16mb\n"); > return 0; > } > > -kyleAs John pointed out, your code will likely bomb if there happens to be a memory failure (or at least return incorrect results). In any case, what I would do is a more exhaustive test. That is writing a simple test pattern to the memory and verifying the pattern. It works for me as I did this in my homebrew Z80 sbc's firmware and it detected memory wiring errors 100%. I am not claiming it is perfect, but it is an improvement over your suggested method.
Reply by ●February 10, 20062006-02-10
kyle.tk@gmail.com wrote:> I am trying to write so code to find the amount of memory available in > a device. It can either have 2,4,8, or 16 meg's. The memory starts at > 0x00000000. What is the best way to find how much is their. Here is > what I am trying now but is their a better (prettier) way.First of all, use a simple FOR loop to generate your test addresses. Since *your* memory sizes are always a power of 2, start with 16MB and halve your address (ie. shift right by 1) each time your test fails. for (addr=(16<<20); addr; addr>>=1) { if (test_succeeds_just_below_this_address) break; } printk ("%d MB\n", addr>>20); (I'm assuming your C pre-processor can do the arithmetic) A few caveats with memory tests like this... 1. Make sure you don't have address aliasing - i.e. the addresses don't wrap at some limit and writing to a high address actually writes to a lower address. 2. In some cases you can write to 'nothing' and pre-charge the bus so that reading from 'nothing' returns the same result! You should also exercise all byte lanes and read/write 32-bit values. For a *simple* test, write different values to two sucessive addresses (eg. 16MB-4 & 16MB-8) and then read them both back (in the same order). And a tip on 'prettiness' - never use what I scientifically refer to as 'yucky numbers' - especially is there are a bunch of them - make the C pre-processor do the work for you! Instead of ...> #define DRAM_BASE 0x00000000 > #define DRAM_END_2MB 0x001FFFFF > #define DRAM_END_4MB 0x003FFFFFUse: #define MB(x) ((x)<<20) #define DRAM_END_MB(x) (MB(x)-1) So, again assuming a decent C pre-processor, using 'DRAM_END_MB(4)' will result in '0x003FFFFF' being compiled into your code. Regards, Mark