mirror of
https://github.com/apache/nuttx.git
synced 2026-05-19 11:53:25 +08:00
qemu: get reg and irq from devicetree node rather than macro
fdt address is at 0x4000000, so it needs to be reserved at ld script. Signed-off-by: liaoao <liaoao@xiaomi.com>
This commit is contained in:
@@ -25,7 +25,7 @@ PHDRS
|
||||
}
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x40000000;
|
||||
. = 0x40101000;
|
||||
.text : {
|
||||
_stext = .; /* Text section */
|
||||
*(.vectors)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/virtio/virtio-mmio.h>
|
||||
#include <nuttx/fdt.h>
|
||||
#include <libfdt.h>
|
||||
|
||||
#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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/virtio/virtio-mmio.h>
|
||||
#include <nuttx/fdt.h>
|
||||
#include <libfdt.h>
|
||||
|
||||
#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);
|
||||
|
||||
Reference in New Issue
Block a user