forked from Mirrors/opensbi
		
	utils: Remove tinyfdt.c
tinyfdt.c was originally added to provide a minimal implementation of fdt parsing. However, we have already included libfdt in OpenSBI for more complicated operations. Remove tinfdt and replace its functiolity using libfdt. Signed-off-by: Atish Patra <atish.patra@wdc.com> Acked-by: Anup Patel <anup.patel@wdc.com>
This commit is contained in:
		@@ -1,67 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2019 Western Digital Corporation or its affiliates.
 | 
			
		||||
 *
 | 
			
		||||
 * Authors:
 | 
			
		||||
 *   Anup Patel <anup.patel@wdc.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __FDT_H__
 | 
			
		||||
#define __FDT_H__
 | 
			
		||||
 | 
			
		||||
#include <sbi/sbi_types.h>
 | 
			
		||||
 | 
			
		||||
struct fdt_node {
 | 
			
		||||
	char *data;
 | 
			
		||||
	const struct fdt_node *parent;
 | 
			
		||||
	const char *name;
 | 
			
		||||
	int depth;
 | 
			
		||||
	int address_cells;
 | 
			
		||||
	int size_cells;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct fdt_prop {
 | 
			
		||||
	const struct fdt_node *node;
 | 
			
		||||
	const char *name;
 | 
			
		||||
	void *value;
 | 
			
		||||
	u32 len;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Reverse byte-order of 32bit number */
 | 
			
		||||
u32 fdt_rev32(u32 v);
 | 
			
		||||
 | 
			
		||||
/* Length of a string */
 | 
			
		||||
ulong fdt_strlen(const char *str);
 | 
			
		||||
 | 
			
		||||
/* Compate two strings */
 | 
			
		||||
int fdt_strcmp(const char *a, const char *b);
 | 
			
		||||
 | 
			
		||||
/* Find index of matching string from a list of strings */
 | 
			
		||||
int fdt_prop_string_index(const struct fdt_prop *prop, const char *str);
 | 
			
		||||
 | 
			
		||||
/* Iterate over each property of matching node */
 | 
			
		||||
int fdt_match_node_prop(void *fdt,
 | 
			
		||||
			int (*match)(const struct fdt_node *node,
 | 
			
		||||
				     const struct fdt_prop *prop, void *priv),
 | 
			
		||||
			void *match_priv,
 | 
			
		||||
			void (*fn)(const struct fdt_node *node,
 | 
			
		||||
				   const struct fdt_prop *prop, void *priv),
 | 
			
		||||
			void *fn_priv);
 | 
			
		||||
 | 
			
		||||
/* Iterate over each property of compatible node */
 | 
			
		||||
int fdt_compat_node_prop(void *fdt, const char *compat,
 | 
			
		||||
			 void (*fn)(const struct fdt_node *node,
 | 
			
		||||
				    const struct fdt_prop *prop, void *priv),
 | 
			
		||||
			 void *fn_priv);
 | 
			
		||||
 | 
			
		||||
/* Iterate over each node and property */
 | 
			
		||||
int fdt_walk(void *fdt,
 | 
			
		||||
	     void (*fn)(const struct fdt_node *node,
 | 
			
		||||
			const struct fdt_prop *prop, void *priv),
 | 
			
		||||
	     void *fn_priv);
 | 
			
		||||
 | 
			
		||||
/* Get size of FDT */
 | 
			
		||||
u32 fdt_size(void *fdt);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -11,8 +11,9 @@
 | 
			
		||||
#include <sbi/riscv_encoding.h>
 | 
			
		||||
#include <sbi/sbi_console.h>
 | 
			
		||||
#include <sbi/sbi_string.h>
 | 
			
		||||
#include <sbi_utils/tinyfdt.h>
 | 
			
		||||
#include <sbi_utils/irqchip/plic.h>
 | 
			
		||||
#include <libfdt.h>
 | 
			
		||||
#include <fdt.h>
 | 
			
		||||
 | 
			
		||||
#define PLIC_PRIORITY_BASE 0x0
 | 
			
		||||
#define PLIC_PENDING_BASE 0x1000
 | 
			
		||||
@@ -46,34 +47,31 @@ static void plic_set_ie(u32 cntxid, u32 word_index, u32 val)
 | 
			
		||||
	writel(val, plic_ie + word_index * 4);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void plic_fdt_fixup_prop(const struct fdt_node *node,
 | 
			
		||||
				const struct fdt_prop *prop, void *priv)
 | 
			
		||||
void plic_fdt_fixup(void *fdt, const char *compat)
 | 
			
		||||
{
 | 
			
		||||
	u32 *cells;
 | 
			
		||||
	u32 i, cells_count;
 | 
			
		||||
	int i, cells_count;
 | 
			
		||||
	u32 plic_off;
 | 
			
		||||
 | 
			
		||||
	if (!prop)
 | 
			
		||||
		return;
 | 
			
		||||
	if (sbi_strcmp(prop->name, "interrupts-extended"))
 | 
			
		||||
	plic_off = fdt_node_offset_by_compatible(fdt, 0, compat);
 | 
			
		||||
	if (plic_off < 0)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	cells	    = prop->value;
 | 
			
		||||
	cells_count = prop->len / sizeof(u32);
 | 
			
		||||
	cells = (u32 *)fdt_getprop(fdt, plic_off,
 | 
			
		||||
				   "interrupts-extended", &cells_count);
 | 
			
		||||
	if (!cells)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	cells_count = cells_count / sizeof(u32);
 | 
			
		||||
	if (!cells_count)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < (cells_count / 2); i++) {
 | 
			
		||||
		if (fdt_rev32(cells[2 * i + 1]) == IRQ_M_EXT)
 | 
			
		||||
			cells[2 * i + 1] = fdt_rev32(0xffffffff);
 | 
			
		||||
		if (fdt32_to_cpu(cells[2 * i + 1]) == IRQ_M_EXT)
 | 
			
		||||
			cells[2 * i + 1] = fdt32_to_cpu(0xffffffff);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void plic_fdt_fixup(void *fdt, const char *compat)
 | 
			
		||||
{
 | 
			
		||||
	fdt_compat_node_prop(fdt, compat, plic_fdt_fixup_prop, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int plic_warm_irqchip_init(u32 target_hart, int m_cntx_id, int s_cntx_id)
 | 
			
		||||
{
 | 
			
		||||
	size_t i, ie_words = plic_num_sources / 32 + 1;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +0,0 @@
 | 
			
		||||
#
 | 
			
		||||
# SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
#
 | 
			
		||||
# Copyright (c) 2019 Western Digital Corporation or its affiliates.
 | 
			
		||||
#
 | 
			
		||||
# Authors:
 | 
			
		||||
#   Anup Patel <anup.patel@wdc.com>
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
libsbiutils-objs-y += tinyfdt.o
 | 
			
		||||
@@ -1,280 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2019 Western Digital Corporation or its affiliates.
 | 
			
		||||
 *
 | 
			
		||||
 * Authors:
 | 
			
		||||
 *   Anup Patel <anup.patel@wdc.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sbi/sbi_string.h>
 | 
			
		||||
#include <sbi_utils/tinyfdt.h>
 | 
			
		||||
 | 
			
		||||
#define FDT_MAGIC 0xd00dfeed
 | 
			
		||||
#define FDT_VERSION 17
 | 
			
		||||
 | 
			
		||||
struct fdt_header {
 | 
			
		||||
	u32 magic;
 | 
			
		||||
	u32 totalsize;
 | 
			
		||||
	u32 off_dt_struct;
 | 
			
		||||
	u32 off_dt_strings;
 | 
			
		||||
	u32 off_mem_rsvmap;
 | 
			
		||||
	u32 version;
 | 
			
		||||
	u32 last_comp_version; /* <= 17 */
 | 
			
		||||
	u32 boot_cpuid_phys;
 | 
			
		||||
	u32 size_dt_strings;
 | 
			
		||||
	u32 size_dt_struct;
 | 
			
		||||
} __attribute__((packed));
 | 
			
		||||
 | 
			
		||||
#define FDT_BEGIN_NODE 1
 | 
			
		||||
#define FDT_END_NODE 2
 | 
			
		||||
#define FDT_PROP 3
 | 
			
		||||
#define FDT_NOP 4
 | 
			
		||||
#define FDT_END 9
 | 
			
		||||
 | 
			
		||||
u32 fdt_rev32(u32 v)
 | 
			
		||||
{
 | 
			
		||||
	return ((v & 0x000000FF) << 24) | ((v & 0x0000FF00) << 8) |
 | 
			
		||||
	       ((v & 0x00FF0000) >> 8) | ((v & 0xFF000000) >> 24);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fdt_prop_string_index(const struct fdt_prop *prop, const char *str)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	ulong l = 0;
 | 
			
		||||
	const char *p, *end;
 | 
			
		||||
 | 
			
		||||
	p   = prop->value;
 | 
			
		||||
	end = p + prop->len;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; p < end; i++, p += l) {
 | 
			
		||||
		l = sbi_strlen(p) + 1;
 | 
			
		||||
		if (p + l > end)
 | 
			
		||||
			return -1;
 | 
			
		||||
		if (sbi_strcmp(str, p) == 0)
 | 
			
		||||
			return i; /* Found it; return index */
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct recursive_iter_info {
 | 
			
		||||
	void (*fn)(const struct fdt_node *node, const struct fdt_prop *prop,
 | 
			
		||||
		   void *priv);
 | 
			
		||||
	void *fn_priv;
 | 
			
		||||
	const char *str;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define DATA32(ptr) fdt_rev32(*((u32 *)ptr))
 | 
			
		||||
 | 
			
		||||
static void recursive_iter(char **data, struct recursive_iter_info *info,
 | 
			
		||||
			   const struct fdt_node *parent)
 | 
			
		||||
{
 | 
			
		||||
	struct fdt_node node;
 | 
			
		||||
	struct fdt_prop prop;
 | 
			
		||||
 | 
			
		||||
	if (DATA32(*data) != FDT_BEGIN_NODE)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	node.data = *data;
 | 
			
		||||
 | 
			
		||||
	(*data) += sizeof(u32);
 | 
			
		||||
 | 
			
		||||
	node.parent = parent;
 | 
			
		||||
	node.name   = *data;
 | 
			
		||||
 | 
			
		||||
	*data += sbi_strlen(*data) + 1;
 | 
			
		||||
	while ((ulong)(*data) % sizeof(u32) != 0)
 | 
			
		||||
		(*data)++;
 | 
			
		||||
 | 
			
		||||
	node.depth = (parent) ? (parent->depth + 1) : 1;
 | 
			
		||||
 | 
			
		||||
	/* Default cell counts, as per the FDT spec */
 | 
			
		||||
	node.address_cells = 2;
 | 
			
		||||
	node.size_cells	   = 1;
 | 
			
		||||
 | 
			
		||||
	info->fn(&node, NULL, info->fn_priv);
 | 
			
		||||
 | 
			
		||||
	while (DATA32(*data) != FDT_END_NODE) {
 | 
			
		||||
		switch (DATA32(*data)) {
 | 
			
		||||
		case FDT_PROP:
 | 
			
		||||
			prop.node = &node;
 | 
			
		||||
			*data += sizeof(u32);
 | 
			
		||||
			prop.len = DATA32(*data);
 | 
			
		||||
			*data += sizeof(u32);
 | 
			
		||||
			prop.name = &info->str[DATA32(*data)];
 | 
			
		||||
			*data += sizeof(u32);
 | 
			
		||||
			prop.value = *data;
 | 
			
		||||
			*data += prop.len;
 | 
			
		||||
			while ((ulong)(*data) % sizeof(u32) != 0)
 | 
			
		||||
				(*data)++;
 | 
			
		||||
			info->fn(&node, &prop, info->fn_priv);
 | 
			
		||||
			break;
 | 
			
		||||
		case FDT_NOP:
 | 
			
		||||
			*data += sizeof(u32);
 | 
			
		||||
			break;
 | 
			
		||||
		case FDT_BEGIN_NODE:
 | 
			
		||||
			recursive_iter(data, info, &node);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			return;
 | 
			
		||||
		};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*data += sizeof(u32);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct match_iter_info {
 | 
			
		||||
	int (*match)(const struct fdt_node *node, const struct fdt_prop *prop,
 | 
			
		||||
		     void *priv);
 | 
			
		||||
	void *match_priv;
 | 
			
		||||
	void (*fn)(const struct fdt_node *node, const struct fdt_prop *prop,
 | 
			
		||||
		   void *priv);
 | 
			
		||||
	void *fn_priv;
 | 
			
		||||
	const char *str;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void match_iter(const struct fdt_node *node, const struct fdt_prop *prop,
 | 
			
		||||
		       void *priv)
 | 
			
		||||
{
 | 
			
		||||
	char *data;
 | 
			
		||||
	struct match_iter_info *minfo = priv;
 | 
			
		||||
	struct fdt_prop nprop;
 | 
			
		||||
 | 
			
		||||
	/* Do nothing if node+prop dont match */
 | 
			
		||||
	if (!minfo->match(node, prop, minfo->match_priv))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	/* Call function for node */
 | 
			
		||||
	if (minfo->fn)
 | 
			
		||||
		minfo->fn(node, NULL, minfo->fn_priv);
 | 
			
		||||
 | 
			
		||||
	/* Convert node to character stream */
 | 
			
		||||
	data = node->data;
 | 
			
		||||
	data += sizeof(u32);
 | 
			
		||||
 | 
			
		||||
	/* Skip node name */
 | 
			
		||||
	data += sbi_strlen(data) + 1;
 | 
			
		||||
	while ((ulong)(data) % sizeof(u32) != 0)
 | 
			
		||||
		data++;
 | 
			
		||||
 | 
			
		||||
	/* Find node property and its value */
 | 
			
		||||
	while (DATA32(data) == FDT_PROP) {
 | 
			
		||||
		nprop.node = node;
 | 
			
		||||
		data += sizeof(u32);
 | 
			
		||||
		nprop.len = DATA32(data);
 | 
			
		||||
		data += sizeof(u32);
 | 
			
		||||
		nprop.name = &minfo->str[DATA32(data)];
 | 
			
		||||
		data += sizeof(u32);
 | 
			
		||||
		nprop.value = data;
 | 
			
		||||
		data += nprop.len;
 | 
			
		||||
		while ((ulong)(data) % sizeof(u32) != 0)
 | 
			
		||||
			(data)++;
 | 
			
		||||
		/* Call function for every property */
 | 
			
		||||
		if (minfo->fn)
 | 
			
		||||
			minfo->fn(node, &nprop, minfo->fn_priv);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fdt_match_node_prop(void *fdt,
 | 
			
		||||
			int (*match)(const struct fdt_node *node,
 | 
			
		||||
				     const struct fdt_prop *prop, void *priv),
 | 
			
		||||
			void *match_priv,
 | 
			
		||||
			void (*fn)(const struct fdt_node *node,
 | 
			
		||||
				   const struct fdt_prop *prop, void *priv),
 | 
			
		||||
			void *fn_priv)
 | 
			
		||||
{
 | 
			
		||||
	char *data;
 | 
			
		||||
	u32 string_offset, data_offset;
 | 
			
		||||
	struct fdt_header *header;
 | 
			
		||||
	struct match_iter_info minfo;
 | 
			
		||||
	struct recursive_iter_info rinfo;
 | 
			
		||||
 | 
			
		||||
	if (!fdt || !match)
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	header = fdt;
 | 
			
		||||
	if (fdt_rev32(header->magic) != FDT_MAGIC ||
 | 
			
		||||
	    fdt_rev32(header->last_comp_version) > FDT_VERSION)
 | 
			
		||||
		return -1;
 | 
			
		||||
	string_offset = fdt_rev32(header->off_dt_strings);
 | 
			
		||||
	data_offset   = fdt_rev32(header->off_dt_struct);
 | 
			
		||||
 | 
			
		||||
	minfo.match	 = match;
 | 
			
		||||
	minfo.match_priv = match_priv;
 | 
			
		||||
	minfo.fn	 = fn;
 | 
			
		||||
	minfo.fn_priv	 = fn_priv;
 | 
			
		||||
	minfo.str	 = (const char *)(fdt + string_offset);
 | 
			
		||||
 | 
			
		||||
	rinfo.fn      = match_iter;
 | 
			
		||||
	rinfo.fn_priv = &minfo;
 | 
			
		||||
	rinfo.str     = minfo.str;
 | 
			
		||||
 | 
			
		||||
	data = (char *)(fdt + data_offset);
 | 
			
		||||
	recursive_iter(&data, &rinfo, NULL);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct match_compat_info {
 | 
			
		||||
	const char *compat;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int match_compat(const struct fdt_node *node,
 | 
			
		||||
			const struct fdt_prop *prop, void *priv)
 | 
			
		||||
{
 | 
			
		||||
	struct match_compat_info *cinfo = priv;
 | 
			
		||||
 | 
			
		||||
	if (!prop)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (sbi_strcmp(prop->name, "compatible"))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (fdt_prop_string_index(prop, cinfo->compat) < 0)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fdt_compat_node_prop(void *fdt, const char *compat,
 | 
			
		||||
			 void (*fn)(const struct fdt_node *node,
 | 
			
		||||
				    const struct fdt_prop *prop, void *priv),
 | 
			
		||||
			 void *fn_priv)
 | 
			
		||||
{
 | 
			
		||||
	struct match_compat_info cinfo = { .compat = compat };
 | 
			
		||||
 | 
			
		||||
	return fdt_match_node_prop(fdt, match_compat, &cinfo, fn, fn_priv);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int match_walk(const struct fdt_node *node, const struct fdt_prop *prop,
 | 
			
		||||
		      void *priv)
 | 
			
		||||
{
 | 
			
		||||
	if (!prop)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int fdt_walk(void *fdt,
 | 
			
		||||
	     void (*fn)(const struct fdt_node *node,
 | 
			
		||||
			const struct fdt_prop *prop, void *priv),
 | 
			
		||||
	     void *fn_priv)
 | 
			
		||||
{
 | 
			
		||||
	return fdt_match_node_prop(fdt, match_walk, NULL, fn, fn_priv);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u32 fdt_size(void *fdt)
 | 
			
		||||
{
 | 
			
		||||
	struct fdt_header *header;
 | 
			
		||||
 | 
			
		||||
	if (!fdt)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	header = fdt;
 | 
			
		||||
	if (fdt_rev32(header->magic) != FDT_MAGIC ||
 | 
			
		||||
	    fdt_rev32(header->last_comp_version) > FDT_VERSION)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	return fdt_rev32(header->totalsize);
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user