|
@@ -34,13 +34,13 @@
|
|
|
#include "hw/riscv/sifive_clint.h"
|
|
|
#include "hw/riscv/sifive_test.h"
|
|
|
#include "hw/riscv/virt.h"
|
|
|
+#include "hw/riscv/boot.h"
|
|
|
#include "chardev/char.h"
|
|
|
#include "sysemu/arch_init.h"
|
|
|
#include "sysemu/device_tree.h"
|
|
|
#include "exec/address-spaces.h"
|
|
|
#include "hw/pci/pci.h"
|
|
|
#include "hw/pci-host/gpex.h"
|
|
|
-#include "elf.h"
|
|
|
|
|
|
#include <libfdt.h>
|
|
|
|
|
@@ -61,47 +61,6 @@ static const struct MemmapEntry {
|
|
|
[VIRT_PCIE_ECAM] = { 0x30000000, 0x10000000 },
|
|
|
};
|
|
|
|
|
|
-static target_ulong load_kernel(const char *kernel_filename)
|
|
|
-{
|
|
|
- uint64_t kernel_entry, kernel_high;
|
|
|
-
|
|
|
- if (load_elf(kernel_filename, NULL, NULL, NULL,
|
|
|
- &kernel_entry, NULL, &kernel_high,
|
|
|
- 0, EM_RISCV, 1, 0) < 0) {
|
|
|
- error_report("could not load kernel '%s'", kernel_filename);
|
|
|
- exit(1);
|
|
|
- }
|
|
|
- return kernel_entry;
|
|
|
-}
|
|
|
-
|
|
|
-static hwaddr load_initrd(const char *filename, uint64_t mem_size,
|
|
|
- uint64_t kernel_entry, hwaddr *start)
|
|
|
-{
|
|
|
- int size;
|
|
|
-
|
|
|
- /* We want to put the initrd far enough into RAM that when the
|
|
|
- * kernel is uncompressed it will not clobber the initrd. However
|
|
|
- * on boards without much RAM we must ensure that we still leave
|
|
|
- * enough room for a decent sized initrd, and on boards with large
|
|
|
- * amounts of RAM we must avoid the initrd being so far up in RAM
|
|
|
- * that it is outside lowmem and inaccessible to the kernel.
|
|
|
- * So for boards with less than 256MB of RAM we put the initrd
|
|
|
- * halfway into RAM, and for boards with 256MB of RAM or more we put
|
|
|
- * the initrd at 128MB.
|
|
|
- */
|
|
|
- *start = kernel_entry + MIN(mem_size / 2, 128 * MiB);
|
|
|
-
|
|
|
- size = load_ramdisk(filename, *start, mem_size - *start);
|
|
|
- if (size == -1) {
|
|
|
- size = load_image_targphys(filename, *start, mem_size - *start);
|
|
|
- if (size == -1) {
|
|
|
- error_report("could not load ramdisk '%s'", filename);
|
|
|
- exit(1);
|
|
|
- }
|
|
|
- }
|
|
|
- return *start + size;
|
|
|
-}
|
|
|
-
|
|
|
static void create_pcie_irq_map(void *fdt, char *nodename,
|
|
|
uint32_t plic_phandle)
|
|
|
{
|
|
@@ -440,13 +399,13 @@ static void riscv_virt_board_init(MachineState *machine)
|
|
|
mask_rom);
|
|
|
|
|
|
if (machine->kernel_filename) {
|
|
|
- uint64_t kernel_entry = load_kernel(machine->kernel_filename);
|
|
|
+ uint64_t kernel_entry = riscv_load_kernel(machine->kernel_filename);
|
|
|
|
|
|
if (machine->initrd_filename) {
|
|
|
hwaddr start;
|
|
|
- hwaddr end = load_initrd(machine->initrd_filename,
|
|
|
- machine->ram_size, kernel_entry,
|
|
|
- &start);
|
|
|
+ hwaddr end = riscv_load_initrd(machine->initrd_filename,
|
|
|
+ machine->ram_size, kernel_entry,
|
|
|
+ &start);
|
|
|
qemu_fdt_setprop_cell(fdt, "/chosen",
|
|
|
"linux,initrd-start", start);
|
|
|
qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
|