From c95597522c4fcaf11340bbbc3fa2ffcb7243973d Mon Sep 17 00:00:00 2001 From: ligd Date: Tue, 5 Mar 2024 22:30:59 +0800 Subject: [PATCH] fdt: move fdx_xx extend APIs from boards to drivers Signed-off-by: ligd --- arch/arm/src/goldfish/chip.h | 1 + arch/arm/src/qemu/chip.h | 1 + .../arm/qemu/qemu-armv7a/src/qemu_bringup.c | 89 +--------- .../arm64/qemu/qemu-armv8a/src/qemu_bringup.c | 89 +--------- drivers/devicetree/CMakeLists.txt | 2 + drivers/devicetree/Make.defs | 2 + drivers/devicetree/fdt.c | 117 +++++++++++--- include/nuttx/fdt.h | 153 ++++++++++++++++++ 8 files changed, 261 insertions(+), 193 deletions(-) diff --git a/arch/arm/src/goldfish/chip.h b/arch/arm/src/goldfish/chip.h index 7d5592c2482d5..5dee28a9bf919 100644 --- a/arch/arm/src/goldfish/chip.h +++ b/arch/arm/src/goldfish/chip.h @@ -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 diff --git a/arch/arm/src/qemu/chip.h b/arch/arm/src/qemu/chip.h index c0a58b16f01de..ab2ccc38fa9c1 100644 --- a/arch/arm/src/qemu/chip.h +++ b/arch/arm/src/qemu/chip.h @@ -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 diff --git a/boards/arm/qemu/qemu-armv7a/src/qemu_bringup.c b/boards/arm/qemu/qemu-armv7a/src/qemu_bringup.c index 790b0350876a3..202c44065beaf 100644 --- a/boards/arm/qemu/qemu-armv7a/src/qemu_bringup.c +++ b/boards/arm/qemu/qemu-armv7a/src/qemu_bringup.c @@ -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); diff --git a/boards/arm64/qemu/qemu-armv8a/src/qemu_bringup.c b/boards/arm64/qemu/qemu-armv8a/src/qemu_bringup.c index 6852ff237f550..cc096517d1e6b 100644 --- a/boards/arm64/qemu/qemu-armv8a/src/qemu_bringup.c +++ b/boards/arm64/qemu/qemu-armv8a/src/qemu_bringup.c @@ -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); diff --git a/drivers/devicetree/CMakeLists.txt b/drivers/devicetree/CMakeLists.txt index 465401bc6134e..e9585d2da57c8 100644 --- a/drivers/devicetree/CMakeLists.txt +++ b/drivers/devicetree/CMakeLists.txt @@ -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() diff --git a/drivers/devicetree/Make.defs b/drivers/devicetree/Make.defs index 956de78a0d43f..c8af98c8cf6ba 100644 --- a/drivers/devicetree/Make.defs +++ b/drivers/devicetree/Make.defs @@ -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 diff --git a/drivers/devicetree/fdt.c b/drivers/devicetree/fdt.c index f07f23357df24..b0202eb89473c 100644 --- a/drivers/devicetree/fdt.c +++ b/drivers/devicetree/fdt.c @@ -28,6 +28,7 @@ #include #include #include +#include /**************************************************************************** * 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)); +} + diff --git a/include/nuttx/fdt.h b/include/nuttx/fdt.h index 4e432a1394106..8a3208b2afa9b 100644 --- a/include/nuttx/fdt.h +++ b/include/nuttx/fdt.h @@ -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 */