Replaces remaining uses of TARGET_PHYS_ADDR_SPACE_BITS with
runtime calls to loongarch_palen_mask() to fetch the physical
address mask from the cpucfg PALEN field.
Signed-off-by: Anton Johansson <anjo@rev.ng>
---
include/hw/loongarch/boot.h | 3 ++-
hw/loongarch/boot.c | 28 ++++++++++++++++------------
hw/loongarch/virt.c | 5 ++++-
3 files changed, 22 insertions(+), 14 deletions(-)
diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h
index 9819f7fbe3..4984322f75 100644
--- a/include/hw/loongarch/boot.h
+++ b/include/hw/loongarch/boot.h
@@ -113,6 +113,7 @@ struct memmap_entry {
uint32_t reserved;
};
-void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info);
+void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info,
+ uint64_t phys_addr_mask);
#endif /* HW_LOONGARCH_BOOT_H */
diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
index 711d5ffbbc..ef8eae237c 100644
--- a/hw/loongarch/boot.c
+++ b/hw/loongarch/boot.c
@@ -217,10 +217,12 @@ static void init_cmdline(struct loongarch_boot_info *info, void *p, void *start)
static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
{
- return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
+ uint64_t *phys_addr_mask = opaque;
+ return addr & *phys_addr_mask;
}
static int64_t load_loongarch_linux_image(const char *filename,
+ uint64_t phys_addr_mask,
uint64_t *kernel_entry,
uint64_t *kernel_low,
uint64_t *kernel_high)
@@ -251,10 +253,8 @@ static int64_t load_loongarch_linux_image(const char *filename,
}
/* Early kernel versions may have those fields in virtual address */
- *kernel_entry = extract64(le64_to_cpu(hdr->kernel_entry),
- 0, TARGET_PHYS_ADDR_SPACE_BITS);
- *kernel_low = extract64(le64_to_cpu(hdr->load_offset),
- 0, TARGET_PHYS_ADDR_SPACE_BITS);
+ *kernel_entry = le64_to_cpu(hdr->kernel_entry) & phys_addr_mask;
+ *kernel_low = le64_to_cpu(hdr->load_offset) & phys_addr_mask;
*kernel_high = *kernel_low + size;
rom_add_blob_fixed(filename, buffer, size, *kernel_low);
@@ -303,19 +303,21 @@ static ram_addr_t alloc_initrd_memory(struct loongarch_boot_info *info,
exit(1);
}
-static int64_t load_kernel_info(struct loongarch_boot_info *info)
+static int64_t load_kernel_info(struct loongarch_boot_info *info,
+ uint64_t phys_addr_mask)
{
uint64_t kernel_entry, kernel_low, kernel_high, initrd_offset = 0;
ssize_t kernel_size;
kernel_size = load_elf(info->kernel_filename, NULL,
- cpu_loongarch_virt_to_phys, NULL,
+ cpu_loongarch_virt_to_phys, &phys_addr_mask,
&kernel_entry, &kernel_low,
&kernel_high, NULL, ELFDATA2LSB,
EM_LOONGARCH, 1, 0);
- kernel_entry = cpu_loongarch_virt_to_phys(NULL, kernel_entry);
+ kernel_entry = cpu_loongarch_virt_to_phys(&phys_addr_mask, kernel_entry);
if (kernel_size < 0) {
kernel_size = load_loongarch_linux_image(info->kernel_filename,
+ phys_addr_mask,
&kernel_entry, &kernel_low,
&kernel_high);
}
@@ -395,14 +397,15 @@ static void init_boot_rom(MachineState *ms,
}
static void loongarch_direct_kernel_boot(MachineState *ms,
- struct loongarch_boot_info *info)
+ struct loongarch_boot_info *info,
+ uint64_t phys_addr_mask)
{
void *p, *bp;
int64_t kernel_addr = VIRT_FLASH0_BASE;
uint64_t *data;
if (info->kernel_filename) {
- kernel_addr = load_kernel_info(info);
+ kernel_addr = load_kernel_info(info, phys_addr_mask);
} else {
if (!qtest_enabled()) {
warn_report("No kernel provided, booting from flash drive.");
@@ -429,7 +432,8 @@ static void loongarch_direct_kernel_boot(MachineState *ms,
g_free(bp);
}
-void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info)
+void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info,
+ uint64_t phys_addr_mask)
{
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(ms);
@@ -440,6 +444,6 @@ void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info)
if (lvms->bios_loaded) {
loongarch_firmware_boot(lvms, info);
} else {
- loongarch_direct_kernel_boot(ms, info);
+ loongarch_direct_kernel_boot(ms, info, phys_addr_mask);
}
}
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 6efa15da47..1e7b55e05c 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -33,6 +33,7 @@
#include "hw/misc/unimp.h"
#include "hw/loongarch/fw_cfg.h"
#include "target/loongarch/cpu.h"
+#include "target/loongarch/cpu-mmu.h"
#include "hw/firmware/smbios.h"
#include "qapi/qapi-visit-common.h"
#include "hw/acpi/generic_event_device.h"
@@ -785,6 +786,7 @@ static void virt_init(MachineState *machine)
hwaddr base, size, ram_size = machine->ram_size;
MachineClass *mc = MACHINE_GET_CLASS(machine);
Object *cpuobj;
+ uint64_t phys_addr_mask = 0;
if (!cpu_model) {
cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
@@ -872,7 +874,8 @@ static void virt_init(MachineState *machine)
qemu_register_powerdown_notifier(&lvms->powerdown_notifier);
lvms->bootinfo.ram_size = ram_size;
- loongarch_load_kernel(machine, &lvms->bootinfo);
+ phys_addr_mask = loongarch_palen_mask(&LOONGARCH_CPU(first_cpu)->env);
+ loongarch_load_kernel(machine, &lvms->bootinfo, phys_addr_mask);
}
static void virt_get_acpi(Object *obj, Visitor *v, const char *name,
--
2.51.0