mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-03-25 04:22:02 +08:00
riscv/riscv: refactor FDT helper functions
Adds bsp/riscv-fdt.h with new functions for pulling information from the FDT.
This commit is contained in:
69
bsps/riscv/include/bsp/riscv-fdt.h
Normal file
69
bsps/riscv/include/bsp/riscv-fdt.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup RTEMSBSPsRISCVShared
|
||||
*
|
||||
* @brief This header file provides interfaces for probing the RISC-V ISA
|
||||
* extensions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2026 Gedare Bloom
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
|
||||
*/
|
||||
|
||||
#ifndef _BSP_RISCV_FDT_H
|
||||
#define _BSP_RISCV_FDT_H
|
||||
|
||||
#include <rtems/score/cpu.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* @brief Finds the end of memory from the @a fdt properties.
|
||||
*
|
||||
* @return Returns the last valid address of memory.
|
||||
*/
|
||||
void *riscv_fdt_get_end_of_memory(const void *fdt);
|
||||
|
||||
/**
|
||||
* @brief Finds the timebase frequency from the @a fdt properties.
|
||||
*
|
||||
* @return Returns the timebase frequency.
|
||||
*/
|
||||
uint32_t riscv_clock_get_timebase_frequency(const void *fdt);
|
||||
|
||||
/**
|
||||
* @brief Searches for the ISA @a extension within the @a fdt.
|
||||
*/
|
||||
bool riscv_has_isa_extension(const void *fdt, const char *extension);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _BSP_RISCV_FDT_H */
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <bsp/fdt.h>
|
||||
#include <bsp/irq.h>
|
||||
#include <bsp/riscv.h>
|
||||
#include <bsp/riscv-fdt.h>
|
||||
|
||||
#include <rtems/sysinit.h>
|
||||
#include <rtems/timecounter.h>
|
||||
@@ -49,7 +50,6 @@
|
||||
#include <libfdt.h>
|
||||
|
||||
#ifdef RISCV_USE_S_MODE
|
||||
#include <string.h>
|
||||
#include <machine/sbi.h>
|
||||
|
||||
static bool riscv_has_sstc;
|
||||
@@ -111,30 +111,6 @@ static uint64_t riscv_clock_read_mtime(volatile RISCV_CLINT_timer_reg *mtime)
|
||||
}
|
||||
#endif /* !RISCV_USE_S_MODE */
|
||||
|
||||
#ifdef RISCV_USE_S_MODE
|
||||
static bool riscv_has_isa_extension(const void *fdt, const char *ext)
|
||||
{
|
||||
int node;
|
||||
const char *val;
|
||||
int len = 0;
|
||||
|
||||
node = fdt_path_offset(fdt, "/cpus");
|
||||
|
||||
val = (const char *) fdt_getprop(fdt, node, "riscv,isa", &len);
|
||||
|
||||
if (val == NULL || len == 0) {
|
||||
int cpu0 = fdt_subnode_offset(fdt, node, "cpu@0");
|
||||
val = (const char *) fdt_getprop(fdt, cpu0, "riscv,isa", &len);
|
||||
|
||||
if (val == NULL || len == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return strstr( val, ext ) != NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void riscv_clock_handler_install(rtems_interrupt_handler handler)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
@@ -166,27 +142,6 @@ static uint32_t riscv_clock_get_timecount(struct timecounter *base)
|
||||
return timecount;
|
||||
}
|
||||
|
||||
static uint32_t riscv_clock_get_timebase_frequency(const void *fdt)
|
||||
{
|
||||
int node;
|
||||
const fdt32_t *val;
|
||||
int len=0;
|
||||
|
||||
node = fdt_path_offset(fdt, "/cpus");
|
||||
|
||||
val = (fdt32_t *) fdt_getprop(fdt, node, "timebase-frequency", &len);
|
||||
|
||||
if (val == NULL || len < 4) {
|
||||
int cpu0 = fdt_subnode_offset(fdt, node, "cpu@0");
|
||||
val = (fdt32_t *) fdt_getprop(fdt, cpu0, "timebase-frequency", &len);
|
||||
|
||||
if (val == NULL || len < 4) {
|
||||
bsp_fatal(RISCV_FATAL_NO_TIMEBASE_FREQUENCY_IN_DEVICE_TREE);
|
||||
}
|
||||
}
|
||||
return fdt32_to_cpu(*val);
|
||||
}
|
||||
|
||||
static uint64_t riscv_clock_read_timer(riscv_timecounter *tc)
|
||||
{
|
||||
uint64_t now;
|
||||
|
||||
147
bsps/riscv/shared/fdt/riscv-fdt.c
Normal file
147
bsps/riscv/shared/fdt/riscv-fdt.c
Normal file
@@ -0,0 +1,147 @@
|
||||
/* SPDX-License-Identifier: BSD-2-Clause */
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup RTEMSBSPsRISCVShared
|
||||
*
|
||||
* @brief Helpers to probe the RISC-V ISA extensions.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2026 Gedare Bloom
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 <bsp.h>
|
||||
#include <bsp/fatal.h>
|
||||
#include <bsp/riscv-fdt.h>
|
||||
|
||||
#include <libfdt.h>
|
||||
#include <string.h>
|
||||
|
||||
void *riscv_fdt_get_end_of_memory( const void *fdt )
|
||||
{
|
||||
const void *val;
|
||||
int node;
|
||||
int parent;
|
||||
int ac;
|
||||
int sc;
|
||||
int len;
|
||||
uintptr_t start;
|
||||
uintptr_t size;
|
||||
|
||||
node = fdt_path_offset( fdt, "/memory" );
|
||||
|
||||
if (node < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
parent = fdt_parent_offset(fdt, node);
|
||||
if (parent < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ac = fdt_address_cells(fdt, parent);
|
||||
if (ac != 1 && ac != 2) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sc = fdt_size_cells(fdt, parent);
|
||||
if (sc != 1 && sc != 2) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sc > ac) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
val = fdt_getprop(fdt, node, "reg", &len);
|
||||
if (len < sc + ac) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ac == 1) {
|
||||
start = fdt32_ld(&((fdt32_t *)val)[0]);
|
||||
size = fdt32_ld(&((fdt32_t *)val)[1]);
|
||||
}
|
||||
|
||||
if (ac == 2) {
|
||||
start = fdt64_ld(&((fdt64_t *)val)[0]);
|
||||
if (sc == 1) {
|
||||
size = fdt32_ld(&((fdt32_t *)(val+8))[0]);
|
||||
} else {
|
||||
size = fdt64_ld(&((fdt64_t *)val)[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return (void*) (start + size);
|
||||
}
|
||||
|
||||
uint32_t riscv_clock_get_timebase_frequency(const void *fdt)
|
||||
{
|
||||
int node;
|
||||
const fdt32_t *val;
|
||||
int len=0;
|
||||
|
||||
node = fdt_path_offset(fdt, "/cpus");
|
||||
|
||||
val = (fdt32_t *) fdt_getprop(fdt, node, "timebase-frequency", &len);
|
||||
|
||||
if (val == NULL || len < 4) {
|
||||
int cpu0 = fdt_subnode_offset(fdt, node, "cpu@0");
|
||||
val = (fdt32_t *) fdt_getprop(fdt, cpu0, "timebase-frequency", &len);
|
||||
|
||||
if (val == NULL || len < 4) {
|
||||
bsp_fatal(RISCV_FATAL_NO_TIMEBASE_FREQUENCY_IN_DEVICE_TREE);
|
||||
}
|
||||
}
|
||||
return fdt32_to_cpu(*val);
|
||||
}
|
||||
|
||||
bool riscv_has_isa_extension(const void *fdt, const char *ext)
|
||||
{
|
||||
int node;
|
||||
const char *val;
|
||||
int len = 0;
|
||||
|
||||
node = fdt_path_offset(fdt, "/cpus");
|
||||
|
||||
if ( node < 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
val = (const char *) fdt_getprop(fdt, node, "riscv,isa", &len);
|
||||
|
||||
if (val == NULL || len == 0) {
|
||||
int cpu0 = fdt_subnode_offset(fdt, node, "cpu@0");
|
||||
val = (const char *) fdt_getprop(fdt, cpu0, "riscv,isa", &len);
|
||||
|
||||
if (val == NULL || len == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return strstr( val, ext ) != NULL;
|
||||
}
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/fdt.h>
|
||||
#include <bsp/riscv-fdt.h>
|
||||
|
||||
#include <rtems/sysinit.h>
|
||||
|
||||
@@ -49,79 +50,13 @@ extern char RamEnd[];
|
||||
|
||||
static Memory_Area _Memory_Areas[ 1 ];
|
||||
|
||||
static const char memory_path[] = "/memory";
|
||||
|
||||
static void* get_end_of_memory_from_fdt(void)
|
||||
{
|
||||
const void *fdt;
|
||||
const void *val;
|
||||
int node;
|
||||
int parent;
|
||||
int ac;
|
||||
int sc;
|
||||
int len;
|
||||
uintptr_t start;
|
||||
uintptr_t size;
|
||||
|
||||
fdt = bsp_fdt_get();
|
||||
|
||||
node = fdt_path_offset_namelen(
|
||||
fdt,
|
||||
memory_path,
|
||||
(int) sizeof(memory_path) - 1
|
||||
);
|
||||
|
||||
if (node < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
parent = fdt_parent_offset(fdt, node);
|
||||
if (parent < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ac = fdt_address_cells(fdt, parent);
|
||||
if (ac != 1 && ac != 2) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sc = fdt_size_cells(fdt, parent);
|
||||
if (sc != 1 && sc != 2) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sc > ac) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
val = fdt_getprop(fdt, node, "reg", &len);
|
||||
if (len < sc + ac) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ac == 1) {
|
||||
start = fdt32_ld(&((fdt32_t *)val)[0]);
|
||||
size = fdt32_ld(&((fdt32_t *)val)[1]);
|
||||
}
|
||||
|
||||
if (ac == 2) {
|
||||
start = fdt64_ld(&((fdt64_t *)val)[0]);
|
||||
if (sc == 1) {
|
||||
size = fdt32_ld(&((fdt32_t *)(val+8))[0]);
|
||||
} else {
|
||||
size = fdt64_ld(&((fdt64_t *)val)[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return (void*) (start + size);
|
||||
}
|
||||
|
||||
static void bsp_memory_initialize( void )
|
||||
{
|
||||
void *end;
|
||||
const void *fdt = bsp_fdt_get();
|
||||
|
||||
/* get end of memory from the "/memory" node in the fdt */
|
||||
end = get_end_of_memory_from_fdt();
|
||||
end = riscv_fdt_get_end_of_memory(fdt);
|
||||
if (end == NULL) {
|
||||
/* fall back to linker symbol if "/memory" node not found or invalid */
|
||||
end = RamEnd;
|
||||
|
||||
@@ -12,6 +12,7 @@ install:
|
||||
source:
|
||||
- bsps/include/bsp/linker-symbols.h
|
||||
- bsps/riscv/include/bsp/linker-symbols-arch.h
|
||||
- bsps/riscv/include/bsp/riscv-fdt.h
|
||||
ldflags: []
|
||||
links: []
|
||||
type: build
|
||||
|
||||
@@ -23,6 +23,7 @@ source:
|
||||
- bsps/riscv/riscv/irq/irq.c
|
||||
- bsps/riscv/noel/start/bsp_fatal_halt.c
|
||||
- bsps/riscv/riscv/start/bspstart.c
|
||||
- bsps/riscv/shared/fdt/riscv-fdt.c
|
||||
- bsps/riscv/shared/start/bspgetworkarea.c
|
||||
- bsps/shared/cache/nocache.c
|
||||
- bsps/shared/dev/btimer/btimer-cpucounter.c
|
||||
|
||||
@@ -29,6 +29,7 @@ source:
|
||||
- bsps/riscv/riscv/irq/irq.c
|
||||
- bsps/riscv/riscv/start/bsp_fatal_halt.c
|
||||
- bsps/riscv/riscv/start/bspstart.c
|
||||
- bsps/riscv/shared/fdt/riscv-fdt.c
|
||||
- bsps/riscv/shared/start/bspgetworkarea.c
|
||||
- bsps/shared/cache/nocache.c
|
||||
- bsps/shared/dev/btimer/btimer-cpucounter.c
|
||||
|
||||
Reference in New Issue
Block a user