arch/riscv: Pass the bootrom-provided FDT to the payload

The RISC-V boot protocol foresees that at every stage boundary (bootrom
to boot loader, boot loader -> OS), register a0 contains the Hart ID and
a1 contains the physical address of the Flattened Device Tree that the
stage shall use.

As a first step, pass the bootrom-provided FDT to the payload,
unmodified.

Change-Id: I468bc64a47153d564087235f1c7e2d10e3d7a658
Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
Reviewed-on: https://review.coreboot.org/23797
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
Jonathan Neuschäfer 2018-02-16 13:36:47 +01:00 committed by Martin Roth
parent b26759d703
commit 042a8336f3
5 changed files with 78 additions and 16 deletions

View File

@ -15,20 +15,35 @@
#include <program_loading.h>
#include <vm.h>
#include <arch/boot.h>
#include <arch/encoding.h>
#include <rules.h>
#include <console/console.h>
/*
* A pointer to the Flattened Device Tree passed to coreboot by the boot ROM.
* Presumably this FDT is also in ROM.
*
* This pointer is only used in ramstage!
*/
const void *rom_fdt;
void arch_prog_run(struct prog *prog)
{
void (*doit)(void *) = prog_entry(prog);
void riscvpayload(const char *configstring, void *payload);
const char *config = NULL;
void riscvpayload(const void *fdt, void *payload);
if (ENV_RAMSTAGE && prog_type(prog) == PROG_PAYLOAD) {
printk(BIOS_SPEW, "Config string: '%s'\n", config);
/*
* FIXME: This is wrong and will crash. Linux can't (in early
* boot) access memory that's before its own loading address.
* We need to copy the FDT to a place where Linux can access it.
*/
const void *fdt = rom_fdt;
printk(BIOS_SPEW, "FDT is at %p\n", fdt);
printk(BIOS_SPEW, "OK, let's go\n");
riscvpayload(config, doit);
riscvpayload(fdt, doit);
}
doit(prog_entry_arg(prog));

View File

@ -25,7 +25,14 @@
.globl _start
_start:
# The boot ROM may pass the following arguments to coreboot:
# a0: the value of mhartid
# a1: a pointer to the flattened devicetree
#
# Preserve only the FDT pointer. We can query mhartid ourselves at any
# time.
#
csrw mscratch, a1
# N.B. This only works on low 4G of the address space
# and the stack must be page-aligned.

View File

@ -0,0 +1,21 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2018 Jonathan Neuschäfer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that 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.
*/
#ifndef ARCH_RISCV_INCLUDE_ARCH_BOOT_H
#define ARCH_RISCV_INCLUDE_ARCH_BOOT_H
extern const void *rom_fdt;
#endif

View File

@ -1,6 +1,9 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2016 Google Inc
* Copyright (C) 2018 Jonathan Neuschäfer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
@ -11,17 +14,22 @@
* GNU General Public License for more details.
*/
// "return" to a payload pointed to by a1 with
// an M-mode pointer (or, to upper levels, physical address)
// to the config string in a0.
// "return" to a payload. a0: FDT, a1: entry point
.global riscvpayload
riscvpayload:
mv t0,a1
csrw mepc, t0
csrr t0, mstatus
li t1, ~(3<<11)
and t0, t0, t1
li t2, (1<<11)
or t0, t0, t2
csrw mstatus, t0
/* Load the entry point */
mv t0, a1
csrw mepc, t0
csrr t0, mstatus
/* Set mstatus.MPP (the previous privilege mode) to supervisor mode */
li t1, ~(3<<11)
and t0, t0, t1
li t2, (1<<11)
or t0, t0, t2
csrw mstatus, t0
/* Pass the right arguments and jump! */
mv a1, a0
csrr a0, mhartid
mret

View File

@ -24,9 +24,20 @@
* linker script.
*/
#include <arch/boot.h>
#include <arch/encoding.h>
#include <arch/stages.h>
#include <rules.h>
void stage_entry(void)
{
/*
* Save the FDT pointer before entering ramstage, because mscratch
* might be overwritten in the trap handler, and there is code in
* ramstage that generates misaligned access faults.
*/
if (ENV_RAMSTAGE)
rom_fdt = (const void *)read_csr(mscratch);
main();
}