hw/arm/virt: Introduce virt_set_high_memmap() helper

This introduces virt_set_high_memmap() helper. The logic of high
memory region address assignment is moved to the helper. The intention
is to make the subsequent optimization for high memory region address
assignment easier.

No functional change intended.

Signed-off-by: Gavin Shan <gshan@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Tested-by: Zhenyu Zhang <zhenyzha@redhat.com>
Message-id: 20221029224307.138822-2-gshan@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Gavin Shan 2022-12-14 14:27:04 +00:00 committed by Peter Maydell
parent ae2b87341b
commit 4af6b6edec

View File

@ -1690,6 +1690,46 @@ static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx)
return arm_cpu_mp_affinity(idx, clustersz);
}
static void virt_set_high_memmap(VirtMachineState *vms,
hwaddr base, int pa_bits)
{
int i;
for (i = VIRT_LOWMEMMAP_LAST; i < ARRAY_SIZE(extended_memmap); i++) {
hwaddr size = extended_memmap[i].size;
bool fits;
base = ROUND_UP(base, size);
vms->memmap[i].base = base;
vms->memmap[i].size = size;
/*
* Check each device to see if they fit in the PA space,
* moving highest_gpa as we go.
*
* For each device that doesn't fit, disable it.
*/
fits = (base + size) <= BIT_ULL(pa_bits);
if (fits) {
vms->highest_gpa = base + size - 1;
}
switch (i) {
case VIRT_HIGH_GIC_REDIST2:
vms->highmem_redists &= fits;
break;
case VIRT_HIGH_PCIE_ECAM:
vms->highmem_ecam &= fits;
break;
case VIRT_HIGH_PCIE_MMIO:
vms->highmem_mmio &= fits;
break;
}
base += size;
}
}
static void virt_set_memmap(VirtMachineState *vms, int pa_bits)
{
MachineState *ms = MACHINE(vms);
@ -1745,39 +1785,7 @@ static void virt_set_memmap(VirtMachineState *vms, int pa_bits)
/* We know for sure that at least the memory fits in the PA space */
vms->highest_gpa = memtop - 1;
for (i = VIRT_LOWMEMMAP_LAST; i < ARRAY_SIZE(extended_memmap); i++) {
hwaddr size = extended_memmap[i].size;
bool fits;
base = ROUND_UP(base, size);
vms->memmap[i].base = base;
vms->memmap[i].size = size;
/*
* Check each device to see if they fit in the PA space,
* moving highest_gpa as we go.
*
* For each device that doesn't fit, disable it.
*/
fits = (base + size) <= BIT_ULL(pa_bits);
if (fits) {
vms->highest_gpa = base + size - 1;
}
switch (i) {
case VIRT_HIGH_GIC_REDIST2:
vms->highmem_redists &= fits;
break;
case VIRT_HIGH_PCIE_ECAM:
vms->highmem_ecam &= fits;
break;
case VIRT_HIGH_PCIE_MMIO:
vms->highmem_mmio &= fits;
break;
}
base += size;
}
virt_set_high_memmap(vms, base, pa_bits);
if (device_memory_size > 0) {
ms->device_memory = g_malloc0(sizeof(*ms->device_memory));