fdt: move fdx_xx extend APIs from boards to drivers

Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
ligd 2024-03-05 22:30:59 +08:00 committed by Xiang Xiao
parent 22877e0fa5
commit a1836de09a
17 changed files with 262 additions and 201 deletions

View File

@ -31,6 +31,7 @@
* Pre-processor Definitions
****************************************************************************/
#define QEMU_SPI_IRQ_BASE 32
#define CHIP_MPCORE_VBASE 0x8000000
#define MPCORE_ICD_OFFSET 0x0000
#define MPCORE_ICC_OFFSET 0x10000

View File

@ -31,6 +31,7 @@
* Pre-processor Definitions
****************************************************************************/
#define QEMU_SPI_IRQ_BASE 32
#define CHIP_MPCORE_VBASE 0x8000000
#define MPCORE_ICD_OFFSET 0x0000
#define MPCORE_ICC_OFFSET 0x10000

View File

@ -41,96 +41,15 @@
* Pre-processor Definitions
****************************************************************************/
#define QEMU_SPI_IRQ_BASE 32
#ifndef QEMU_SPI_IRQ_BASE
#define QEMU_SPI_IRQ_BASE 32
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
#if defined(CONFIG_LIBC_FDT) && defined(CONFIG_DEVICE_TREE)
/****************************************************************************
* Name: fdt_get_irq
*
* Description:
* Only can be use when the corresponding node's parent interrupt
* controller is intc node.
*
****************************************************************************/
static int unused_code
fdt_get_irq(const void *fdt, int offset)
{
const fdt32_t *pv;
int irq = -ENOENT;
pv = fdt_getprop(fdt, offset, "interrupts", NULL);
if (pv != NULL)
{
irq = fdt32_ld(pv + 1) + QEMU_SPI_IRQ_BASE;
}
return irq;
}
/****************************************************************************
* Name: fdt_get_irq_by_path
*
* Description:
* Only can be use when the corresponding node's parent interrupt
* controller is intc node.
*
****************************************************************************/
static int unused_code
fdt_get_irq_by_path(const void *fdt, const char *path)
{
return fdt_get_irq(fdt, fdt_path_offset(fdt, path));
}
/****************************************************************************
* Name: fdt_get_reg_base
****************************************************************************/
static uintptr_t unused_code
fdt_get_reg_base(const void *fdt, int offset)
{
const void *reg;
uintptr_t addr = 0;
int parentoff;
parentoff = fdt_parent_offset(fdt, offset);
if (parentoff < 0)
{
return addr;
}
reg = fdt_getprop(fdt, offset, "reg", NULL);
if (reg != NULL)
{
if (fdt_address_cells(fdt, parentoff) == 2)
{
addr = fdt64_ld(reg);
}
else
{
addr = fdt32_ld(reg);
}
}
return addr;
}
/****************************************************************************
* Name: fdt_get_reg_base_by_path
****************************************************************************/
static uintptr_t unused_code
fdt_get_reg_base_by_path(const void *fdt, const char *path)
{
return fdt_get_reg_base(fdt, fdt_path_offset(fdt, path));
}
#ifdef CONFIG_DRIVERS_VIRTIO_MMIO
/****************************************************************************
@ -152,7 +71,7 @@ static void register_virtio_devices_from_fdt(const void *fdt)
}
addr = fdt_get_reg_base(fdt, offset);
irqnum = fdt_get_irq(fdt, offset);
irqnum = fdt_get_irq(fdt, offset, 1, QEMU_SPI_IRQ_BASE);
if (addr > 0 && irqnum >= 0)
{
virtio_register_mmio_device((void *)addr, irqnum);

View File

@ -46,7 +46,6 @@ CONFIG_IOB_BUFSIZE=1534
CONFIG_IOB_NBUFFERS=64
CONFIG_IOB_NCHAINS=64
CONFIG_IOB_THROTTLE=8
CONFIG_LIBC_FDT=y
CONFIG_MM_IOB=y
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y

View File

@ -47,7 +47,6 @@ CONFIG_IOB_ALIGNMENT=16
CONFIG_IOB_BUFSIZE=1534
CONFIG_IOB_NBUFFERS=64
CONFIG_IOB_THROTTLE=8
CONFIG_LIBC_FDT=y
CONFIG_NET=y
CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDB_DNSCLIENT_ENTRIES=4

View File

@ -48,7 +48,6 @@ CONFIG_IOB_ALIGNMENT=16
CONFIG_IOB_BUFSIZE=1534
CONFIG_IOB_NBUFFERS=64
CONFIG_IOB_THROTTLE=8
CONFIG_LIBC_FDT=y
CONFIG_NET=y
CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDB_DNSCLIENT_ENTRIES=4

View File

@ -45,7 +45,6 @@ CONFIG_INTELHEX_BINARY=y
CONFIG_IOB_BUFSIZE=1534
CONFIG_IOB_NBUFFERS=64
CONFIG_IOB_THROTTLE=8
CONFIG_LIBC_FDT=y
CONFIG_NET=y
CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDB_DNSCLIENT_ENTRIES=4

View File

@ -46,7 +46,6 @@ CONFIG_INTELHEX_BINARY=y
CONFIG_IOB_BUFSIZE=1534
CONFIG_IOB_NBUFFERS=64
CONFIG_IOB_THROTTLE=8
CONFIG_LIBC_FDT=y
CONFIG_NET=y
CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETDB_DNSCLIENT_ENTRIES=4

View File

@ -39,7 +39,6 @@ CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=8192
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_FDT=y
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512

View File

@ -41,7 +41,6 @@ CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=8192
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_FDT=y
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512

View File

@ -47,7 +47,6 @@ CONFIG_IDLETHREAD_STACKSIZE=8192
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_DLFCN=y
CONFIG_LIBC_FDT=y
CONFIG_MODLIB_DUMPBUFFER=y
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y

View File

@ -41,96 +41,15 @@
* Pre-processor Definitions
****************************************************************************/
#define QEMU_SPI_IRQ_BASE 32
#ifndef QEMU_SPI_IRQ_BASE
#define QEMU_SPI_IRQ_BASE 32
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
#if defined(CONFIG_LIBC_FDT) && defined(CONFIG_DEVICE_TREE)
/****************************************************************************
* Name: fdt_get_irq
*
* Description:
* Only can be use when the corresponding node's parent interrupt
* controller is intc node.
*
****************************************************************************/
static int unused_code
fdt_get_irq(const void *fdt, int offset)
{
const fdt32_t *pv;
int irq = -ENOENT;
pv = fdt_getprop(fdt, offset, "interrupts", NULL);
if (pv != NULL)
{
irq = fdt32_ld(pv + 1) + QEMU_SPI_IRQ_BASE;
}
return irq;
}
/****************************************************************************
* Name: fdt_get_irq_by_path
*
* Description:
* Only can be use when the corresponding node's parent interrupt
* controller is intc node.
*
****************************************************************************/
static int unused_code
fdt_get_irq_by_path(const void *fdt, const char *path)
{
return fdt_get_irq(fdt, fdt_path_offset(fdt, path));
}
/****************************************************************************
* Name: fdt_get_reg_base
****************************************************************************/
static uintptr_t unused_code
fdt_get_reg_base(const void *fdt, int offset)
{
const void *reg;
uintptr_t addr = 0;
int parentoff;
parentoff = fdt_parent_offset(fdt, offset);
if (parentoff < 0)
{
return addr;
}
reg = fdt_getprop(fdt, offset, "reg", NULL);
if (reg != NULL)
{
if (fdt_address_cells(fdt, parentoff) == 2)
{
addr = fdt64_ld(reg);
}
else
{
addr = fdt32_ld(reg);
}
}
return addr;
}
/****************************************************************************
* Name: fdt_get_reg_base_by_path
****************************************************************************/
static uintptr_t unused_code
fdt_get_reg_base_by_path(const void *fdt, const char *path)
{
return fdt_get_reg_base(fdt, fdt_path_offset(fdt, path));
}
#ifdef CONFIG_DRIVERS_VIRTIO_MMIO
/****************************************************************************
@ -152,7 +71,7 @@ static void register_virtio_devices_from_fdt(const void *fdt)
}
addr = fdt_get_reg_base(fdt, offset);
irqnum = fdt_get_irq(fdt, offset);
irqnum = fdt_get_irq(fdt, offset, 1, QEMU_SPI_IRQ_BASE);
if (addr > 0 && irqnum >= 0)
{
virtio_register_mmio_device((void *)addr, irqnum);

View File

@ -20,5 +20,7 @@
if(CONFIG_DEVICE_TREE)
set(SRCS fdt.c)
target_include_directories(drivers
PRIVATE ${NUTTX_DIR}/libs/libc/fdt/dtc/libfdt)
target_sources(drivers PRIVATE ${SRCS})
endif()

View File

@ -6,5 +6,6 @@
menuconfig DEVICE_TREE
bool "Device Tree Support"
default n
select LIBC_FDT
---help---
Interface for interacting with devicetree.

View File

@ -22,6 +22,8 @@ ifeq ($(CONFIG_DEVICE_TREE),y)
CSRCS += fdt.c
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)fdt$(DELIM)dtc$(DELIM)libfdt
DEPPATH += --dep-path devicetree
VPATH += :devicetree

View File

@ -28,6 +28,7 @@
#include <assert.h>
#include <nuttx/compiler.h>
#include <nuttx/fdt.h>
#include <libfdt.h>
/****************************************************************************
* Private Data
@ -41,20 +42,6 @@ static FAR const char *g_fdt_base = NULL;
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: fdt_register
*
* Description:
* Store the pointer to the flattened device tree and verify that it at
* least appears to be valid. This function will not fully parse the FDT.
*
* Return:
* Return -EINVAL if the fdt header does not have the expected magic value.
* otherwise return OK. If OK is not returned the existing entry for FDT
* is not modified.
*
****************************************************************************/
int fdt_register(FAR const char *fdt_base)
{
struct fdt_header_s *fdt_header;
@ -71,16 +58,100 @@ int fdt_register(FAR const char *fdt_base)
return OK;
}
/****************************************************************************
* Name: fdt_get
*
* Description:
* Return the pointer to a raw FDT. NULL is returned if no FDT has been
* loaded.
*
****************************************************************************/
FAR const char *fdt_get(void)
{
return g_fdt_base;
}
int fdt_get_irq(FAR const void *fdt, int nodeoffset,
int offset, int irqbase)
{
FAR const fdt32_t *pv;
int irq = -1;
pv = fdt_getprop(fdt, nodeoffset, "interrupts", NULL);
if (pv != NULL)
{
irq = fdt32_ld(pv + offset) + irqbase;
}
return irq;
}
int fdt_get_irq_by_path(FAR const void *fdt, int offset,
const char *path, int irqbase)
{
return fdt_get_irq(fdt, fdt_path_offset(fdt, path), offset, irqbase);
}
int fdt_get_parent_address_cells(FAR const void *fdt, int offset)
{
int parentoff;
parentoff = fdt_parent_offset(fdt, offset);
if (parentoff < 0)
{
return parentoff;
}
return fdt_address_cells(fdt, parentoff);
}
int fdt_get_parent_size_cells(FAR const void *fdt, int offset)
{
int parentoff;
parentoff = fdt_parent_offset(fdt, offset);
if (parentoff < 0)
{
return parentoff;
}
return fdt_size_cells(fdt, parentoff);
}
uintptr_t fdt_ld_by_cells(FAR const void *value, int cells)
{
if (cells == 2)
{
return fdt64_ld(value);
}
else
{
return fdt32_ld(value);
}
}
uintptr_t fdt_get_reg_base(FAR const void *fdt, int offset)
{
FAR const void *reg;
uintptr_t addr = 0;
reg = fdt_getprop(fdt, offset, "reg", NULL);
if (reg != NULL)
{
addr = fdt_ld_by_cells(reg, fdt_get_parent_address_cells(fdt, offset));
}
return addr;
}
uintptr_t fdt_get_reg_size(FAR const void *fdt, int offset)
{
FAR const void *reg;
uintptr_t size = 0;
reg = fdt_getprop(fdt, offset, "reg", NULL);
if (reg != NULL)
{
size = fdt_ld_by_cells(reg, fdt_get_parent_size_cells(fdt, offset));
}
return size;
}
uintptr_t fdt_get_reg_base_by_path(FAR const void *fdt, FAR const char *path)
{
return fdt_get_reg_base(fdt, fdt_path_offset(fdt, path));
}

View File

@ -65,6 +65,9 @@ struct fdt_header_s
* Store the pointer to the flattened device tree and verify that it at
* least appears to be valid. This function will not fully parse the FDT.
*
* Input Parameters:
* fdt_base - The pointer to the raw FDT.
*
* Return:
* Return -EINVAL if the fdt header does not have the expected magic value.
* otherwise return OK. If OK is not returned the existing entry for FDT
@ -81,8 +84,158 @@ int fdt_register(FAR const char *fdt_base);
* Return the pointer to a raw FDT. NULL is returned if no FDT has been
* loaded.
*
* Input Parameters:
* None
*
* Return:
* The pointer to the raw FDT.
*
****************************************************************************/
FAR const char *fdt_get(void);
/****************************************************************************
* Name: fdt_get_irq
*
* Description:
* Get the interrupt number of the node
*
* Input Parameters:
* fdt - The pointer to the raw FDT.
* nodeoffset - The offset of the node
* offset - The offset of the property
* irqbase - The base of the interrupt number
*
* Return:
* The interrupt number of the node
*
****************************************************************************/
int fdt_get_irq(FAR const void *fdt, int nodeoffset,
int offset, int irqbase);
/****************************************************************************
* Name: fdt_get_irq_by_path
*
* Description:
* Get the interrupt number of the node
*
* Input Parameters:
* fdt - The pointer to the raw FDT.
* offset - The offset of the node
* path - The path of the node
* irqbase - The base of the interrupt number
*
* Return:
* The interrupt number of the node
*
****************************************************************************/
int fdt_get_irq_by_path(FAR const void *fdt, int offset,
const char *path, int irqbase);
/****************************************************************************
* Name: fdt_get_parent_address_cells
*
* Description:
* Get the parent address of the register space
*
* Input Parameters:
* fdt - The pointer to the raw FDT.
* offset - The offset of the node
*
* Return:
* The parent address of the register space
*
****************************************************************************/
int fdt_get_parent_address_cells(FAR const void *fdt, int offset);
/****************************************************************************
* Name: fdt_get_parent_size_cells
*
* Description:
* Get the parent size of the register space
*
* Input Parameters:
* fdt - The pointer to the raw FDT.
* offset - The offset of the node
*
* Return:
* The parent size of the register space
*
****************************************************************************/
int fdt_get_parent_size_cells(FAR const void *fdt, int offset);
/****************************************************************************
* Name: fdt_ld_by_cells
*
* Description:
* Load a 32-bit or 64-bit value from a buffer, depending on the number
* of address cells.
*
* Input Parameters:
* value - The pointer to the buffer
* cells - The number of address cells
*
* Return:
* The 32-bit or 64-bit value
*
****************************************************************************/
uintptr_t fdt_ld_by_cells(FAR const void *value, int cells);
/****************************************************************************
* Name: fdt_get_reg_base
*
* Description:
* Get the base address of the register space
*
* Input Parameters:
* fdt - The pointer to the raw FDT.
* offset - The offset of the node
*
* Return:
* The base address of the register space
*
****************************************************************************/
uintptr_t fdt_get_reg_base(FAR const void *fdt, int offset);
/****************************************************************************
* Name: fdt_get_reg_size
*
* Description:
* Get the size of the register space
*
* Input Parameters:
* fdt - The pointer to the raw FDT.
* offset - The offset of the node
*
* Return:
* The size of the register space
*
****************************************************************************/
uintptr_t fdt_get_reg_size(FAR const void *fdt, int offset);
/****************************************************************************
* Name: fdt_get_reg_base_by_path
*
* Description:
* Get the base address of the register space
*
* Input Parameters:
* fdt - The pointer to the raw FDT.
* path - The path of the node
*
* Return:
* The base address of the register space
*
****************************************************************************/
uintptr_t fdt_get_reg_base_by_path(FAR const void *fdt,
FAR const char *path);
#endif /* __INCLUDE_NUTTX_FDT_H */