Files
kunlun/dtest/dtest3/kl3_cache_ram_test
2024-09-28 14:24:04 +08:00
..
2024-09-28 14:24:04 +08:00
2024-09-28 14:24:04 +08:00
2024-09-28 14:24:04 +08:00

cache ram测试用例说明文档

虽然本例程名称叫做unit_cache_ram_test但是ram仅包含一个读写测试因此本文档主要介绍cache。

cache简介

cache主要用于将外部的储存器flash、psram、dmem等映射到系统的内存空间是的CPU通过cache可以透明的访问这些大的存储空间cache屏蔽了这些外部存储器访问的复杂性。

cache的工作原理

cache本质上是基于cache line数据结构的一种多对一的映射kl3的cache line是32bytescache自身存储空间是32KB所以系统空间的每个32KB的第一个32bytes共享cache的第一个cache line所以需要一个tag来存储cache line当前道理是哪一块32B的数据。

一个cache可以是多个way的意思是每个cache line其实有多个32B的存储器这样当发生cache miss的时候替换操作占用多个way的一个从而降低cache line冲突提高系统访问效率。

kl3 cache特性

  • 一共5个buffer cache其中3个32KB容量2个64KB容量。
  • 2 way分别对应flash和psram空间的映射。
  • 可灵活配置为cache或者on-chip ram使用。
  • 支持“指定地址范围”的flush操作。
  • 支持全cache clear操作。
  • 支持cache miss统计。
  • 支持“指定地址段范围”访问监测(?)。

cache工作模式

cache主要有四种工作模式。

clear mode

当设置Clear mode的时候cache内部的状态机会把cache整个tag memory中的信息全部清空完成后cache中是完全空白的。

在clear过程中如果系统有下发读写操作cache会等clear操作完成后才会响应这些操作。

如果在clear mode有效的时候cache还在进行读写操作则会等待当前读写操作完成之后才会响应clear操作。

【注】clear操作只会对tag信息进行操作在这个过程中如果有dirty的cache line不会对这些cache line发起flush操作cache line dirty数据会丢失。

flush mode

当设置flush mode的时候软件会预先设置一段将要flush的地址空间起始地址、结束地址cache内部的状态机会控制扫描所有的tag memory检查要flush的地址空间内的cache line时候存在于cache中。如果扫描到有个cache line是需要flush的则检查其是否是dirty的如果dirty则会吧这个cache line的数据flush到external memory中对应的位置然后把这个cache line对应的tag设置为无效的cache line如果这个cache line不是dirty的则直接设置这个cache line对应的tag为无效的cache line。

flush mode主要是把cache中的dirty数据flush到exeternal memory中姐姐cache和external memory之间的数据一致性问题。

normal mode

在非clear和flush mode下即为normal mode此时cache响应系统正常的读写请求。

如果cache hit则直接响应系统的读写请求。

如果cache miss则自动进行cache line data的替换操作。

monitor mode

cache空间中可能存在多个堆栈当发生堆栈数据被破坏的时候可以开启cache的monitor模式。

通过cache_acc_saddr和cache_acc_eaddr定义了检测时允许访问的空间。

通过cache_mon_saddr和cache_mon_eaddr定义了检测时允许访问空间内部禁止访问的空间即禁止访问的空间应当在允许访问空间范围内

当访问到禁止访问空间以及访问到允许访问空间以外的空间时,都会触发访问错误告警。

测试例程说明

cache_ram测试例程使用到的外设包含cache、ram、smc、sfc、uart、gptimer。

  • ram测试对象主要测试读写正确性。
  • cache测试对象主要测试cache访问外部memory以及cache自身功能完整性。
  • sfc辅助测试对象用于辅助测试cache访问外部flash。
  • smc辅助测试对象用于辅助测试cache访问外部psram。
  • uart使用uart0实现调试信息打印接收case配置信息等与PC的交互功能。
  • gptimer使用gptimer0用于测试“普冉flash工厂模式”时延时功能。

cache_ram测试例程遵循自动化测试框架在例程执行之后初始化串口0通过串口发送“start”字段到PC并等待PC发送“config”字段来获取本次需要执行的测试case。

在获取到case组合之后初始化cache、ram、sfc、smc、psram、flash以及gptimer并根据case组合开始执行测试case。

case0ram读写测试

本case用于测试ram读写功能。读写的区域为除代码段、数据段、heap空间以外的区域。

通过导入链接脚本中定义的符号_start、_flash_end、_data、_iram_end确定ram需要测试的区域。一共有3个区域可进行读写测试

  1. ram开始位置保留给rom代码使用的空间。
  2. dtest链接脚本中flash段剩余空间。
  3. dtest链接脚本中iram段剩余空间。

dtest程序汇总dram段存放数据段后剩余的空间全部用作heap因此不参与测试。

测试的方法相对简单在所有参与测试的区域写入0x55或者0xaa并读取出数据对比是否与写入数据一致。

测试结果通过。

case1cache读写外部存储器

本case用于测试cache对外部存储器的读写其测试流程如下

  1. 使用cache0在psram的指定位置写入数据A。
  2. 使用sfc api在flash指定位置写入数据Acache无法直接对flash erase或者program
  3. 使用所有cache读取psram指定位置得到数据B如果数据A和数据B不相等则判定测试失败。
  4. 使用所有cache读取flash指定位置得到数据C如果数据C和数据A不相等则判定测试失败。

【注】在写入psram数据是使用到cache_flush函数在读取数据时使用到cache_invalid函数这两个函数在设计上传入的地址参数应该减去cache基地址但是当cache同时连接到flash和psram时没有基地址的地址参数将不能区分其属于flash或者是属于psram除非操作flash地址时加上0x4000000在实际使用中地址参数加上cache基地址依然可以正常工作asic已经确认可以正常工作因此后续大core使用这两个api时地址参数需要加上cache基地址

case2cache当做内部ram使用。

本case用于测试cache作为内部ram使用。

kl3 cache可以配置为内部ram使用需要使能cache并将cache_ctr0寄存器中的icache_mode位置1即可。作为ram使用时其ram空间为cache开始位置的前32KBicache\64KBdcache

测试方法相对简单,配置完成之后对地址空间进行读写操作即可,测试结果通过。

cache3cache脏数据和miss

本case用于测试cache脏数据、数据同步、cache miss以及auto load功能。

在使用cache时以下两种情况会导致cache中数据与实际存储设备中的数据不一致的情况

  1. cache在读取存储设备数据之后数据已经保存在cache中通过其他手段如其他cache、sfc apismc api等更改数据源保留的数据此时cache并不知道数据已经被更改。
  2. cache读取存储设备数据之后更改了cache数据此时数据更改的行为仅发生在cache内部未同步到存储设备中。

以上两种情况则可称cache中的数据为脏数据dirty data此时需要等待cache miss才会触发cache同步数据根据情况从存储设备中重新读取数据或者将数据写入到存储设备中。

当然我们也可以选择软件干预的方式在任何时候实现数据同步数据同步设计到的cache api如下

  • cache_clear对应cache clear mode清空所有的cache tag下次使用cache读时必定重新从存储设备中读取新数据。除非很有把握使用clear否则建议使用invalid清理数据。
  • cache_invalidata相当于指定地址范围的cache clearcache会遍历所有的tag如果存在tag对应的地址在invalid地址范围内则抛弃该tag对应数据此时重新访问该地址范围时将会重新读取存储设备的数据。
  • cache_flush对应flush mode将cache中的数据同步到存储设备中flush操作在之前的测试中已经使用则不再测试。

选取sfc作为测试对象设定测试地址为addr测试数据data测试方法如下

  1. 使用erase指令擦除addr对应的sector。
  2. 使用cache读取addr得到数据A。
  3. 使用sfc api写入数据到addr。
  4. 使用cache读取addr得到数据B。
  5. 使用cache clear api清理cache数据并重新读取addr得到数据C。
  6. 此时A应该等于0xffffffffB等于AC等于写入数据data否则判定执行失败
  7. 将cache clear替换为cache invalid api重新执行步骤1到步骤6。
  8. 将cache clear替换为连续读取32KB非addr的地址空间数据使所有的cache line都被暂用cache空间被填满之后重新读取addr数据此时A应该等于0xffffffffC等于写入数据data否则判定失败。

以上测试结果通过。

case4cache line测试

cache line的测试来源于beetle的代码测试代码的原作者是“董伟“这里仅简单介绍测试的原理

我们可以把cache或者存储设备的存储空间想象成由横坐标和纵坐标组成的网格坐标系正常情况下各网格相邻的轴互不影响。一旦地址总线或者数据总线发生异常粘连、短路、断路等则对总线发起的操作将影响到相邻的总线或者操作将会不成功。

  • 数据总线对数据总线的测试相对简单即在指定地址写入数据并读出判断数据是否一致即可数据总线为8位每次写入的数据仅置位1个bit如0x1,0x2,0x4等保证所有地址总线均能改变电平如果数据总线发生粘连则在改变其中一条线电平时与之粘连的线电平也会变化则读出的数据会与写入的数据有差异。
  • 地址总线选定一个地址A并以2的幂次方为增量在这些地址上都写入0x55然后在地址A写入0xaa重新读取之前写入的地址对比数据是否发生变化交换0x55和0xaa重复上述流程。

case5cache地址监控

本功能在KL3中已经不再支持硬件已经停止维护该功能实际测试时也失败。此处仅介绍其原理。

地址监控是为了应对如栈空间冲突、地址异常访问等情况而准备的调试手段地址监控功能允许配置cache允许访问的空间acc_addr和被监控空间mon_addr要求监控空间处于允许空间的内部在配置完成使能地址监控功能后如果cache访问了mon_addr地址空间以及出acc_addr地址空间以外的地址范围时将触发告警通过读取mon_int_sts寄存器可获得告警状态使用该状态能够判定地址是否越界等异常。

case6sfc、smc io share

kl3确认不采用io share方案且目前的image均不支持io share因此不再验证该功能代码保留但是测试代码未得到验证这里仅简述其功能原理。

在启用io share之后sfc将共用smc的clk和sio[0:3]信号cs信号使用原有的cs信号。io share的优势是可以节约IO。

case7sfc、smc io remap

该case需要用于测试sfc或者smc自身的io remap功能。

sfc、smc在设计时对内部信号做了编号根据编号和gpio之间进行mapping可以实现信号支持在指定GPIO范围内随意映射以方便芯片封装bonding。

  • sfc外设内部的信号包含clk、si、so、wp、hold、cs0、smc_cs(不使用)、cs1。
  • smc外设内部的信号包含clk、sio0、sio1、sio2、sio3、cs。

在测试时修改外设对应的寄存器即可实现remapsfc对应的寄存器为SPI_IO_MAP0smc对应的寄存器为SMC_SPI_IO_MAP0如sfc该寄存器初始化为0x88543210是标准的映射关系如果想交换wp和hold只需要配置为0x88534210即可。

需要注意的是sfc/smc 控制器产生的是clock enable如果clock换了的话ahb_reg中的EMC_PHY_CFG寄存器需要同步修改才能把clk绑定到其他gpio。

手动测试io remap功能的方法是循环读取flash、psram的数据并在每次读取的间隔时更改寄存器配置并在读取执行时使用逻辑分析仪抓取时序图观察信号是否按配置发生交换。测试结果通过。