Unverified Commit 0ac24d56 authored by Alistair Francis's avatar Alistair Francis Committed by Palmer Dabbelt
Browse files

hw/riscv: Split out the boot functions



Split the common RISC-V boot functions into a seperate file. This allows
us to share the common code.

Signed-off-by: default avatarAlistair Francis <alistair.francis@wdc.com>
Reviewed-by: default avatarBin Meng <bmeng.cn@gmail.com>
Tested-by: default avatarBin Meng <bmeng.cn@gmail.com>
Signed-off-by: default avatarPalmer Dabbelt <palmer@sifive.com>
parent 05446f41
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
obj-y += boot.o
obj-$(CONFIG_SPIKE) += riscv_htif.o
obj-$(CONFIG_HART) += riscv_hart.o
obj-$(CONFIG_SIFIVE_E) += sifive_e.o

hw/riscv/boot.c

0 → 100644
+69 −0
Original line number Diff line number Diff line
/*
 * QEMU RISC-V Boot Helper
 *
 * Copyright (c) 2017 SiFive, Inc.
 * Copyright (c) 2019 Alistair Francis <alistair.francis@wdc.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2 or later, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qemu/error-report.h"
#include "exec/cpu-defs.h"
#include "hw/loader.h"
#include "hw/riscv/boot.h"
#include "elf.h"

target_ulong riscv_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;
}

hwaddr riscv_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;
}
+2 −15
Original line number Diff line number Diff line
@@ -44,10 +44,10 @@
#include "hw/riscv/sifive_prci.h"
#include "hw/riscv/sifive_uart.h"
#include "hw/riscv/sifive_e.h"
#include "hw/riscv/boot.h"
#include "chardev/char.h"
#include "sysemu/arch_init.h"
#include "exec/address-spaces.h"
#include "elf.h"

static const struct MemmapEntry {
    hwaddr base;
@@ -74,19 +74,6 @@ static const struct MemmapEntry {
    [SIFIVE_E_DTIM] =     { 0x80000000,     0x4000 }
};

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 void sifive_mmio_emulate(MemoryRegion *parent, const char *name,
                             uintptr_t offset, uintptr_t length)
{
@@ -131,7 +118,7 @@ static void riscv_sifive_e_init(MachineState *machine)
                          memmap[SIFIVE_E_MROM].base, &address_space_memory);

    if (machine->kernel_filename) {
        load_kernel(machine->kernel_filename);
        riscv_load_kernel(machine->kernel_filename);
    }
}

+2 −15
Original line number Diff line number Diff line
@@ -41,11 +41,11 @@
#include "hw/riscv/sifive_uart.h"
#include "hw/riscv/sifive_prci.h"
#include "hw/riscv/sifive_u.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 "elf.h"

#include <libfdt.h>

@@ -65,19 +65,6 @@ static const struct MemmapEntry {

#define GEM_REVISION        0x10070109

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 void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
    uint64_t mem_size, const char *cmdline)
{
@@ -283,7 +270,7 @@ static void riscv_sifive_u_init(MachineState *machine)
    create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);

    if (machine->kernel_filename) {
        load_kernel(machine->kernel_filename);
        riscv_load_kernel(machine->kernel_filename);
    }

    /* reset vector */
+4 −17
Original line number Diff line number Diff line
@@ -36,12 +36,12 @@
#include "hw/riscv/riscv_hart.h"
#include "hw/riscv/sifive_clint.h"
#include "hw/riscv/spike.h"
#include "hw/riscv/boot.h"
#include "chardev/char.h"
#include "sysemu/arch_init.h"
#include "sysemu/device_tree.h"
#include "sysemu/qtest.h"
#include "exec/address-spaces.h"
#include "elf.h"

#include <libfdt.h>

@@ -54,19 +54,6 @@ static const struct MemmapEntry {
    [SPIKE_DRAM] =     { 0x80000000,        0x0 },
};

static target_ulong load_kernel(const char *kernel_filename)
{
    uint64_t kernel_entry, kernel_high;

    if (load_elf_ram_sym(kernel_filename, NULL, NULL, NULL,
            &kernel_entry, NULL, &kernel_high, 0, EM_RISCV, 1, 0,
            NULL, true, htif_symbol_callback) < 0) {
        error_report("could not load kernel '%s'", kernel_filename);
        exit(1);
    }
    return kernel_entry;
}

static void create_fdt(SpikeState *s, const struct MemmapEntry *memmap,
    uint64_t mem_size, const char *cmdline)
{
@@ -199,7 +186,7 @@ static void spike_board_init(MachineState *machine)
                                mask_rom);

    if (machine->kernel_filename) {
        load_kernel(machine->kernel_filename);
        riscv_load_kernel(machine->kernel_filename);
    }

    /* reset vector */
@@ -287,7 +274,7 @@ static void spike_v1_10_0_board_init(MachineState *machine)
                                mask_rom);

    if (machine->kernel_filename) {
        load_kernel(machine->kernel_filename);
        riscv_load_kernel(machine->kernel_filename);
    }

    /* reset vector */
@@ -372,7 +359,7 @@ static void spike_v1_09_1_board_init(MachineState *machine)
                                mask_rom);

    if (machine->kernel_filename) {
        load_kernel(machine->kernel_filename);
        riscv_load_kernel(machine->kernel_filename);
    }

    /* reset vector */
Loading