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 <program_loading.h>
#include <vm.h> #include <vm.h>
#include <arch/boot.h>
#include <arch/encoding.h> #include <arch/encoding.h>
#include <rules.h> #include <rules.h>
#include <console/console.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 arch_prog_run(struct prog *prog)
{ {
void (*doit)(void *) = prog_entry(prog); void (*doit)(void *) = prog_entry(prog);
void riscvpayload(const char *configstring, void *payload); void riscvpayload(const void *fdt, void *payload);
const char *config = NULL;
if (ENV_RAMSTAGE && prog_type(prog) == PROG_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"); printk(BIOS_SPEW, "OK, let's go\n");
riscvpayload(config, doit); riscvpayload(fdt, doit);
} }
doit(prog_entry_arg(prog)); doit(prog_entry_arg(prog));

View File

@ -25,7 +25,14 @@
.globl _start .globl _start
_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 # N.B. This only works on low 4G of the address space
# and the stack must be page-aligned. # 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. * 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 * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License. * the Free Software Foundation; version 2 of the License.
@ -11,17 +14,22 @@
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
// "return" to a payload pointed to by a1 with // "return" to a payload. a0: FDT, a1: entry point
// an M-mode pointer (or, to upper levels, physical address)
// to the config string in a0.
.global riscvpayload .global riscvpayload
riscvpayload: riscvpayload:
mv t0,a1 /* Load the entry point */
csrw mepc, t0 mv t0, a1
csrr t0, mstatus csrw mepc, t0
li t1, ~(3<<11) csrr t0, mstatus
and t0, t0, t1
li t2, (1<<11) /* Set mstatus.MPP (the previous privilege mode) to supervisor mode */
or t0, t0, t2 li t1, ~(3<<11)
csrw mstatus, t0 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 mret

View File

@ -24,9 +24,20 @@
* linker script. * linker script.
*/ */
#include <arch/boot.h>
#include <arch/encoding.h>
#include <arch/stages.h> #include <arch/stages.h>
#include <rules.h>
void stage_entry(void) 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(); main();
} }