-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
hw/loongarch: Move boot functions to boot.c
Move some boot functions to boot.c and struct loongarch_boot_info into struct LoongArchMachineState. Signed-off-by: Song Gao <gaosong@loongson.cn> Reviewed-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-Id: <20240426091551.2397867-2-gaosong@loongson.cn>
- Loading branch information
1 parent
fd87be1
commit d771ca1
Showing
5 changed files
with
160 additions
and
113 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
/* SPDX-License-Identifier: GPL-2.0-or-later */ | ||
/* | ||
* LoongArch boot helper functions. | ||
* | ||
* Copyright (c) 2023 Loongson Technology Corporation Limited | ||
*/ | ||
|
||
#include "qemu/osdep.h" | ||
#include "qemu/units.h" | ||
#include "target/loongarch/cpu.h" | ||
#include "hw/loongarch/virt.h" | ||
#include "hw/loader.h" | ||
#include "elf.h" | ||
#include "qemu/error-report.h" | ||
#include "sysemu/reset.h" | ||
#include "sysemu/qtest.h" | ||
|
||
static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr) | ||
{ | ||
return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS); | ||
} | ||
|
||
static int64_t load_kernel_info(struct loongarch_boot_info *info) | ||
{ | ||
uint64_t kernel_entry, kernel_low, kernel_high; | ||
ssize_t kernel_size; | ||
|
||
kernel_size = load_elf(info->kernel_filename, NULL, | ||
cpu_loongarch_virt_to_phys, NULL, | ||
&kernel_entry, &kernel_low, | ||
&kernel_high, NULL, 0, | ||
EM_LOONGARCH, 1, 0); | ||
|
||
if (kernel_size < 0) { | ||
error_report("could not load kernel '%s': %s", | ||
info->kernel_filename, | ||
load_elf_strerror(kernel_size)); | ||
exit(1); | ||
} | ||
return kernel_entry; | ||
} | ||
|
||
static void reset_load_elf(void *opaque) | ||
{ | ||
LoongArchCPU *cpu = opaque; | ||
CPULoongArchState *env = &cpu->env; | ||
|
||
cpu_reset(CPU(cpu)); | ||
if (env->load_elf) { | ||
cpu_set_pc(CPU(cpu), env->elf_address); | ||
} | ||
} | ||
|
||
static void fw_cfg_add_kernel_info(struct loongarch_boot_info *info, | ||
FWCfgState *fw_cfg) | ||
{ | ||
/* | ||
* Expose the kernel, the command line, and the initrd in fw_cfg. | ||
* We don't process them here at all, it's all left to the | ||
* firmware. | ||
*/ | ||
load_image_to_fw_cfg(fw_cfg, | ||
FW_CFG_KERNEL_SIZE, FW_CFG_KERNEL_DATA, | ||
info->kernel_filename, | ||
false); | ||
|
||
if (info->initrd_filename) { | ||
load_image_to_fw_cfg(fw_cfg, | ||
FW_CFG_INITRD_SIZE, FW_CFG_INITRD_DATA, | ||
info->initrd_filename, false); | ||
} | ||
|
||
if (info->kernel_cmdline) { | ||
fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, | ||
strlen(info->kernel_cmdline) + 1); | ||
fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, | ||
info->kernel_cmdline); | ||
} | ||
} | ||
|
||
static void loongarch_firmware_boot(LoongArchMachineState *lams, | ||
struct loongarch_boot_info *info) | ||
{ | ||
fw_cfg_add_kernel_info(info, lams->fw_cfg); | ||
} | ||
|
||
static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) | ||
{ | ||
int64_t kernel_addr = 0; | ||
LoongArchCPU *lacpu; | ||
CPUState *cs; | ||
|
||
if (info->kernel_filename) { | ||
kernel_addr = load_kernel_info(info); | ||
} else { | ||
if(!qtest_enabled()) { | ||
error_report("Need kernel filename\n"); | ||
exit(1); | ||
} | ||
} | ||
|
||
CPU_FOREACH(cs) { | ||
lacpu = LOONGARCH_CPU(cs); | ||
lacpu->env.load_elf = true; | ||
lacpu->env.elf_address = kernel_addr; | ||
} | ||
} | ||
|
||
void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info) | ||
{ | ||
LoongArchMachineState *lams = LOONGARCH_MACHINE(ms); | ||
int i; | ||
|
||
/* register reset function */ | ||
for (i = 0; i < ms->smp.cpus; i++) { | ||
qemu_register_reset(reset_load_elf, LOONGARCH_CPU(qemu_get_cpu(i))); | ||
} | ||
|
||
info->kernel_filename = ms->kernel_filename; | ||
info->kernel_cmdline = ms->kernel_cmdline; | ||
info->initrd_filename = ms->initrd_filename; | ||
|
||
if (lams->bios_loaded) { | ||
loongarch_firmware_boot(lams, info); | ||
} else { | ||
loongarch_direct_kernel_boot(info); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/* SPDX-License-Identifier: GPL-2.0-or-later */ | ||
/* | ||
* Definitions for LoongArch boot. | ||
* | ||
* Copyright (C) 2023 Loongson Technology Corporation Limited | ||
*/ | ||
|
||
#ifndef HW_LOONGARCH_BOOT_H | ||
#define HW_LOONGARCH_BOOT_H | ||
|
||
struct loongarch_boot_info { | ||
uint64_t ram_size; | ||
const char *kernel_filename; | ||
const char *kernel_cmdline; | ||
const char *initrd_filename; | ||
uint64_t a0, a1, a2; | ||
}; | ||
|
||
void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info); | ||
|
||
#endif /* HW_LOONGARCH_BOOT_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters