Skip to content

Commit

Permalink
fdt: move fdx_xx extend APIs from boards to drivers
Browse files Browse the repository at this point in the history
Signed-off-by: ligd <[email protected]>
  • Loading branch information
GUIDINGLI committed Mar 21, 2024
1 parent 306c1c0 commit c955975
Show file tree
Hide file tree
Showing 8 changed files with 261 additions and 193 deletions.
1 change: 1 addition & 0 deletions arch/arm/src/goldfish/chip.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions arch/arm/src/qemu/chip.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
89 changes: 4 additions & 85 deletions boards/arm/qemu/qemu-armv7a/src/qemu_bringup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

/****************************************************************************
Expand All @@ -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);
Expand Down
89 changes: 4 additions & 85 deletions boards/arm64/qemu/qemu-armv8a/src/qemu_bringup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

/****************************************************************************
Expand All @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions drivers/devicetree/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
2 changes: 2 additions & 0 deletions drivers/devicetree/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
117 changes: 94 additions & 23 deletions drivers/devicetree/fdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <assert.h>
#include <nuttx/compiler.h>
#include <nuttx/fdt.h>
#include <libfdt.h>

/****************************************************************************
* Private Data
Expand All @@ -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;
Expand All @@ -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));
}

Loading

0 comments on commit c955975

Please sign in to comment.