Skip to content

Conversation

KouweiLee
Copy link
Contributor

@KouweiLee KouweiLee commented Sep 2, 2025

I added the AArch32 virtual machine support for ROC-RK3588-PC. The changes are as follows:

  1. Replace rk3588 soc with rk3588_aarch64 and rk3588_aarch32. The rk3588_aarch64 soc is the same with the code in board: arm64: Add suport for ROC-RK3588-PC #94288. The rk3588_aarch32 soc is used for zephyr running as an aarch32 guest OS on ROC-RK3588-PC. We have tested rk3588_aarch32 zephyr on the hypervisor hvisor and the screenshot is as follows:
image
  1. I found gicv3 driver has one bug for armv7. Armv7 doesn't support aff3 so arm_gic_aff_matching should only compare the lower 24 bits.

  2. I’ve encountered a bug I can’t explain: On AArch32 Zephyr, uart_ns16550 uses DEVICE_MMIO_MAP to map its MMIO region into the kernel VA space. The mapping call succeeds, but any access to the resulting virtual address triggers a data-abort. Flushing the data cache inside arch_mem_map (arm_mmu.c) makes the fault disappear. The underlying cause is unclear.

Future work: Now aarch32 zephyr only supports single core. Next we will add smp for it.

This commit enables Zephyr to run as an AArch32 virtual machine on the
ROC-RK3588-PC board. The ROC-RK3588-PC supports both AArch64
and AArch32 CPU execution modes. With AArch32 virtual machine support,
Zephyr can now be booted in ARMv7 architecture mode through
AArch32-compatible hypervisors.

Signed-off-by: Guowei Li <[email protected]>
… map

This commit fixes the assignment of the L2 page table
by using the virtual address instead of the physical address.
Additionally, it ensures that the cache is flushed
after a successful memory mapping operation.

Signed-off-by: Guowei Li <[email protected]>
This commit introduces a new comparison for the ARM (AArch32) architecture
in the GICv3 interrupt controller.
It specifically compares the lower 24 bits of the affinity values,
because there is no aff3 in AArch32 or Arm-v7.

Signed-off-by: Guowei Li <[email protected]>
@@ -673,6 +673,9 @@ static bool arm_gic_aff_matching(uint64_t gicr_aff, uint64_t aff)
uint64_t mask = BIT64_MASK(8);

return (gicr_aff & mask) == (aff & mask);
#elif defined(CONFIG_ARM)
/* For ARM (AArch32), only compare aff2:aff1:aff0 (lower 24 bits) */
return (gicr_aff & 0xFFFFFF) == (aff & 0xFFFFFF);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes the first bug I mentioned. Armv7 doesn't have aff3.

@@ -958,6 +959,7 @@ void arch_mem_map(void *virt, uintptr_t phys, size_t size, uint32_t flags)
LOG_ERR("__arch_mem_map() returned %d", ret);
k_panic();
} else {
sys_cache_data_flush_all();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will make the second bug disappear. But the reason I don't know.

@@ -571,7 +572,7 @@ static void arm_mmu_l2_map_page(uint32_t va, uint32_t pa,

if (l1_page_table.entries[l1_index].undefined.id == ARM_MMU_PTE_ID_INVALID ||
(l1_page_table.entries[l1_index].undefined.id & ARM_MMU_PTE_ID_SECTION) != 0) {
l2_page_table = arm_mmu_assign_l2_table(pa);
l2_page_table = arm_mmu_assign_l2_table(va);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way, I think this was a mistake before, but it doesn’t really have any impact.

Copy link

sonarqubecloud bot commented Sep 2, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: ARM ARM (32-bit) Architecture area: Interrupt Controller platform: ARM Arm Limited
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants