QEMU MIPS32 - 在自定义板上实现16550 Uart

8

我正在尝试使用QEMU模拟一段固件,但我无法让UART设备正确更新行状态寄存器并显示输入字符。

细节:

目标设备:高通QCA9533(如果您感兴趣,文档在此

目标固件:带有U-Boot引导程序的VxWorks 6.6

CPU:MIPS 24Kc

板子:mipssim(修改过)

内存:512MB

使用的命令:qemu-system-mips -S -s -cpu 24Kc -M mipssim –nographic -device loader,addr=0xBF000000,cpu-num=0 -serial /dev/ttyS0 -bios target_image.bin

我很抱歉,无法分享我的源代码。然而,由于我正在尝试重新配置mipssim板,我只对代码进行了轻微更改,如下:

  • bios内存区域的基址重定位到0x1F000000

  • load_image_targphys() 的目标地址更改为0x1F000000

  • 将 $pc 的初始值更改为0xBF000000 (TLB 重新映射的0x1F000000)

  • mipssim serial_init()的调用替换为 serial_mm_init(isa, 0x20000, env->irq[0], 115200, serial_hd(0), DEVICE_NATIVE_ENDIAN).

虽然 serial_init() 看起来可能是当前被接受的标准,但我在重映射它时没有任何运气。我注意到malta板没有问题地输出了我给它的MIPS测试内核,所以我尝试模仿那里所做的。然而,我仍然无法理解QEMU的工作原理,也找不到许多解释它的好资源。我在源代码和包含的文档中继续浏览,但同时我希望有人能对我做错了什么有所了解。

二进制文件可以从地址0xBF000000正确加载和执行,但在第一个UART轮询循环时挂起。在QEMU监视器中查看mtree,显示I/O设备被正确映射到地址范围0x18020000-0x1802003F,当固件写入Tx缓冲区时,gdb显示字符成功写入内存。只是串行设备没有进一步的操作来拉取该字符并显示它,因此固件无休止地轮询LSR等待更新。

在QEMU中进行串行/硬件交互时,我是否漏掉了什么?我原以为重新映射mipssim板的所有现有功能组件就足以使串行通信正常工作,特别是目标使用与mipssim相同的16550 UART。如果您有任何见解,请告诉我。如果我能找到一种使用符号调试QEMU本身的方法将非常有帮助,但同时我不确定我要寻找什么。即使是关于如何缩小问题范围的建议也会很有用。

谢谢!


1
进一步更新:我仔细查看了文档,似乎需要实现一个APB,因为QCA9533没有直接连接到GPIO引脚的UART。我在SPARC代码中找到了一个APB UART的实现,但我仍在努力将其移植以适应MIPS。不确定这是否是正确答案,但这是我目前唯一得到的线索。 - SwarthyMantooth
1个回答

6
经过大量的努力,我成功使UART工作。这个问题的答案在于serial_ioport_read()serial_ioport_write()函数。当数据被读取或写入串行设备的MemoryRegion时(该设备在serial_init()serial_mm_init()中初始化),QEMU调用这两个方法作为回调。这些函数对地址(作为addr传递给函数)进行一定的掩码处理以确定正在引用哪个寄存器,然后从与该寄存器对应的SerialState结构返回值。这非常简单,但我猜一旦你搞清楚了所有的东西,一切似乎都很简单。一个重要转折点是意识到QEMU实际上将串行设备实现为带有特殊功能的MemoryRegion,并通过内存操作触发它。
无论如何,希望这能帮助未来的某个人避免我经历的噩梦。祝福!

1
干得好!继续加油 :) - not2qubit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接