diff --git a/arch/arm/src/goldfish/chip.h b/arch/arm/src/goldfish/chip.h index 7d5592c248..5dee28a9bf 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 c0a58b16f0..ab2ccc38fa 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 790b035087..202c44065b 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/configs/fb/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/fb/defconfig index f3c3a59b0b..2d8d7edd50 100644 --- a/boards/arm64/qemu/qemu-armv8a/configs/fb/defconfig +++ b/boards/arm64/qemu/qemu-armv8a/configs/fb/defconfig @@ -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 diff --git a/boards/arm64/qemu/qemu-armv8a/configs/netnsh/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/netnsh/defconfig index dfeb2d93ea..6636dea2ee 100644 --- a/boards/arm64/qemu/qemu-armv8a/configs/netnsh/defconfig +++ b/boards/arm64/qemu/qemu-armv8a/configs/netnsh/defconfig @@ -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 diff --git a/boards/arm64/qemu/qemu-armv8a/configs/netnsh_hv/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/netnsh_hv/defconfig index 6aeaae9e29..055edb8c77 100644 --- a/boards/arm64/qemu/qemu-armv8a/configs/netnsh_hv/defconfig +++ b/boards/arm64/qemu/qemu-armv8a/configs/netnsh_hv/defconfig @@ -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 diff --git a/boards/arm64/qemu/qemu-armv8a/configs/netnsh_smp/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/netnsh_smp/defconfig index b912b613d5..58bd9851e0 100644 --- a/boards/arm64/qemu/qemu-armv8a/configs/netnsh_smp/defconfig +++ b/boards/arm64/qemu/qemu-armv8a/configs/netnsh_smp/defconfig @@ -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 diff --git a/boards/arm64/qemu/qemu-armv8a/configs/netnsh_smp_hv/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/netnsh_smp_hv/defconfig index 1c9daa343e..7e5d0d812f 100644 --- a/boards/arm64/qemu/qemu-armv8a/configs/netnsh_smp_hv/defconfig +++ b/boards/arm64/qemu/qemu-armv8a/configs/netnsh_smp_hv/defconfig @@ -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 diff --git a/boards/arm64/qemu/qemu-armv8a/configs/nsh/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/nsh/defconfig index aa5334edb3..3ba6aac5a8 100644 --- a/boards/arm64/qemu/qemu-armv8a/configs/nsh/defconfig +++ b/boards/arm64/qemu/qemu-armv8a/configs/nsh/defconfig @@ -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 diff --git a/boards/arm64/qemu/qemu-armv8a/configs/nsh_fiq/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/nsh_fiq/defconfig index 225100b379..df5a8611a4 100644 --- a/boards/arm64/qemu/qemu-armv8a/configs/nsh_fiq/defconfig +++ b/boards/arm64/qemu/qemu-armv8a/configs/nsh_fiq/defconfig @@ -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 diff --git a/boards/arm64/qemu/qemu-armv8a/configs/sotest/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/sotest/defconfig index db830a4acd..dde988e6b4 100644 --- a/boards/arm64/qemu/qemu-armv8a/configs/sotest/defconfig +++ b/boards/arm64/qemu/qemu-armv8a/configs/sotest/defconfig @@ -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 diff --git a/boards/arm64/qemu/qemu-armv8a/src/qemu_bringup.c b/boards/arm64/qemu/qemu-armv8a/src/qemu_bringup.c index 6852ff237f..cc096517d1 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 465401bc61..e9585d2da5 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/Kconfig b/drivers/devicetree/Kconfig index 123dcb5f00..80e0e16cc6 100644 --- a/drivers/devicetree/Kconfig +++ b/drivers/devicetree/Kconfig @@ -6,5 +6,6 @@ menuconfig DEVICE_TREE bool "Device Tree Support" default n + select LIBC_FDT ---help--- Interface for interacting with devicetree. diff --git a/drivers/devicetree/Make.defs b/drivers/devicetree/Make.defs index 956de78a0d..c8af98c8cf 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 f07f23357d..b0202eb894 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 4e432a1394..8a3208b2af 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 */