diff --git a/boards/arm/qemu/qemu-armv7a/scripts/dramboot.ld b/boards/arm/qemu/qemu-armv7a/scripts/dramboot.ld index e1ccbbe8689..38db4219382 100644 --- a/boards/arm/qemu/qemu-armv7a/scripts/dramboot.ld +++ b/boards/arm/qemu/qemu-armv7a/scripts/dramboot.ld @@ -25,7 +25,7 @@ PHDRS } SECTIONS { - . = 0x40000000; + . = 0x40101000; .text : { _stext = .; /* Text section */ *(.vectors) diff --git a/boards/arm/qemu/qemu-armv7a/src/Makefile b/boards/arm/qemu/qemu-armv7a/src/Makefile index 4de74ccb43b..d14fc7d6eee 100644 --- a/boards/arm/qemu/qemu-armv7a/src/Makefile +++ b/boards/arm/qemu/qemu-armv7a/src/Makefile @@ -26,4 +26,6 @@ ifeq ($(CONFIG_BOARDCTL),y) CSRCS += qemu_appinit.c endif +CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)fdt$(DELIM)dtc$(DELIM)libfdt + include $(TOPDIR)/boards/Board.mk diff --git a/boards/arm/qemu/qemu-armv7a/src/qemu_bringup.c b/boards/arm/qemu/qemu-armv7a/src/qemu_bringup.c index ff827658f25..aafaaf06ec9 100644 --- a/boards/arm/qemu/qemu-armv7a/src/qemu_bringup.c +++ b/boards/arm/qemu/qemu-armv7a/src/qemu_bringup.c @@ -29,6 +29,8 @@ #include #include +#include +#include #include "qemu-armv7a.h" @@ -36,32 +38,145 @@ * Pre-processor Definitions ****************************************************************************/ -#define QEMU_VIRTIO_MMIO_BASE 0x0a000000 -#define QEMU_VIRTIO_MMIO_REGSIZE 0x200 -#define QEMU_VIRTIO_MMIO_IRQ 48 -#define QEMU_VIRTIO_MMIO_NUM 32 +#define QEMU_SPI_IRQ_BASE 32 /**************************************************************************** * Private Functions ****************************************************************************/ +#if defined(CONFIG_LIBC_FDT) && defined(CONFIG_DEVICE_TREE) + /**************************************************************************** - * Name: qemu_virtio_register_mmio_devices + * Name: fdt_get_irq + * + * Description: + * Only can be use when the corresponding node's parent interrupt + * controller is intc node. + * ****************************************************************************/ -#ifdef CONFIG_DRIVERS_VIRTIO_MMIO -static void qemu_virtio_register_mmio_devices(void) +static int unused_code +fdt_get_irq(const void *fdt, int offset) { - uintptr_t virtio = (uintptr_t)QEMU_VIRTIO_MMIO_BASE; - size_t size = QEMU_VIRTIO_MMIO_REGSIZE; - int irq = QEMU_VIRTIO_MMIO_IRQ; - int i; + const fdt32_t *pv; + int irq = -ENOENT; - for (i = 0; i < QEMU_VIRTIO_MMIO_NUM; i++) + pv = fdt_getprop(fdt, offset, "interrupts", NULL); + if (pv != NULL) { - virtio_register_mmio_device((void *)(virtio + size * i), irq + i); + 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 + +/**************************************************************************** + * Name: register_virtio_devices_from_fdt + ****************************************************************************/ + +static void register_virtio_devices_from_fdt(const void *fdt) +{ + uintptr_t addr; + int offset = -1; + int irqnum; + + for (; ; ) + { + offset = fdt_node_offset_by_compatible(fdt, offset, "virtio,mmio"); + if (offset == -FDT_ERR_NOTFOUND) + { + break; + } + + addr = fdt_get_reg_base(fdt, offset); + irqnum = fdt_get_irq(fdt, offset); + if (addr > 0 && irqnum >= 0) + { + virtio_register_mmio_device((FAR void *)addr, irqnum); + } } } + +#endif + +/**************************************************************************** + * Name: register_devices_from_fdt + ****************************************************************************/ + +static void register_devices_from_fdt(void) +{ + const void *fdt = fdt_get(); + + if (fdt == NULL) + { + return; + } + +#ifdef CONFIG_DRIVERS_VIRTIO_MMIO + register_virtio_devices_from_fdt(fdt); +#endif +} + #endif /**************************************************************************** @@ -90,8 +205,8 @@ int qemu_bringup(void) } #endif -#ifdef CONFIG_DRIVERS_VIRTIO_MMIO - qemu_virtio_register_mmio_devices(); +#if defined(CONFIG_LIBC_FDT) && defined(CONFIG_DEVICE_TREE) + register_devices_from_fdt(); #endif UNUSED(ret); diff --git a/boards/arm64/qemu/qemu-armv8a/configs/fb/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/fb/defconfig index 790520f24cb..d3445247f47 100644 --- a/boards/arm64/qemu/qemu-armv8a/configs/fb/defconfig +++ b/boards/arm64/qemu/qemu-armv8a/configs/fb/defconfig @@ -20,6 +20,7 @@ CONFIG_BUILTIN=y CONFIG_DEBUG_FULLOPT=y CONFIG_DEBUG_SYMBOLS=y CONFIG_DEFAULT_TASK_STACKSIZE=8192 +CONFIG_DEVICE_TREE=y CONFIG_DEV_ZERO=y CONFIG_DRIVERS_VIDEO=y CONFIG_DRIVERS_VIRTIO=y @@ -44,6 +45,7 @@ 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 @@ -67,6 +69,7 @@ CONFIG_START_MONTH=11 CONFIG_START_YEAR=2022 CONFIG_SYMTAB_ORDEREDBYNAME=y CONFIG_SYSLOG_TIMESTAMP=y +CONFIG_SYSTEM_FDTDUMP=y CONFIG_SYSTEM_NSH=y CONFIG_SYSTEM_SYSTEM=y CONFIG_SYSTEM_TIME64=y diff --git a/boards/arm64/qemu/qemu-armv8a/configs/netnsh/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/netnsh/defconfig index 799034a8151..1c9e6086c8a 100644 --- a/boards/arm64/qemu/qemu-armv8a/configs/netnsh/defconfig +++ b/boards/arm64/qemu/qemu-armv8a/configs/netnsh/defconfig @@ -20,6 +20,7 @@ CONFIG_CODECS_HASH_MD5=y CONFIG_DEBUG_FULLOPT=y CONFIG_DEBUG_SYMBOLS=y CONFIG_DEFAULT_TASK_STACKSIZE=8192 +CONFIG_DEVICE_TREE=y CONFIG_DEV_ZERO=y CONFIG_DRIVERS_VIRTIO=y CONFIG_DRIVERS_VIRTIO_BLK=y @@ -42,6 +43,7 @@ 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 @@ -89,6 +91,7 @@ CONFIG_START_YEAR=2022 CONFIG_SYMTAB_ORDEREDBYNAME=y CONFIG_SYSLOG_TIMESTAMP=y CONFIG_SYSTEM_DHCPC_RENEW=y +CONFIG_SYSTEM_FDTDUMP=y CONFIG_SYSTEM_NSH=y CONFIG_SYSTEM_PING=y CONFIG_SYSTEM_SYSTEM=y diff --git a/boards/arm64/qemu/qemu-armv8a/configs/netnsh_hv/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/netnsh_hv/defconfig index 3f8787235a0..5fc96d3c902 100644 --- a/boards/arm64/qemu/qemu-armv8a/configs/netnsh_hv/defconfig +++ b/boards/arm64/qemu/qemu-armv8a/configs/netnsh_hv/defconfig @@ -21,6 +21,7 @@ CONFIG_CODECS_HASH_MD5=y CONFIG_DEBUG_FULLOPT=y CONFIG_DEBUG_SYMBOLS=y CONFIG_DEFAULT_TASK_STACKSIZE=8192 +CONFIG_DEVICE_TREE=y CONFIG_DEV_ZERO=y CONFIG_DRIVERS_VIRTIO=y CONFIG_DRIVERS_VIRTIO_BLK=y @@ -43,6 +44,7 @@ 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 @@ -90,6 +92,7 @@ CONFIG_START_YEAR=2022 CONFIG_SYMTAB_ORDEREDBYNAME=y CONFIG_SYSLOG_TIMESTAMP=y CONFIG_SYSTEM_DHCPC_RENEW=y +CONFIG_SYSTEM_FDTDUMP=y CONFIG_SYSTEM_NSH=y CONFIG_SYSTEM_PING=y CONFIG_SYSTEM_SYSTEM=y diff --git a/boards/arm64/qemu/qemu-armv8a/configs/netnsh_smp/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/netnsh_smp/defconfig index 607aeca6249..5a41f6d6af7 100644 --- a/boards/arm64/qemu/qemu-armv8a/configs/netnsh_smp/defconfig +++ b/boards/arm64/qemu/qemu-armv8a/configs/netnsh_smp/defconfig @@ -19,6 +19,7 @@ CONFIG_CODECS_HASH_MD5=y CONFIG_DEBUG_FULLOPT=y CONFIG_DEBUG_SYMBOLS=y CONFIG_DEFAULT_TASK_STACKSIZE=8192 +CONFIG_DEVICE_TREE=y CONFIG_DEV_ZERO=y CONFIG_DRIVERS_VIRTIO=y CONFIG_DRIVERS_VIRTIO_BLK=y @@ -40,6 +41,7 @@ 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 @@ -88,6 +90,7 @@ CONFIG_START_YEAR=2022 CONFIG_SYMTAB_ORDEREDBYNAME=y CONFIG_SYSLOG_TIMESTAMP=y CONFIG_SYSTEM_DHCPC_RENEW=y +CONFIG_SYSTEM_FDTDUMP=y CONFIG_SYSTEM_NSH=y CONFIG_SYSTEM_PING=y CONFIG_SYSTEM_SYSTEM=y 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 bbda07e5c65..bf1c33f148f 100644 --- a/boards/arm64/qemu/qemu-armv8a/configs/netnsh_smp_hv/defconfig +++ b/boards/arm64/qemu/qemu-armv8a/configs/netnsh_smp_hv/defconfig @@ -21,6 +21,7 @@ CONFIG_CODECS_HASH_MD5=y CONFIG_DEBUG_FULLOPT=y CONFIG_DEBUG_SYMBOLS=y CONFIG_DEFAULT_TASK_STACKSIZE=8192 +CONFIG_DEVICE_TREE=y CONFIG_DEV_ZERO=y CONFIG_DRIVERS_VIRTIO=y CONFIG_DRIVERS_VIRTIO_BLK=y @@ -41,6 +42,7 @@ 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 @@ -89,6 +91,7 @@ CONFIG_START_YEAR=2022 CONFIG_SYMTAB_ORDEREDBYNAME=y CONFIG_SYSLOG_TIMESTAMP=y CONFIG_SYSTEM_DHCPC_RENEW=y +CONFIG_SYSTEM_FDTDUMP=y CONFIG_SYSTEM_NSH=y CONFIG_SYSTEM_PING=y CONFIG_SYSTEM_SYSTEM=y diff --git a/boards/arm64/qemu/qemu-armv8a/src/Makefile b/boards/arm64/qemu/qemu-armv8a/src/Makefile index 4fb236eb412..5a380d3a3e1 100644 --- a/boards/arm64/qemu/qemu-armv8a/src/Makefile +++ b/boards/arm64/qemu/qemu-armv8a/src/Makefile @@ -26,4 +26,6 @@ ifeq ($(CONFIG_BOARDCTL),y) CSRCS += qemu_appinit.c endif +CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)fdt$(DELIM)dtc$(DELIM)libfdt + include $(TOPDIR)/boards/Board.mk diff --git a/boards/arm64/qemu/qemu-armv8a/src/qemu_bringup.c b/boards/arm64/qemu/qemu-armv8a/src/qemu_bringup.c index 38361957918..ad15fd82893 100644 --- a/boards/arm64/qemu/qemu-armv8a/src/qemu_bringup.c +++ b/boards/arm64/qemu/qemu-armv8a/src/qemu_bringup.c @@ -29,6 +29,8 @@ #include #include +#include +#include #include "qemu-armv8a.h" @@ -36,32 +38,145 @@ * Pre-processor Definitions ****************************************************************************/ -#define QEMU_VIRTIO_MMIO_BASE 0x0a000000 -#define QEMU_VIRTIO_MMIO_REGSIZE 0x200 -#define QEMU_VIRTIO_MMIO_IRQ 48 -#define QEMU_VIRTIO_MMIO_NUM 32 +#define QEMU_SPI_IRQ_BASE 32 /**************************************************************************** * Private Functions ****************************************************************************/ +#if defined(CONFIG_LIBC_FDT) && defined(CONFIG_DEVICE_TREE) + /**************************************************************************** - * Name: qemu_virtio_register_mmio_devices + * Name: fdt_get_irq + * + * Description: + * Only can be use when the corresponding node's parent interrupt + * controller is intc node. + * ****************************************************************************/ -#ifdef CONFIG_DRIVERS_VIRTIO_MMIO -static void qemu_virtio_register_mmio_devices(void) +static int unused_code +fdt_get_irq(const void *fdt, int offset) { - uintptr_t virtio = (uintptr_t)QEMU_VIRTIO_MMIO_BASE; - size_t size = QEMU_VIRTIO_MMIO_REGSIZE; - int irq = QEMU_VIRTIO_MMIO_IRQ; - int i; + const fdt32_t *pv; + int irq = -ENOENT; - for (i = 0; i < QEMU_VIRTIO_MMIO_NUM; i++) + pv = fdt_getprop(fdt, offset, "interrupts", NULL); + if (pv != NULL) { - virtio_register_mmio_device((FAR void *)(virtio + size * i), irq + i); + 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 + +/**************************************************************************** + * Name: register_virtio_devices_from_fdt + ****************************************************************************/ + +static void register_virtio_devices_from_fdt(const void *fdt) +{ + uintptr_t addr; + int offset = -1; + int irqnum; + + for (; ; ) + { + offset = fdt_node_offset_by_compatible(fdt, offset, "virtio,mmio"); + if (offset == -FDT_ERR_NOTFOUND) + { + break; + } + + addr = fdt_get_reg_base(fdt, offset); + irqnum = fdt_get_irq(fdt, offset); + if (addr > 0 && irqnum >= 0) + { + virtio_register_mmio_device((FAR void *)addr, irqnum); + } } } + +#endif + +/**************************************************************************** + * Name: register_devices_from_fdt + ****************************************************************************/ + +static void register_devices_from_fdt(void) +{ + const void *fdt = fdt_get(); + + if (fdt == NULL) + { + return; + } + +#ifdef CONFIG_DRIVERS_VIRTIO_MMIO + register_virtio_devices_from_fdt(fdt); +#endif +} + #endif /**************************************************************************** @@ -90,8 +205,8 @@ int qemu_bringup(void) } #endif -#ifdef CONFIG_DRIVERS_VIRTIO_MMIO - qemu_virtio_register_mmio_devices(); +#if defined(CONFIG_LIBC_FDT) && defined(CONFIG_DEVICE_TREE) + register_devices_from_fdt(); #endif UNUSED(ret);