payloads/libpayload: Add support for RISC-V 64-bit architecture
This patch adds config ARCH_RISCV_RV64 to support build of riscv64 payloads. New files under arch/riscv contain: - Basic ldscript and payload entry point. - Functions for riscv64 io and cache operations. - Default timer code based on mtime delegation. - Default cb_header_ptr passing with device tree to payload. Change-Id: Ieb3d456d5edda87a3a4886ccfc17a7824c630427 Signed-off-by: Ziang Wang <wangziang.ok@bytedance.com> Signed-off-by: Dong Wei <weidong.wd@bytedance.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/89646 Reviewed-by: Maximilian Brune <maximilian.brune@9elements.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
4decc72c23
commit
82f9c593ab
23 changed files with 693 additions and 6 deletions
|
|
@ -127,6 +127,15 @@ config ARCH_ARM64
|
|||
help
|
||||
Support the ARM64 architecture
|
||||
|
||||
config ARCH_RISCV_RV64
|
||||
bool "RISCV64"
|
||||
depends on GPL
|
||||
depends on EXPERIMENTAL
|
||||
help
|
||||
Support the RISC-V 64-bit architecture
|
||||
Please note that support for riscv64 payload is experimental at this time, may have
|
||||
fundamental change in the future.
|
||||
|
||||
config ARCH_MOCK
|
||||
bool "Mock architecture (for unit tests)"
|
||||
help
|
||||
|
|
@ -523,3 +532,4 @@ source "arch/arm/Kconfig"
|
|||
source "arch/arm64/Kconfig"
|
||||
source "arch/x86/Kconfig"
|
||||
source "arch/mock/Kconfig"
|
||||
source "arch/riscv/Kconfig"
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ ARCHDIR-$(CONFIG_LP_ARCH_ARM) := arm
|
|||
ARCHDIR-$(CONFIG_LP_ARCH_ARM64) := arm64
|
||||
ARCHDIR-$(CONFIG_LP_ARCH_X86) := x86
|
||||
ARCHDIR-$(CONFIG_LP_ARCH_MOCK) := mock
|
||||
ARCHDIR-$(CONFIG_LP_ARCH_RISCV_RV64) := riscv
|
||||
|
||||
ARCH-y := $(ARCHDIR-y)
|
||||
|
||||
|
|
@ -121,6 +122,7 @@ ARCH-$(CONFIG_LP_ARCH_ARM64) := arm64
|
|||
ARCH-$(CONFIG_LP_ARCH_X86_32) := x86_32
|
||||
ARCH-$(CONFIG_LP_ARCH_X86_64) := x86_64
|
||||
ARCH-$(CONFIG_LP_ARCH_MOCK) := mock
|
||||
ARCH-$(CONFIG_LP_ARCH_RISCV_RV64) := riscv
|
||||
|
||||
# Five cases where we don't need fully populated $(obj) lists:
|
||||
# 1. when no .config exists
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ ARCHDIR-$(CONFIG_LP_ARCH_ARM) := arm
|
|||
ARCHDIR-$(CONFIG_LP_ARCH_ARM64) := arm64
|
||||
ARCHDIR-$(CONFIG_LP_ARCH_X86) := x86
|
||||
ARCHDIR-$(CONFIG_LP_ARCH_MOCK) := mock
|
||||
ARCHDIR-$(CONFIG_LP_ARCH_RISCV_RV64) := riscv
|
||||
DESTDIR ?= install
|
||||
|
||||
real-target: lib
|
||||
|
|
|
|||
4
payloads/libpayload/arch/riscv/Kconfig
Normal file
4
payloads/libpayload/arch/riscv/Kconfig
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
## SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
config ARCH_RISCV_RV64
|
||||
select LITTLE_ENDIAN
|
||||
7
payloads/libpayload/arch/riscv/Makefile.mk
Normal file
7
payloads/libpayload/arch/riscv/Makefile.mk
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
## SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
libc-y += head.S
|
||||
libc-y += main.c sysinfo.c
|
||||
libc-y += timer.c coreboot.c cache.c util.S virtual.c
|
||||
|
||||
CFLAGS += -mcmodel=medany
|
||||
13
payloads/libpayload/arch/riscv/cache.c
Normal file
13
payloads/libpayload/arch/riscv/cache.c
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <arch/cache.h>
|
||||
|
||||
void tlb_invalidate_all(void)
|
||||
{
|
||||
asm volatile ("sfence.vma" : : : "memory");
|
||||
}
|
||||
|
||||
void dcache_clean_invalidate_all(void)
|
||||
{
|
||||
|
||||
}
|
||||
34
payloads/libpayload/arch/riscv/coreboot.c
Normal file
34
payloads/libpayload/arch/riscv/coreboot.c
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <libpayload-config.h>
|
||||
#include <libpayload.h>
|
||||
#include <coreboot_tables.h>
|
||||
|
||||
/*
|
||||
* This pointer is no longer set in head.S by default like in other arch, payloads should have
|
||||
* their own ways to init it from any source before using it.
|
||||
* e.g. If run after OpenSBI, this could be retrieved from fdt node.
|
||||
* If run directly after Ramstage, could be from arg0.
|
||||
*/
|
||||
void *cb_header_ptr;
|
||||
|
||||
/* == Architecture specific == */
|
||||
|
||||
int cb_parse_arch_specific(struct cb_record *rec, struct sysinfo_t *info)
|
||||
{
|
||||
switch (rec->tag) {
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int get_coreboot_info(struct sysinfo_t *info)
|
||||
{
|
||||
return cb_parse_header(cb_header_ptr, 1, info);
|
||||
}
|
||||
|
||||
void *get_cb_header_ptr(void)
|
||||
{
|
||||
return cb_header_ptr;
|
||||
}
|
||||
24
payloads/libpayload/arch/riscv/head.S
Normal file
24
payloads/libpayload/arch/riscv/head.S
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <arch/asm.h>
|
||||
|
||||
/*
|
||||
* Our entry point
|
||||
*/
|
||||
ENTRY(_entry)
|
||||
|
||||
/* Setup new stack */
|
||||
lla t0, 1f
|
||||
ld sp, 0(t0)
|
||||
//mov sp, x1
|
||||
|
||||
/* Let's rock. */
|
||||
j start_main
|
||||
|
||||
ret
|
||||
ENDPROC(_entry)
|
||||
|
||||
.section .entry, "ax", %progbits
|
||||
.align 4
|
||||
1:
|
||||
.quad _stack
|
||||
65
payloads/libpayload/arch/riscv/libpayload.ldscript
Normal file
65
payloads/libpayload/arch/riscv/libpayload.ldscript
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
OUTPUT_ARCH(riscv)
|
||||
|
||||
ENTRY(_entry)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = CONFIG_LP_BASE_ADDRESS;
|
||||
|
||||
. = ALIGN(16);
|
||||
_start = .;
|
||||
|
||||
.text : {
|
||||
_text = .;
|
||||
*(.text._entry)
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
_etext = .;
|
||||
}
|
||||
|
||||
.rodata : {
|
||||
_rodata = .;
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
_erodata = .;
|
||||
}
|
||||
|
||||
.data : {
|
||||
_data = .;
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
_edata = .;
|
||||
}
|
||||
|
||||
.bss : {
|
||||
_bss = .;
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(COMMON)
|
||||
_ebss = .;
|
||||
|
||||
/* Stack and heap */
|
||||
|
||||
. = ALIGN(16);
|
||||
_heap = .;
|
||||
. += CONFIG_LP_HEAP_SIZE;
|
||||
. = ALIGN(16);
|
||||
_eheap = .;
|
||||
|
||||
_estack = .;
|
||||
. += CONFIG_LP_STACK_SIZE;
|
||||
. = ALIGN(16);
|
||||
_stack = .;
|
||||
}
|
||||
|
||||
_end = .;
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.comment)
|
||||
*(.note*)
|
||||
}
|
||||
}
|
||||
53
payloads/libpayload/arch/riscv/main.c
Normal file
53
payloads/libpayload/arch/riscv/main.c
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <libpayload.h>
|
||||
#include <endian.h>
|
||||
#include <commonlib/device_tree.h>
|
||||
|
||||
uint64_t boot_hartid;
|
||||
/**
|
||||
* This is our C entry function - set up the system and jump into the payload entry point.
|
||||
* Unlike other archs, we do not save a0~a2 from previous stage as global variables in head.S,
|
||||
* but pass them to start_main directly as arg0, arg1, arg2 instead.
|
||||
*
|
||||
* arg0 is the preferred boot hart id.
|
||||
* arg1 is a pointer to the DTB.
|
||||
* This interface is static no matter whether previous stage is OpenSBI or coreboot Ramstage.
|
||||
*
|
||||
* arg2 is reserved for possible future usage.
|
||||
*/
|
||||
void start_main(uint64_t arg0, uint64_t arg1, uint64_t arg2);
|
||||
void start_main(uint64_t arg0, uint64_t arg1, uint64_t arg2)
|
||||
{
|
||||
extern int main(int argc, char **argv);
|
||||
extern void *cb_header_ptr;
|
||||
|
||||
/* cbtable pointer is stored in the dtb passed by previous stage */
|
||||
boot_hartid = arg0;
|
||||
const void *dtb = (const void *)arg1;
|
||||
if (dtb && fdt_is_valid(dtb)) {
|
||||
/* Look for the "coreboot-table" node in the DTB */
|
||||
u32 node_offset = fdt_find_node_by_path(dtb, "/chosen", NULL, NULL);
|
||||
if (node_offset) {
|
||||
struct fdt_property prop;
|
||||
if (fdt_read_prop(dtb, node_offset, "coreboot-table", &prop)) {
|
||||
/* Extract the coreboot table pointer from the property */
|
||||
cb_header_ptr = (void *)be64dec(prop.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Gather system information. */
|
||||
lib_get_sysinfo();
|
||||
|
||||
#if !CONFIG(LP_SKIP_CONSOLE_INIT)
|
||||
console_init();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Go to the entry point.
|
||||
* In the future we may care about the return value.
|
||||
*/
|
||||
main(0, NULL);
|
||||
printf("Unexpected return from payload\n");
|
||||
}
|
||||
70
payloads/libpayload/arch/riscv/sysinfo.c
Normal file
70
payloads/libpayload/arch/riscv/sysinfo.c
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2008 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <libpayload-config.h>
|
||||
#include <libpayload.h>
|
||||
#include <coreboot_tables.h>
|
||||
|
||||
/**
|
||||
* This is a global structure that is used through the library - we set it
|
||||
* up initially with some dummy values - hopefully they will be overridden.
|
||||
*/
|
||||
struct sysinfo_t lib_sysinfo = {
|
||||
.cpu_khz = 200,
|
||||
};
|
||||
|
||||
int lib_get_sysinfo(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Get the CPU speed (for delays). */
|
||||
lib_sysinfo.cpu_khz = get_cpu_speed();
|
||||
|
||||
/* Get information from the coreboot tables,
|
||||
* if they exist */
|
||||
|
||||
ret = get_coreboot_info(&lib_sysinfo);
|
||||
|
||||
if (!lib_sysinfo.n_memranges) {
|
||||
/* If we can't get a good memory range, use the default. */
|
||||
lib_sysinfo.n_memranges = 1;
|
||||
|
||||
lib_sysinfo.memrange[0].base = 0;
|
||||
lib_sysinfo.memrange[0].size = 1024 * 1024;
|
||||
lib_sysinfo.memrange[0].type = CB_MEM_RAM;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void lib_sysinfo_get_memranges(struct memrange **ranges,
|
||||
uint64_t *nranges)
|
||||
{
|
||||
*ranges = &lib_sysinfo.memrange[0];
|
||||
*nranges = lib_sysinfo.n_memranges;
|
||||
}
|
||||
53
payloads/libpayload/arch/riscv/timer.c
Normal file
53
payloads/libpayload/arch/riscv/timer.c
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2008 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file riscv64/timer.c
|
||||
* RISCV64 specific timer routines
|
||||
*/
|
||||
|
||||
#include <libpayload.h>
|
||||
|
||||
/**
|
||||
* @ingroup arch
|
||||
* Global variable containing the speed of the processor in KHz.
|
||||
*/
|
||||
u32 cpu_khz;
|
||||
|
||||
/**
|
||||
* Calculate the speed of the processor for use in delays.
|
||||
*
|
||||
* @return The CPU speed in kHz.
|
||||
*/
|
||||
unsigned int get_cpu_speed(void)
|
||||
{
|
||||
/* FIXME */
|
||||
cpu_khz = 1000000U;
|
||||
|
||||
return cpu_khz;
|
||||
}
|
||||
34
payloads/libpayload/arch/riscv/util.S
Normal file
34
payloads/libpayload/arch/riscv/util.S
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2012 Google, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arch/asm.h>
|
||||
|
||||
/* This function puts the system into a halt. */
|
||||
ENTRY(halt)
|
||||
j halt
|
||||
ENDPROC(halt)
|
||||
36
payloads/libpayload/arch/riscv/virtual.c
Normal file
36
payloads/libpayload/arch/riscv/virtual.c
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2008 coresystems GmbH
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
unsigned long virtual_offset = 0;
|
||||
|
||||
int getpagesize(void)
|
||||
{
|
||||
return 4096;
|
||||
}
|
||||
|
|
@ -64,6 +64,7 @@ libc-y += timer/generic.c
|
|||
endif
|
||||
libc-$(CONFIG_LP_TIMER_RDTSC) += timer/rdtsc.c
|
||||
libc-$(CONFIG_LP_TIMER_ARM64_ARCH) += timer/arm64_arch_timer.c
|
||||
libc-$(CONFIG_LP_TIMER_RISCV64_ARCH) += timer/riscv64_arch_timer.c
|
||||
|
||||
# Video console drivers
|
||||
libc-$(CONFIG_LP_VIDEO_CONSOLE) += video/video.c
|
||||
|
|
|
|||
|
|
@ -36,6 +36,12 @@ config TIMER_ARM64_ARCH
|
|||
help
|
||||
The cntfrq register needs to have been pre-initialized.
|
||||
|
||||
config TIMER_RISCV64_ARCH
|
||||
bool "Architecture Timer for RISCV64 platforms"
|
||||
depends on ARCH_RISCV_RV64
|
||||
help
|
||||
Payloads usually run in S-Mode, which has a time CSR for timer implementation.
|
||||
|
||||
config TIMER_RK3288
|
||||
bool "Timer for Rockchip RK3288"
|
||||
|
||||
|
|
|
|||
16
payloads/libpayload/drivers/timer/riscv64_arch_timer.c
Normal file
16
payloads/libpayload/drivers/timer/riscv64_arch_timer.c
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <libpayload.h>
|
||||
|
||||
uint64_t timer_hz(void)
|
||||
{
|
||||
/* FIXME */
|
||||
return 1000000;
|
||||
}
|
||||
|
||||
uint64_t timer_raw_value(void)
|
||||
{
|
||||
uint64_t value;
|
||||
asm volatile ("csrr %0, time" : "=r" (value));
|
||||
return value;
|
||||
}
|
||||
23
payloads/libpayload/include/riscv/arch/asm.h
Normal file
23
payloads/libpayload/include/riscv/arch/asm.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RISCV64_ASM_H
|
||||
#define __RISCV64_ASM_H
|
||||
|
||||
#define ENDPROC(name) \
|
||||
.type name, %function; \
|
||||
END(name)
|
||||
|
||||
#define ENTRY(name) \
|
||||
.section .text.name, "ax", %progbits; \
|
||||
.global name; \
|
||||
.align 2; \
|
||||
name:
|
||||
|
||||
#define END(name) \
|
||||
.size name, .-name
|
||||
|
||||
#endif /* __RISCV64_ASM_H */
|
||||
21
payloads/libpayload/include/riscv/arch/cache.h
Normal file
21
payloads/libpayload/include/riscv/arch/cache.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef RISCV64_CACHE_H
|
||||
#define RISCV64_CACHE_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* tlb invalidate all */
|
||||
void tlb_invalidate_all(void);
|
||||
|
||||
void dcache_clean_invalidate_all(void);
|
||||
|
||||
/* Invalidate all of the instruction cache for PE to PoU. */
|
||||
static inline void icache_invalidate_all(void)
|
||||
{
|
||||
__asm__ __volatile__("fence.i\n\t");
|
||||
}
|
||||
|
||||
|
||||
#endif /* RISCV64_CACHE_H */
|
||||
106
payloads/libpayload/include/riscv/arch/io.h
Normal file
106
payloads/libpayload/include/riscv/arch/io.h
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef _ARCH_IO_H
|
||||
#define _ARCH_IO_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <arch/cache.h>
|
||||
|
||||
#define fence_i_r() __asm__ __volatile__("fence i,r" : : : "memory")
|
||||
#define fence_ow_ow() __asm__ __volatile__("fence ow,ow" : : : "memory")
|
||||
|
||||
/*
|
||||
* readb/w/l writeb/w/l are deprecated. use read8/16/32 and write8/16/32
|
||||
* instead for future development.
|
||||
*/
|
||||
|
||||
static inline uint8_t readb(volatile const void *_a)
|
||||
{
|
||||
return *(volatile const uint8_t *)_a;
|
||||
fence_i_r();
|
||||
}
|
||||
|
||||
static inline uint16_t readw(volatile const void *_a)
|
||||
{
|
||||
return *(volatile const uint16_t *)_a;
|
||||
fence_i_r();
|
||||
}
|
||||
|
||||
static inline uint32_t readl(volatile const void *_a)
|
||||
{
|
||||
return *(volatile const uint32_t *)_a;
|
||||
fence_i_r();
|
||||
}
|
||||
|
||||
static inline void writeb(uint8_t _v, volatile void *_a)
|
||||
{
|
||||
fence_ow_ow();
|
||||
*(volatile uint8_t *)_a = _v;
|
||||
}
|
||||
|
||||
static inline void writew(uint16_t _v, volatile void *_a)
|
||||
{
|
||||
fence_ow_ow();
|
||||
*(volatile uint16_t *)_a = _v;
|
||||
}
|
||||
|
||||
static inline void writel(uint32_t _v, volatile void *_a)
|
||||
{
|
||||
fence_ow_ow();
|
||||
*(volatile uint32_t *)_a = _v;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: make the existing code use read8/16/32 and write8/16/32 then remove
|
||||
* readb/w/l and writeb/w/l.
|
||||
*/
|
||||
|
||||
static inline uint8_t read8(volatile const void *addr)
|
||||
{
|
||||
return *(volatile uint8_t *)addr;
|
||||
fence_i_r();
|
||||
}
|
||||
|
||||
static inline uint16_t read16(volatile const void *addr)
|
||||
{
|
||||
return *(volatile uint16_t *)addr;
|
||||
fence_i_r();
|
||||
}
|
||||
|
||||
static inline uint32_t read32(volatile const void *addr)
|
||||
{
|
||||
return *(volatile uint32_t *)addr;
|
||||
fence_i_r();
|
||||
}
|
||||
|
||||
static inline uint64_t read64(volatile const void *addr)
|
||||
{
|
||||
return *(volatile uint64_t *)addr;
|
||||
fence_i_r();
|
||||
}
|
||||
|
||||
static inline void write8(volatile void *addr, uint8_t val)
|
||||
{
|
||||
fence_ow_ow();
|
||||
*(volatile uint8_t *)addr = val;
|
||||
}
|
||||
|
||||
static inline void write16(volatile void *addr, uint16_t val)
|
||||
{
|
||||
fence_ow_ow();
|
||||
*(volatile uint16_t *)addr = val;
|
||||
}
|
||||
|
||||
static inline void write32(volatile void *addr, uint32_t val)
|
||||
{
|
||||
fence_ow_ow();
|
||||
*(volatile uint32_t *)addr = val;
|
||||
}
|
||||
|
||||
static inline void write64(volatile void *addr, uint64_t val)
|
||||
{
|
||||
fence_ow_ow();
|
||||
*(volatile uint64_t *)addr = val;
|
||||
}
|
||||
|
||||
#endif
|
||||
33
payloads/libpayload/include/riscv/arch/types.h
Normal file
33
payloads/libpayload/include/riscv/arch/types.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef _ARCH_TYPES_H
|
||||
#define _ARCH_TYPES_H
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned char u8;
|
||||
typedef signed char int8_t;
|
||||
typedef signed char s8;
|
||||
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned short u16;
|
||||
typedef signed short int16_t;
|
||||
typedef signed short s16;
|
||||
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned int u32;
|
||||
typedef signed int int32_t;
|
||||
typedef signed int s32;
|
||||
|
||||
typedef unsigned long long uint64_t;
|
||||
typedef unsigned long long u64;
|
||||
typedef signed long long int64_t;
|
||||
typedef signed long long s64;
|
||||
|
||||
typedef long time_t;
|
||||
typedef long suseconds_t;
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
14
payloads/libpayload/include/riscv/arch/virtual.h
Normal file
14
payloads/libpayload/include/riscv/arch/virtual.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef _ARCH_VIRTUAL_H
|
||||
#define _ARCH_VIRTUAL_H
|
||||
|
||||
extern unsigned long virtual_offset;
|
||||
|
||||
#define virt_to_phys(virt) ((unsigned long) (virt) + virtual_offset)
|
||||
#define phys_to_virt(phys) ((void *) ((unsigned long) (phys) - virtual_offset))
|
||||
|
||||
#define virt_to_bus(addr) virt_to_phys(addr)
|
||||
#define bus_to_virt(addr) phys_to_virt(addr)
|
||||
|
||||
#endif
|
||||
|
|
@ -8,12 +8,58 @@
|
|||
#include <mcall.h>
|
||||
#include <cbfs.h>
|
||||
#include <console/console.h>
|
||||
#include <commonlib/device_tree.h>
|
||||
#include <cbmem.h>
|
||||
|
||||
struct arch_prog_run_args {
|
||||
struct prog *prog;
|
||||
struct prog *opensbi;
|
||||
};
|
||||
|
||||
/*
|
||||
* At the moment devicetree is the default handoff format to the payload instead of
|
||||
* coreboot tables (on RISC-V only). That may change in the future, but for now we will put a
|
||||
* reference to the coreboot tables inside the FDT (similar to what we do in ACPI).
|
||||
*/
|
||||
static void *add_coreboot_table_to_fdt(void *fdt)
|
||||
{
|
||||
if (!fdt || !fdt_is_valid(fdt)) {
|
||||
printk(BIOS_ERR, "Invalid FDT provided\n");
|
||||
return fdt;
|
||||
}
|
||||
|
||||
void *coreboot_table = cbmem_find(CBMEM_ID_CBTABLE);
|
||||
if (!coreboot_table) {
|
||||
printk(BIOS_ERR, "coreboot table not found in CBMEM\n");
|
||||
return fdt;
|
||||
}
|
||||
|
||||
struct device_tree *tree = fdt_unflatten(fdt);
|
||||
if (!tree) {
|
||||
printk(BIOS_ERR, "Failed to unflatten FDT\n");
|
||||
return fdt;
|
||||
}
|
||||
|
||||
struct device_tree_node *chosen_node = dt_find_node_by_path(tree, "/chosen", NULL, NULL, 1);
|
||||
if (!chosen_node) {
|
||||
printk(BIOS_ERR, "Failed to find or create /chosen node\n");
|
||||
return fdt;
|
||||
}
|
||||
|
||||
printk(BIOS_INFO, "Adding cbtable@%p to fdt\n", coreboot_table);
|
||||
dt_add_u64_prop(chosen_node, "coreboot-table", (uint64_t)(uintptr_t)coreboot_table);
|
||||
|
||||
size_t next_size = dt_flat_size(tree);
|
||||
void *next_fdt = malloc(next_size);
|
||||
if (!next_fdt) {
|
||||
printk(BIOS_ERR, "Failed to allocate memory for next-stage FDT\n");
|
||||
return fdt;
|
||||
}
|
||||
|
||||
dt_flatten(tree, next_fdt);
|
||||
return next_fdt;
|
||||
}
|
||||
|
||||
/*
|
||||
* A pointer to the Flattened Device Tree passed to coreboot by the boot ROM.
|
||||
* Presumably this FDT is also in ROM.
|
||||
|
|
@ -51,14 +97,29 @@ void arch_prog_run(struct prog *prog)
|
|||
|
||||
args.prog = prog;
|
||||
|
||||
/* In case of OpenSBI we have to load it before resuming all HARTs */
|
||||
if (ENV_RAMSTAGE && CONFIG(RISCV_OPENSBI)) {
|
||||
struct prog sbi = PROG_INIT(PROG_OPENSBI, CONFIG_CBFS_PREFIX"/opensbi");
|
||||
if (ENV_RAMSTAGE) {
|
||||
int hart_count = CONFIG_MAX_CPUS;
|
||||
if (CONFIG(RISCV_GET_HART_COUNT_AT_RUNTIME))
|
||||
hart_count = smp_get_hart_count();
|
||||
|
||||
if (!selfload_check(&sbi, BM_MEM_OPENSBI))
|
||||
die("OpenSBI load failed");
|
||||
/* Embed coreboot table pointer into fdt, so that payload can find it. */
|
||||
void *fdt = HLS()->fdt;
|
||||
void *next_fdt = add_coreboot_table_to_fdt(fdt);
|
||||
|
||||
args.opensbi = &sbi;
|
||||
/* Update per hart's fdt with "coreboot-table" node embedded */
|
||||
for (int i = 0; i < hart_count; i++) {
|
||||
OTHER_HLS(i)->fdt = next_fdt;
|
||||
}
|
||||
|
||||
/* In case of OpenSBI we have to load it before resuming all HARTs */
|
||||
if (CONFIG(RISCV_OPENSBI)) {
|
||||
struct prog sbi = PROG_INIT(PROG_OPENSBI, CONFIG_CBFS_PREFIX"/opensbi");
|
||||
|
||||
if (!selfload_check(&sbi, BM_MEM_OPENSBI))
|
||||
die("OpenSBI load failed");
|
||||
|
||||
args.opensbi = &sbi;
|
||||
}
|
||||
}
|
||||
|
||||
smp_resume((void (*)(void *))do_arch_prog_run, &args);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue