搜索
bottom↓
回复: 4

一段获取ddr大小的C语言代码,来自uboot小弟没看懂

[复制链接]

出0入0汤圆

发表于 2019-7-16 18:04:06 | 显示全部楼层 |阅读模式
本帖最后由 WM_CH 于 2019-7-16 18:05 编辑

这段代码是获取ddr大小的,前边对membase的写读写操作和最后对memskip的写操作有什么关系呢?
  1. /*
  2. DMB
  3. 数据存储器隔离。DMB 指令保证: 仅当所有在它前面的存储器访问操作
  4. 都执行完毕后,才提交(commit)在它后面的存储器访问操作。
  5. DSB
  6. 数据同步隔离。比 DMB 严格: 仅当所有在它前面的存储器访问操作
  7. 都执行完毕后,才执行在它后面的指令(亦即任何指令都要等待存储器访 问操作——译者注)
  8. ISB
  9. 指令同步隔离。最严格:它会清洗流水线,以保证所有它前面的指令都执
  10. 行完毕之后,才执行它后面的指令。
  11. */
  12. unsigned int get_ddr_size(void)
  13. {
  14. #define TO_UINT32(_p)   (*(volatile unsigned int *)(_p))
  15.         volatile unsigned char *memskip;
  16.         volatile unsigned char *membase = (unsigned char *)MEM_BASE_DDR;
  17.         unsigned int orgin = TO_UINT32(membase);
  18.         unsigned int rd_origin = 0, rd_verify = 0;
  19.         unsigned int tmp = 0;

  20.         if (ddr_size)
  21.                 return ddr_size;

  22.         //没看懂
  23.         for (memskip = membase + SZ_16M;
  24.              memskip <= membase + get_max_ddr_size();
  25.              memskip += SZ_16M) {

  26.                 TO_UINT32(membase) = 0xA9A9A9A9;
  27.                 tmp = TO_UINT32(membase);
  28.                 TO_UINT32(membase) = tmp;
  29.                 dsb();

  30.                 rd_origin = TO_UINT32(memskip);

  31.                 TO_UINT32(membase) = 0x53535352;
  32.                 tmp = TO_UINT32(membase);
  33.                 TO_UINT32(membase) = tmp;
  34.                 dsb();

  35.                 rd_verify = TO_UINT32(memskip);

  36.                 if (rd_origin != rd_verify) {
  37.                         ddr_size = (unsigned int)(memskip - membase);
  38.                         break;
  39.                 }

  40.                 if (_HI3798CV100A == get_chipid()
  41.                         || _HI3798CV100 == get_chipid()
  42.                         || _HI3796CV100 == get_chipid()) {
  43.                         if ((unsigned int)(memskip - membase) >= (SZ_2G - SZ_16M)) {
  44.                                 ddr_size = SZ_2G;
  45.                                 break;
  46.                         }
  47.                 }

  48.                 if ((unsigned int)(memskip - membase) >= (SZ_3G + SZ_512M)) {
  49.                         ddr_size = SZ_3G + SZ_750M;
  50.                         break;
  51.                 }
  52.         }

  53.         /* restore membase value. */
  54.         TO_UINT32(membase) = orgin;
  55.         return ddr_size;
  56. }
复制代码



重点就是这段:
                TO_UINT32(membase) = 0xA9A9A9A9;
                tmp = TO_UINT32(membase);
                TO_UINT32(membase) = tmp;
                dsb();

                rd_origin = TO_UINT32(memskip);
没明白这段
大哥们指点一下小弟,谢谢








阿莫论坛20周年了!感谢大家的支持与爱护!!

如果想吃一顿饺子,就得从冰箱里取出肉,剁馅儿,倒面粉、揉面、醒面,擀成皮儿,下锅……
一整个繁琐流程,就是为了出锅时那一嘴滚烫流油的热饺子。

如果这个过程,禁不住饿,零食下肚了,饺子出锅时也就不香了……《非诚勿扰3》

出0入0汤圆

 楼主| 发表于 2019-7-17 10:02:51 | 显示全部楼层
顶一下                  

出0入0汤圆

 楼主| 发表于 2019-7-17 10:25:15 | 显示全部楼层
如果 memskip对应实际的DDR时,写membase不会影响到memskip上的值;
否则,你去读写memskip地址,实际上读写的是membase
原因:
就像2440一样,sdram基址是0x30000000,大小是64M,即最大地址是 0x34000000 - 1;
如果你去读写0x34000000,因为这个地址线A26并没有接到硬件上,它发给SDRAM的地址就跟访问0x30000000一样了




出0入0汤圆

发表于 2019-8-30 09:49:26 | 显示全部楼层
这种对于位址转换还真的有点难理解

出0入0汤圆

发表于 2019-10-28 00:17:36 | 显示全部楼层
个人理解,这里实际上是利用内存到内存最大容量后会回读的特性,即:
如果内存为1G,0x0~0x20000000,那从0x20000000读到的数据就是从0x0的值,也就是往0x0内的数据值会影响0x20000000读到的值。
用上述的原理再看代码:
以16M为单位(认为内存总容量是16M的倍数),每次都是先对base写2个不同的数,并在写后读当前假定的容量所在地址,如果到达了容量值2次读的就不一样(分别对base写的2次,这时break就得到了),如果没达到那2次的值应该一样(该地址本身的值)。
上述过程都只是对base地址写,对skip地址读,最后测试完,还要恢复base地址原来的值。

这个方法的能工作的前提应该是:
1. CPU能访问比实际容量大的地址(对于有MMU的CPU,要有相应map);
2. CPU在访问超实际容量的内存地址时,物理上是读回的是回转到base的。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-28 18:46

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表