加载/存储寄存器的结果与内存查看器

时间:2016-09-28 18:57:24

标签: arm qemu xilinx bare-metal zynq

我正在开发一个在Xilinx的QEMU版本下运行的程序。这个问题被标记为,但我实际上是针对QEMU中的Zynq MP,特别是Cortex-R5。

我的背景是微控制器和Cortex-M,所以这是一个很大的跳跃,并且有很多我不习惯的功能(MPU,AXI,额外的缓存)。我正在编写一个访问其中一个硬件外设(低功耗域)中的外设寄存器的驱动程序。我已经编写了一个函数reginsert来简化访问这些寄存器中的位。

void reginsert(uint32_t base, uint32_t offset,
               uint32_t mask, uint32_t data)
{
    uint32_t volatile * reg = (uint32_t volatile *)(base + offset);
    uint32_t regdata;
    /* This section actually happens in a critical section for atomicity, 
     * but I've trimmed that out for brevity */
    regdata = *reg;
    *reg = (regdata & ~mask) | data;
    /* End of critical section */
}

根本不是一个非常令人兴奋的功能。对我来说,它也很简单。

我这样称呼函数:

/* Magic number provided by Xilinx, I don't actually plan to keep it as such a
 * magical number, but for now while trying things to debug. */
reginsert(XPAR_PSU_UART_0_BASEADDR, XUARTPS_CR_OFFSET, 0x3C, 0);

其他信息:

#define XPART_PSU_UART_0_BASEADDR 0xFF000000
#define XUARTPS_CR_OFFSET         0x00000000

在单步执行代码时,我发现此函数正确地将寄存器的地址计算为0xFF000000,在查看{{1}的值时,我可以在Xilinx SDK调试器(基于gdb)中看到这一点。 }}。我还可以看到,逐步通过程序集,寄存器reg加载了正确的地址。

执行到达时:

r3

反汇编有:

regdata = *reg;

我在ldr r3, [r3] 获得0x00000000。如果我使用内存视图,我可以看到r3的值为0xFF000000。如果我查看变量视图,我可以看到0x00000114具有相同的值(*reg)。如果我走到掩盖本地副本然后写回的行,我最终会得到指令:

0x00000114

单步过去,我看到str r2, [r3] ; r3 has been reloaded with the register address, ; and r2 contains the read-modify-write data. 的值(虽然不是正确的值)应该已经写好,但是值实际上并没有改变(通过内存或变量视图)。在这些视图中,我可以手动更改值并正确写入。

我不知道Zynq MP的总线架构在这个QEMU版本中的仿真程度有多彻底,但硅片有独立的内存端口用于调试访问和处理器访问,并且不通过CPU访问内存,因此有可能以不同的方式映射事物。但是,Xilinx演示代码可以正确执行相同的操作。

所以,我已尝试过的摘要:

  1. 验证反汇编应从寄存器位置加载/存储。
  2. 逐步指示验证CPU寄存器是否具有访问外设寄存器的正确值。
  3. 直接通过调试器访问内存和变量。
  4. 使用Xilinx代码验证QEMU是否模拟外设。
  5. 已检查的MPU设置(该区域设置为非共享且对访问没有限制)
  6. 我不知道还应该尝试什么,而且我基本上都难过了。似乎QEMU,至少通过gdb接口,正确模拟外设寄存器,所以我认为CPU读/写相当简单。我感谢任何帮助,指示,提示等。对我来说,这是很多新事物,包括使用QEMU作为开发平台。

0 个答案:

没有答案