内存概述

内存分类

DRAM:基本存储器件是小电容,需要定期充电(刷新),存储速度较慢。
SRAM:不需要刷新,存取速度快,但功耗大,成本高,常用于存储容量不高,但要求存取速度快的场合,比如stepping stone和cache。
Alt text

内存内部结构

内存的内部如同表格,数据就存在每个单元格中。数据读写时,先指定行号(行地址),再指定列号(列地址),这张表称为Logical Bank(L-Bank)。
由于技术、成本等原因,一块内存芯片不可能把所有的单元格都做到一个L-Bank,现在内存内部基本都会分割成4个L-Bank。Alt text

内存的寻址需要提供以下几个信息:

  1. L-Bank选择信号
  2. 行地址
  3. 列地址

内存容量推导计算公式:
内存容量 = L-Bank数目 单元格数目 单元格容量
以下面这款内存芯片为例:
Alt text

其内存容量为:
64M * 16bit = 128MByte

S3C2440内存初始化

地址空间

Alt text

S3C2440芯片对外提供了27根地址线和32根数据线,单靠芯片上的27根引脚,它只能访问128MB的外设空间。为了扩大外设的访问范围,S3C2440芯片又提供了8个片选信号nGCS0~nGCS7。当某个片选信号nGCSx有效时,则可以通过27根地址线去访问对应这个芯片的128MB空间。所以2440能访问的外设空间总共为8*128=1GB,而1GB(0x40000000)以上的空间,则安排给了2440内部的寄存器,访问这些内部寄存器,则是通过32位的处理器内部总线来完成的。
Alt text

内存一般放在片选6或片选7上,所以2440的内存起始地址是从0x30000000开始。

内存芯片硬件连接

单个内存芯片数据位宽是16位,而2440本身的数据线有32根,所以2440使用两个32MB的芯片并联的方式来存储数据。

设置2440存储控制器

芯片手册第6章讲解存储控制器的相关寄存器控制,第一个寄存器是BWSCON,用于控制总线宽度和等待状态。
Alt text

按如下方式配置:

  1. 不使用UB/LB
  2. 不使用等待状态
  3. 32位数据总线宽度

需要设置Bank6和Bank7,因为只有在这两个Bank上才接了内存。

下一组寄存器是BANKCON0~BANKCON5,由于这几个BANK上没有接内存,所以不需要设置,保持默认值即可。

下面要设置的寄存器是BANKCON6和BANKCON7
Alt text

按如下方式配置:

  1. 内存类型是SDRAM,MT=11
  2. 由于MT=11,所以只需要设置0~3位,其余位保持0
  3. Trcd域,行列时序转换延时取2clock,即00,由下面的时序图可推导出结果:
  4. Alt text

4.列地址数目,需要从内存芯片上去查找,以column为关键字查找,结果是9bit。

下一个要设置的寄存器是REFRESH,用于控制SDRAM的刷新。
Alt text

按如下方式设置:

  1. 使能刷新,REFEN=0
  2. 使用自动刷新,TREFMD=0
  3. 刷新时间2 clocks,Trp=00,从前面的内存时序图可知
  4. SDRAM一行的刷新时间是7 clocks,Tsrc=11
  5. 刷新间隔计算,直接按示例的计算结果,赋值1269.

下一个寄存器是BANKSIZE
Alt text

按如下方式配置:

  1. 打开突发模式,BURST_EN=1
  2. 打开节电模式,SCKE_EN=1
  3. SCLK_EN使用推荐配置
  4. BK76MAP按64MB设置,BK76MAP=001

下一个寄存器是MRSRB6和MRSRB7,用于设置bank6和bank7的模式
Alt text

需要设置的域只有CL,参考时序图,得到 CAS延时是3个clock(RAS变为低电平到CAS变为低电平的延时),CL=011。

编码实现

#define mem_contrl 0x48000000
init_sdram:
    ldr r0, =mem_contrl 
    add r3, r0, #4*13
    adrl r1, mem_data   @adrl用于将语句标号的地址赋值给寄存器

0:
    ldr r2, [r1], #4
    str r2, [r0], #4
    cmp r0, r3
    bne 0b   @加b表示往前跳转
    mov pc, lr

mem_data:
    .long 0x22000000 
    .long 0x00000700
    .long 0x00000700
    .long 0x00000700
    .long 0x00000700
    .long 0x00000700
    .long 0x00000700
    .long 0x00018001
    .long 0x00018001
    .long 0x008c04f5
    .long 0x000000b1
    .long 0x00000030
    .long 0x00000030

S3C6410内存初始化

地址空间

6410拥有32位地址总线,寻址空间为4GB,其中高2GB为保留区域,低2GB又可划分为两部分:主存储区和外设区。
Alt text

外设区指的是各种寄存器的地址,所有外设寄存器的地址都是从0x70000000开始。

主存储区的内存映像如下图所示:
Alt text

启动镜像区:用于启动ARM系统,并没有固定的存储介质与之对应,而是通过修改启动选项,把不同的启动介质映射到该区域,比如选择了IROM启动方式后,就把IROM映射到该区域。
内部存储区:包括IROM和ISRAM,IROM实际只有32KB,ISRAM实际只有8KB。
静态存储区:用于访问挂在外部总线上的设备,比如NOR flash、oneNand等。这个区域被分割为6个bank,每个bank128MB,数据宽度最大支持16bit,每个bank由片选Xm0CS0-Xm0CS5选中。
动态存储区:设备的主存储区,安排DDR,两个128MB区域,由片选Xm1CS0-Xm1CS1来进行2个区间的选择。

内存芯片硬件连接

Alt text

同样由两片16bit的128MB内存并联而成。

存储控制器导读

芯片手册第5章是关于存储控制器的介绍,首先查看5.4小节关于内存初始化的流程:
Alt text

相关顺序描述如下:

  1. 往memc_cmd中写入100,使DRAM进入配置模式,memc_cmd位于P1MEMCCMD寄存器。
  2. 写入时序参数,芯片配置,ID配置到相关寄存器。
  3. 等待200us,让SDRAM上电和时序稳定,但是当CPU已经开始工作时,上电和时序应该都已经稳定了,所以这一步可以省略。
  4. 执行内存初始化步骤,参考5.4.3小节。
  5. 往memc_cmd中写入000,使DRAM进入就绪模式。
  6. 检查内存状态域memc_stat直到这个域变成01,表示内存已经就绪。

5.4.3小节介绍了内存初始化的步骤,如下:

  1. 往direct_cmd中写入11(以寄存器部分的描述为准),使DRAM控制器执行NOP指令,direct_cmd位于P1 DIRECTCMD寄存器的18,19位。
  2. 往direct_cmd中写入00,执行Prechargeall命令。
  3. 往direct_cmd中写入01(以寄存器部分的描述为准),执行Autorefresh命令。
  4. 重复上一条指令一次。
  5. 往direct_cmd中写入10,执行MRS命令

下面参考uboot中关于6410内存初始化的代码进行分析,内存初始化的相关语句从mem_ctrl_asm_init标号开始。
Alt text

编码实现

.text
.global mem_init
mem_init:
    @set data pin
    ldr r0, =0x7e00f120
    mov r1, #0x0
    str r1, [r0]

    @Enter config state
    ldr r0, =0x7e001004
    mov r1, #0x4
    str r1, [r0]
    
    @Time parameter, chip configuration, id configuration
    ldr r0, =0x7e001004  @allow configuration
    mov r1, #0x4
    str r1, [r0]
    
    ldr r0, =0x7e001010  @refresh period
    ldr r1, =( ( 7800 / ( 1000000000/133000000 ) + 1 ) )
    str r1, [r0]
    
    ldr r0, =0x7e001014  @CAS latency
    mov r1, #(3 << 1)
    str r1, [r0]
    
    ldr r0, =0x7e001018  @t_DQSS
    mov r1, #0x1
    str r1, [r0]
    
    ldr r0, =0x7e00101c  @t_MRD
    mov r1, #0x2
    str r1, [r0]
    
    ldr r0, =0x7e001020   @t_RAS
    ldr r1, =( ( 45 / ( 1000000000 / 133000000 ) + 1 ) )
    str r1, [r0]
    
    ldr r0, =0x7e001024   @t_RC
    ldr r1, =( ( 68 / ( 1000000000 / 133000000 ) + 1 ) )
    str r1, [r0]
    
    ldr r0, =0x7e001028   @t_RCD
    ldr r1, =( ( 23 / ( 1000000000 / 133000000 ) + 1 ) )
    str r1, [r0]
    
    ldr r0, =0x7e00102c   @t_RFC
    ldr r1, =( ( 80 / ( 1000000000 / 133000000 ) + 1 ) )
    str r1, [r0]
    
    ldr r0, =0x7e001030   @t_RP
    ldr r1, =( ( 23 / ( 1000000000 / 133000000 ) + 1 ) )
    str r1, [r0]
    
    ldr r0, =0x7e001034   @t_RRD
    ldr r1, =( ( 15 / ( 1000000000 / 133000000 ) + 1 ) )
    str r1, [r0]
    
    ldr r0, =0x7e001038   @t_WR
    ldr r1, =( ( 15 / ( 1000000000 / 133000000 ) + 1 ) )
    str r1, [r0]
    
    ldr r0, =0x7e00103c   @t_WTR
    mov r1, #0x07
    str r1, [r0]
    
    ldr r0, =0x7e001040   @t_XP
    mov r1, #0x02
    str r1, [r0]
    
    ldr r0, =0x7e001044   @t_XSR
    ldr r1, =( ( 120 / ( 1000000000 / 133000000 ) + 1 ) )
    str r1, [r0]
    
    ldr r0, =0x7e001048   @t_ESR
    ldr r1, =( ( 120 / ( 1000000000 / 133000000 ) + 1 ) )
    str r1, [r0]
    
    ldr r0, =0x7e00100c   @内存控制配置寄存器
    ldr r1, =0x00010012   @配置控制器
    str r1, [r0]

    ldr r0, =0x7e00104c   @32位DRAM配置控制寄存器
    ldr r1, =0x0b45
    str r1, [r0]

    ldr r0, =0x7e001200   @片选寄存器
    ldr r1, =0x150f8
    str r1, [r0]

    ldr r0, =0x7e001304   @用户配置寄存器
    mov r1, #0x0
    str r1, [r0]

    @Excute memory initialization sequence
    ldr r0, =0x7e001008  @NOP
    ldr r1, =0xc0000
    str r1, [r0]
    
    ldr r0, =0x7e001008  @prechargeall
    ldr r1, =0x0        
    str r1, [r0]
    
    ldr r0, =0x7e001008  @autorefresh
    ldr r1, =0x4        
    str r1, [r0]
    
    ldr r0, =0x7e001008  @autorefresh
    ldr r1, =0x4        
    str r1, [r0]
    
    ldr r0, =0x7e001008  @MRS-EMRS muse be set
    ldr r1, =0xa0000        
    str r1, [r0]
    
    ldr r0, =0x7e001008  @MRS-MRS muse be set
    ldr r1, =0x80032        
    str r1, [r0]
    
    @Enter Ready state
    ldr r0, =0x7e001004
    mov r1, #0x0
    str r1, [r0]
    
    @Check until memory state is ready
check_ready:
    ldr r0, =0x7e001000
    ldr r1, [r0]
    mov r2, #0x3
    and r1, r1, r2
    cmp r1, #0x1
    bne check_ready

    mov pc, lr

S5PV210内存初始化

地址空间

Alt text

210使用DDR2内存芯片,内存地址空间从0x20000000开始,DRAM0大小是512MB,DRAM1大小是1GB。

内存芯片硬件连接

210内存芯片数据宽度是8bit,所以210开发板常采用8片或4片128*8bit芯片级联的办法。
Alt text

存储控制器导读

参考芯片手册section05_memory, 第1.2.1.3小节关于DDR2内存的初始化。
Alt text
Alt text

编码实现

  • 无标签